[llvm-branch-commits] [llvm-branch] r70246 - in /llvm/branches/Apple/Dib: lib/Analysis/ScalarEvolution.cpp lib/Transforms/Scalar/InstructionCombining.cpp lib/Transforms/Scalar/LoopStrengthReduce.cpp test/CodeGen/X86/change-compare-stride-0.ll test/CodeGen/X86/change-compare-stride-1.ll test/CodeGen/X86/masked-iv-safe.ll test/CodeGen/X86/masked-iv-unsafe.ll test/Transforms/InstCombine/signed-comparison.ll test/Transforms/LoopStrengthReduce/change-compare-stride-trickiness-1.ll

Bill Wendling isanbard at gmail.com
Mon Apr 27 13:54:32 PDT 2009


Author: void
Date: Mon Apr 27 15:54:32 2009
New Revision: 70246

URL: http://llvm.org/viewvc/llvm-project?rev=70246&view=rev
Log:
--- Merging r70053 into '.':
A    test/Transforms/InstCombine/signed-comparison.ll
U    lib/Transforms/Scalar/InstructionCombining.cpp

--- Merging r70241 into '.':
U    test/Transforms/LoopStrengthReduce/change-compare-stride-trickiness-1.ll
A    test/CodeGen/X86/masked-iv-unsafe.ll
A    test/CodeGen/X86/masked-iv-safe.ll
U    lib/Analysis/ScalarEvolution.cpp

--- Merging r70244 into '.':
A    test/CodeGen/X86/change-compare-stride-0.ll
A    test/CodeGen/X86/change-compare-stride-1.ll
U    lib/Transforms/Scalar/LoopStrengthReduce.cpp

Added:
    llvm/branches/Apple/Dib/test/CodeGen/X86/change-compare-stride-0.ll
      - copied unchanged from r70244, llvm/trunk/test/CodeGen/X86/change-compare-stride-0.ll
    llvm/branches/Apple/Dib/test/CodeGen/X86/change-compare-stride-1.ll
      - copied unchanged from r70244, llvm/trunk/test/CodeGen/X86/change-compare-stride-1.ll
    llvm/branches/Apple/Dib/test/CodeGen/X86/masked-iv-safe.ll
      - copied unchanged from r70241, llvm/trunk/test/CodeGen/X86/masked-iv-safe.ll
    llvm/branches/Apple/Dib/test/CodeGen/X86/masked-iv-unsafe.ll
      - copied unchanged from r70241, llvm/trunk/test/CodeGen/X86/masked-iv-unsafe.ll
    llvm/branches/Apple/Dib/test/Transforms/InstCombine/signed-comparison.ll
      - copied unchanged from r70053, llvm/trunk/test/Transforms/InstCombine/signed-comparison.ll
Modified:
    llvm/branches/Apple/Dib/lib/Analysis/ScalarEvolution.cpp
    llvm/branches/Apple/Dib/lib/Transforms/Scalar/InstructionCombining.cpp
    llvm/branches/Apple/Dib/lib/Transforms/Scalar/LoopStrengthReduce.cpp
    llvm/branches/Apple/Dib/test/Transforms/LoopStrengthReduce/change-compare-stride-trickiness-1.ll

Modified: llvm/branches/Apple/Dib/lib/Analysis/ScalarEvolution.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Dib/lib/Analysis/ScalarEvolution.cpp?rev=70246&r1=70245&r2=70246&view=diff

==============================================================================
--- llvm/branches/Apple/Dib/lib/Analysis/ScalarEvolution.cpp (original)
+++ llvm/branches/Apple/Dib/lib/Analysis/ScalarEvolution.cpp Mon Apr 27 15:54:32 2009
@@ -701,17 +701,81 @@
   if (SCEVZeroExtendExpr *SZ = dyn_cast<SCEVZeroExtendExpr>(Op))
     return getZeroExtendExpr(SZ->getOperand(), Ty);
 
-  // FIXME: If the input value is a chrec scev, and we can prove that the value
+  // If the input value is a chrec scev, and we can prove that the value
   // did not overflow the old, smaller, value, we can zero extend all of the
-  // operands (often constants).  This would allow analysis of something like
+  // operands (often constants).  This allows analysis of something like
   // this:  for (unsigned char X = 0; X < 100; ++X) { int Y = X; }
