[InstCombine] foldShiftIntoShiftInAnotherHandOfAndInICmp(): fix miscompile (PR44802)
authorRoman Lebedev <lebedev.ri@gmail.com>
Tue, 25 Feb 2020 14:24:27 +0000 (17:24 +0300)
committerRoman Lebedev <lebedev.ri@gmail.com>
Tue, 25 Feb 2020 15:23:58 +0000 (18:23 +0300)
commit2855c8fed9326ec44526767f1596a4fe4e55dc70
tree4d7e876b9a5d8e4ccba09f221bb31a111768be25
parent6f807ca00d951d3e74f7ea4fe1daa8e3560f4c0d
[InstCombine] foldShiftIntoShiftInAnotherHandOfAndInICmp(): fix miscompile (PR44802)

Much like with reassociateShiftAmtsOfTwoSameDirectionShifts(),
as input, we have the following pattern:
  icmp eq/ne (and ((x shift Q), (y oppositeshift K))), 0
We want to rewrite that as:
  icmp eq/ne (and (x shift (Q+K)), y), 0  iff (Q+K) u< bitwidth(x)

While we know that originally (Q+K) would not overflow
(because  2 * (N-1) u<= iN -1), we may have looked past extensions of
shift amounts. so it may now overflow in smaller bitwidth.

To ensure that does not happen, we need to ensure that the total maximal
shift amount is still representable in that smaller bitwidth.
If the overflow would happen, (Q+K) u< bitwidth(x) check would be bogus.

https://bugs.llvm.org/show_bug.cgi?id=44802
llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
llvm/test/Transforms/InstCombine/shift-amount-reassociation-in-bittest.ll