[llvm-commits] [llvm] r48715 - in /llvm/trunk: lib/Transforms/Scalar/InstructionCombining.cpp test/Transforms/InstCombine/zext-or-icmp.ll

Evan Cheng evan.cheng at apple.com
Sun Mar 23 17:21:34 PDT 2008


Author: evancheng
Date: Sun Mar 23 19:21:34 2008
New Revision: 48715

URL: http://llvm.org/viewvc/llvm-project?rev=48715&view=rev
Log:
Transform (zext (or (icmp), (icmp))) to (or (zext (cimp), (zext icmp))) if at least one of the (zext icmp) can be transformed to eliminate an icmp.

Added:
    llvm/trunk/test/Transforms/InstCombine/zext-or-icmp.ll
Modified:
    llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp

Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp?rev=48715&r1=48714&r2=48715&view=diff

==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Sun Mar 23 19:21:34 2008
@@ -236,6 +236,8 @@
     Instruction *visitCallSite(CallSite CS);
     bool transformConstExprCastCall(CallSite CS);
     Instruction *transformCallThroughTrampoline(CallSite CS);
+    Instruction *transformZExtICmp(ICmpInst *ICI, Instruction &CI,
+                                   bool DoXform = true);
 
   public:
     // InsertNewInstBefore - insert an instruction New before instruction Old
@@ -4363,18 +4365,22 @@
   if (CastInst *Op0C = dyn_cast<CastInst>(Op0)) {
     if (CastInst *Op1C = dyn_cast<CastInst>(Op1))
       if (Op0C->getOpcode() == Op1C->getOpcode()) {// same cast kind ?
-        const Type *SrcTy = Op0C->getOperand(0)->getType();
-        if (SrcTy == Op1C->getOperand(0)->getType() && SrcTy->isInteger() &&
-            // Only do this if the casts both really cause code to be generated.
-            ValueRequiresCast(Op0C->getOpcode(), Op0C->getOperand(0), 
-                              I.getType(), TD) &&
-            ValueRequiresCast(Op1C->getOpcode(), Op1C->getOperand(0), 
-                              I.getType(), TD)) {
-          Instruction *NewOp = BinaryOperator::createOr(Op0C->getOperand(0),
-                                                        Op1C->getOperand(0),
-                                                        I.getName());
-          InsertNewInstBefore(NewOp, I);
-          return CastInst::create(Op0C->getOpcode(), NewOp, I.getType());
+        if (!isa<ICmpInst>(Op0C->getOperand(0)) ||
+            !isa<ICmpInst>(Op1C->getOperand(0))) {
+          const Type *SrcTy = Op0C->getOperand(0)->getType();
+          if (SrcTy == Op1C->getOperand(0)->getType() && SrcTy->isInteger() &&
+              // Only do this if the casts both really cause code to be
+              // generated.
+              ValueRequiresCast(Op0C->getOpcode(), Op0C->getOperand(0), 
+                                I.getType(), TD) &&
+              ValueRequiresCast(Op1C->getOpcode(), Op1C->getOperand(0), 
+                                I.getType(), TD)) {
+            Instruction *NewOp = BinaryOperator::createOr(Op0C->getOperand(0),
+                                                          Op1C->getOperand(0),
+                                                          I.getName());
+            InsertNewInstBefore(NewOp, I);
+            return CastInst::create(Op0C->getOpcode(), NewOp, I.getType());
+          }
         }
       }
   }
@@ -7188,6 +7194,101 @@
   return 0;
 }
 