+  if (SCEVAddRecExpr *AR = dyn_cast<SCEVAddRecExpr>(Op))
+    if (AR->isAffine()) {
+      // Check whether the backedge-taken count is SCEVCouldNotCompute.
+      // Note that this serves two purposes: It filters out loops that are
+      // simply not analyzable, and it covers the case where this code is
+      // being called from within backedge-taken count analysis, such that
+      // attempting to ask for the backedge-taken count would likely result
+      // in infinite recursion. In the later case, the analysis code will
+      // cope with a conservative value, and it will take care to purge
+      // that value once it has finished.
+      SCEVHandle BECount = getBackedgeTakenCount(AR->getLoop());
+      if (!isa<SCEVCouldNotCompute>(BECount)) {
+        // Compute the extent of AR and divide it by the step value. This is
+        // used to determine if it's safe to extend the stride value.
+        SCEVHandle Start = AR->getStart();
+        SCEVHandle Step = AR->getStepRecurrence(*this);
+
+        // Check whether the backedge-taken count can be losslessly casted to
+        // the addrec's type. The count is always unsigned.
+        SCEVHandle CastedBECount =
+          getTruncateOrZeroExtend(BECount, Start->getType());
+        if (BECount ==
+            getTruncateOrZeroExtend(CastedBECount, BECount->getType())) {
+          const Type *WideTy =
+            IntegerType::get(getTypeSizeInBits(Start->getType()) * 2);
+          SCEVHandle ZMul =
+            getMulExpr(CastedBECount,
+                       getTruncateOrZeroExtend(Step, Start->getType()));
+          // Check whether Start+Step*BECount has no unsigned overflow.
+          if (getZeroExtendExpr(ZMul, WideTy) ==
+              getMulExpr(getZeroExtendExpr(CastedBECount, WideTy),
+                         getZeroExtendExpr(Step, WideTy))) {
+            SCEVHandle Add = getAddExpr(Start, ZMul);
+            if (getZeroExtendExpr(Add, WideTy) ==
+                getAddExpr(getZeroExtendExpr(Start, WideTy),
+                           getZeroExtendExpr(ZMul, WideTy)))
+              // Return the expression with the addrec on the outside.
+              return getAddRecExpr(getZeroExtendExpr(Start, Ty),
+                                   getZeroExtendExpr(Step, Ty),
+                                   AR->getLoop());
+          }
+
+          // Similar to above, only this time treat the step value as signed.
+          // This covers loops that count down.
+          SCEVHandle SMul =
+            getMulExpr(CastedBECount,
+                       getTruncateOrSignExtend(Step, Start->getType()));
+          // Check whether Start+Step*BECount has no unsigned overflow.
+          if (getSignExtendExpr(SMul, WideTy) ==
+              getMulExpr(getZeroExtendExpr(CastedBECount, WideTy),
+                         getSignExtendExpr(Step, WideTy))) {
+            SCEVHandle Add = getAddExpr(Start, SMul);
+            if (getZeroExtendExpr(Add, WideTy) ==
+                getAddExpr(getZeroExtendExpr(Start, WideTy),
+                           getSignExtendExpr(SMul, WideTy)))
+              // Return the expression with the addrec on the outside.
+              return getAddRecExpr(getZeroExtendExpr(Start, Ty),
+                                   getSignExtendExpr(Step, Ty),
+                                   AR->getLoop());
+          }
+        }
+      }
+    }
 
   SCEVZeroExtendExpr *&Result = (*SCEVZeroExtends)[std::make_pair(Op, Ty)];
   if (Result == 0) Result = new SCEVZeroExtendExpr(Op, Ty);
   return Result;
 }
 
