OSDN Git Service

InstCombine: Don't just copy known bits from the first operand of an srem.
authorBenjamin Kramer <benny.kra@googlemail.com>
Thu, 9 May 2013 16:32:32 +0000 (16:32 +0000)
committerBenjamin Kramer <benny.kra@googlemail.com>
Thu, 9 May 2013 16:32:32 +0000 (16:32 +0000)
That's obviously wrong. Conservatively restrict it to the sign bit, which
matches the original intention of this analysis. Fixes PR15940.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@181518 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
test/Transforms/InstCombine/icmp.ll

index 8add1ea..a7bfe09 100644 (file)
@@ -754,7 +754,7 @@ Value *InstCombiner::SimplifyDemandedUseBits(Value *V, APInt DemandedMask,
       ComputeMaskedBits(I->getOperand(0), LHSKnownZero, LHSKnownOne, Depth+1);
       // If it's known zero, our sign bit is also zero.
       if (LHSKnownZero.isNegative())
-        KnownZero |= LHSKnownZero;
+        KnownZero.setBit(KnownZero.getBitWidth() - 1);
     }
     break;
   case Instruction::URem: {
index c912a57..ed1cd1e 100644 (file)
@@ -707,6 +707,18 @@ define i1 @test69(i32 %c) nounwind uwtable {
   ret i1 %3
 }
 
+; PR15940
+; CHECK: @test70
+; CHECK-NEXT: %A = srem i32 5, %X
+; CHECK-NEXT: %C = icmp ne i32 %A, 2
+; CHECK-NEXT: ret i1 %C
+define i1 @test70(i32 %X) {
+  %A = srem i32 5, %X
+  %B = add i32 %A, 2
+  %C = icmp ne i32 %B, 4
+  ret i1 %C
+}
+
 ; CHECK: @icmp_sext16trunc
 ; CHECK-NEXT: %1 = trunc i32 %x to i16
 ; CHECK-NEXT: %cmp = icmp slt i16 %1, 36