[llvm-commits] [llvm] r122174 - /llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp

Chris Lattner sabre at nondot.org
Sun Dec 19 09:52:50 PST 2010


Author: lattner
Date: Sun Dec 19 11:52:50 2010
New Revision: 122174

URL: http://llvm.org/viewvc/llvm-project?rev=122174&view=rev
Log:
rework the code added in r122072 to pull it out to its own
helper function, clean up comments, and reduce indentation.
No functionality change.

Modified:
    llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp

Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp?rev=122174&r1=122173&r2=122174&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp (original)
+++ llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp Sun Dec 19 11:52:50 2010
@@ -1583,6 +1583,62 @@
   return BinaryOperator::CreateNot(Result);
 }
 
+/// ProcessUGT_ADDCST_ADD - The caller has matched a pattern of the form:
+///   I = icmp ugt (add (add A, B), CI2), CI1
+static Instruction *ProcessUGT_ADDCST_ADD(ICmpInst &I, Value *A, Value *B,
+                                          ConstantInt *CI2, ConstantInt *CI1,
+                                          InstCombiner::BuilderTy *Builder) {
+  const IntegerType *WideType = cast<IntegerType>(CI1->getType());
+  unsigned WideWidth = WideType->getBitWidth();
+  unsigned NarrowWidth = WideWidth / 2;
+  const IntegerType *NarrowType =
+  IntegerType::get(CI1->getContext(), NarrowWidth);
+  
+  // NarrowAllOnes and NarrowSignBit are the magic constants used to
+  // perform an overflow check in the wider type: 0x00..00FF..FF and
+  // 0x00..0010..00 respectively, where the highest set bit in each is
+  // what would be the sign bit in the narrower type.
+  ConstantInt *NarrowAllOnes = cast<ConstantInt>(ConstantInt::get(WideType,
+                          APInt::getAllOnesValue(NarrowWidth).zext(WideWidth)));
+  APInt SignBit(WideWidth, 0);
+  SignBit.setBit(NarrowWidth-1);
+  ConstantInt *NarrowSignBit =
+  cast<ConstantInt>(ConstantInt::get(WideType, SignBit));
+  
+  if (CI1 != NarrowAllOnes || CI2 != NarrowSignBit)
+    return 0;
+  
+  Module *M = I.getParent()->getParent()->getParent();
+  
+  const Type *IntrinsicType = NarrowType;
+  Value *F = Intrinsic::getDeclaration(M, Intrinsic::sadd_with_overflow,
+                                       &IntrinsicType, 1);
+  
+  BasicBlock *InitialBlock = Builder->GetInsertBlock();
+  BasicBlock::iterator InitialInsert = Builder->GetInsertPoint();
+  
+  // If the pattern matches, truncate the inputs to the narrower type and
+  // use the sadd_with_overflow intrinsic to efficiently compute both the
+  // result and the overflow bit.
+  Instruction *OrigAdd =
+  cast<Instruction>(cast<Instruction>(I.getOperand(0))->getOperand(0));
+  Builder->SetInsertPoint(OrigAdd->getParent(),
+                          BasicBlock::iterator(OrigAdd));
+  
+  Value *TruncA = Builder->CreateTrunc(A, NarrowType, A->getName());
+  Value *TruncB = Builder->CreateTrunc(B, NarrowType, B->getName());
+  CallInst *Call = Builder->CreateCall2(F, TruncA, TruncB);
+  Value *Add = Builder->CreateExtractValue(Call, 0);
+  Value *ZExt = Builder->CreateZExt(Add, WideType);
+  
+  // The inner add was the result of the narrow add, zero extended to the
+  // wider type.  Replace it with the result computed by the intrinsic.
+  OrigAdd->replaceAllUsesWith(ZExt);
+  
+  Builder->SetInsertPoint(InitialBlock, InitialInsert);
+  
+  return ExtractValueInst::Create(Call, 1);
+}
 
 
 Instruction *InstCombiner::visitICmpInst(ICmpInst &I) {
@@ -1662,72 +1718,19 @@
     // addition in wider type, and explicitly checks for overflow using
     // comparisons against INT_MIN and INT_MAX.  Simplify this by using the
     // sadd_with_overflow intrinsic.
-    // FIXME: This could probably be generalized to handle other overflow-safe
+    //
+    // TODO: This could probably be generalized to handle other overflow-safe
     // operations if we worked out the formulas to compute the appropriate 
     // magic constants.
     // 
-    // INT64 : a, b, sum = a + b
-    // if sum < INT32_MIN || sum > INT_MAX then
-    //   ...
-    // else
-    //   ...
+    // sum = a + b
+    // if (sum+128 >u 255)  ...  -> llvm.sadd.with.overflow.i8
     {
-    ConstantInt *CI2;
-    
-    // I = icmp ugt (add (add A B) CI2) CI
+    ConstantInt *CI2;    // I = icmp ugt (add (add A, B), CI2), CI
     if (I.getPredicate() == ICmpInst::ICMP_UGT &&
-        match(Op0, m_Add(m_Add(m_Value(A), m_Value(B)),
-                   m_ConstantInt(CI2)))) {
-      const IntegerType *WideType = cast<IntegerType>(CI->getType());
-      unsigned WideWidth = WideType->getBitWidth();
-      unsigned NarrowWidth = WideWidth / 2;
-      const IntegerType *NarrowType =
-        IntegerType::get(CI->getContext(), NarrowWidth);
-      
-      // NarrowAllOnes and NarrowSignBit are the magic constants used to
-      // perform an overflow check in the wider type: 0x00..00FF..FF and
-      // 0x00..0010..00 respectively, where the highest set bit in each is
-      // what would be the sign bit in the narrower type.
-      ConstantInt *NarrowAllOnes = cast<ConstantInt>(ConstantInt::get(WideType,
-        APInt::getAllOnesValue(NarrowWidth).zext(WideWidth)));
-      APInt SignBit(WideWidth, 0);
-      SignBit.setBit(NarrowWidth-1);
-      ConstantInt *NarrowSignBit =
-       cast<ConstantInt>(ConstantInt::get(WideType, SignBit));
-      
-      if (CI == NarrowAllOnes && CI2 == NarrowSignBit) {
-        Module *M = I.getParent()->getParent()->getParent();
-        
-        const Type *IntrinsicType = NarrowType;
-        Value *F = Intrinsic::getDeclaration(M, Intrinsic::sadd_with_overflow,
-          &IntrinsicType, 1);
-        
-        BasicBlock *InitialBlock = Builder->GetInsertBlock();
-        BasicBlock::iterator InitialInsert = Builder->GetInsertPoint();
-        
-        // If the pattern matches, truncate the inputs to the narrower type and
-        // use the sadd_with_overflow intrinsic to efficiently compute both the
-        // result and the overflow bit.
-        Instruction *OrigAdd =
-          cast<Instruction>(cast<Instruction>(I.getOperand(0))->getOperand(0));
-        Builder->SetInsertPoint(OrigAdd->getParent(),
-                                BasicBlock::iterator(OrigAdd));
-        
-        Value *TruncA = Builder->CreateTrunc(A, NarrowType, A->getName());
-        Value *TruncB = Builder->CreateTrunc(B, NarrowType, B->getName());
-        CallInst *Call = Builder->CreateCall2(F, TruncA, TruncB);
-        Value *Add = Builder->CreateExtractValue(Call, 0);
-        Value *ZExt = Builder->CreateZExt(Add, WideType);
-        
-        // The inner add was the result of the narrow add, zero extended to the
-        // wider type.  Replace it with the result computed by the intrinsic.
-        OrigAdd->replaceAllUsesWith(ZExt);
-        
-        Builder->SetInsertPoint(InitialBlock, InitialInsert);
-        
-        return ExtractValueInst::Create(Call, 1);
-      }
-    }
+        match(Op0, m_Add(m_Add(m_Value(A), m_Value(B)), m_ConstantInt(CI2))))
+      if (Instruction *Res = ProcessUGT_ADDCST_ADD(I, A, B, CI2, CI, Builder))
+        return Res;
     }
     
     // (icmp ne/eq (sub A B) 0) -> (icmp ne/eq A, B)





More information about the llvm-commits mailing list