+/// transformZExtICmp - Transform (zext icmp) to bitwise / integer operations
+/// in order to eliminate the icmp.
+Instruction *InstCombiner::transformZExtICmp(ICmpInst *ICI, Instruction &CI,
+                                             bool DoXform) {
+  // 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();
+      
+    // zext (x <s  0) to i32 --> x>>u31      true if signbit set.
+    // zext (x >s -1) to i32 --> (x>>u31)^1  true if signbit clear.
+    if ((ICI->getPredicate() == ICmpInst::ICMP_SLT && Op1CV == 0) ||
+        (ICI->getPredicate() == ICmpInst::ICMP_SGT &&Op1CV.isAllOnesValue())) {
+      if (!DoXform) return ICI;
+
+      Value *In = ICI->getOperand(0);
+      Value *Sh = ConstantInt::get(In->getType(),
+                                   In->getType()->getPrimitiveSizeInBits()-1);
+      In = InsertNewInstBefore(BinaryOperator::createLShr(In, Sh,
+                                                        In->getName()+".lobit"),
+                               CI);
+      if (In->getType() != CI.getType())
+        In = CastInst::createIntegerCast(In, CI.getType(),
+                                         false/*ZExt*/, "tmp", &CI);
+
+      if (ICI->getPredicate() == ICmpInst::ICMP_SGT) {
+        Constant *One = ConstantInt::get(In->getType(), 1);
+        In = InsertNewInstBefore(BinaryOperator::createXor(In, One,
+                                                         In->getName()+".not"),
+                                 CI);
+      }
+
+      return ReplaceInstUsesWith(CI, In);
+    }
+      
+      
+      
+    // zext (X == 0) to i32 --> X^1      iff X has only the low bit set.
+    // zext (X == 0) to i32 --> (X>>1)^1 iff X has only the 2nd bit set.
+    // zext (X == 1) to i32 --> X        iff X has only the low bit set.
+    // zext (X == 2) to i32 --> X>>1     iff X has only the 2nd bit set.
+    // zext (X != 0) to i32 --> X        iff X has only the low bit set.
+    // zext (X != 0) to i32 --> X>>1     iff X has only the 2nd bit set.
+    // zext (X != 1) to i32 --> X^1      iff X has only the low bit set.
+    // zext (X != 2) to i32 --> (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?
+        if (!DoXform) return ICI;
+
+        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;
+}
+
 Instruction *InstCombiner::visitZExt(ZExtInst &CI) {
   // If one of the common conversion will work ..
   if (Instruction *Result = commonIntCastTransforms(CI))
@@ -7224,92 +7325,24 @@
     }
   }
 
-  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();
-      
-      // zext (x <s  0) to i32 --> x>>u31      true if signbit set.
-      // zext (x >s -1) to i32 --> (x>>u31)^1  true if signbit clear.
-      if ((ICI->getPredicate() == ICmpInst::ICMP_SLT && Op1CV == 0) ||
-          (ICI->getPredicate() == ICmpInst::ICMP_SGT &&Op1CV.isAllOnesValue())){
-        Value *In = ICI->getOperand(0);
-        Value *Sh = ConstantInt::get(In->getType(),
-                                    In->getType()->getPrimitiveSizeInBits()-1);
-        In = InsertNewInstBefore(BinaryOperator::createLShr(In, Sh,
-                                                        In->getName()+".lobit"),
-                                 CI);
-        if (In->getType() != CI.getType())
-          In = CastInst::createIntegerCast(In, CI.getType(),
-                                           false/*ZExt*/, "tmp", &CI);
+  if (ICmpInst *ICI = dyn_cast<ICmpInst>(Src))
+    return transformZExtICmp(ICI, CI);
 
-        if (ICI->getPredicate() == ICmpInst::ICMP_SGT) {
-          Constant *One = ConstantInt::get(In->getType(), 1);
-          In = InsertNewInstBefore(BinaryOperator::createXor(In, One,
-                                                          In->getName()+".not"),
-                                   CI);
-        }
-
-        return ReplaceInstUsesWith(CI, In);
-      }
-      
-      
-      
-      // zext (X == 0) to i32 --> X^1      iff X has only the low bit set.
-      // zext (X == 0) to i32 --> (X>>1)^1 iff X has only the 2nd bit set.
-      // zext (X == 1) to i32 --> X        iff X has only the low bit set.
-      // zext (X == 2) to i32 --> X>>1     iff X has only the 2nd bit set.
-      // zext (X != 0) to i32 --> X        iff X has only the low bit set.
-      // zext (X != 0) to i32 --> X>>1     iff X has only the 2nd bit set.
-      // zext (X != 1) to i32 --> X^1      iff X has only the low bit set.
-      // zext (X != 2) to i32 --> (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*/);
-        }
-      }
+  BinaryOperator *SrcI = dyn_cast<BinaryOperator>(Src);
+  if (SrcI && SrcI->getOpcode() == Instruction::Or) {
+    // zext (or icmp, icmp) --> or (zext icmp), (zext icmp) if at least one
+    // of the (zext icmp) will be transformed.
+    ICmpInst *LHS = dyn_cast<ICmpInst>(SrcI->getOperand(0));
+    ICmpInst *RHS = dyn_cast<ICmpInst>(SrcI->getOperand(1));
+    if (LHS && RHS && LHS->hasOneUse() && RHS->hasOneUse() &&
+        (transformZExtICmp(LHS, CI, false) ||
+         transformZExtICmp(RHS, CI, false))) {
+      Value *LCast = InsertCastBefore(Instruction::ZExt, LHS, CI.getType(), CI);
+      Value *RCast = InsertCastBefore(Instruction::ZExt, RHS, CI.getType(), CI);
+      return BinaryOperator::create(Instruction::Or, LCast, RCast);
     }
-  }    
+  }
+
   return 0;
 }
 

