Bug 108397 - Missed optimization with [0, 0][-1U,-1U] range arithmetics
Summary: Missed optimization with [0, 0][-1U,-1U] range arithmetics
Status: ASSIGNED
Alias: None
Product: gcc
Classification: Unclassified
Component: tree-optimization (show other bugs)
Version: 13.0
: P3 enhancement
Target Milestone: ---
Assignee: Andrew Pinski
URL:
Keywords: missed-optimization
Depends on: 107131
Blocks: VRP
  Show dependency treegraph
 
Reported: 2023-01-13 16:52 UTC by Jakub Jelinek
Modified: 2023-08-31 19:53 UTC (History)
9 users (show)

See Also:
Host: x86_64-pc-linux-gnu
Target: x86_64-pc-linux-gnu
Build:
Known to work:
Known to fail:
Last reconfirmed: 2023-01-13 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Jakub Jelinek 2023-01-13 16:52:09 UTC
+++ This bug was initially created as a clone of Bug #107131 +++

__attribute__((noipa)) unsigned long long                                                                                                                                            
foo (unsigned char o)                                                                                                                                                                
{                                                                                                                                                                                    
  unsigned long long t1 = -(long long) (o == 0);                                                                                                                                     
  unsigned long long t2 = -(long long) (t1 > 10439075533421201520ULL);                                                                                                               
  unsigned long long t3 = -(long long) (t1 <= t2);                                                                                                                                   
  return t3;                                                                                                                                                                         
}                                                                                                                                                                                    

from comment 8 of that PR could be optimized into return -1ULL.
t1 has range [0,0][-1ULL,-1ULL], t2 is set to 0 if t1 is 0 and to -1ULL if t1 is -1ULL
and thus t2 could be optimized to t2 = t1.  And t1 <= t2 can then trivially fold to
t1 <= t1 aka true.
Comment 1 Andrew Pinski 2023-01-13 19:01:52 UTC
Confirmed.
Comment 2 Andrew Pinski 2023-08-08 21:39:54 UTC
I think the simple missed optimization here is:
```
int f2(int a)
{
 if(a != -1 && a != 0)
   __builtin_unreachable();
  unsigned c = a;
  if(c > 121212)
    return 1;
  return 0;
}
```
This should be optimized to just:
```
int f2_(int a)
{
  return a != 0;
}
```


That is if we have:
```
  # RANGE [irange] unsigned int [0, 0][+INF, +INF]
  a.0_1 = (unsigned int) a_4(D);
  if (a.0_1 > 121212)
```
Since we have two values for a.0_1 we can just compare to one or the other in the above case.

Then that will optimize the original testcase as we can optimize away the nop_convert and then negative and then we get:
t1 <= t1
and that is folded trivially to true.
Comment 3 Andrew Pinski 2023-08-08 21:40:37 UTC
I have seen other bug reports having a similar issue too.
Comment 4 Andrew Pinski 2023-08-08 21:45:09 UTC
Also:
```
int f(int a, int b)
{
        int c = a == b;
        c = -c;
        return c <= -1;
}
```
At `-O2 -fwrapv` is not optimized at the gimple level but is at the RTL level even.
Comment 5 Andrew Pinski 2023-08-08 22:38:02 UTC
I am going to change/fix va-values.cc:test_for_singularity to implement this.

The comment before this function even says:
```
/* We are comparing trees OP0 and OP1 using COND_CODE.  OP0 has
   a known value range VR.

   If there is one and only one value which will satisfy the
   conditional, then return that value.  Else return NULL.
```
Which does make it sound like it should have done that too.
Comment 6 Andrew Pinski 2023-08-09 01:09:57 UTC
I have a patch to fix the testcase in comment #2.

After that patch we have:
```
  _1 = o_10(D) == 0;
  _2 = (long long int) _1;
  _3 = -_2;
  t1_11 = (long long unsigned int) _3;
  _4 = t1_11 == 18446744073709551615;
  _5 = (long long int) _4;
  _6 = -_5;
  t2_12 = (long long unsigned int) _6;
  _7 = t1_11 <= t2_12;
  _8 = (long long int) _7;
  _9 = -_8;
  t3_13 = (long long unsigned int) _9;
```

Forwprop will not change _4 to _1 though. because t1_11 is used twice.
Comment 7 Andrew Pinski 2023-08-31 19:53:57 UTC
(In reply to Andrew Pinski from comment #6)
> Forwprop will not change _4 to _1 though. because t1_11 is used twice.

But combined with PR 107137, we are able to optimize it just fine.