[Bug tree-optimization/53986] missing vrp on bit-mask test, LSHIFT_EXPR not handled
vries at gcc dot gnu.org
gcc-bugzilla@gcc.gnu.org
Sun Aug 5 09:36:00 GMT 2012
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53986
vries at gcc dot gnu.org changed:
What |Removed |Added
----------------------------------------------------------------------------
Keywords| |wrong-code
CC| |steven at gcc dot gnu.org
--- Comment #3 from vries at gcc dot gnu.org 2012-08-05 09:36:43 UTC ---
(In reply to comment #1)
> VRP does not handle LSHIFT like
>
> D.1734_10 = (long unsigned int) D.1731_7;
> csui.1_9 = 1 << D.1734_10;
>
> it only handles LSHIFTs with a constant shift amount:
>
That's true, but AFAIU that's not the reason tree-vrp doesn't optimize this
example.
The example is optimized with -fwrapv:
...
Found new range for s_12: ~[-16, -9]
Visiting statement:
D.1731_6 = sD.1710_12 + 16;
Meeting
[-2147483632, -1]
and
~[-2147483632, 7]
to
~[0, 7]
Found new range for D.1731_6: ~[0, 7]
Visiting statement:
D.1732_7 = (unsigned int) D.1731_6;
Meeting
[2147483648, +INF]
and
[8, 2147483647]
to
[8, +INF]
Found new range for D.1732_7: [8, +INF]
Visiting statement:
if (D.1732_7 > 7)
Visiting conditional with predicate: if (D.1732_7 > 7)
With known ranges
D.1732_7: [8, +INF]
Predicate evaluates to: 1
...
but not with -fno-wrapv:
...
Found new range for s_12: ~[-16, -9]
Visiting statement:
D.1731_6 = sD.1710_12 + 16;
Meeting
[-2147483632, -1]
and
[8, +INF(OVF)]
to
[-2147483632, +INF(OVF)]
Found new range for D.1731_6: [-2147483632, +INF(OVF)]
Visiting statement:
D.1732_7 = (unsigned int) D.1731_6;
Found new range for D.1732_7: [0, +INF]
Visiting statement:
if (D.1732_7 > 7)
Visiting conditional with predicate: if (D.1732_7 > 7)
With known ranges
D.1732_7: [0, +INF]
Predicate evaluates to: DON'T KNOW
...
AFAIU, introducing the + 16 in emit_case_bit_tests on a signed type introduces
potential signed overflow, which is undefined with -fno-wrapv, so this is a
correctness bug as well:
...
int D.1730;
unsigned int D.1731;
<bb 3>:
D.1730_6 = s_1(D) + 16;
D.1731_7 = (unsigned int) D.1730_6;
...
I think we should cast to unsigned first, then add. That will solve the
correctness bug, and probably will allow tree-vrp to handle this even with
-fno-wrapv.
More information about the Gcc-bugs
mailing list