aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDuncan Sands <baldrick@free.fr>2010-12-20 14:47:04 +0000
committerDuncan Sands <baldrick@free.fr>2010-12-20 14:47:04 +0000
commitee9a2e322af96accc9e55ed6373c0057453714b1 (patch)
treeeff3cc7ef14c9ed10d46dacd8378c3dc053f5f43
parentc41f4de754a76e0c1bb251cdc10fac587d2f7dbd (diff)
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
-rw-r--r--lib/Analysis/InstructionSimplify.cpp32
-rw-r--r--test/Transforms/InstCombine/2010-11-01-lshr-mask.ll6
2 files changed, 31 insertions, 7 deletions
diff --git a/lib/Analysis/InstructionSimplify.cpp b/lib/Analysis/InstructionSimplify.cpp
index 2458d204bc..f4636553ca 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<Constant>(Op0)) {
if (Constant *CRHS = dyn_cast<Constant>(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<Constant>(Op0))
if (Constant *CRHS = dyn_cast<Constant>(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<Constant>(LHS))
if (Constant *CRHS = dyn_cast<Constant>(RHS)) {
diff --git a/test/Transforms/InstCombine/2010-11-01-lshr-mask.ll b/test/Transforms/InstCombine/2010-11-01-lshr-mask.ll
index 34b165bcbe..441d5f9b0b 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