[llvm-commits] [llvm] r53446 - /llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp

Chris Lattner sabre at nondot.org
Thu Jul 10 22:40:06 PDT 2008


Author: lattner
Date: Fri Jul 11 00:40:05 2008
New Revision: 53446

URL: http://llvm.org/viewvc/llvm-project?rev=53446&view=rev
Log:
simplify and merge a bunch of code.  Instead of comparing against
the min/max values for an integer type, compare against the min/max
values we can prove contain the input.  This might be a tighter bound,
so this is general goodness.

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=53446&r1=53445&r2=53446&view=diff

==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Fri Jul 11 00:40:05 2008
@@ -2964,24 +2964,6 @@
   return commonRemTransforms(I);
 }
 
-// isMaxValueMinusOne - return true if this is Max-1
-static bool isMaxValueMinusOne(const ConstantInt *C, bool isSigned) {
-  uint32_t TypeBits = C->getType()->getPrimitiveSizeInBits();
-  if (!isSigned)
-    return C->getValue() == APInt::getAllOnesValue(TypeBits) - 1;
-  return C->getValue() == APInt::getSignedMaxValue(TypeBits)-1;
-}
-
-// isMinValuePlusOne - return true if this is Min+1
-static bool isMinValuePlusOne(const ConstantInt *C, bool isSigned) {
-  if (!isSigned)
-    return C->getValue() == 1; // unsigned
-    
-  // Calculate 1111111111000000000000
-  uint32_t TypeBits = C->getType()->getPrimitiveSizeInBits();
-  return C->getValue() == APInt::getSignedMinValue(TypeBits)+1;
-}
-
 // isOneBitSet - Return true if there is exactly one bit set in the specified
 // constant.
 static bool isOneBitSet(const ConstantInt *CI) {
@@ -5274,63 +5256,16 @@
       return new ICmpInst(ICmpInst::ICMP_SGT, Op0, SubOne(CI));
     }
     
-    switch (I.getPredicate()) {
-    default: break;
-    case ICmpInst::ICMP_ULT:                        // A <u MIN -> FALSE
-      if (CI->isMinValue(false))
-        return ReplaceInstUsesWith(I, ConstantInt::getFalse());
-      if (CI->isMaxValue(false))                    // A <u MAX -> A != MAX
-        return new ICmpInst(ICmpInst::ICMP_NE, Op0,Op1);
-      if (isMinValuePlusOne(CI,false))              // A <u MIN+1 -> A == MIN
-        return new ICmpInst(ICmpInst::ICMP_EQ, Op0, SubOne(CI));
-      // (x <u 2147483648) -> (x >s -1)  -> true if sign bit clear
-      if (CI->isMinValue(true))
-        return new ICmpInst(ICmpInst::ICMP_SGT, Op0,
-                            ConstantInt::getAllOnesValue(Op0->getType()));
-          
-      break;
-
-    case ICmpInst::ICMP_SLT:
-      if (CI->isMinValue(true))                    // A <s MIN -> FALSE
-        return ReplaceInstUsesWith(I, ConstantInt::getFalse());
-      if (CI->isMaxValue(true))                    // A <s MAX -> A != MAX
-        return new ICmpInst(ICmpInst::ICMP_NE, Op0, Op1);
-      if (isMinValuePlusOne(CI,true))              // A <s MIN+1 -> A == MIN
-        return new ICmpInst(ICmpInst::ICMP_EQ, Op0, SubOne(CI));
-      break;
-
-    case ICmpInst::ICMP_UGT:
-      if (CI->isMaxValue(false))                  // A >u MAX -> FALSE
-        return ReplaceInstUsesWith(I, ConstantInt::getFalse());
-      if (CI->isMinValue(false))                  // A >u MIN -> A != MIN
-        return new ICmpInst(ICmpInst::ICMP_NE, Op0, Op1);
-      if (isMaxValueMinusOne(CI, false))          // A >u MAX-1 -> A == MAX
-        return new ICmpInst(ICmpInst::ICMP_EQ, Op0, AddOne(CI));
-        
-      // (x >u 2147483647) -> (x <s 0)  -> true if sign bit set
-      if (CI->isMaxValue(true))
-        return new ICmpInst(ICmpInst::ICMP_SLT, Op0,
-                            ConstantInt::getNullValue(Op0->getType()));
-      break;
-
-    case ICmpInst::ICMP_SGT:
-      if (CI->isMaxValue(true))                   // A >s MAX -> FALSE
-        return ReplaceInstUsesWith(I, ConstantInt::getFalse());
-      if (CI->isMinValue(true))                   // A >s MIN -> A != MIN
-        return new ICmpInst(ICmpInst::ICMP_NE, Op0, Op1);
-      if (isMaxValueMinusOne(CI, true))           // A >s MAX-1 -> A == MAX
-        return new ICmpInst(ICmpInst::ICMP_EQ, Op0, AddOne(CI));
-      break;
-    }
-
-    // See if we can fold the comparison based on bits known to be zero or one
-    // in the input.  If this comparison is a normal comparison, it demands all
+    // See if we can fold the comparison based on range information we can get
+    // by checking whether bits are known to be zero or one in the input.
+    uint32_t BitWidth = cast<IntegerType>(Ty)->getBitWidth();
+    APInt KnownZero(BitWidth, 0), KnownOne(BitWidth, 0);
+    
+    // If this comparison is a normal comparison, it demands all
     // bits, if it is a sign bit comparison, it only demands the sign bit.
     bool UnusedBit;
     bool isSignBit = isSignBitCheck(I.getPredicate(), CI, UnusedBit);
     
