[llvm-commits] CVS: llvm/lib/Transforms/Scalar/InstructionCombining.cpp

Chris Lattner sabre at nondot.org
Tue Apr 10 22:45:56 PDT 2007



Changes in directory llvm/lib/Transforms/Scalar:

InstructionCombining.cpp updated: 1.738 -> 1.739
---
Log message:

fix a miscompilation of:
define i32 @test(i32 %X) {
entry:
        %Y = and i32 %X, 4              ; <i32> [#uses=1]
        icmp eq i32 %Y, 0               ; <i1>:0 [#uses=1]
        sext i1 %0 to i32               ; <i32>:1 [#uses=1]
        ret i32 %1
}

by moving code out of commonIntCastTransforms into visitZExt.  Simplify the
APInt gymnastics in it etc.



---
Diffs of the changes:  (+59 -63)

 InstructionCombining.cpp |  122 ++++++++++++++++++++++-------------------------
 1 files changed, 59 insertions(+), 63 deletions(-)


Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp
diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.738 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.739
--- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.738	Mon Apr  9 18:52:13 2007
+++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp	Wed Apr 11 00:45:39 2007
@@ -6457,69 +6457,6 @@
       }
     }
     break;
-
-  case Instruction::ICmp:
-    // If we are just checking for a icmp eq of a single bit and casting it
-    // to an integer, then shift the bit to the appropriate place and then
-    // cast to integer to avoid the comparison.
-    if (ConstantInt *Op1C = dyn_cast<ConstantInt>(Op1)) {
-      const APInt& Op1CV = Op1C->getValue();
-      // cast (X == 0) to int --> X^1      iff X has only the low bit set.
-      // cast (X == 0) to int --> (X>>1)^1 iff X has only the 2nd bit set.
-      // cast (X == 1) to int --> X        iff X has only the low bit set.
-      // cast (X == 2) to int --> X>>1     iff X has only the 2nd bit set.
-      // cast (X != 0) to int --> X        iff X has only the low bit set.
-      // cast (X != 0) to int --> X>>1     iff X has only the 2nd bit set.
-      // cast (X != 1) to int --> X^1      iff X has only the low bit set.
-      // cast (X != 2) to int --> (X>>1)^1 iff X has only the 2nd bit set.
-      if (Op1CV == 0 || Op1CV.isPowerOf2()) {
-        // If Op1C some other power of two, convert:
-        uint32_t BitWidth = Op1C->getType()->getBitWidth();
-        APInt KnownZero(BitWidth, 0), KnownOne(BitWidth, 0);
-        APInt TypeMask(APInt::getAllOnesValue(BitWidth));
-        ComputeMaskedBits(Op0, TypeMask, KnownZero, KnownOne);
-
-        // This only works for EQ and NE
-        ICmpInst::Predicate pred = cast<ICmpInst>(SrcI)->getPredicate();
-        if (pred != ICmpInst::ICMP_NE && pred != ICmpInst::ICMP_EQ)
-          break;
-        
-        APInt KnownZeroMask(KnownZero ^ TypeMask);
-        if (KnownZeroMask.isPowerOf2()) { // Exactly 1 possible 1?
-          bool isNE = pred == ICmpInst::ICMP_NE;
-          if (Op1CV != 0 && (Op1CV != KnownZeroMask)) {
-            // (X&4) == 2 --> false
-            // (X&4) != 2 --> true
-            Constant *Res = ConstantInt::get(Type::Int1Ty, isNE);
-            Res = ConstantExpr::getZExt(Res, CI.getType());
-            return ReplaceInstUsesWith(CI, Res);
-          }
-          
-          uint32_t ShiftAmt = KnownZeroMask.logBase2();
-          Value *In = Op0;
-          if (ShiftAmt) {
-            // Perform a logical shr by shiftamt.
-            // Insert the shift to put the result in the low bit.
-            In = InsertNewInstBefore(
-              BinaryOperator::createLShr(In,
-                                     ConstantInt::get(In->getType(), ShiftAmt),
-                                     In->getName()+".lobit"), CI);
-          }
-          
-          if ((Op1CV != 0) == isNE) { // Toggle the low bit.
-            Constant *One = ConstantInt::get(In->getType(), 1);
-            In = BinaryOperator::createXor(In, One, "tmp");
-            InsertNewInstBefore(cast<Instruction>(In), CI);
-          }
-          
-          if (CI.getType() == In->getType())
-            return ReplaceInstUsesWith(CI, In);
-          else
-            return CastInst::createIntegerCast(In, CI.getType(), false/*ZExt*/);
-        }
-      }
-    }
-    break;
   }
   return 0;
 }