-SCEVHandle ScalarEvolution::getSignExtendExpr(const SCEVHandle &Op, const Type *Ty) {
+SCEVHandle ScalarEvolution::getSignExtendExpr(const SCEVHandle &Op,
+                                              const Type *Ty) {
   assert(getTypeSizeInBits(Op->getType()) < getTypeSizeInBits(Ty) &&
          "This is not an extending conversion!");
 
@@ -726,10 +790,54 @@
   if (SCEVSignExtendExpr *SS = dyn_cast<SCEVSignExtendExpr>(Op))
     return getSignExtendExpr(SS->getOperand(), Ty);
 
-  // FIXME: If the input value is a chrec scev, and we can prove that the value
+  // If the input value is a chrec scev, and we can prove that the value
   // did not overflow the old, smaller, value, we can sign extend all of the
-  // operands (often constants).  This would allow analysis of something like
+  // operands (often constants).  This allows analysis of something like
   // this:  for (signed char X = 0; X < 100; ++X) { int Y = X; }
+  if (SCEVAddRecExpr *AR = dyn_cast<SCEVAddRecExpr>(Op))
+    if (AR->isAffine()) {
+      // Check whether the backedge-taken count is SCEVCouldNotCompute.
+      // Note that this serves two purposes: It filters out loops that are
+      // simply not analyzable, and it covers the case where this code is
+      // being called from within backedge-taken count analysis, such that
+      // attempting to ask for the backedge-taken count would likely result
+      // in infinite recursion. In the later case, the analysis code will
+      // cope with a conservative value, and it will take care to purge
+      // that value once it has finished.
+      SCEVHandle BECount = getBackedgeTakenCount(AR->getLoop());
+      if (!isa<SCEVCouldNotCompute>(BECount)) {
+        // Compute the extent of AR and divide it by the step value. This is
+        // used to determine if it's safe to extend the stride value.
+        SCEVHandle Start = AR->getStart();
+        SCEVHandle Step = AR->getStepRecurrence(*this);
+
+        // Check whether the backedge-taken count can be losslessly casted to
+        // the addrec's type. The count is always unsigned.
+        SCEVHandle CastedBECount =
+          getTruncateOrZeroExtend(BECount, Start->getType());
+        if (BECount ==
+            getTruncateOrZeroExtend(CastedBECount, BECount->getType())) {
+          const Type *WideTy =
+            IntegerType::get(getTypeSizeInBits(Start->getType()) * 2);
+          SCEVHandle SMul =
+            getMulExpr(CastedBECount,
+                       getTruncateOrSignExtend(Step, Start->getType()));
+          // Check whether Start+Step*BECount has no signed overflow.
+          if (getSignExtendExpr(SMul, WideTy) ==
+              getMulExpr(getSignExtendExpr(CastedBECount, WideTy),
+                         getSignExtendExpr(Step, WideTy))) {
+            SCEVHandle Add = getAddExpr(Start, SMul);
+            if (getSignExtendExpr(Add, WideTy) ==
+                getAddExpr(getSignExtendExpr(Start, WideTy),
+                           getSignExtendExpr(SMul, WideTy)))
+              // Return the expression with the addrec on the outside.
+              return getAddRecExpr(getSignExtendExpr(Start, Ty),
+                                   getSignExtendExpr(Step, Ty),
+                                   AR->getLoop());
+          }
+        }
+      }
+    }
 
   SCEVSignExtendExpr *&Result = (*SCEVSignExtends)[std::make_pair(Op, Ty)];
   if (Result == 0) Result = new SCEVSignExtendExpr(Op, Ty);
@@ -1953,20 +2061,36 @@
 /// hasLoopInvariantBackedgeTakenCount).
 ///
 SCEVHandle ScalarEvolution::getBackedgeTakenCount(const Loop *L) {
-  std::map<const Loop*, SCEVHandle>::iterator I = BackedgeTakenCounts.find(L);
-  if (I == BackedgeTakenCounts.end()) {
+  // Initially insert a CouldNotCompute for this loop. If the insertion
+  // succeeds, procede to actually compute a backedge-taken count and
+  // update the value. The temporary CouldNotCompute value tells SCEV
+  // code elsewhere that it shouldn't attempt to request a new
+  // backedge-taken count, which could result in infinite recursion.
+  std::pair<std::map<const Loop*, SCEVHandle>::iterator, bool> Pair =
+    BackedgeTakenCounts.insert(std::make_pair(L, getCouldNotCompute()));
+  if (Pair.second) {
     SCEVHandle ItCount = ComputeBackedgeTakenCount(L);
-    I = BackedgeTakenCounts.insert(std::make_pair(L, ItCount)).first;
     if (ItCount != UnknownValue) {
       assert(ItCount->isLoopInvariant(L) &&
              "Computed trip count isn't loop invariant for loop!");
       ++NumTripCountsComputed;
+
+      // Now that we know the trip count for this loop, forget any
+      // existing SCEV values for PHI nodes in this loop since they
+      // are only conservative estimates made without the benefit
+      // of trip count information.
+      for (BasicBlock::iterator I = L->getHeader()->begin();
+           PHINode *PN = dyn_cast<PHINode>(I); ++I)
+        deleteValueFromRecords(PN);
+
+      // Update the value in the map.
+      Pair.first->second = ItCount;
     } else if (isa<PHINode>(L->getHeader()->begin())) {
       // Only count loops that have phi nodes as not being computable.
       ++NumTripCountsNotComputed;
     }
   }
-  return I->second;
+  return Pair.first->second;
 }
 
 /// forgetLoopBackedgeTakenCount - This method should be called by the

Modified: llvm/branches/Apple/Dib/lib/Transforms/Scalar/InstructionCombining.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Dib/lib/Transforms/Scalar/InstructionCombining.cpp?rev=70246&r1=70245&r2=70246&view=diff

==============================================================================
--- llvm/branches/Apple/Dib/lib/Transforms/Scalar/InstructionCombining.cpp (original)
+++ llvm/branches/Apple/Dib/lib/Transforms/Scalar/InstructionCombining.cpp Mon Apr 27 15:54:32 2009
@@ -708,15 +708,13 @@
 // set of known zero and one bits, compute the maximum and minimum values that
 // could have the specified known zero and known one bits, returning them in
 // min/max.
-static void ComputeSignedMinMaxValuesFromKnownBits(const Type *Ty,
-                                                   const APInt& KnownZero,
+static void ComputeSignedMinMaxValuesFromKnownBits(const APInt& KnownZero,
                                                    const APInt& KnownOne,
                                                    APInt& Min, APInt& Max) {
-  uint32_t BitWidth = cast<IntegerType>(Ty)->getBitWidth();
-  assert(KnownZero.getBitWidth() == BitWidth && 
-         KnownOne.getBitWidth() == BitWidth &&
-         Min.getBitWidth() == BitWidth && Max.getBitWidth() == BitWidth &&
-         "Ty, KnownZero, KnownOne and Min, Max must have equal bitwidth.");
+  assert(KnownZero.getBitWidth() == KnownOne.getBitWidth() &&
+         KnownZero.getBitWidth() == Min.getBitWidth() &&
+         KnownZero.getBitWidth() == Max.getBitWidth() &&
+         "KnownZero, KnownOne and Min, Max must have equal bitwidth.");
   APInt UnknownBits = ~(KnownZero|KnownOne);
 
   // The minimum value is when all unknown bits are zeros, EXCEPT for the sign
@@ -724,9 +722,9 @@
   Min = KnownOne;
   Max = KnownOne|UnknownBits;
   
-  if (UnknownBits[BitWidth-1]) { // Sign bit is unknown
-    Min.set(BitWidth-1);
-    Max.clear(BitWidth-1);
+  if (UnknownBits.isNegative()) { // Sign bit is unknown
+    Min.set(Min.getBitWidth()-1);
+    Max.clear(Max.getBitWidth()-1);
   }
 }
 
@@ -734,14 +732,12 @@
 // a set of known zero and one bits, compute the maximum and minimum values that
 // could have the specified known zero and known one bits, returning them in
 // min/max.
-static void ComputeUnsignedMinMaxValuesFromKnownBits(const Type *Ty,
-                                                     const APInt &KnownZero,
+static void ComputeUnsignedMinMaxValuesFromKnownBits(const APInt &KnownZero,
                                                      const APInt &KnownOne,
                                                      APInt &Min, APInt &Max) {
-  uint32_t BitWidth = cast<IntegerType>(Ty)->getBitWidth(); BitWidth = BitWidth;
-  assert(KnownZero.getBitWidth() == BitWidth && 
-         KnownOne.getBitWidth() == BitWidth &&
-         Min.getBitWidth() == BitWidth && Max.getBitWidth() &&
+  assert(KnownZero.getBitWidth() == KnownOne.getBitWidth() &&
+         KnownZero.getBitWidth() == Min.getBitWidth() &&
+         KnownZero.getBitWidth() == Max.getBitWidth() &&
          "Ty, KnownZero, KnownOne and Min, Max must have equal bitwidth.");
   APInt UnknownBits = ~(KnownZero|KnownOne);
   
@@ -808,9 +804,13 @@
   assert(V != 0 && "Null pointer of Value???");
   assert(Depth <= 6 && "Limit Search Depth");
   uint32_t BitWidth = DemandedMask.getBitWidth();
-  const IntegerType *VTy = cast<IntegerType>(V->getType());
-  assert(VTy->getBitWidth() == BitWidth && 
-         KnownZero.getBitWidth() == BitWidth && 
+  const Type *VTy = V->getType();
+  assert((TD || !isa<PointerType>(VTy)) &&
+         "SimplifyDemandedBits needs to know bit widths!");
+  assert((!TD || TD->getTypeSizeInBits(VTy) == BitWidth) &&
+         (!isa<IntegerType>(VTy) ||
+          VTy->getPrimitiveSizeInBits() == BitWidth) &&
+         KnownZero.getBitWidth() == BitWidth &&
          KnownOne.getBitWidth() == BitWidth &&
          "Value *V, DemandedMask, KnownZero and KnownOne \
           must have same BitWidth");
@@ -820,7 +820,13 @@
     KnownZero = ~KnownOne & DemandedMask;
     return 0;
   }
-  
+  if (isa<ConstantPointerNull>(V)) {
+    // We know all of the bits for a constant!
+    KnownOne.clear();
+    KnownZero = DemandedMask;
+    return 0;
+  }
+
   KnownZero.clear();
   KnownOne.clear();
   if (DemandedMask == 0) {   // Not demanding any bits from V.
@@ -832,12 +838,15 @@
   if (Depth == 6)        // Limit search depth.
     return 0;
   
-  Instruction *I = dyn_cast<Instruction>(V);
-  if (!I) return 0;        // Only analyze instructions.
-  
   APInt LHSKnownZero(BitWidth, 0), LHSKnownOne(BitWidth, 0);
   APInt &RHSKnownZero = KnownZero, &RHSKnownOne = KnownOne;
 
+  Instruction *I = dyn_cast<Instruction>(V);
+  if (!I) {
+    ComputeMaskedBits(V, DemandedMask, RHSKnownZero, RHSKnownOne, Depth);
+    return 0;        // Only analyze instructions.
+  }
+
   // If there are multiple uses of this value and we aren't at the root, then
   // we can't do any simplifications of the operands, because DemandedMask
   // only reflects the bits demanded by *one* of the users.
@@ -1399,8 +1408,12 @@
   
   // If the client is only demanding bits that we know, return the known
   // constant.
-  if ((DemandedMask & (RHSKnownZero|RHSKnownOne)) == DemandedMask)
-    return ConstantInt::get(RHSKnownOne);
+  if ((DemandedMask & (RHSKnownZero|RHSKnownOne)) == DemandedMask) {
+    Constant *C = ConstantInt::get(RHSKnownOne);
+    if (isa<PointerType>(V->getType()))
+      C = ConstantExpr::getIntToPtr(C, V->getType());
+    return C;
+  }
   return false;
 }
 
@@ -5831,6 +5844,14 @@
     }
   }
 
+  unsigned BitWidth = 0;
+  if (TD)
+    BitWidth = TD->getTypeSizeInBits(Ty);
+  else if (isa<IntegerType>(Ty))
+    BitWidth = Ty->getPrimitiveSizeInBits();
+
+  bool isSignBit = false;
+
   // See if we are doing a comparison with a constant.
   if (ConstantInt *CI = dyn_cast<ConstantInt>(Op1)) {
     Value *A = 0, *B = 0;
@@ -5865,105 +5886,161 @@
       return new ICmpInst(ICmpInst::ICMP_SGT, Op0, SubOne(CI));
     }
     
-    // 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);
-    
-    if (SimplifyDemandedBits(I.getOperandUse(0), 
+    isSignBit = isSignBitCheck(I.getPredicate(), CI, UnusedBit);
+  }
+
+  // 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.
+  if (BitWidth != 0) {
+    APInt Op0KnownZero(BitWidth, 0), Op0KnownOne(BitWidth, 0);
+    APInt Op1KnownZero(BitWidth, 0), Op1KnownOne(BitWidth, 0);
+
+    if (SimplifyDemandedBits(I.getOperandUse(0),
                              isSignBit ? APInt::getSignBit(BitWidth)
                                        : APInt::getAllOnesValue(BitWidth),
-                             KnownZero, KnownOne, 0))
+                             Op0KnownZero, Op0KnownOne, 0))
       return &I;
-        
+    if (SimplifyDemandedBits(I.getOperandUse(1),
+                             APInt::getAllOnesValue(BitWidth),
+                             Op1KnownZero, Op1KnownOne, 0))
+      return &I;
+
     // Given the known and unknown bits, compute a range that the LHS could be
     // 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);
-    if (ICmpInst::isSignedPredicate(I.getPredicate()))
-      ComputeSignedMinMaxValuesFromKnownBits(Ty, KnownZero, KnownOne, Min, Max);
-    else
-      ComputeUnsignedMinMaxValuesFromKnownBits(Ty, KnownZero, KnownOne,Min,Max);
-    
+    APInt Op0Min(BitWidth, 0), Op0Max(BitWidth, 0);
+    APInt Op1Min(BitWidth, 0), Op1Max(BitWidth, 0);
+    if (ICmpInst::isSignedPredicate(I.getPredicate())) {
+      ComputeSignedMinMaxValuesFromKnownBits(Op0KnownZero, Op0KnownOne,
+                                             Op0Min, Op0Max);
+      ComputeSignedMinMaxValuesFromKnownBits(Op1KnownZero, Op1KnownOne,
+                                             Op1Min, Op1Max);
+    } else {
+      ComputeUnsignedMinMaxValuesFromKnownBits(Op0KnownZero, Op0KnownOne,
+                                               Op0Min, Op0Max);
+      ComputeUnsignedMinMaxValuesFromKnownBits(Op1KnownZero, Op1KnownOne,
+                                               Op1Min, Op1Max);
+    }
+
     // 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));
-    
+    if (!isa<Constant>(Op0) && Op0Min == Op0Max)
+      return new ICmpInst(I.getPredicate(), ConstantInt::get(Op0Min), Op1);
+    if (!isa<Constant>(Op1) && Op1Min == Op1Max)
+      return new ICmpInst(I.getPredicate(), Op0, ConstantInt::get(Op1Min));
+
     // 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.
+    switch (I.getPredicate()) {
     default: assert(0 && "Unknown icmp opcode!");
     case ICmpInst::ICMP_EQ:
-      if (Max.ult(RHSVal) || Min.ugt(RHSVal))
+      if (Op0Max.ult(Op1Min) || Op0Min.ugt(Op1Max))
         return ReplaceInstUsesWith(I, ConstantInt::getFalse());
       break;
     case ICmpInst::ICMP_NE:
-      if (Max.ult(RHSVal) || Min.ugt(RHSVal))
+      if (Op0Max.ult(Op1Min) || Op0Min.ugt(Op1Max))
         return ReplaceInstUsesWith(I, ConstantInt::getTrue());
       break;
     case ICmpInst::ICMP_ULT:
-      if (Max.ult(RHSVal))                    // A <u C -> true iff max(A) < C
+      if (Op0Max.ult(Op1Min))          // A <u B -> true if max(A) < min(B)
         return ReplaceInstUsesWith(I, ConstantInt::getTrue());
-      if (Min.uge(RHSVal))                    // A <u C -> false iff min(A) >= C
+      if (Op0Min.uge(Op1Max))          // A <u B -> false if min(A) >= max(B)
         return ReplaceInstUsesWith(I, ConstantInt::getFalse());
-      if (RHSVal == Max)                      // A <u MAX -> A != MAX
+      if (Op1Min == Op0Max)            // A <u B -> A != B if max(A) == min(B)
         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,
+      if (ConstantInt *CI = dyn_cast<ConstantInt>(Op1)) {
+        if (Op1Max == Op0Min+1)        // A <u C -> A == C-1 if min(A)+1 == C
+          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))                    // A >u C -> true iff min(A) > C
+      if (Op0Min.ugt(Op1Max))          // A >u B -> true if min(A) > max(B)
         return ReplaceInstUsesWith(I, ConstantInt::getTrue());
-      if (Max.ule(RHSVal))                    // A >u C -> false iff max(A) <= C
+      if (Op0Max.ule(Op1Min))          // A >u B -> false if max(A) <= max(B)
         return ReplaceInstUsesWith(I, ConstantInt::getFalse());
-        
-      if (RHSVal == Min)                      // A >u MIN -> A != MIN
+
+      if (Op1Max == Op0Min)            // A >u B -> A != B if min(A) == max(B)
         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()));
+      if (ConstantInt *CI = dyn_cast<ConstantInt>(Op1)) {
+        if (Op1Min == Op0Max-1)        // A >u C -> A == C+1 if max(a)-1 == C
+          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))                    // A <s C -> true iff max(A) < C
+      if (Op0Max.slt(Op1Min))          // A <s B -> true if max(A) < min(C)
         return ReplaceInstUsesWith(I, ConstantInt::getTrue());
-      if (Min.sge(RHSVal))                    // A <s C -> false iff min(A) >= C
+      if (Op0Min.sge(Op1Max))          // A <s B -> false if min(A) >= max(C)
         return ReplaceInstUsesWith(I, ConstantInt::getFalse());
-      if (RHSVal == Max)                      // A <s MAX -> A != MAX
+      if (Op1Min == Op0Max)            // A <s B -> A != B if max(A) == min(B)
         return new ICmpInst(ICmpInst::ICMP_NE, Op0, Op1);
-      if (RHSVal == Min+1)                    // A <s MIN+1 -> A == MIN
-        return new ICmpInst(ICmpInst::ICMP_EQ, Op0, SubOne(CI));
+      if (ConstantInt *CI = dyn_cast<ConstantInt>(Op1)) {
+        if (Op1Max == Op0Min+1)        // A <s C -> A == C-1 if min(A)+1 == C
+          return new ICmpInst(ICmpInst::ICMP_EQ, Op0, SubOne(CI));
+      }
       break;
-    case ICmpInst::ICMP_SGT: 
-      if (Min.sgt(RHSVal))                    // A >s C -> true iff min(A) > C
+    case ICmpInst::ICMP_SGT:
+      if (Op0Min.sgt(Op1Max))          // A >s B -> true if min(A) > max(B)
         return ReplaceInstUsesWith(I, ConstantInt::getTrue());
-      if (Max.sle(RHSVal))                    // A >s C -> false iff max(A) <= C
+      if (Op0Max.sle(Op1Min))          // A >s B -> false if max(A) <= min(B)
         return ReplaceInstUsesWith(I, ConstantInt::getFalse());
-        
-      if (RHSVal == Min)                      // A >s MIN -> A != MIN
+
+      if (Op1Max == Op0Min)            // A >s B -> A != B if min(A) == max(B)
         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));
+      if (ConstantInt *CI = dyn_cast<ConstantInt>(Op1)) {
+        if (Op1Min == Op0Max-1)        // A >s C -> A == C+1 if max(A)-1 == C
+          return new ICmpInst(ICmpInst::ICMP_EQ, Op0, AddOne(CI));
+      }
+      break;
+    case ICmpInst::ICMP_SGE:
+      assert(!isa<ConstantInt>(Op1) && "ICMP_SGE with ConstantInt not folded!");
+      if (Op0Min.sge(Op1Max))          // A >=s B -> true if min(A) >= max(B)
+        return ReplaceInstUsesWith(I, ConstantInt::getTrue());
+      if (Op0Max.slt(Op1Min))          // A >=s B -> false if max(A) < min(B)
+        return ReplaceInstUsesWith(I, ConstantInt::getFalse());
+      break;
+    case ICmpInst::ICMP_SLE:
+      assert(!isa<ConstantInt>(Op1) && "ICMP_SLE with ConstantInt not folded!");
+      if (Op0Max.sle(Op1Min))          // A <=s B -> true if max(A) <= min(B)
+        return ReplaceInstUsesWith(I, ConstantInt::getTrue());
+      if (Op0Min.sgt(Op1Max))          // A <=s B -> false if min(A) > max(B)
+        return ReplaceInstUsesWith(I, ConstantInt::getFalse());
+      break;
+    case ICmpInst::ICMP_UGE:
+      assert(!isa<ConstantInt>(Op1) && "ICMP_UGE with ConstantInt not folded!");
+      if (Op0Min.uge(Op1Max))          // A >=u B -> true if min(A) >= max(B)
+        return ReplaceInstUsesWith(I, ConstantInt::getTrue());
+      if (Op0Max.ult(Op1Min))          // A >=u B -> false if max(A) < min(B)
+        return ReplaceInstUsesWith(I, ConstantInt::getFalse());
+      break;
+    case ICmpInst::ICMP_ULE:
+      assert(!isa<ConstantInt>(Op1) && "ICMP_ULE with ConstantInt not folded!");
+      if (Op0Max.ule(Op1Min))          // A <=u B -> true if max(A) <= min(B)
+        return ReplaceInstUsesWith(I, ConstantInt::getTrue());
+      if (Op0Min.ugt(Op1Max))          // A <=u B -> false if min(A) > max(B)
+        return ReplaceInstUsesWith(I, ConstantInt::getFalse());
       break;
     }
