diff options
author | Benjamin Kramer <benny.kra@googlemail.com> | 2011-06-13 15:24:24 +0000 |
---|---|---|
committer | Benjamin Kramer <benny.kra@googlemail.com> | 2011-06-13 15:24:24 +0000 |
commit | c970849ea0252181c19a52722f606bc9a1eadd68 (patch) | |
tree | 4a975ceaf4e3268ee2b583d6a4affdd7d7564d91 | |
parent | 975c29629f6ffd8e1d8eb714d34d955cf77c5452 (diff) | |
download | bcm5719-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.txt | 5 | ||||
-rw-r--r-- | llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp | 23 | ||||
-rw-r--r-- | llvm/test/Transforms/InstCombine/icmp.ll | 16 |
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 +} |