[InstCombine] Fix wrong folding of constant comparisons involving ashr and negative...
authorAndrea Di Biagio <Andrea_DiBiagio@sn.scee.net>
Thu, 9 Oct 2014 12:41:49 +0000 (12:41 +0000)
committerAndrea Di Biagio <Andrea_DiBiagio@sn.scee.net>
Thu, 9 Oct 2014 12:41:49 +0000 (12:41 +0000)
This patch fixes a bug in method InstCombiner::FoldCmpCstShrCst where we
wrongly computed the distance between the highest bits set of two negative
values.

This fixes PR21222.

Differential Revision: http://reviews.llvm.org/D5700

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

lib/Transforms/InstCombine/InstCombineCompares.cpp
test/Transforms/InstCombine/icmp-shr.ll

index 00623b1cbf6d2487882f125f1133c44390cfa9f2..2918f031b3fb46089e8fd132229f617153edbfde 100644 (file)
@@ -1107,7 +1107,8 @@ Instruction *InstCombiner::FoldICmpCstShrCst(ICmpInst &I, Value *Op, Value *A,
   // Get the distance between the highest bit that's set.
   int Shift;
   if (IsNegative)
-    Shift = (-AP2).logBase2() - (-AP1).logBase2();
+    // Get the ones' complement of AP2 and AP1 when computing the distance.
+    Shift = (~AP2).logBase2() - (~AP1).logBase2();
   else
     Shift = AP2.logBase2() - AP1.logBase2();
 
index 8e7c906a5450d03a2958cccfbcdb85e042f0f27f..7562f24a35d847c0e075a4b8e33f53b773da7be1 100644 (file)
@@ -688,3 +688,11 @@ define i1 @PR20945(i32 %B) {
   %cmp = icmp ne i32 %shr, -5
   ret i1 %cmp
 }
+
+; CHECK-LABEL: @PR21222
+; CHECK: icmp eq i32 %B, 6
+define i1 @PR21222(i32 %B) {
+  %shr = ashr i32 -93, %B
+  %cmp = icmp eq i32 %shr, -2
+  ret i1 %cmp
+}