diff options
author | Nick Lewycky <nicholas@mxc.ca> | 2009-09-20 00:04:02 +0000 |
---|---|---|
committer | Nick Lewycky <nicholas@mxc.ca> | 2009-09-20 00:04:02 +0000 |
commit | 605109d151b4f8faab0fb25371ee4c0173e1dfba (patch) | |
tree | b2e04b3b0f5791a1fd9cec52456aeece21978984 /llvm | |
parent | fa9c6f43a0a03ff4883dc801ce1982de637c3b30 (diff) | |
download | bcm5719-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.cpp | 31 | ||||
-rw-r--r-- | llvm/test/Transforms/ConstProp/2009-09-19-ConstFold-i1-ConstExpr.ll | 25 |
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 |