This code is based on basic_string_view::_S_compare, which should probably be improved (just cast if int is big enough, otherwise always return something in {-1,0,1}), but here is the missed optimization: bool f(long long l){ if(l>1000) return false; if(l<-1000) return true; return (int)l<0; } It is equivalent to l<0, but not that easy for the compiler. Without the cast in the last line, reassoc1 manages to get rid of the test l<-1000 and reassoc2 deals with l>1000. But with the cast, we are stuck. The easiest way I can think of is in VRP to notice that l fits in int and simplify (int)l<0 to l<0 (which the reassoc passes can handle later). On the other hand, as with all those narrowing / promotion transformations, it isn't always clear if it is beneficial by itself. If long long is emulated using 2 int-sized registers, (int)l<0 is clearly cheaper than l<0, which only becomes worth it because of the simplifications it allows.
# RANGE [-1000, 1000] _1 = (intD.9) l_3(D); _4 = _1 < 0; It should not be too hard to do this.
I thought simplify_casted_compare in vr-values.cc was supposed to do that but it looks like it is not. Let me try to see how to fix simplify_casted_compare .
This was literally 4 lines which needed to change now. The use of range_of_expr inside simplify_casted_compare just needed to be passed the statement and that fixed it ....
Created attachment 55714 [details] Patch which I am testing
Some failures ... gnat.dg/opt86a.adb: pattern found 1 times FAIL: gnat.dg/opt86a.adb scan-tree-dump-times optimized ">>" 4 +FAIL: gnat.dg/opt86b.adb scan-tree-dump-not optimized "> 13" +FAIL: gnat.dg/opt86c.adb scan-tree-dump-not optimized "> 26" +FAIL: gnat.dg/opt86c.adb scan-tree-dump-not optimized "> 29"
(In reply to Andrew Pinski from comment #5) > Some failures ... > > gnat.dg/opt86a.adb: pattern found 1 times > FAIL: gnat.dg/opt86a.adb scan-tree-dump-times optimized ">>" 4 Ok, this is PR 110965 . I have not looked into the rest yet.