-    uint32_t BitWidth = cast<IntegerType>(Ty)->getBitWidth();
-    APInt KnownZero(BitWidth, 0), KnownOne(BitWidth, 0);
     if (SimplifyDemandedBits(Op0, 
                              isSignBit ? APInt::getSignBit(BitWidth)
                                        : APInt::getAllOnesValue(BitWidth),
@@ -5341,12 +5276,22 @@
     // in.  Compute the Min, Max and RHS values based on the known bits. For the
     // EQ and NE we use unsigned values.
     APInt Min(BitWidth, 0), Max(BitWidth, 0);
-    const APInt& RHSVal = CI->getValue();
     if (ICmpInst::isSignedPredicate(I.getPredicate()))
       ComputeSignedMinMaxValuesFromKnownBits(Ty, KnownZero, KnownOne, Min, Max);
     else
       ComputeUnsignedMinMaxValuesFromKnownBits(Ty, KnownZero, KnownOne,Min,Max);
     
+    // If Min and Max are known to be the same, then SimplifyDemandedBits
+    // figured out that the LHS is a constant.  Just constant fold this now so
+    // that code below can assume that Min != Max.
+    if (Min == Max)
+      return ReplaceInstUsesWith(I, ConstantExpr::getICmp(I.getPredicate(),
+                                                          ConstantInt::get(Min),
+                                                          CI));
+    
+    // Based on the range information we know about the LHS, see if we can
+    // simplify this comparison.  For example, (x&4) < 8  is always true.
+    const APInt &RHSVal = CI->getValue();
     switch (I.getPredicate()) {  // LE/GE have been folded already.
     default: assert(0 && "Unknown icmp opcode!");
     case ICmpInst::ICMP_EQ:
@@ -5358,30 +5303,56 @@
         return ReplaceInstUsesWith(I, ConstantInt::getTrue());
       break;
     case ICmpInst::ICMP_ULT:
-      if (Max.ult(RHSVal))
+      if (Max.ult(RHSVal))                    // A <u C -> true iff max(A) < C
         return ReplaceInstUsesWith(I, ConstantInt::getTrue());
-      if (Min.uge(RHSVal))
+      if (Min.uge(RHSVal))                    // A <u C -> false iff min(A) >= C
         return ReplaceInstUsesWith(I, ConstantInt::getFalse());
+      if (RHSVal == Max)                      // A <u MAX -> A != MAX
+        return new ICmpInst(ICmpInst::ICMP_NE, Op0, Op1);
+      if (RHSVal == Min+1)                    // A <u MIN+1 -> A == MIN
+        return new ICmpInst(ICmpInst::ICMP_EQ, Op0, SubOne(CI));
+        
+      // (x <u 2147483648) -> (x >s -1)  -> true if sign bit clear
+      if (CI->isMinValue(true))
+        return new ICmpInst(ICmpInst::ICMP_SGT, Op0,
+                            ConstantInt::getAllOnesValue(Op0->getType()));
       break;
     case ICmpInst::ICMP_UGT:
-      if (Min.ugt(RHSVal))
+      if (Min.ugt(RHSVal))                    // A >u C -> true iff min(A) > C
         return ReplaceInstUsesWith(I, ConstantInt::getTrue());
-      if (Max.ule(RHSVal))
+      if (Max.ule(RHSVal))                    // A >u C -> false iff max(A) <= C
         return ReplaceInstUsesWith(I, ConstantInt::getFalse());
+        
+      if (RHSVal == Min)                      // A >u MIN -> A != MIN
+        return new ICmpInst(ICmpInst::ICMP_NE, Op0, Op1);
+      if (RHSVal == Max-1)                    // A >u MAX-1 -> A == MAX
+        return new ICmpInst(ICmpInst::ICMP_EQ, Op0, AddOne(CI));
+      
+      // (x >u 2147483647) -> (x <s 0)  -> true if sign bit set
+      if (CI->isMaxValue(true))
+        return new ICmpInst(ICmpInst::ICMP_SLT, Op0,
+                            ConstantInt::getNullValue(Op0->getType()));
       break;
     case ICmpInst::ICMP_SLT:
-      if (Max.slt(RHSVal))
+      if (Max.slt(RHSVal))                    // A <s C -> true iff max(A) < C
         return ReplaceInstUsesWith(I, ConstantInt::getTrue());
-      if (Min.sgt(RHSVal))
+      if (Min.sgt(RHSVal))                    // A <s C -> false iff min(A) >= C
         return ReplaceInstUsesWith(I, ConstantInt::getFalse());
-      if (Max == RHSVal)  // A <s MAX -> A != MAX
+      if (RHSVal == Max)                      // A <s MAX -> A != MAX
+        return new ICmpInst(ICmpInst::ICMP_NE, Op0, Op1);
+      if (RHSVal == Min-1)                    // A <s MIN+1 -> A == MIN
         return new ICmpInst(ICmpInst::ICMP_NE, Op0, Op1);
       break;
     case ICmpInst::ICMP_SGT: 
-      if (Min.sgt(RHSVal))
+      if (Min.sgt(RHSVal))                    // A >s C -> true iff min(A) > C
         return ReplaceInstUsesWith(I, ConstantInt::getTrue());
-      if (Max.sle(RHSVal))
+      if (Max.sle(RHSVal))                    // A >s C -> false iff max(A) <= C
         return ReplaceInstUsesWith(I, ConstantInt::getFalse());
+        
+      if (RHSVal == Min)                      // A >s MIN -> A != MIN
+        return new ICmpInst(ICmpInst::ICMP_NE, Op0, Op1);
+      if (RHSVal == Max-1)                    // A >s MAX-1 -> A == MAX
+        return new ICmpInst(ICmpInst::ICMP_EQ, Op0, AddOne(CI));
       break;
     }
           





More information about the llvm-commits mailing list