move some select simplifications out out instcombine into

inst simplify.  No functionality change.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@101873 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chris Lattner 2010-04-20 05:32:14 +00:00
parent a78130c320
commit 047542669a
3 changed files with 49 additions and 31 deletions

View File

@ -46,6 +46,10 @@ namespace llvm {
Value *SimplifyFCmpInst(unsigned Predicate, Value *LHS, Value *RHS,
const TargetData *TD = 0);
/// SimplifySelectInst - Given operands for a SelectInst, see if we can fold
/// the result. If not, this returns null.
Value *SimplifySelectInst(Value *Cond, Value *TrueVal, Value *FalseVal,
const TargetData *TD = 0);
/// SimplifyGEPInst - Given operands for an GetElementPtrInst, see if we can
/// fold the result. If not, this returns null.

View File

@ -314,6 +314,35 @@ Value *llvm::SimplifyFCmpInst(unsigned Predicate, Value *LHS, Value *RHS,
return 0;
}
/// SimplifySelectInst - Given operands for a SelectInst, see if we can fold
/// the result. If not, this returns null.
Value *llvm::SimplifySelectInst(Value *CondVal, Value *TrueVal, Value *FalseVal,
const TargetData *TD) {
// select true, X, Y -> X
// select false, X, Y -> Y
if (ConstantInt *CB = dyn_cast<ConstantInt>(CondVal))
return CB->getZExtValue() ? TrueVal : FalseVal;
// select C, X, X -> X
if (TrueVal == FalseVal)
return TrueVal;
if (isa<UndefValue>(TrueVal)) // select C, undef, X -> X
return FalseVal;
if (isa<UndefValue>(FalseVal)) // select C, X, undef -> X
return TrueVal;
if (isa<UndefValue>(CondVal)) { // select undef, X, Y -> X or Y
if (isa<Constant>(TrueVal))
return TrueVal;
return FalseVal;
}
return 0;
}
/// SimplifyGEPInst - Given operands for an GetElementPtrInst, see if we can
/// fold the result. If not, this returns null.
Value *llvm::SimplifyGEPInst(Value *const *Ops, unsigned NumOps,
@ -391,6 +420,9 @@ Value *llvm::SimplifyInstruction(Instruction *I, const TargetData *TD) {
case Instruction::FCmp:
return SimplifyFCmpInst(cast<FCmpInst>(I)->getPredicate(),
I->getOperand(0), I->getOperand(1), TD);
case Instruction::Select:
return SimplifySelectInst(I->getOperand(0), I->getOperand(1),
I->getOperand(2), TD);
case Instruction::GetElementPtr: {
SmallVector<Value*, 8> Ops(I->op_begin(), I->op_end());
return SimplifyGEPInst(&Ops[0], Ops.size(), TD);

View File

@ -13,6 +13,7 @@
#include "InstCombine.h"
#include "llvm/Support/PatternMatch.h"
#include "llvm/Analysis/InstructionSimplify.h"
using namespace llvm;
using namespace PatternMatch;
@ -421,49 +422,30 @@ Instruction *InstCombiner::visitSelectInst(SelectInst &SI) {
Value *TrueVal = SI.getTrueValue();
Value *FalseVal = SI.getFalseValue();
// select true, X, Y -> X
// select false, X, Y -> Y
if (ConstantInt *C = dyn_cast<ConstantInt>(CondVal))
return ReplaceInstUsesWith(SI, C->getZExtValue() ? TrueVal : FalseVal);
// select C, X, X -> X
if (TrueVal == FalseVal)
return ReplaceInstUsesWith(SI, TrueVal);
if (isa<UndefValue>(TrueVal)) // select C, undef, X -> X
return ReplaceInstUsesWith(SI, FalseVal);
if (isa<UndefValue>(FalseVal)) // select C, X, undef -> X
return ReplaceInstUsesWith(SI, TrueVal);
if (isa<UndefValue>(CondVal)) { // select undef, X, Y -> X or Y
if (isa<Constant>(TrueVal))
return ReplaceInstUsesWith(SI, TrueVal);
else
return ReplaceInstUsesWith(SI, FalseVal);
}
if (Value *V = SimplifySelectInst(CondVal, TrueVal, FalseVal, TD))
return ReplaceInstUsesWith(SI, V);
if (SI.getType()->isIntegerTy(1)) {
if (ConstantInt *C = dyn_cast<ConstantInt>(TrueVal)) {
if (C->getZExtValue()) {
// Change: A = select B, true, C --> A = or B, C
return BinaryOperator::CreateOr(CondVal, FalseVal);
} else {
// Change: A = select B, false, C --> A = and !B, C
Value *NotCond =
InsertNewInstBefore(BinaryOperator::CreateNot(CondVal,
"not."+CondVal->getName()), SI);
return BinaryOperator::CreateAnd(NotCond, FalseVal);
}
// Change: A = select B, false, C --> A = and !B, C
Value *NotCond =
InsertNewInstBefore(BinaryOperator::CreateNot(CondVal,
"not."+CondVal->getName()), SI);
return BinaryOperator::CreateAnd(NotCond, FalseVal);
} else if (ConstantInt *C = dyn_cast<ConstantInt>(FalseVal)) {
if (C->getZExtValue() == false) {
// Change: A = select B, C, false --> A = and B, C
return BinaryOperator::CreateAnd(CondVal, TrueVal);
} else {
// Change: A = select B, C, true --> A = or !B, C
Value *NotCond =
InsertNewInstBefore(BinaryOperator::CreateNot(CondVal,
"not."+CondVal->getName()), SI);
return BinaryOperator::CreateOr(NotCond, TrueVal);
}
// Change: A = select B, C, true --> A = or !B, C
Value *NotCond =
InsertNewInstBefore(BinaryOperator::CreateNot(CondVal,
"not."+CondVal->getName()), SI);
return BinaryOperator::CreateOr(NotCond, TrueVal);
}
// select a, b, a -> a&b