summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBenjamin Kramer <benny.kra@googlemail.com>2011-06-13 15:24:24 +0000
committerBenjamin Kramer <benny.kra@googlemail.com>2011-06-13 15:24:24 +0000
commitc970849ea0252181c19a52722f606bc9a1eadd68 (patch)
tree4a975ceaf4e3268ee2b583d6a4affdd7d7564d91
parent975c29629f6ffd8e1d8eb714d34d955cf77c5452 (diff)
downloadbcm5719-llvm-c970849ea0252181c19a52722f606bc9a1eadd68.tar.gz
bcm5719-llvm-c970849ea0252181c19a52722f606bc9a1eadd68.zip
InstCombine: Fold A-b == C --> b == A-C if A and C are constants.
The backend already knew this trick. llvm-svn: 132915
-rw-r--r--llvm/lib/Target/README.txt5
-rw-r--r--llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp23
-rw-r--r--llvm/test/Transforms/InstCombine/icmp.ll16
3 files changed, 32 insertions, 12 deletions
diff --git a/llvm/lib/Target/README.txt b/llvm/lib/Target/README.txt
index fcec368a213..4e382e8f8ec 100644
--- a/llvm/lib/Target/README.txt
+++ b/llvm/lib/Target/README.txt
@@ -870,11 +870,6 @@ rshift_gt (unsigned int a)
bar ();
}
-void neg_eq_cst(unsigned int a) {
-if (-a == 123)
-bar();
-}
-
All should simplify to a single comparison. All of these are
currently not optimized with "clang -emit-llvm-bc | opt
-std-compile-opts".
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
index 5ddf23ba8e1..42db444ff6d 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -1407,18 +1407,27 @@ Instruction *InstCombiner::visitICmpInstWithInstAndIntCst(ICmpInst &ICI,
case Instruction::Xor:
// For the xor case, we can xor two constants together, eliminating
// the explicit xor.
- if (Constant *BOC = dyn_cast<Constant>(BO->getOperand(1)))
- return new ICmpInst(ICI.getPredicate(), BO->getOperand(0),
+ if (Constant *BOC = dyn_cast<Constant>(BO->getOperand(1))) {
+ return new ICmpInst(ICI.getPredicate(), BO->getOperand(0),
ConstantExpr::getXor(RHS, BOC));
-
- // FALLTHROUGH
+ } else if (RHSV == 0) {
+ // Replace ((xor A, B) != 0) with (A != B)
+ return new ICmpInst(ICI.getPredicate(), BO->getOperand(0),
+ BO->getOperand(1));
+ }
+ break;
case Instruction::Sub:
- // Replace (([sub|xor] A, B) != 0) with (A != B)
- if (RHSV == 0)
+ // Replace ((sub A, B) != C) with (B != A-C) if A & C are constants.
+ if (ConstantInt *BOp0C = dyn_cast<ConstantInt>(BO->getOperand(0))) {
+ if (BO->hasOneUse())
+ return new ICmpInst(ICI.getPredicate(), BO->getOperand(1),
+ ConstantExpr::getSub(BOp0C, RHS));
+ } else if (RHSV == 0) {
+ // Replace ((sub A, B) != 0) with (A != B)
return new ICmpInst(ICI.getPredicate(), BO->getOperand(0),
BO->getOperand(1));
+ }
break;
-
case Instruction::Or:
// If bits are being or'd in that are not present in the constant we
// are comparing against, then the comparison could never succeed!
diff --git a/llvm/test/Transforms/InstCombine/icmp.ll b/llvm/test/Transforms/InstCombine/icmp.ll
index ecbba23091c..c8f7f81468f 100644
--- a/llvm/test/Transforms/InstCombine/icmp.ll
+++ b/llvm/test/Transforms/InstCombine/icmp.ll
@@ -531,3 +531,19 @@ define i1 @test54(i8 %a) nounwind {
%ret = icmp eq i32 %and, 128
ret i1 %ret
}
+
+; CHECK: @test55
+; CHECK-NEXT: icmp eq i32 %a, -123
+define i1 @test55(i32 %a) {
+ %sub = sub i32 0, %a
+ %cmp = icmp eq i32 %sub, 123
+ ret i1 %cmp
+}
+
+; CHECK: @test56
+; CHECK-NEXT: icmp eq i32 %a, -113
+define i1 @test56(i32 %a) {
+ %sub = sub i32 10, %a
+ %cmp = icmp eq i32 %sub, 123
+ ret i1 %cmp
+}
OpenPOWER on IntegriCloud