From ee9a2e322af96accc9e55ed6373c0057453714b1 Mon Sep 17 00:00:00 2001 From: Duncan Sands Date: Mon, 20 Dec 2010 14:47:04 +0000 Subject: [PATCH] Have SimplifyBinOp dispatch Xor, Add and Sub to the corresponding methods (they had just been forgotten before). Adding Xor causes "main" in the existing testcase 2010-11-01-lshr-mask.ll to be hugely more simplified. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@122245 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Analysis/InstructionSimplify.cpp | 32 ++++++++++++++++--- .../InstCombine/2010-11-01-lshr-mask.ll | 6 ++-- 2 files changed, 31 insertions(+), 7 deletions(-) diff --git a/lib/Analysis/InstructionSimplify.cpp b/lib/Analysis/InstructionSimplify.cpp index 2458d204bca..f4636553ca2 100644 --- a/lib/Analysis/InstructionSimplify.cpp +++ b/lib/Analysis/InstructionSimplify.cpp @@ -11,7 +11,9 @@ // that do not require creating new instructions. This does constant folding // ("add i32 1, 1" -> "2") but can also handle non-constant operands, either // returning a constant ("and i32 %x, 0" -> "0") or an already existing value -// ("and i32 %x, %x" -> "%x"). +// ("and i32 %x, %x" -> "%x"). All operands are assumed to have already been +// simplified: This is usually true and assuming it simplifies the logic (if +// they have not been simplified then results are correct but maybe suboptimal). // //===----------------------------------------------------------------------===// @@ -229,8 +231,9 @@ static Value *ThreadCmpOverPHI(CmpInst::Predicate Pred, Value *LHS, Value *RHS, /// SimplifyAddInst - Given operands for an Add, see if we can /// fold the result. If not, this returns null. -Value *llvm::SimplifyAddInst(Value *Op0, Value *Op1, bool isNSW, bool isNUW, - const TargetData *TD, const DominatorTree *) { +static Value *SimplifyAddInst(Value *Op0, Value *Op1, bool isNSW, bool isNUW, + const TargetData *TD, const DominatorTree *DT, + unsigned MaxRecurse) { if (Constant *CLHS = dyn_cast(Op0)) { if (Constant *CRHS = dyn_cast(Op1)) { Constant *Ops[] = { CLHS, CRHS }; @@ -252,6 +255,7 @@ Value *llvm::SimplifyAddInst(Value *Op0, Value *Op1, bool isNSW, bool isNUW, // X + (Y - X) -> Y // (Y - X) + X -> Y + // Eg: X + -X -> 0 Value *Y = 0; if (match(Op1, m_Sub(m_Value(Y), m_Specific(Op0))) || match(Op0, m_Sub(m_Value(Y), m_Specific(Op1)))) @@ -274,10 +278,16 @@ Value *llvm::SimplifyAddInst(Value *Op0, Value *Op1, bool isNSW, bool isNUW, return 0; } +Value *llvm::SimplifyAddInst(Value *Op0, Value *Op1, bool isNSW, bool isNUW, + const TargetData *TD, const DominatorTree *DT) { + return ::SimplifyAddInst(Op0, Op1, isNSW, isNUW, TD, DT, RecursionLimit); +} + /// 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 *) { +static Value *SimplifySubInst(Value *Op0, Value *Op1, bool isNSW, bool isNUW, + const TargetData *TD, const DominatorTree *, + unsigned MaxRecurse) { if (Constant *CLHS = dyn_cast(Op0)) if (Constant *CRHS = dyn_cast(Op1)) { Constant *Ops[] = { CLHS, CRHS }; @@ -317,6 +327,11 @@ Value *llvm::SimplifySubInst(Value *Op0, Value *Op1, bool isNSW, bool isNUW, return 0; } +Value *llvm::SimplifySubInst(Value *Op0, Value *Op1, bool isNSW, bool isNUW, + const TargetData *TD, const DominatorTree *DT) { + return ::SimplifySubInst(Op0, Op1, isNSW, isNUW, TD, DT, RecursionLimit); +} + /// 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, @@ -826,6 +841,13 @@ static Value *SimplifyBinOp(unsigned Opcode, Value *LHS, Value *RHS, switch (Opcode) { case Instruction::And: return SimplifyAndInst(LHS, RHS, TD, DT, MaxRecurse); case Instruction::Or: return SimplifyOrInst(LHS, RHS, TD, DT, MaxRecurse); + case Instruction::Xor: return SimplifyXorInst(LHS, RHS, TD, DT, MaxRecurse); + case Instruction::Add: return SimplifyAddInst(LHS, RHS, /* isNSW */ false, + /* isNUW */ false, TD, DT, + MaxRecurse); + case Instruction::Sub: return SimplifySubInst(LHS, RHS, /* isNSW */ false, + /* isNUW */ false, TD, DT, + MaxRecurse); default: if (Constant *CLHS = dyn_cast(LHS)) if (Constant *CRHS = dyn_cast(RHS)) { diff --git a/test/Transforms/InstCombine/2010-11-01-lshr-mask.ll b/test/Transforms/InstCombine/2010-11-01-lshr-mask.ll index 34b165bcbe7..441d5f9b0b6 100644 --- a/test/Transforms/InstCombine/2010-11-01-lshr-mask.ll +++ b/test/Transforms/InstCombine/2010-11-01-lshr-mask.ll @@ -5,14 +5,16 @@ define i32 @main(i32 %argc) nounwind ssp { entry: %tmp3151 = trunc i32 %argc to i8 +; CHECK: %tmp3162 = shl i8 %tmp3151, 5 +; CHECK: and i8 %tmp3162, 64 +; CHECK-NOT: shl +; CHECK-NOT: shr %tmp3161 = or i8 %tmp3151, -17 %tmp3162 = and i8 %tmp3151, 122 %tmp3163 = xor i8 %tmp3162, -17 %tmp4114 = shl i8 %tmp3163, 6 %tmp4115 = xor i8 %tmp4114, %tmp3163 %tmp4120 = xor i8 %tmp3161, %tmp4115 -; CHECK: lshr i8 %tmp4115, 1 -; CHECK-NOT: shl i8 %tmp4126, 6 %tmp4126 = lshr i8 %tmp4120, 7 %tmp4127 = mul i8 %tmp4126, 64 %tmp4086 = zext i8 %tmp4127 to i32