aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNick Lewycky <nicholas@mxc.ca>2009-09-20 06:24:51 +0000
committerNick Lewycky <nicholas@mxc.ca>2009-09-20 06:24:51 +0000
commitc9c524ea42f9ed437369879c709b95f24bd3a4e8 (patch)
treea55669da79302b25c8f4dc435b28803f4a0c2a77
parente4a6ac9ba8cd5339cb954d9830b1d2a06223355b (diff)
downloadexternal_llvm-c9c524ea42f9ed437369879c709b95f24bd3a4e8.zip
external_llvm-c9c524ea42f9ed437369879c709b95f24bd3a4e8.tar.gz
external_llvm-c9c524ea42f9ed437369879c709b95f24bd3a4e8.tar.bz2
Teach the constant folder how to not a cmpinst.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@82378 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/VMCore/ConstantFold.cpp14
-rw-r--r--test/Transforms/ConstProp/2009-09-19-ConstFold-i1-ConstExpr.ll6
2 files changed, 20 insertions, 0 deletions
diff --git a/lib/VMCore/ConstantFold.cpp b/lib/VMCore/ConstantFold.cpp
index 3f5c7ef..1cf7b29 100644
--- a/lib/VMCore/ConstantFold.cpp
+++ b/lib/VMCore/ConstantFold.cpp
@@ -704,6 +704,20 @@ Constant *llvm::ConstantFoldBinaryInstruction(LLVMContext &Context,
break;
case Instruction::Xor:
if (CI2->equalsInt(0)) return C1; // X ^ 0 == X
+
+ if (ConstantExpr *CE1 = dyn_cast<ConstantExpr>(C1)) {
+ switch (CE1->getOpcode()) {
+ default: break;
+ case Instruction::ICmp:
+ case Instruction::FCmp:
+ // icmp pred ^ true -> icmp !pred
+ assert(CI2->equalsInt(1));
+ CmpInst::Predicate pred = (CmpInst::Predicate)CE1->getPredicate();
+ pred = CmpInst::getInversePredicate(pred);
+ return ConstantExpr::getCompare(pred, CE1->getOperand(0),
+ CE1->getOperand(1));
+ }
+ }
break;
case Instruction::AShr:
// ashr (zext C to Ty), C2 -> lshr (zext C, CSA), C2
diff --git a/test/Transforms/ConstProp/2009-09-19-ConstFold-i1-ConstExpr.ll b/test/Transforms/ConstProp/2009-09-19-ConstFold-i1-ConstExpr.ll
index 0a40c0c..66a3a85 100644
--- a/test/Transforms/ConstProp/2009-09-19-ConstFold-i1-ConstExpr.ll
+++ b/test/Transforms/ConstProp/2009-09-19-ConstFold-i1-ConstExpr.ll
@@ -28,3 +28,9 @@ global i1 icmp ule (i32* bitcast (i8* @X to i32*), i32* bitcast (i8* @Y to i32*)
; CHECK-NOT: bitcast
; CHECK: icmp
+global i1 icmp eq (i1 icmp ult (i8* @X, i8* @Y), i1 false)
+; CHECK-NOT: false
+; CHECK: icmp
+global i1 icmp eq (i1 icmp ult (i8* @X, i8* @Y), i1 true)
+; CHECK-NOT: true
+; CHECK: icmp