[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