mirror of
https://github.com/RPCS3/llvm.git
synced 2024-12-04 17:58:22 +00:00
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:
parent
a78130c320
commit
047542669a
@ -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.
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user