mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-24 03:33:20 +01:00
Optimize icmp of null and select of two constants even if the select has
multiple uses. (The construct in question was found in gcc.) llvm-svn: 91675
This commit is contained in:
parent
d97d025eba
commit
c8ab298dbd
@ -6356,24 +6356,26 @@ Instruction *InstCombiner::visitICmpInst(ICmpInst &I) {
|
||||
// comparison into the select arms, which will cause one to be
|
||||
// constant folded and the select turned into a bitwise or.
|
||||
Value *Op1 = 0, *Op2 = 0;
|
||||
if (LHSI->hasOneUse()) {
|
||||
if (Constant *C = dyn_cast<Constant>(LHSI->getOperand(1))) {
|
||||
// Fold the known value into the constant operand.
|
||||
Op1 = ConstantExpr::getICmp(I.getPredicate(), C, RHSC);
|
||||
// Insert a new ICmp of the other select operand.
|
||||
Op2 = Builder->CreateICmp(I.getPredicate(), LHSI->getOperand(2),
|
||||
RHSC, I.getName());
|
||||
} else if (Constant *C = dyn_cast<Constant>(LHSI->getOperand(2))) {
|
||||
// Fold the known value into the constant operand.
|
||||
Op2 = ConstantExpr::getICmp(I.getPredicate(), C, RHSC);
|
||||
// Insert a new ICmp of the other select operand.
|
||||
if (Constant *C = dyn_cast<Constant>(LHSI->getOperand(1)))
|
||||
Op1 = ConstantExpr::getICmp(I.getPredicate(), C, RHSC);
|
||||
if (Constant *C = dyn_cast<Constant>(LHSI->getOperand(2)))
|
||||
Op2 = ConstantExpr::getICmp(I.getPredicate(), C, RHSC);
|
||||
|
||||
// We only want to perform this transformation if it will not lead to
|
||||
// additional code. This is true if either both sides of the select
|
||||
// fold to a constant (in which case the icmp is replaced with a select
|
||||
// which will usually simplify) or this is the only user of the
|
||||
// select (in which case we are trading a select+icmp for a simpler
|
||||
// select+icmp).
|
||||
if ((Op1 && Op2) || (LHSI->hasOneUse() && (Op1 || Op2))) {
|
||||
if (!Op1)
|
||||
Op1 = Builder->CreateICmp(I.getPredicate(), LHSI->getOperand(1),
|
||||
RHSC, I.getName());
|
||||
}
|
||||
}
|
||||
|
||||
if (Op1)
|
||||
if (!Op2)
|
||||
Op2 = Builder->CreateICmp(I.getPredicate(), LHSI->getOperand(2),
|
||||
RHSC, I.getName());
|
||||
return SelectInst::Create(LHSI->getOperand(0), Op1, Op2);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Instruction::Call:
|
||||
|
16
test/Transforms/InstCombine/2009-12-17-CmpSelectNull.ll
Normal file
16
test/Transforms/InstCombine/2009-12-17-CmpSelectNull.ll
Normal file
@ -0,0 +1,16 @@
|
||||
; RUN: opt < %s -instcombine -S | FileCheck %s
|
||||
|
||||
@.str254 = internal constant [2 x i8] c".\00"
|
||||
@.str557 = internal constant [3 x i8] c"::\00"
|
||||
|
||||
define i8* @demangle_qualified(i32 %isfuncname) nounwind {
|
||||
entry:
|
||||
%tobool272 = icmp ne i32 %isfuncname, 0
|
||||
%cond276 = select i1 %tobool272, i8* getelementptr inbounds ([2 x i8]* @.str254, i32 0, i32 0), i8* getelementptr inbounds ([3 x i8]* @.str557, i32 0, i32 0) ; <i8*> [#uses=4]
|
||||
%cmp.i504 = icmp eq i8* %cond276, null
|
||||
%rval = getelementptr i8* %cond276, i1 %cmp.i504
|
||||
ret i8* %rval
|
||||
}
|
||||
|
||||
; CHECK: %cond276 = select i1
|
||||
; CHECK: ret i8* %cond276
|
Loading…
Reference in New Issue
Block a user