Added: llvm/trunk/test/Transforms/InstCombine/zext-or-icmp.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/zext-or-icmp.ll?rev=48715&view=auto

==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/zext-or-icmp.ll (added)
+++ llvm/trunk/test/Transforms/InstCombine/zext-or-icmp.ll Sun Mar 23 19:21:34 2008
@@ -0,0 +1,35 @@
+; RUN: llvm-as < %s | opt -instcombine | llvm-dis | grep icmp | count 1
+
+	%struct.FooBar = type <{ i8, i8, [2 x i8], i8, i8, i8, i8, i16, i16, [4 x i8], [8 x %struct.Rock] }>
+	%struct.Rock = type { i16, i16 }
+ at some_idx = internal constant [4 x i8] c"\0A\0B\0E\0F"		; <[4 x i8]*> [#uses=1]
+
+define i8 @t(%struct.FooBar* %up, i8 zeroext  %intra_flag, i32 %blk_i) zeroext nounwind  {
+entry:
+	%tmp2 = lshr i32 %blk_i, 1		; <i32> [#uses=1]
+	%tmp3 = and i32 %tmp2, 2		; <i32> [#uses=1]
+	%tmp5 = and i32 %blk_i, 1		; <i32> [#uses=1]
+	%tmp6 = or i32 %tmp3, %tmp5		; <i32> [#uses=1]
+	%tmp8 = getelementptr %struct.FooBar* %up, i32 0, i32 7		; <i16*> [#uses=1]
+	%tmp9 = load i16* %tmp8, align 1		; <i16> [#uses=1]
+	%tmp910 = zext i16 %tmp9 to i32		; <i32> [#uses=1]
+	%tmp12 = getelementptr [4 x i8]* @some_idx, i32 0, i32 %tmp6		; <i8*> [#uses=1]
+	%tmp13 = load i8* %tmp12, align 1		; <i8> [#uses=1]
+	%tmp1314 = zext i8 %tmp13 to i32		; <i32> [#uses=1]
+	%tmp151 = lshr i32 %tmp910, %tmp1314		; <i32> [#uses=1]
+	%tmp1516 = trunc i32 %tmp151 to i8		; <i8> [#uses=1]
+	%tmp18 = getelementptr %struct.FooBar* %up, i32 0, i32 0		; <i8*> [#uses=1]
+	%tmp19 = load i8* %tmp18, align 1		; <i8> [#uses=1]
+	%tmp22 = and i8 %tmp1516, %tmp19		; <i8> [#uses=1]
+	%tmp24 = getelementptr %struct.FooBar* %up, i32 0, i32 0		; <i8*> [#uses=1]
+	%tmp25 = load i8* %tmp24, align 1		; <i8> [#uses=1]
+	%tmp26.mask = and i8 %tmp25, 1		; <i8> [#uses=1]
+	%toBool = icmp eq i8 %tmp26.mask, 0		; <i1> [#uses=1]
+	%toBool.not = xor i1 %toBool, true		; <i1> [#uses=1]
+	%toBool33 = icmp eq i8 %intra_flag, 0		; <i1> [#uses=1]
+	%bothcond = or i1 %toBool.not, %toBool33		; <i1> [#uses=1]
+	%iftmp.1.0 = select i1 %bothcond, i8 0, i8 1		; <i8> [#uses=1]
+	%tmp40 = or i8 %tmp22, %iftmp.1.0		; <i8> [#uses=1]
+	%tmp432 = and i8 %tmp40, 1		; <i8> [#uses=1]
+	ret i8 %tmp432
+}





More information about the llvm-commits mailing list