summaryrefslogtreecommitdiffstats
path: root/llvm
diff options
context:
space:
mode:
authorNick Lewycky <nicholas@mxc.ca>2009-09-20 00:04:02 +0000
committerNick Lewycky <nicholas@mxc.ca>2009-09-20 00:04:02 +0000
commit605109d151b4f8faab0fb25371ee4c0173e1dfba (patch)
treeb2e04b3b0f5791a1fd9cec52456aeece21978984 /llvm
parentfa9c6f43a0a03ff4883dc801ce1982de637c3b30 (diff)
downloadbcm5719-llvm-605109d151b4f8faab0fb25371ee4c0173e1dfba.tar.gz
bcm5719-llvm-605109d151b4f8faab0fb25371ee4c0173e1dfba.zip
Teach the constant folder how to handle a few simple i1 cases.
llvm-svn: 82340
Diffstat (limited to 'llvm')
-rw-r--r--llvm/lib/VMCore/ConstantFold.cpp31
-rw-r--r--llvm/test/Transforms/ConstProp/2009-09-19-ConstFold-i1-ConstExpr.ll25
2 files changed, 56 insertions, 0 deletions
diff --git a/llvm/lib/VMCore/ConstantFold.cpp b/llvm/lib/VMCore/ConstantFold.cpp
index 15b6df90a44..f2b8ad5d92c 100644
--- a/llvm/lib/VMCore/ConstantFold.cpp
+++ b/llvm/lib/VMCore/ConstantFold.cpp
@@ -1010,6 +1010,37 @@ Constant *llvm::ConstantFoldBinaryInstruction(LLVMContext &Context,
}
}
+ // i1 can be simplified in many cases.
+ if (C1->getType() == Type::getInt1Ty(Context)) {
+ switch (Opcode) {
+ case Instruction::Add:
+ case Instruction::Sub:
+ return ConstantExpr::getXor(const_cast<Constant*>(C1),
+ const_cast<Constant*>(C2));
+ case Instruction::Mul:
+ return ConstantExpr::getAnd(const_cast<Constant*>(C1),
+ const_cast<Constant*>(C2));
+ case Instruction::Shl:
+ case Instruction::LShr:
+ case Instruction::AShr:
+ // We can assume that C2 == 0. If it were one the result would be
+ // undefined because the shift value is as large as the bitwidth.
+ return const_cast<Constant*>(C1);
+ case Instruction::SDiv:
+ case Instruction::UDiv:
+ // We can assume that C2 == 1. If it were zero the result would be
+ // undefined through division by zero.
+ return const_cast<Constant*>(C1);
+ case Instruction::URem:
+ case Instruction::SRem:
+ // We can assume that C2 == 1. If it were zero the result would be
+ // undefined through division by zero.
+ return ConstantInt::getFalse(Context);
+ default:
+ break;
+ }
+ }
+
// We don't know how to fold this.
return 0;
}
diff --git a/llvm/test/Transforms/ConstProp/2009-09-19-ConstFold-i1-ConstExpr.ll b/llvm/test/Transforms/ConstProp/2009-09-19-ConstFold-i1-ConstExpr.ll
new file mode 100644
index 00000000000..debf9a8e5cd
--- /dev/null
+++ b/llvm/test/Transforms/ConstProp/2009-09-19-ConstFold-i1-ConstExpr.ll
@@ -0,0 +1,25 @@
+; RUN: llvm-as < %s | llvm-dis | FileCheck %s
+
+@X = external global i8
+@Y = external global i8
+@Z = external global i8
+
+global i1 add (i1 icmp ult (i8* @X, i8* @Y), i1 icmp ult (i8* @X, i8* @Z))
+; CHECK: xor
+global i1 sub (i1 icmp ult (i8* @X, i8* @Y), i1 icmp ult (i8* @X, i8* @Z))
+; CHECK: xor
+global i1 mul (i1 icmp ult (i8* @X, i8* @Y), i1 icmp ult (i8* @X, i8* @Z))
+; CHECK: and
+
+global i1 sdiv (i1 icmp ult (i8* @X, i8* @Y), i1 icmp ult (i8* @X, i8* @Z))
+; CHECK-NOT: @Z
+; CHECK: i1 icmp ult (i8* @X, i8* @Y)
+global i1 udiv (i1 icmp ult (i8* @X, i8* @Y), i1 icmp ult (i8* @X, i8* @Z))
+; CHECK-NOT: @Z
+; CHECK: i1 icmp ult (i8* @X, i8* @Y)
+global i1 srem (i1 icmp ult (i8* @X, i8* @Y), i1 icmp ult (i8* @X, i8* @Z))
+; CHECK-NOT: icmp
+; CHECK: i1 false
+global i1 urem (i1 icmp ult (i8* @X, i8* @Y), i1 icmp ult (i8* @X, i8* @Z))
+; CHECK-NOT: icmp
+; CHECK: i1 false
OpenPOWER on IntegriCloud