@@ -6617,6 +6554,65 @@
     }
   }
 
+  if (ICmpInst *ICI = dyn_cast<ICmpInst>(Src)) {
+    // If we are just checking for a icmp eq of a single bit and zext'ing it
+    // to an integer, then shift the bit to the appropriate place and then
+    // cast to integer to avoid the comparison.
+    if (ConstantInt *Op1C = dyn_cast<ConstantInt>(ICI->getOperand(1))) {
+      const APInt& Op1CV = Op1C->getValue();
+      // cast (X == 0) to int --> X^1      iff X has only the low bit set.
+      // cast (X == 0) to int --> (X>>1)^1 iff X has only the 2nd bit set.
+      // cast (X == 1) to int --> X        iff X has only the low bit set.
+      // cast (X == 2) to int --> X>>1     iff X has only the 2nd bit set.
+      // cast (X != 0) to int --> X        iff X has only the low bit set.
+      // cast (X != 0) to int --> X>>1     iff X has only the 2nd bit set.
+      // cast (X != 1) to int --> X^1      iff X has only the low bit set.
+      // cast (X != 2) to int --> (X>>1)^1 iff X has only the 2nd bit set.
+      if ((Op1CV == 0 || Op1CV.isPowerOf2()) && 
+          // This only works for EQ and NE
+          ICI->isEquality()) {
+        // If Op1C some other power of two, convert:
+        uint32_t BitWidth = Op1C->getType()->getBitWidth();
+        APInt KnownZero(BitWidth, 0), KnownOne(BitWidth, 0);
+        APInt TypeMask(APInt::getAllOnesValue(BitWidth));
+        ComputeMaskedBits(ICI->getOperand(0), TypeMask, KnownZero, KnownOne);
+        
+        APInt KnownZeroMask(~KnownZero);
+        if (KnownZeroMask.isPowerOf2()) { // Exactly 1 possible 1?
+          bool isNE = ICI->getPredicate() == ICmpInst::ICMP_NE;
+          if (Op1CV != 0 && (Op1CV != KnownZeroMask)) {
+            // (X&4) == 2 --> false
+            // (X&4) != 2 --> true
+            Constant *Res = ConstantInt::get(Type::Int1Ty, isNE);
+            Res = ConstantExpr::getZExt(Res, CI.getType());
+            return ReplaceInstUsesWith(CI, Res);
+          }
+          
+          uint32_t ShiftAmt = KnownZeroMask.logBase2();
+          Value *In = ICI->getOperand(0);
+          if (ShiftAmt) {
+            // Perform a logical shr by shiftamt.
+            // Insert the shift to put the result in the low bit.
+            In = InsertNewInstBefore(
+                   BinaryOperator::createLShr(In,
+                                     ConstantInt::get(In->getType(), ShiftAmt),
+                                              In->getName()+".lobit"), CI);
+          }
+          
+          if ((Op1CV != 0) == isNE) { // Toggle the low bit.
+            Constant *One = ConstantInt::get(In->getType(), 1);
+            In = BinaryOperator::createXor(In, One, "tmp");
+            InsertNewInstBefore(cast<Instruction>(In), CI);
+          }
+          
+          if (CI.getType() == In->getType())
+            return ReplaceInstUsesWith(CI, In);
+          else
+            return CastInst::createIntegerCast(In, CI.getType(), false/*ZExt*/);
+        }
+      }
+    }
+  }    
   return 0;
 }
 






More information about the llvm-commits mailing list