+
+    // Turn a signed comparison into an unsigned one if both operands
+    // are known to have the same sign.
+    if (I.isSignedPredicate() &&
+        ((Op0KnownZero.isNegative() && Op1KnownZero.isNegative()) ||
+         (Op0KnownOne.isNegative() && Op1KnownOne.isNegative())))
+      return new ICmpInst(I.getUnsignedPredicate(), Op0, Op1);
   }
 
   // Test if the ICmpInst instruction is used exclusively by a select as

Modified: llvm/branches/Apple/Dib/lib/Transforms/Scalar/LoopStrengthReduce.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Dib/lib/Transforms/Scalar/LoopStrengthReduce.cpp?rev=70246&r1=70245&r2=70246&view=diff

==============================================================================
--- llvm/branches/Apple/Dib/lib/Transforms/Scalar/LoopStrengthReduce.cpp (original)
+++ llvm/branches/Apple/Dib/lib/Transforms/Scalar/LoopStrengthReduce.cpp Mon Apr 27 15:54:32 2009
@@ -2028,7 +2028,9 @@
       if (!isa<SCEVConstant>(SI->first))
         continue;
       int64_t SSInt = cast<SCEVConstant>(SI->first)->getValue()->getSExtValue();
-      if (abs(SSInt) <= abs(CmpSSInt) || (SSInt % CmpSSInt) != 0)
+      if (SSInt == CmpSSInt ||
+          abs(SSInt) < abs(CmpSSInt) ||
+          (SSInt % CmpSSInt) != 0)
         continue;
 
       Scale = SSInt / CmpSSInt;

