[llvm-commits] [llvm] r121861 - in /llvm/trunk: include/llvm/Analysis/InstructionSimplify.h lib/Analysis/InstructionSimplify.cpp lib/Transforms/InstCombine/InstCombineAddSub.cpp test/Analysis/BasicAA/modref.ll
Duncan Sands
baldrick at free.fr
Wed Dec 15 06:07:39 PST 2010
Author: baldrick
Date: Wed Dec 15 08:07:39 2010
New Revision: 121861
URL: http://llvm.org/viewvc/llvm-project?rev=121861&view=rev
Log:
Move Sub simplifications and additional Add simplifications out of
instcombine and into InstructionSimplify.
Modified:
llvm/trunk/include/llvm/Analysis/InstructionSimplify.h
llvm/trunk/lib/Analysis/InstructionSimplify.cpp
llvm/trunk/lib/Transforms/InstCombine/InstCombineAddSub.cpp
llvm/trunk/test/Analysis/BasicAA/modref.ll
Modified: llvm/trunk/include/llvm/Analysis/InstructionSimplify.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/InstructionSimplify.h?rev=121861&r1=121860&r2=121861&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Analysis/InstructionSimplify.h (original)
+++ llvm/trunk/include/llvm/Analysis/InstructionSimplify.h Wed Dec 15 08:07:39 2010
@@ -29,6 +29,11 @@
Value *SimplifyAddInst(Value *LHS, Value *RHS, bool isNSW, bool isNUW,
const TargetData *TD = 0, const DominatorTree *DT = 0);
+ /// SimplifySubInst - Given operands for a Sub, see if we can
+ /// fold the result. If not, this returns null.
+ Value *SimplifySubInst(Value *LHS, Value *RHS, bool isNSW, bool isNUW,
+ const TargetData *TD = 0, const DominatorTree *DT = 0);
+
/// SimplifyAndInst - Given operands for an And, see if we can
/// fold the result. If not, this returns null.
Value *SimplifyAndInst(Value *LHS, Value *RHS, const TargetData *TD = 0,
Modified: llvm/trunk/lib/Analysis/InstructionSimplify.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/InstructionSimplify.cpp?rev=121861&r1=121860&r2=121861&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/InstructionSimplify.cpp (original)
+++ llvm/trunk/lib/Analysis/InstructionSimplify.cpp Wed Dec 15 08:07:39 2010
@@ -242,17 +242,25 @@
std::swap(Op0, Op1);
}
- if (Constant *Op1C = dyn_cast<Constant>(Op1)) {
- // X + undef -> undef
- if (isa<UndefValue>(Op1C))
- return Op1C;
+ // X + undef -> undef
+ if (isa<UndefValue>(Op1))
+ return Op1;
- // X + 0 --> X
- if (Op1C->isNullValue())
- return Op0;
- }
+ // X + 0 -> X
+ if (match(Op1, m_Zero()))
+ return Op0;
- // FIXME: Could pull several more out of instcombine.
+ // X + (Y - X) -> Y
+ // (Y - X) + X -> Y
+ Value *Y = 0;
+ if (match(Op1, m_Sub(m_Value(Y), m_Specific(Op0))) ||
+ match(Op0, m_Sub(m_Value(Y), m_Specific(Op1))))
+ return Y;
+
+ // X + ~X -> -1 since ~X = -X-1
+ if (match(Op0, m_Not(m_Specific(Op1))) ||
+ match(Op1, m_Not(m_Specific(Op0))))
+ return Constant::getAllOnesValue(Op0->getType());
// Threading Add over selects and phi nodes is pointless, so don't bother.
// Threading over the select in "A + select(cond, B, C)" means evaluating
@@ -266,6 +274,49 @@
return 0;
}
+/// SimplifySubInst - Given operands for a Sub, see if we can
+/// fold the result. If not, this returns null.
+Value *llvm::SimplifySubInst(Value *Op0, Value *Op1, bool isNSW, bool isNUW,
+ const TargetData *TD, const DominatorTree *) {
+ if (Constant *CLHS = dyn_cast<Constant>(Op0))
+ if (Constant *CRHS = dyn_cast<Constant>(Op1)) {
+ Constant *Ops[] = { CLHS, CRHS };
+ return ConstantFoldInstOperands(Instruction::Sub, CLHS->getType(),
+ Ops, 2, TD);
+ }
+
+ // X - undef -> undef
+ // undef - X -> undef
+ if (isa<UndefValue>(Op0) || isa<UndefValue>(Op1))
+ return UndefValue::get(Op0->getType());
+
+ // X - 0 -> X
+ if (match(Op1, m_Zero()))
+ return Op0;
+
+ // X - X -> 0
+ if (Op0 == Op1)
+ return Constant::getNullValue(Op0->getType());
+
+ // (X + Y) - Y -> X
+ // (Y + X) - Y -> X
+ Value *X = 0;
+ if (match(Op0, m_Add(m_Value(X), m_Specific(Op1))) ||
+ match(Op0, m_Add(m_Specific(Op1), m_Value(X))))
+ return X;
+
+ // Threading Sub over selects and phi nodes is pointless, so don't bother.
+ // Threading over the select in "A - select(cond, B, C)" means evaluating
+ // "A-B" and "A-C" and seeing if they are equal; but they are equal if and
+ // only if B and C are equal. If B and C are equal then (since we assume
+ // that operands have already been simplified) "select(cond, B, C)" should
+ // have been simplified to the common value of B and C already. Analysing
+ // "A-B" and "A-C" thus gains nothing, but costs compile time. Similarly
+ // for threading over phi nodes.
+
+ return 0;
+}
+
/// SimplifyAndInst - Given operands for an And, see if we can
/// fold the result. If not, this returns null.
static Value *SimplifyAndInst(Value *Op0, Value *Op1, const TargetData *TD,
@@ -835,6 +886,12 @@
cast<BinaryOperator>(I)->hasNoUnsignedWrap(),
TD, DT);
break;
+ case Instruction::Sub:
+ Result = SimplifySubInst(I->getOperand(0), I->getOperand(1),
+ cast<BinaryOperator>(I)->hasNoSignedWrap(),
+ cast<BinaryOperator>(I)->hasNoUnsignedWrap(),
+ TD, DT);
+ break;
case Instruction::And:
Result = SimplifyAndInst(I->getOperand(0), I->getOperand(1), TD, DT);
break;
Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineAddSub.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineAddSub.cpp?rev=121861&r1=121860&r2=121861&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/InstCombine/InstCombineAddSub.cpp (original)
+++ llvm/trunk/lib/Transforms/InstCombine/InstCombineAddSub.cpp Wed Dec 15 08:07:39 2010
@@ -154,17 +154,6 @@
// X + X --> X << 1
if (LHS == RHS)
return BinaryOperator::CreateShl(LHS, ConstantInt::get(I.getType(), 1));
-
- if (Instruction *RHSI = dyn_cast<Instruction>(RHS)) {
- if (RHSI->getOpcode() == Instruction::Sub)
- if (LHS == RHSI->getOperand(1)) // A + (B - A) --> B
- return ReplaceInstUsesWith(I, RHSI->getOperand(0));
- }
- if (Instruction *LHSI = dyn_cast<Instruction>(LHS)) {
- if (LHSI->getOpcode() == Instruction::Sub)
- if (RHS == LHSI->getOperand(1)) // (B - A) + A --> B
- return ReplaceInstUsesWith(I, LHSI->getOperand(0));
- }
}
// -A + B --> B - A
@@ -201,11 +190,6 @@
if (dyn_castFoldableMul(RHS, C2) == LHS)
return BinaryOperator::CreateMul(LHS, AddOne(C2));
- // X + ~X --> -1 since ~X = -X-1
- if (match(LHS, m_Not(m_Specific(RHS))) ||
- match(RHS, m_Not(m_Specific(LHS))))
- return ReplaceInstUsesWith(I, Constant::getAllOnesValue(I.getType()));
-
// A+B --> A|B iff A and B have no bits set in common.
if (const IntegerType *IT = dyn_cast<IntegerType>(I.getType())) {
APInt Mask = APInt::getAllOnesValue(IT->getBitWidth());
@@ -547,8 +531,9 @@
Instruction *InstCombiner::visitSub(BinaryOperator &I) {
Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
- if (Op0 == Op1) // sub X, X -> 0
- return ReplaceInstUsesWith(I, Constant::getNullValue(I.getType()));
+ if (Value *V = SimplifySubInst(Op0, Op1, I.hasNoSignedWrap(),
+ I.hasNoUnsignedWrap(), TD))
+ return ReplaceInstUsesWith(I, V);
if (Instruction *NV = SimplifyByFactorizing(I)) // (A*B)-(A*C) -> A*(B-C)
return NV;
@@ -561,10 +546,6 @@
return Res;
}
- if (isa<UndefValue>(Op0))
- return ReplaceInstUsesWith(I, Op0); // undef - X -> undef
- if (isa<UndefValue>(Op1))
- return ReplaceInstUsesWith(I, Op1); // X - undef -> undef
if (I.getType()->isIntegerTy(1))
return BinaryOperator::CreateXor(Op0, Op1);
@@ -693,12 +674,7 @@
}
if (BinaryOperator *Op0I = dyn_cast<BinaryOperator>(Op0)) {
- if (Op0I->getOpcode() == Instruction::Add) {
- if (Op0I->getOperand(0) == Op1) // (Y+X)-Y == X
- return ReplaceInstUsesWith(I, Op0I->getOperand(1));
- else if (Op0I->getOperand(1) == Op1) // (X+Y)-Y == X
- return ReplaceInstUsesWith(I, Op0I->getOperand(0));
- } else if (Op0I->getOpcode() == Instruction::Sub) {
+ if (Op0I->getOpcode() == Instruction::Sub) {
if (Op0I->getOperand(0) == Op1) // (X-Y)-X == -Y
return BinaryOperator::CreateNeg(Op0I->getOperand(1),
I.getName());
Modified: llvm/trunk/test/Analysis/BasicAA/modref.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Analysis/BasicAA/modref.ll?rev=121861&r1=121860&r2=121861&view=diff
==============================================================================
--- llvm/trunk/test/Analysis/BasicAA/modref.ll (original)
+++ llvm/trunk/test/Analysis/BasicAA/modref.ll Wed Dec 15 08:07:39 2010
@@ -105,7 +105,7 @@
; CHECK: load i32* @G
; CHECK: memset.p0i8.i32
; CHECK-NOT: load
-; CHECK: sub i32 %tmp, %tmp
+; CHECK: ret i32 0
}
; Verify that basicaa is handling variable length memcpy, knowing it doesn't
@@ -120,7 +120,7 @@
; CHECK: load i32* @G
; CHECK: memcpy.p0i8.p0i8.i32
; CHECK-NOT: load
-; CHECK: sub i32 %tmp, %tmp
+; CHECK: ret i32 0
}
define i8 @test6(i8* %p, i8* noalias %a) {
More information about the llvm-commits
mailing list