Teach the constant folder how to handle a few simple i1 cases.

llvm-svn: 82340
This commit is contained in:
Nick Lewycky 2009-09-20 00:04:02 +00:00
parent fa9c6f43a0
commit 605109d151
2 changed files with 56 additions and 0 deletions

View File

@ -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. // We don't know how to fold this.
return 0; return 0;
} }

View File

@ -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