Bug 114539 - `__builtin_add_overflow(unsigned, b, &r); r < b` where b is a CST is not optimized to using the overflow
Summary: `__builtin_add_overflow(unsigned, b, &r); r < b` where b is a CST is not opt...
Status: ASSIGNED
Alias: None
Product: gcc
Classification: Unclassified
Component: tree-optimization (show other bugs)
Version: 14.0
: P3 enhancement
Target Milestone: ---
Assignee: Andrew Pinski
URL:
Keywords: missed-optimization
Depends on:
Blocks:
 
Reported: 2024-04-01 02:45 UTC by Andrew Pinski
Modified: 2024-04-01 15:18 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2024-04-01 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Andrew Pinski 2024-04-01 02:45:49 UTC
Take:
```
bool f(unsigned v, unsigned tt)
{
 unsigned r;
 unsigned t = __builtin_add_overflow(v, tt, &r);
 return (r < tt) == t;
}


bool f1(unsigned v, unsigned tt)
{
 tt = 3;
 unsigned r;
 unsigned t = __builtin_add_overflow(v, tt, &r);
 return (r < tt) == t;
}
```

f is able to be optimized to 1 but f1 is not due to the `r < 3` being Canonical form being `r <= 2` (or in the case of 1, `r == 0`).

I found this while looking into PR 114538 if we change things slightly.
Comment 1 Andrew Pinski 2024-04-01 02:47:47 UTC
This is the current pattern that matches the non-CST case:
```
/* Testing for overflow is unnecessary if we already know the result.  */
/* A - B > A  */
(for cmp (gt le)
     out (ne eq)
 (simplify
  (cmp:c (realpart (IFN_SUB_OVERFLOW@2 @0 @1)) @0)
  (if (TYPE_UNSIGNED (TREE_TYPE (@0))
       && types_match (TREE_TYPE (@0), TREE_TYPE (@1)))
   (out (imagpart @2) { build_zero_cst (TREE_TYPE (@0)); }))))
/* A + B < A  */
(for cmp (lt ge)
     out (ne eq)
 (simplify
  (cmp:c (realpart (IFN_ADD_OVERFLOW:c@2 @0 @1)) @0)
  (if (TYPE_UNSIGNED (TREE_TYPE (@0))
       && types_match (TREE_TYPE (@0), TREE_TYPE (@1)))
   (out (imagpart @2) { build_zero_cst (TREE_TYPE (@0)); }))))
```

Mine for GCC 15.