Modified: llvm/branches/Apple/Dib/test/Transforms/LoopStrengthReduce/change-compare-stride-trickiness-1.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Dib/test/Transforms/LoopStrengthReduce/change-compare-stride-trickiness-1.ll?rev=70246&r1=70245&r2=70246&view=diff

==============================================================================
--- llvm/branches/Apple/Dib/test/Transforms/LoopStrengthReduce/change-compare-stride-trickiness-1.ll (original)
+++ llvm/branches/Apple/Dib/test/Transforms/LoopStrengthReduce/change-compare-stride-trickiness-1.ll Mon Apr 27 15:54:32 2009
@@ -1,4 +1,4 @@
-; RUN: llvm-as < %s | llc --x86-asm-syntax=att | grep {cmpl	\$8}
+; RUN: llvm-as < %s | llc --x86-asm-syntax=att | grep {cmpq	\$8}
 target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128"
 target triple = "x86_64-apple-darwin9"
 
@@ -6,7 +6,7 @@
 ; happens after the relevant use, so the comparison stride can be
 ; easily changed.
 
-define void @foo() {
+define void @foo() nounwind {
 entry:
 	br label %loop
 
@@ -14,9 +14,11 @@
 	%indvar = phi i32 [ 0, %entry ], [ %i.2.0.us1534, %loop ]		; <i32> [#uses=1]
 	%i.2.0.us1534 = add i32 %indvar, 1		; <i32> [#uses=3]
 	%tmp628.us1540 = shl i32 %i.2.0.us1534, 1		; <i32> [#uses=1]
-	%tmp645646647.us1547 = sext i32 %tmp628.us1540 to i64		; <i64> [#uses=0]
+	%tmp645646647.us1547 = sext i32 %tmp628.us1540 to i64		; <i64> [#uses=1]
+	store i64 %tmp645646647.us1547, i64* null
 	%tmp611.us1535 = icmp eq i32 %i.2.0.us1534, 4		; <i1> [#uses=2]
-	%tmp623.us1538 = select i1 %tmp611.us1535, i32 6, i32 0		; <i32> [#uses=0]
+	%tmp623.us1538 = select i1 %tmp611.us1535, i32 6, i32 0		; <i32> [#uses=1]
+	store i32 %tmp623.us1538, i32* null
 	br i1 %tmp611.us1535, label %exit, label %loop
 
 exit:





More information about the llvm-branch-commits mailing list