[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