2010-01-05 14:05:07 +08:00
|
|
|
//===- InstCombineSelect.cpp ----------------------------------------------===//
|
2010-01-05 14:03:12 +08:00
|
|
|
//
|
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//
|
2010-01-05 14:05:07 +08:00
|
|
|
// This file implements the visitSelect function.
|
2010-01-05 14:03:12 +08:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
#include "InstCombine.h"
|
2011-07-21 05:57:23 +08:00
|
|
|
#include "llvm/Analysis/ConstantFolding.h"
|
2010-04-20 13:32:14 +08:00
|
|
|
#include "llvm/Analysis/InstructionSimplify.h"
|
2014-03-04 19:08:18 +08:00
|
|
|
#include "llvm/IR/PatternMatch.h"
|
2010-01-05 14:03:12 +08:00
|
|
|
using namespace llvm;
|
|
|
|
using namespace PatternMatch;
|
|
|
|
|
2014-04-22 10:55:47 +08:00
|
|
|
#define DEBUG_TYPE "instcombine"
|
|
|
|
|
2010-01-05 14:03:12 +08:00
|
|
|
/// MatchSelectPattern - Pattern match integer [SU]MIN, [SU]MAX, and ABS idioms,
|
|
|
|
/// returning the kind and providing the out parameter results if we
|
|
|
|
/// successfully match.
|
|
|
|
static SelectPatternFlavor
|
|
|
|
MatchSelectPattern(Value *V, Value *&LHS, Value *&RHS) {
|
|
|
|
SelectInst *SI = dyn_cast<SelectInst>(V);
|
2014-04-25 13:29:35 +08:00
|
|
|
if (!SI) return SPF_UNKNOWN;
|
2011-01-08 05:33:13 +08:00
|
|
|
|
2010-01-05 14:03:12 +08:00
|
|
|
ICmpInst *ICI = dyn_cast<ICmpInst>(SI->getCondition());
|
2014-04-25 13:29:35 +08:00
|
|
|
if (!ICI) return SPF_UNKNOWN;
|
2011-01-08 05:33:13 +08:00
|
|
|
|
2014-06-06 14:54:45 +08:00
|
|
|
ICmpInst::Predicate Pred = ICI->getPredicate();
|
|
|
|
Value *CmpLHS = ICI->getOperand(0);
|
|
|
|
Value *CmpRHS = ICI->getOperand(1);
|
|
|
|
Value *TrueVal = SI->getTrueValue();
|
|
|
|
Value *FalseVal = SI->getFalseValue();
|
|
|
|
|
|
|
|
LHS = CmpLHS;
|
|
|
|
RHS = CmpRHS;
|
2011-01-08 05:33:13 +08:00
|
|
|
|
|
|
|
// (icmp X, Y) ? X : Y
|
2014-06-06 14:54:45 +08:00
|
|
|
if (TrueVal == CmpLHS && FalseVal == CmpRHS) {
|
|
|
|
switch (Pred) {
|
2010-01-05 14:03:12 +08:00
|
|
|
default: return SPF_UNKNOWN; // Equality.
|
|
|
|
case ICmpInst::ICMP_UGT:
|
|
|
|
case ICmpInst::ICMP_UGE: return SPF_UMAX;
|
|
|
|
case ICmpInst::ICMP_SGT:
|
|
|
|
case ICmpInst::ICMP_SGE: return SPF_SMAX;
|
|
|
|
case ICmpInst::ICMP_ULT:
|
|
|
|
case ICmpInst::ICMP_ULE: return SPF_UMIN;
|
|
|
|
case ICmpInst::ICMP_SLT:
|
|
|
|
case ICmpInst::ICMP_SLE: return SPF_SMIN;
|
|
|
|
}
|
|
|
|
}
|
2011-01-08 05:33:13 +08:00
|
|
|
|
|
|
|
// (icmp X, Y) ? Y : X
|
2014-06-06 14:54:45 +08:00
|
|
|
if (TrueVal == CmpRHS && FalseVal == CmpLHS) {
|
|
|
|
switch (Pred) {
|
|
|
|
default: return SPF_UNKNOWN; // Equality.
|
|
|
|
case ICmpInst::ICMP_UGT:
|
|
|
|
case ICmpInst::ICMP_UGE: return SPF_UMIN;
|
|
|
|
case ICmpInst::ICMP_SGT:
|
|
|
|
case ICmpInst::ICMP_SGE: return SPF_SMIN;
|
|
|
|
case ICmpInst::ICMP_ULT:
|
|
|
|
case ICmpInst::ICMP_ULE: return SPF_UMAX;
|
|
|
|
case ICmpInst::ICMP_SLT:
|
|
|
|
case ICmpInst::ICMP_SLE: return SPF_SMAX;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ConstantInt *C1 = dyn_cast<ConstantInt>(CmpRHS)) {
|
|
|
|
if ((CmpLHS == TrueVal && match(FalseVal, m_Neg(m_Specific(CmpLHS)))) ||
|
|
|
|
(CmpLHS == FalseVal && match(TrueVal, m_Neg(m_Specific(CmpLHS))))) {
|
|
|
|
|
|
|
|
// ABS(X) ==> (X >s 0) ? X : -X and (X >s -1) ? X : -X
|
|
|
|
// NABS(X) ==> (X >s 0) ? -X : X and (X >s -1) ? -X : X
|
|
|
|
if (Pred == ICmpInst::ICMP_SGT && (C1->isZero() || C1->isMinusOne())) {
|
|
|
|
return (CmpLHS == TrueVal) ? SPF_ABS : SPF_NABS;
|
|
|
|
}
|
|
|
|
|
|
|
|
// ABS(X) ==> (X <s 0) ? -X : X and (X <s 1) ? -X : X
|
|
|
|
// NABS(X) ==> (X <s 0) ? X : -X and (X <s 1) ? X : -X
|
|
|
|
if (Pred == ICmpInst::ICMP_SLT && (C1->isZero() || C1->isOne())) {
|
|
|
|
return (CmpLHS == FalseVal) ? SPF_ABS : SPF_NABS;
|
|
|
|
}
|
2010-01-05 14:03:12 +08:00
|
|
|
}
|
|
|
|
}
|
2011-01-08 05:33:13 +08:00
|
|
|
|
2010-01-05 14:03:12 +08:00
|
|
|
// TODO: (X > 4) ? X : 5 --> (X >= 5) ? X : 5 --> MAX(X, 5)
|
2011-01-08 05:33:13 +08:00
|
|
|
|
2010-01-05 14:03:12 +08:00
|
|
|
return SPF_UNKNOWN;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// GetSelectFoldableOperands - We want to turn code that looks like this:
|
|
|
|
/// %C = or %A, %B
|
|
|
|
/// %D = select %cond, %C, %A
|
|
|
|
/// into:
|
|
|
|
/// %C = select %cond, %B, 0
|
|
|
|
/// %D = or %A, %C
|
|
|
|
///
|
|
|
|
/// Assuming that the specified instruction is an operand to the select, return
|
|
|
|
/// a bitmask indicating which operands of this instruction are foldable if they
|
|
|
|
/// equal the other incoming value of the select.
|
|
|
|
///
|
|
|
|
static unsigned GetSelectFoldableOperands(Instruction *I) {
|
|
|
|
switch (I->getOpcode()) {
|
|
|
|
case Instruction::Add:
|
|
|
|
case Instruction::Mul:
|
|
|
|
case Instruction::And:
|
|
|
|
case Instruction::Or:
|
|
|
|
case Instruction::Xor:
|
|
|
|
return 3; // Can fold through either operand.
|
|
|
|
case Instruction::Sub: // Can only fold on the amount subtracted.
|
|
|
|
case Instruction::Shl: // Can only fold on the shift amount.
|
|
|
|
case Instruction::LShr:
|
|
|
|
case Instruction::AShr:
|
|
|
|
return 1;
|
|
|
|
default:
|
|
|
|
return 0; // Cannot fold
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// GetSelectFoldableConstant - For the same transformation as the previous
|
|
|
|
/// function, return the identity constant that goes into the select.
|
|
|
|
static Constant *GetSelectFoldableConstant(Instruction *I) {
|
|
|
|
switch (I->getOpcode()) {
|
|
|
|
default: llvm_unreachable("This cannot happen!");
|
|
|
|
case Instruction::Add:
|
|
|
|
case Instruction::Sub:
|
|
|
|
case Instruction::Or:
|
|
|
|
case Instruction::Xor:
|
|
|
|
case Instruction::Shl:
|
|
|
|
case Instruction::LShr:
|
|
|
|
case Instruction::AShr:
|
|
|
|
return Constant::getNullValue(I->getType());
|
|
|
|
case Instruction::And:
|
|
|
|
return Constant::getAllOnesValue(I->getType());
|
|
|
|
case Instruction::Mul:
|
|
|
|
return ConstantInt::get(I->getType(), 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// FoldSelectOpOp - Here we have (select c, TI, FI), and we know that TI and FI
|
|
|
|
/// have the same opcode and only one use each. Try to simplify this.
|
|
|
|
Instruction *InstCombiner::FoldSelectOpOp(SelectInst &SI, Instruction *TI,
|
|
|
|
Instruction *FI) {
|
|
|
|
if (TI->getNumOperands() == 1) {
|
|
|
|
// If this is a non-volatile load or a cast from the same type,
|
|
|
|
// merge.
|
|
|
|
if (TI->isCast()) {
|
2013-03-28 09:28:02 +08:00
|
|
|
Type *FIOpndTy = FI->getOperand(0)->getType();
|
|
|
|
if (TI->getOperand(0)->getType() != FIOpndTy)
|
2014-04-25 13:29:35 +08:00
|
|
|
return nullptr;
|
2012-06-08 04:28:57 +08:00
|
|
|
// The select condition may be a vector. We may only change the operand
|
|
|
|
// type if the vector width remains the same (and matches the condition).
|
|
|
|
Type *CondTy = SI.getCondition()->getType();
|
2013-03-28 09:28:02 +08:00
|
|
|
if (CondTy->isVectorTy() && (!FIOpndTy->isVectorTy() ||
|
|
|
|
CondTy->getVectorNumElements() != FIOpndTy->getVectorNumElements()))
|
2014-04-25 13:29:35 +08:00
|
|
|
return nullptr;
|
2010-01-05 14:03:12 +08:00
|
|
|
} else {
|
2014-04-25 13:29:35 +08:00
|
|
|
return nullptr; // unknown unary op.
|
2010-01-05 14:03:12 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// Fold this by inserting a select from the input values.
|
2011-05-19 02:10:28 +08:00
|
|
|
Value *NewSI = Builder->CreateSelect(SI.getCondition(), TI->getOperand(0),
|
|
|
|
FI->getOperand(0), SI.getName()+".v");
|
2011-01-08 05:33:13 +08:00
|
|
|
return CastInst::Create(Instruction::CastOps(TI->getOpcode()), NewSI,
|
2010-01-05 14:03:12 +08:00
|
|
|
TI->getType());
|
|
|
|
}
|
|
|
|
|
|
|
|
// Only handle binary operators here.
|
|
|
|
if (!isa<BinaryOperator>(TI))
|
2014-04-25 13:29:35 +08:00
|
|
|
return nullptr;
|
2010-01-05 14:03:12 +08:00
|
|
|
|
|
|
|
// Figure out if the operations have any operands in common.
|
|
|
|
Value *MatchOp, *OtherOpT, *OtherOpF;
|
|
|
|
bool MatchIsOpZero;
|
|
|
|
if (TI->getOperand(0) == FI->getOperand(0)) {
|
|
|
|
MatchOp = TI->getOperand(0);
|
|
|
|
OtherOpT = TI->getOperand(1);
|
|
|
|
OtherOpF = FI->getOperand(1);
|
|
|
|
MatchIsOpZero = true;
|
|
|
|
} else if (TI->getOperand(1) == FI->getOperand(1)) {
|
|
|
|
MatchOp = TI->getOperand(1);
|
|
|
|
OtherOpT = TI->getOperand(0);
|
|
|
|
OtherOpF = FI->getOperand(0);
|
|
|
|
MatchIsOpZero = false;
|
|
|
|
} else if (!TI->isCommutative()) {
|
2014-04-25 13:29:35 +08:00
|
|
|
return nullptr;
|
2010-01-05 14:03:12 +08:00
|
|
|
} else if (TI->getOperand(0) == FI->getOperand(1)) {
|
|
|
|
MatchOp = TI->getOperand(0);
|
|
|
|
OtherOpT = TI->getOperand(1);
|
|
|
|
OtherOpF = FI->getOperand(0);
|
|
|
|
MatchIsOpZero = true;
|
|
|
|
} else if (TI->getOperand(1) == FI->getOperand(0)) {
|
|
|
|
MatchOp = TI->getOperand(1);
|
|
|
|
OtherOpT = TI->getOperand(0);
|
|
|
|
OtherOpF = FI->getOperand(1);
|
|
|
|
MatchIsOpZero = true;
|
|
|
|
} else {
|
2014-04-25 13:29:35 +08:00
|
|
|
return nullptr;
|
2010-01-05 14:03:12 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// If we reach here, they do have operations in common.
|
2011-05-19 02:10:28 +08:00
|
|
|
Value *NewSI = Builder->CreateSelect(SI.getCondition(), OtherOpT,
|
|
|
|
OtherOpF, SI.getName()+".v");
|
2010-01-05 14:03:12 +08:00
|
|
|
|
|
|
|
if (BinaryOperator *BO = dyn_cast<BinaryOperator>(TI)) {
|
|
|
|
if (MatchIsOpZero)
|
|
|
|
return BinaryOperator::Create(BO->getOpcode(), MatchOp, NewSI);
|
|
|
|
else
|
|
|
|
return BinaryOperator::Create(BO->getOpcode(), NewSI, MatchOp);
|
|
|
|
}
|
|
|
|
llvm_unreachable("Shouldn't get here");
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool isSelect01(Constant *C1, Constant *C2) {
|
|
|
|
ConstantInt *C1I = dyn_cast<ConstantInt>(C1);
|
|
|
|
if (!C1I)
|
|
|
|
return false;
|
|
|
|
ConstantInt *C2I = dyn_cast<ConstantInt>(C2);
|
|
|
|
if (!C2I)
|
|
|
|
return false;
|
2010-12-23 07:12:15 +08:00
|
|
|
if (!C1I->isZero() && !C2I->isZero()) // One side must be zero.
|
|
|
|
return false;
|
|
|
|
return C1I->isOne() || C1I->isAllOnesValue() ||
|
|
|
|
C2I->isOne() || C2I->isAllOnesValue();
|
2010-01-05 14:03:12 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/// FoldSelectIntoOp - Try fold the select into one of the operands to
|
|
|
|
/// facilitate further optimization.
|
|
|
|
Instruction *InstCombiner::FoldSelectIntoOp(SelectInst &SI, Value *TrueVal,
|
|
|
|
Value *FalseVal) {
|
|
|
|
// See the comment above GetSelectFoldableOperands for a description of the
|
|
|
|
// transformation we are doing here.
|
|
|
|
if (Instruction *TVI = dyn_cast<Instruction>(TrueVal)) {
|
|
|
|
if (TVI->hasOneUse() && TVI->getNumOperands() == 2 &&
|
|
|
|
!isa<Constant>(FalseVal)) {
|
|
|
|
if (unsigned SFO = GetSelectFoldableOperands(TVI)) {
|
|
|
|
unsigned OpToFold = 0;
|
|
|
|
if ((SFO & 1) && FalseVal == TVI->getOperand(0)) {
|
|
|
|
OpToFold = 1;
|
2011-03-28 03:51:23 +08:00
|
|
|
} else if ((SFO & 2) && FalseVal == TVI->getOperand(1)) {
|
2010-01-05 14:03:12 +08:00
|
|
|
OpToFold = 2;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (OpToFold) {
|
|
|
|
Constant *C = GetSelectFoldableConstant(TVI);
|
|
|
|
Value *OOp = TVI->getOperand(2-OpToFold);
|
|
|
|
// Avoid creating select between 2 constants unless it's selecting
|
2010-12-23 07:12:15 +08:00
|
|
|
// between 0, 1 and -1.
|
2010-01-05 14:03:12 +08:00
|
|
|
if (!isa<Constant>(OOp) || isSelect01(C, cast<Constant>(OOp))) {
|
2011-05-19 02:10:28 +08:00
|
|
|
Value *NewSel = Builder->CreateSelect(SI.getCondition(), OOp, C);
|
2010-01-05 14:03:12 +08:00
|
|
|
NewSel->takeName(TVI);
|
2011-03-29 01:48:26 +08:00
|
|
|
BinaryOperator *TVI_BO = cast<BinaryOperator>(TVI);
|
2011-03-28 03:51:23 +08:00
|
|
|
BinaryOperator *BO = BinaryOperator::Create(TVI_BO->getOpcode(),
|
|
|
|
FalseVal, NewSel);
|
2011-03-29 01:48:26 +08:00
|
|
|
if (isa<PossiblyExactOperator>(BO))
|
|
|
|
BO->setIsExact(TVI_BO->isExact());
|
|
|
|
if (isa<OverflowingBinaryOperator>(BO)) {
|
|
|
|
BO->setHasNoUnsignedWrap(TVI_BO->hasNoUnsignedWrap());
|
|
|
|
BO->setHasNoSignedWrap(TVI_BO->hasNoSignedWrap());
|
|
|
|
}
|
|
|
|
return BO;
|
2010-01-05 14:03:12 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (Instruction *FVI = dyn_cast<Instruction>(FalseVal)) {
|
|
|
|
if (FVI->hasOneUse() && FVI->getNumOperands() == 2 &&
|
|
|
|
!isa<Constant>(TrueVal)) {
|
|
|
|
if (unsigned SFO = GetSelectFoldableOperands(FVI)) {
|
|
|
|
unsigned OpToFold = 0;
|
|
|
|
if ((SFO & 1) && TrueVal == FVI->getOperand(0)) {
|
|
|
|
OpToFold = 1;
|
2011-03-28 03:51:23 +08:00
|
|
|
} else if ((SFO & 2) && TrueVal == FVI->getOperand(1)) {
|
2010-01-05 14:03:12 +08:00
|
|
|
OpToFold = 2;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (OpToFold) {
|
|
|
|
Constant *C = GetSelectFoldableConstant(FVI);
|
|
|
|
Value *OOp = FVI->getOperand(2-OpToFold);
|
|
|
|
// Avoid creating select between 2 constants unless it's selecting
|
2010-12-23 07:12:15 +08:00
|
|
|
// between 0, 1 and -1.
|
2010-01-05 14:03:12 +08:00
|
|
|
if (!isa<Constant>(OOp) || isSelect01(C, cast<Constant>(OOp))) {
|
2011-05-19 02:10:28 +08:00
|
|
|
Value *NewSel = Builder->CreateSelect(SI.getCondition(), C, OOp);
|
2010-01-05 14:03:12 +08:00
|
|
|
NewSel->takeName(FVI);
|
2011-03-28 03:51:23 +08:00
|
|
|
BinaryOperator *FVI_BO = cast<BinaryOperator>(FVI);
|
|
|
|
BinaryOperator *BO = BinaryOperator::Create(FVI_BO->getOpcode(),
|
|
|
|
TrueVal, NewSel);
|
2011-03-29 01:48:26 +08:00
|
|
|
if (isa<PossiblyExactOperator>(BO))
|
|
|
|
BO->setIsExact(FVI_BO->isExact());
|
|
|
|
if (isa<OverflowingBinaryOperator>(BO)) {
|
|
|
|
BO->setHasNoUnsignedWrap(FVI_BO->hasNoUnsignedWrap());
|
|
|
|
BO->setHasNoSignedWrap(FVI_BO->hasNoSignedWrap());
|
|
|
|
}
|
|
|
|
return BO;
|
2010-01-05 14:03:12 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-04-25 13:29:35 +08:00
|
|
|
return nullptr;
|
2010-01-05 14:03:12 +08:00
|
|
|
}
|
|
|
|
|
2011-05-27 21:00:16 +08:00
|
|
|
/// SimplifyWithOpReplaced - See if V simplifies when its operand Op is
|
|
|
|
/// replaced with RepOp.
|
|
|
|
static Value *SimplifyWithOpReplaced(Value *V, Value *Op, Value *RepOp,
|
2012-10-09 00:38:25 +08:00
|
|
|
const DataLayout *TD,
|
Make use of @llvm.assume in ValueTracking (computeKnownBits, etc.)
This change, which allows @llvm.assume to be used from within computeKnownBits
(and other associated functions in ValueTracking), adds some (optional)
parameters to computeKnownBits and friends. These functions now (optionally)
take a "context" instruction pointer, an AssumptionTracker pointer, and also a
DomTree pointer, and most of the changes are just to pass this new information
when it is easily available from InstSimplify, InstCombine, etc.
As explained below, the significant conceptual change is that known properties
of a value might depend on the control-flow location of the use (because we
care that the @llvm.assume dominates the use because assumptions have
control-flow dependencies). This means that, when we ask if bits are known in a
value, we might get different answers for different uses.
The significant changes are all in ValueTracking. Two main changes: First, as
with the rest of the code, new parameters need to be passed around. To make
this easier, I grouped them into a structure, and I made internal static
versions of the relevant functions that take this structure as a parameter. The
new code does as you might expect, it looks for @llvm.assume calls that make
use of the value we're trying to learn something about (often indirectly),
attempts to pattern match that expression, and uses the result if successful.
By making use of the AssumptionTracker, the process of finding @llvm.assume
calls is not expensive.
Part of the structure being passed around inside ValueTracking is a set of
already-considered @llvm.assume calls. This is to prevent a query using, for
example, the assume(a == b), to recurse on itself. The context and DT params
are used to find applicable assumptions. An assumption needs to dominate the
context instruction, or come after it deterministically. In this latter case we
only handle the specific case where both the assumption and the context
instruction are in the same block, and we need to exclude assumptions from
being used to simplify their own ephemeral values (those which contribute only
to the assumption) because otherwise the assumption would prove its feeding
comparison trivial and would be removed.
This commit adds the plumbing and the logic for a simple masked-bit propagation
(just enough to write a regression test). Future commits add more patterns
(and, correspondingly, more regression tests).
llvm-svn: 217342
2014-09-08 02:57:58 +08:00
|
|
|
const TargetLibraryInfo *TLI,
|
2015-01-04 20:03:27 +08:00
|
|
|
DominatorTree *DT, AssumptionCache *AC) {
|
2011-05-27 21:00:16 +08:00
|
|
|
// Trivial replacement.
|
|
|
|
if (V == Op)
|
|
|
|
return RepOp;
|
|
|
|
|
|
|
|
Instruction *I = dyn_cast<Instruction>(V);
|
|
|
|
if (!I)
|
2014-04-25 13:29:35 +08:00
|
|
|
return nullptr;
|
2011-05-27 21:00:16 +08:00
|
|
|
|
|
|
|
// If this is a binary operator, try to simplify it with the replaced op.
|
|
|
|
if (BinaryOperator *B = dyn_cast<BinaryOperator>(I)) {
|
|
|
|
if (B->getOperand(0) == Op)
|
2011-12-02 09:26:24 +08:00
|
|
|
return SimplifyBinOp(B->getOpcode(), RepOp, B->getOperand(1), TD, TLI);
|
2011-05-27 21:00:16 +08:00
|
|
|
if (B->getOperand(1) == Op)
|
2011-12-02 09:26:24 +08:00
|
|
|
return SimplifyBinOp(B->getOpcode(), B->getOperand(0), RepOp, TD, TLI);
|
2011-05-27 21:00:16 +08:00
|
|
|
}
|
|
|
|
|
2011-05-28 18:16:58 +08:00
|
|
|
// Same for CmpInsts.
|
|
|
|
if (CmpInst *C = dyn_cast<CmpInst>(I)) {
|
|
|
|
if (C->getOperand(0) == Op)
|
2011-12-02 09:26:24 +08:00
|
|
|
return SimplifyCmpInst(C->getPredicate(), RepOp, C->getOperand(1), TD,
|
2015-01-04 20:03:27 +08:00
|
|
|
TLI, DT, AC);
|
2011-05-28 18:16:58 +08:00
|
|
|
if (C->getOperand(1) == Op)
|
2011-12-02 09:26:24 +08:00
|
|
|
return SimplifyCmpInst(C->getPredicate(), C->getOperand(0), RepOp, TD,
|
2015-01-04 20:03:27 +08:00
|
|
|
TLI, DT, AC);
|
2011-05-28 18:16:58 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// TODO: We could hand off more cases to instsimplify here.
|
|
|
|
|
2011-05-27 21:00:16 +08:00
|
|
|
// If all operands are constant after substituting Op for RepOp then we can
|
|
|
|
// constant fold the instruction.
|
|
|
|
if (Constant *CRepOp = dyn_cast<Constant>(RepOp)) {
|
|
|
|
// Build a list of all constant operands.
|
|
|
|
SmallVector<Constant*, 8> ConstOps;
|
|
|
|
for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) {
|
|
|
|
if (I->getOperand(i) == Op)
|
|
|
|
ConstOps.push_back(CRepOp);
|
|
|
|
else if (Constant *COp = dyn_cast<Constant>(I->getOperand(i)))
|
|
|
|
ConstOps.push_back(COp);
|
|
|
|
else
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
// All operands were constants, fold it.
|
2011-10-02 17:12:55 +08:00
|
|
|
if (ConstOps.size() == I->getNumOperands()) {
|
2012-10-20 16:43:52 +08:00
|
|
|
if (CmpInst *C = dyn_cast<CmpInst>(I))
|
|
|
|
return ConstantFoldCompareInstOperands(C->getPredicate(), ConstOps[0],
|
|
|
|
ConstOps[1], TD, TLI);
|
|
|
|
|
2011-10-02 17:12:55 +08:00
|
|
|
if (LoadInst *LI = dyn_cast<LoadInst>(I))
|
|
|
|
if (!LI->isVolatile())
|
|
|
|
return ConstantFoldLoadFromConstPtr(ConstOps[0], TD);
|
|
|
|
|
2011-05-27 21:00:16 +08:00
|
|
|
return ConstantFoldInstOperands(I->getOpcode(), I->getType(),
|
2011-12-02 09:26:24 +08:00
|
|
|
ConstOps, TD, TLI);
|
2011-10-02 17:12:55 +08:00
|
|
|
}
|
2011-05-27 21:00:16 +08:00
|
|
|
}
|
|
|
|
|
2014-04-25 13:29:35 +08:00
|
|
|
return nullptr;
|
2011-05-27 21:00:16 +08:00
|
|
|
}
|
|
|
|
|
2013-04-30 16:57:58 +08:00
|
|
|
/// foldSelectICmpAndOr - We want to turn:
|
|
|
|
/// (select (icmp eq (and X, C1), 0), Y, (or Y, C2))
|
|
|
|
/// into:
|
|
|
|
/// (or (shl (and X, C1), C3), y)
|
|
|
|
/// iff:
|
|
|
|
/// C1 and C2 are both powers of 2
|
|
|
|
/// where:
|
|
|
|
/// C3 = Log(C2) - Log(C1)
|
|
|
|
///
|
|
|
|
/// This transform handles cases where:
|
|
|
|
/// 1. The icmp predicate is inverted
|
|
|
|
/// 2. The select operands are reversed
|
|
|
|
/// 3. The magnitude of C2 and C1 are flipped
|
2014-11-27 07:00:38 +08:00
|
|
|
static Value *foldSelectICmpAndOr(const SelectInst &SI, Value *TrueVal,
|
2013-04-30 16:57:58 +08:00
|
|
|
Value *FalseVal,
|
|
|
|
InstCombiner::BuilderTy *Builder) {
|
|
|
|
const ICmpInst *IC = dyn_cast<ICmpInst>(SI.getCondition());
|
2013-09-28 04:35:39 +08:00
|
|
|
if (!IC || !IC->isEquality() || !SI.getType()->isIntegerTy())
|
2014-04-25 13:29:35 +08:00
|
|
|
return nullptr;
|
2013-04-30 16:57:58 +08:00
|
|
|
|
|
|
|
Value *CmpLHS = IC->getOperand(0);
|
|
|
|
Value *CmpRHS = IC->getOperand(1);
|
|
|
|
|
|
|
|
if (!match(CmpRHS, m_Zero()))
|
2014-04-25 13:29:35 +08:00
|
|
|
return nullptr;
|
2013-04-30 16:57:58 +08:00
|
|
|
|
|
|
|
Value *X;
|
|
|
|
const APInt *C1;
|
|
|
|
if (!match(CmpLHS, m_And(m_Value(X), m_Power2(C1))))
|
2014-04-25 13:29:35 +08:00
|
|
|
return nullptr;
|
2013-04-30 16:57:58 +08:00
|
|
|
|
|
|
|
const APInt *C2;
|
2014-05-15 16:22:55 +08:00
|
|
|
bool OrOnTrueVal = false;
|
|
|
|
bool OrOnFalseVal = match(FalseVal, m_Or(m_Specific(TrueVal), m_Power2(C2)));
|
|
|
|
if (!OrOnFalseVal)
|
|
|
|
OrOnTrueVal = match(TrueVal, m_Or(m_Specific(FalseVal), m_Power2(C2)));
|
2013-04-30 16:57:58 +08:00
|
|
|
|
|
|
|
if (!OrOnFalseVal && !OrOnTrueVal)
|
2014-04-25 13:29:35 +08:00
|
|
|
return nullptr;
|
2013-04-30 16:57:58 +08:00
|
|
|
|
|
|
|
Value *V = CmpLHS;
|
|
|
|
Value *Y = OrOnFalseVal ? TrueVal : FalseVal;
|
|
|
|
|
|
|
|
unsigned C1Log = C1->logBase2();
|
|
|
|
unsigned C2Log = C2->logBase2();
|
|
|
|
if (C2Log > C1Log) {
|
|
|
|
V = Builder->CreateZExtOrTrunc(V, Y->getType());
|
|
|
|
V = Builder->CreateShl(V, C2Log - C1Log);
|
|
|
|
} else if (C1Log > C2Log) {
|
|
|
|
V = Builder->CreateLShr(V, C1Log - C2Log);
|
|
|
|
V = Builder->CreateZExtOrTrunc(V, Y->getType());
|
2013-04-30 18:36:33 +08:00
|
|
|
} else
|
|
|
|
V = Builder->CreateZExtOrTrunc(V, Y->getType());
|
2013-04-30 16:57:58 +08:00
|
|
|
|
|
|
|
ICmpInst::Predicate Pred = IC->getPredicate();
|
|
|
|
if ((Pred == ICmpInst::ICMP_NE && OrOnFalseVal) ||
|
|
|
|
(Pred == ICmpInst::ICMP_EQ && OrOnTrueVal))
|
|
|
|
V = Builder->CreateXor(V, *C2);
|
|
|
|
|
|
|
|
return Builder->CreateOr(V, Y);
|
|
|
|
}
|
|
|
|
|
2010-01-05 14:03:12 +08:00
|
|
|
/// visitSelectInstWithICmp - Visit a SelectInst that has an
|
|
|
|
/// ICmpInst as its first operand.
|
|
|
|
///
|
|
|
|
Instruction *InstCombiner::visitSelectInstWithICmp(SelectInst &SI,
|
|
|
|
ICmpInst *ICI) {
|
|
|
|
bool Changed = false;
|
|
|
|
ICmpInst::Predicate Pred = ICI->getPredicate();
|
|
|
|
Value *CmpLHS = ICI->getOperand(0);
|
|
|
|
Value *CmpRHS = ICI->getOperand(1);
|
|
|
|
Value *TrueVal = SI.getTrueValue();
|
|
|
|
Value *FalseVal = SI.getFalseValue();
|
|
|
|
|
|
|
|
// Check cases where the comparison is with a constant that
|
2011-01-10 00:00:11 +08:00
|
|
|
// can be adjusted to fit the min/max idiom. We may move or edit ICI
|
|
|
|
// here, so make sure the select is the only user.
|
2010-01-05 14:03:12 +08:00
|
|
|
if (ICI->hasOneUse())
|
|
|
|
if (ConstantInt *CI = dyn_cast<ConstantInt>(CmpRHS)) {
|
2011-01-08 05:33:14 +08:00
|
|
|
// X < MIN ? T : F --> F
|
|
|
|
if ((Pred == ICmpInst::ICMP_SLT || Pred == ICmpInst::ICMP_ULT)
|
|
|
|
&& CI->isMinValue(Pred == ICmpInst::ICMP_SLT))
|
|
|
|
return ReplaceInstUsesWith(SI, FalseVal);
|
|
|
|
// X > MAX ? T : F --> F
|
|
|
|
else if ((Pred == ICmpInst::ICMP_SGT || Pred == ICmpInst::ICMP_UGT)
|
|
|
|
&& CI->isMaxValue(Pred == ICmpInst::ICMP_SGT))
|
|
|
|
return ReplaceInstUsesWith(SI, FalseVal);
|
2010-01-05 14:03:12 +08:00
|
|
|
switch (Pred) {
|
|
|
|
default: break;
|
|
|
|
case ICmpInst::ICMP_ULT:
|
2011-01-08 05:33:14 +08:00
|
|
|
case ICmpInst::ICMP_SLT:
|
2010-01-05 14:03:12 +08:00
|
|
|
case ICmpInst::ICMP_UGT:
|
|
|
|
case ICmpInst::ICMP_SGT: {
|
2011-01-08 18:51:36 +08:00
|
|
|
// These transformations only work for selects over integers.
|
2011-07-18 12:54:35 +08:00
|
|
|
IntegerType *SelectTy = dyn_cast<IntegerType>(SI.getType());
|
2011-01-08 18:51:36 +08:00
|
|
|
if (!SelectTy)
|
|
|
|
break;
|
|
|
|
|
2011-01-08 05:33:14 +08:00
|
|
|
Constant *AdjustedRHS;
|
|
|
|
if (Pred == ICmpInst::ICMP_UGT || Pred == ICmpInst::ICMP_SGT)
|
|
|
|
AdjustedRHS = ConstantInt::get(CI->getContext(), CI->getValue() + 1);
|
|
|
|
else // (Pred == ICmpInst::ICMP_ULT || Pred == ICmpInst::ICMP_SLT)
|
|
|
|
AdjustedRHS = ConstantInt::get(CI->getContext(), CI->getValue() - 1);
|
|
|
|
|
2010-01-05 14:03:12 +08:00
|
|
|
// X > C ? X : C+1 --> X < C+1 ? C+1 : X
|
2011-01-08 05:33:14 +08:00
|
|
|
// X < C ? X : C-1 --> X > C-1 ? C-1 : X
|
2010-01-05 14:03:12 +08:00
|
|
|
if ((CmpLHS == TrueVal && AdjustedRHS == FalseVal) ||
|
2011-01-08 05:33:14 +08:00
|
|
|
(CmpLHS == FalseVal && AdjustedRHS == TrueVal))
|
|
|
|
; // Nothing to do here. Values match without any sign/zero extension.
|
|
|
|
|
|
|
|
// Types do not match. Instead of calculating this with mixed types
|
|
|
|
// promote all to the larger type. This enables scalar evolution to
|
|
|
|
// analyze this expression.
|
|
|
|
else if (CmpRHS->getType()->getScalarSizeInBits()
|
2011-01-08 18:51:36 +08:00
|
|
|
< SelectTy->getBitWidth()) {
|
|
|
|
Constant *sextRHS = ConstantExpr::getSExt(AdjustedRHS, SelectTy);
|
2011-01-08 05:33:14 +08:00
|
|
|
|
|
|
|
// X = sext x; x >s c ? X : C+1 --> X = sext x; X <s C+1 ? C+1 : X
|
|
|
|
// X = sext x; x <s c ? X : C-1 --> X = sext x; X >s C-1 ? C-1 : X
|
|
|
|
// X = sext x; x >u c ? X : C+1 --> X = sext x; X <u C+1 ? C+1 : X
|
|
|
|
// X = sext x; x <u c ? X : C-1 --> X = sext x; X >u C-1 ? C-1 : X
|
|
|
|
if (match(TrueVal, m_SExt(m_Specific(CmpLHS))) &&
|
|
|
|
sextRHS == FalseVal) {
|
|
|
|
CmpLHS = TrueVal;
|
|
|
|
AdjustedRHS = sextRHS;
|
|
|
|
} else if (match(FalseVal, m_SExt(m_Specific(CmpLHS))) &&
|
|
|
|
sextRHS == TrueVal) {
|
|
|
|
CmpLHS = FalseVal;
|
|
|
|
AdjustedRHS = sextRHS;
|
|
|
|
} else if (ICI->isUnsigned()) {
|
2011-01-08 18:51:36 +08:00
|
|
|
Constant *zextRHS = ConstantExpr::getZExt(AdjustedRHS, SelectTy);
|
2011-01-08 05:33:14 +08:00
|
|
|
// X = zext x; x >u c ? X : C+1 --> X = zext x; X <u C+1 ? C+1 : X
|
|
|
|
// X = zext x; x <u c ? X : C-1 --> X = zext x; X >u C-1 ? C-1 : X
|
|
|
|
// zext + signed compare cannot be changed:
|
|
|
|
// 0xff <s 0x00, but 0x00ff >s 0x0000
|
|
|
|
if (match(TrueVal, m_ZExt(m_Specific(CmpLHS))) &&
|
|
|
|
zextRHS == FalseVal) {
|
|
|
|
CmpLHS = TrueVal;
|
|
|
|
AdjustedRHS = zextRHS;
|
|
|
|
} else if (match(FalseVal, m_ZExt(m_Specific(CmpLHS))) &&
|
|
|
|
zextRHS == TrueVal) {
|
|
|
|
CmpLHS = FalseVal;
|
|
|
|
AdjustedRHS = zextRHS;
|
|
|
|
} else
|
|
|
|
break;
|
|
|
|
} else
|
|
|
|
break;
|
|
|
|
} else
|
|
|
|
break;
|
|
|
|
|
|
|
|
Pred = ICmpInst::getSwappedPredicate(Pred);
|
|
|
|
CmpRHS = AdjustedRHS;
|
|
|
|
std::swap(FalseVal, TrueVal);
|
|
|
|
ICI->setPredicate(Pred);
|
|
|
|
ICI->setOperand(0, CmpLHS);
|
|
|
|
ICI->setOperand(1, CmpRHS);
|
|
|
|
SI.setOperand(1, TrueVal);
|
|
|
|
SI.setOperand(2, FalseVal);
|
2011-01-10 00:00:11 +08:00
|
|
|
|
|
|
|
// Move ICI instruction right before the select instruction. Otherwise
|
|
|
|
// the sext/zext value may be defined after the ICI instruction uses it.
|
|
|
|
ICI->moveBefore(&SI);
|
|
|
|
|
2011-01-08 05:33:14 +08:00
|
|
|
Changed = true;
|
2010-01-05 14:03:12 +08:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-07-08 19:39:10 +08:00
|
|
|
// Transform (X >s -1) ? C1 : C2 --> ((X >>s 31) & (C2 - C1)) + C1
|
|
|
|
// and (X <s 0) ? C2 : C1 --> ((X >>s 31) & (C2 - C1)) + C1
|
|
|
|
// FIXME: Type and constness constraints could be lifted, but we have to
|
|
|
|
// watch code size carefully. We should consider xor instead of
|
|
|
|
// sub/add when we decide to do that.
|
2011-07-18 12:54:35 +08:00
|
|
|
if (IntegerType *Ty = dyn_cast<IntegerType>(CmpLHS->getType())) {
|
2010-07-08 19:39:10 +08:00
|
|
|
if (TrueVal->getType() == Ty) {
|
|
|
|
if (ConstantInt *Cmp = dyn_cast<ConstantInt>(CmpRHS)) {
|
2014-04-25 13:29:35 +08:00
|
|
|
ConstantInt *C1 = nullptr, *C2 = nullptr;
|
2010-07-08 19:39:10 +08:00
|
|
|
if (Pred == ICmpInst::ICMP_SGT && Cmp->isAllOnesValue()) {
|
|
|
|
C1 = dyn_cast<ConstantInt>(TrueVal);
|
|
|
|
C2 = dyn_cast<ConstantInt>(FalseVal);
|
|
|
|
} else if (Pred == ICmpInst::ICMP_SLT && Cmp->isNullValue()) {
|
|
|
|
C1 = dyn_cast<ConstantInt>(FalseVal);
|
|
|
|
C2 = dyn_cast<ConstantInt>(TrueVal);
|
|
|
|
}
|
|
|
|
if (C1 && C2) {
|
|
|
|
// This shift results in either -1 or 0.
|
|
|
|
Value *AShr = Builder->CreateAShr(CmpLHS, Ty->getBitWidth()-1);
|
|
|
|
|
|
|
|
// Check if we can express the operation with a single or.
|
|
|
|
if (C2->isAllOnesValue())
|
|
|
|
return ReplaceInstUsesWith(SI, Builder->CreateOr(AShr, C1));
|
|
|
|
|
|
|
|
Value *And = Builder->CreateAnd(AShr, C2->getValue()-C1->getValue());
|
|
|
|
return ReplaceInstUsesWith(SI, Builder->CreateAdd(And, C1));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-05-27 21:00:16 +08:00
|
|
|
// If we have an equality comparison then we know the value in one of the
|
|
|
|
// arms of the select. See if substituting this value into the arm and
|
|
|
|
// simplifying the result yields the same value as the other arm.
|
|
|
|
if (Pred == ICmpInst::ICMP_EQ) {
|
2015-01-04 20:03:27 +08:00
|
|
|
if (SimplifyWithOpReplaced(FalseVal, CmpLHS, CmpRHS, DL, TLI, DT, AC) ==
|
|
|
|
TrueVal ||
|
|
|
|
SimplifyWithOpReplaced(FalseVal, CmpRHS, CmpLHS, DL, TLI, DT, AC) ==
|
|
|
|
TrueVal)
|
2010-01-05 14:03:12 +08:00
|
|
|
return ReplaceInstUsesWith(SI, FalseVal);
|
2015-01-04 20:03:27 +08:00
|
|
|
if (SimplifyWithOpReplaced(TrueVal, CmpLHS, CmpRHS, DL, TLI, DT, AC) ==
|
|
|
|
FalseVal ||
|
|
|
|
SimplifyWithOpReplaced(TrueVal, CmpRHS, CmpLHS, DL, TLI, DT, AC) ==
|
|
|
|
FalseVal)
|
2011-10-02 18:37:37 +08:00
|
|
|
return ReplaceInstUsesWith(SI, FalseVal);
|
2011-05-27 21:00:16 +08:00
|
|
|
} else if (Pred == ICmpInst::ICMP_NE) {
|
2015-01-04 20:03:27 +08:00
|
|
|
if (SimplifyWithOpReplaced(TrueVal, CmpLHS, CmpRHS, DL, TLI, DT, AC) ==
|
|
|
|
FalseVal ||
|
|
|
|
SimplifyWithOpReplaced(TrueVal, CmpRHS, CmpLHS, DL, TLI, DT, AC) ==
|
|
|
|
FalseVal)
|
2010-01-05 14:03:12 +08:00
|
|
|
return ReplaceInstUsesWith(SI, TrueVal);
|
2015-01-04 20:03:27 +08:00
|
|
|
if (SimplifyWithOpReplaced(FalseVal, CmpLHS, CmpRHS, DL, TLI, DT, AC) ==
|
|
|
|
TrueVal ||
|
|
|
|
SimplifyWithOpReplaced(FalseVal, CmpRHS, CmpLHS, DL, TLI, DT, AC) ==
|
|
|
|
TrueVal)
|
2011-10-02 18:37:37 +08:00
|
|
|
return ReplaceInstUsesWith(SI, TrueVal);
|
2010-01-05 14:03:12 +08:00
|
|
|
}
|
2011-03-27 15:30:57 +08:00
|
|
|
|
2011-05-27 21:00:16 +08:00
|
|
|
// NOTE: if we wanted to, this is where to detect integer MIN/MAX
|
|
|
|
|
2012-05-29 03:18:16 +08:00
|
|
|
if (CmpRHS != CmpLHS && isa<Constant>(CmpRHS)) {
|
2011-03-27 15:30:57 +08:00
|
|
|
if (CmpLHS == TrueVal && Pred == ICmpInst::ICMP_EQ) {
|
|
|
|
// Transform (X == C) ? X : Y -> (X == C) ? C : Y
|
|
|
|
SI.setOperand(1, CmpRHS);
|
|
|
|
Changed = true;
|
|
|
|
} else if (CmpLHS == FalseVal && Pred == ICmpInst::ICMP_NE) {
|
|
|
|
// Transform (X != C) ? Y : X -> (X != C) ? Y : C
|
|
|
|
SI.setOperand(2, CmpRHS);
|
|
|
|
Changed = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-12-20 12:45:35 +08:00
|
|
|
if (unsigned BitWidth = TrueVal->getType()->getScalarSizeInBits()) {
|
|
|
|
APInt MinSignedValue = APInt::getSignBit(BitWidth);
|
2014-11-27 15:25:21 +08:00
|
|
|
Value *X;
|
|
|
|
const APInt *Y, *C;
|
2014-12-20 12:45:35 +08:00
|
|
|
bool TrueWhenUnset;
|
|
|
|
bool IsBitTest = false;
|
|
|
|
if (ICmpInst::isEquality(Pred) &&
|
|
|
|
match(CmpLHS, m_And(m_Value(X), m_Power2(Y))) &&
|
2014-11-27 15:25:21 +08:00
|
|
|
match(CmpRHS, m_Zero())) {
|
2014-12-20 12:45:35 +08:00
|
|
|
IsBitTest = true;
|
|
|
|
TrueWhenUnset = Pred == ICmpInst::ICMP_EQ;
|
|
|
|
} else if (Pred == ICmpInst::ICMP_SLT && match(CmpRHS, m_Zero())) {
|
|
|
|
X = CmpLHS;
|
|
|
|
Y = &MinSignedValue;
|
|
|
|
IsBitTest = true;
|
|
|
|
TrueWhenUnset = false;
|
|
|
|
} else if (Pred == ICmpInst::ICMP_SGT && match(CmpRHS, m_AllOnes())) {
|
|
|
|
X = CmpLHS;
|
|
|
|
Y = &MinSignedValue;
|
|
|
|
IsBitTest = true;
|
|
|
|
TrueWhenUnset = true;
|
|
|
|
}
|
|
|
|
if (IsBitTest) {
|
2014-11-27 15:25:21 +08:00
|
|
|
Value *V = nullptr;
|
|
|
|
// (X & Y) == 0 ? X : X ^ Y --> X & ~Y
|
2014-12-20 12:45:35 +08:00
|
|
|
if (TrueWhenUnset && TrueVal == X &&
|
2014-11-27 15:25:21 +08:00
|
|
|
match(FalseVal, m_Xor(m_Specific(X), m_APInt(C))) && *Y == *C)
|
|
|
|
V = Builder->CreateAnd(X, ~(*Y));
|
|
|
|
// (X & Y) != 0 ? X ^ Y : X --> X & ~Y
|
2014-12-20 12:45:35 +08:00
|
|
|
else if (!TrueWhenUnset && FalseVal == X &&
|
2014-11-27 15:25:21 +08:00
|
|
|
match(TrueVal, m_Xor(m_Specific(X), m_APInt(C))) && *Y == *C)
|
|
|
|
V = Builder->CreateAnd(X, ~(*Y));
|
|
|
|
// (X & Y) == 0 ? X ^ Y : X --> X | Y
|
2014-12-20 12:45:35 +08:00
|
|
|
else if (TrueWhenUnset && FalseVal == X &&
|
2014-11-27 15:25:21 +08:00
|
|
|
match(TrueVal, m_Xor(m_Specific(X), m_APInt(C))) && *Y == *C)
|
|
|
|
V = Builder->CreateOr(X, *Y);
|
|
|
|
// (X & Y) != 0 ? X : X ^ Y --> X | Y
|
2014-12-20 12:45:35 +08:00
|
|
|
else if (!TrueWhenUnset && TrueVal == X &&
|
2014-11-27 15:25:21 +08:00
|
|
|
match(FalseVal, m_Xor(m_Specific(X), m_APInt(C))) && *Y == *C)
|
|
|
|
V = Builder->CreateOr(X, *Y);
|
|
|
|
|
|
|
|
if (V)
|
|
|
|
return ReplaceInstUsesWith(SI, V);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-04-30 16:57:58 +08:00
|
|
|
if (Value *V = foldSelectICmpAndOr(SI, TrueVal, FalseVal, Builder))
|
|
|
|
return ReplaceInstUsesWith(SI, V);
|
|
|
|
|
2014-04-25 13:29:35 +08:00
|
|
|
return Changed ? &SI : nullptr;
|
2010-01-05 14:03:12 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// CanSelectOperandBeMappingIntoPredBlock - SI is a select whose condition is a
|
|
|
|
/// PHI node (but the two may be in different blocks). See if the true/false
|
|
|
|
/// values (V) are live in all of the predecessor blocks of the PHI. For
|
|
|
|
/// example, cases like this cannot be mapped:
|
|
|
|
///
|
|
|
|
/// X = phi [ C1, BB1], [C2, BB2]
|
|
|
|
/// Y = add
|
|
|
|
/// Z = select X, Y, 0
|
|
|
|
///
|
|
|
|
/// because Y is not live in BB1/BB2.
|
|
|
|
///
|
|
|
|
static bool CanSelectOperandBeMappingIntoPredBlock(const Value *V,
|
|
|
|
const SelectInst &SI) {
|
|
|
|
// If the value is a non-instruction value like a constant or argument, it
|
|
|
|
// can always be mapped.
|
|
|
|
const Instruction *I = dyn_cast<Instruction>(V);
|
2014-04-25 13:29:35 +08:00
|
|
|
if (!I) return true;
|
2011-01-08 05:33:13 +08:00
|
|
|
|
2010-01-05 14:03:12 +08:00
|
|
|
// If V is a PHI node defined in the same block as the condition PHI, we can
|
|
|
|
// map the arguments.
|
|
|
|
const PHINode *CondPHI = cast<PHINode>(SI.getCondition());
|
2011-01-08 05:33:13 +08:00
|
|
|
|
2010-01-05 14:03:12 +08:00
|
|
|
if (const PHINode *VP = dyn_cast<PHINode>(I))
|
|
|
|
if (VP->getParent() == CondPHI->getParent())
|
|
|
|
return true;
|
2011-01-08 05:33:13 +08:00
|
|
|
|
2010-01-05 14:03:12 +08:00
|
|
|
// Otherwise, if the PHI and select are defined in the same block and if V is
|
|
|
|
// defined in a different block, then we can transform it.
|
|
|
|
if (SI.getParent() == CondPHI->getParent() &&
|
|
|
|
I->getParent() != CondPHI->getParent())
|
|
|
|
return true;
|
2011-01-08 05:33:13 +08:00
|
|
|
|
2010-01-05 14:03:12 +08:00
|
|
|
// Otherwise we have a 'hard' case and we can't tell without doing more
|
|
|
|
// detailed dominator based analysis, punt.
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// FoldSPFofSPF - We have an SPF (e.g. a min or max) of an SPF of the form:
|
2011-01-08 05:33:13 +08:00
|
|
|
/// SPF2(SPF1(A, B), C)
|
2010-01-05 14:03:12 +08:00
|
|
|
Instruction *InstCombiner::FoldSPFofSPF(Instruction *Inner,
|
|
|
|
SelectPatternFlavor SPF1,
|
|
|
|
Value *A, Value *B,
|
|
|
|
Instruction &Outer,
|
|
|
|
SelectPatternFlavor SPF2, Value *C) {
|
|
|
|
if (C == A || C == B) {
|
|
|
|
// MAX(MAX(A, B), B) -> MAX(A, B)
|
|
|
|
// MIN(MIN(a, b), a) -> MIN(a, b)
|
|
|
|
if (SPF1 == SPF2)
|
|
|
|
return ReplaceInstUsesWith(Outer, Inner);
|
2011-01-08 05:33:13 +08:00
|
|
|
|
2010-01-05 14:03:12 +08:00
|
|
|
// MAX(MIN(a, b), a) -> a
|
|
|
|
// MIN(MAX(a, b), a) -> a
|
|
|
|
if ((SPF1 == SPF_SMIN && SPF2 == SPF_SMAX) ||
|
|
|
|
(SPF1 == SPF_SMAX && SPF2 == SPF_SMIN) ||
|
|
|
|
(SPF1 == SPF_UMIN && SPF2 == SPF_UMAX) ||
|
|
|
|
(SPF1 == SPF_UMAX && SPF2 == SPF_UMIN))
|
|
|
|
return ReplaceInstUsesWith(Outer, C);
|
|
|
|
}
|
2011-01-08 05:33:13 +08:00
|
|
|
|
Added instcombine for 'MIN(MIN(A, 27), 93)' and 'MAX(MAX(A, 93), 27)'
MIN(MIN(A, 23), 97) -> MIN(A, 23)
MAX(MAX(A, 97), 23) -> MAX(A, 97)
Differential Revision: http://reviews.llvm.org/D3629
llvm-svn: 208849
2014-05-15 14:13:40 +08:00
|
|
|
if (SPF1 == SPF2) {
|
|
|
|
if (ConstantInt *CB = dyn_cast<ConstantInt>(B)) {
|
|
|
|
if (ConstantInt *CC = dyn_cast<ConstantInt>(C)) {
|
|
|
|
APInt ACB = CB->getValue();
|
|
|
|
APInt ACC = CC->getValue();
|
Added inst-combine for 'MIN(MIN(A, 97), 23)' and 'MAX(MAX(A, 23), 97)'
This removes TODO added in r208849 [http://reviews.llvm.org/D3629]
MIN(MIN(A, 97), 23) -> MIN(A, 23)
MAX(MAX(A, 23), 97) -> MAX(A, 97)
Differential Revision: http://reviews.llvm.org/D3785
llvm-svn: 209110
2014-05-19 15:08:32 +08:00
|
|
|
|
|
|
|
// MIN(MIN(A, 23), 97) -> MIN(A, 23)
|
|
|
|
// MAX(MAX(A, 97), 23) -> MAX(A, 97)
|
Added instcombine for 'MIN(MIN(A, 27), 93)' and 'MAX(MAX(A, 93), 27)'
MIN(MIN(A, 23), 97) -> MIN(A, 23)
MAX(MAX(A, 97), 23) -> MAX(A, 97)
Differential Revision: http://reviews.llvm.org/D3629
llvm-svn: 208849
2014-05-15 14:13:40 +08:00
|
|
|
if ((SPF1 == SPF_UMIN && ACB.ule(ACC)) ||
|
|
|
|
(SPF1 == SPF_SMIN && ACB.sle(ACC)) ||
|
|
|
|
(SPF1 == SPF_UMAX && ACB.uge(ACC)) ||
|
|
|
|
(SPF1 == SPF_SMAX && ACB.sge(ACC)))
|
|
|
|
return ReplaceInstUsesWith(Outer, Inner);
|
Added inst-combine for 'MIN(MIN(A, 97), 23)' and 'MAX(MAX(A, 23), 97)'
This removes TODO added in r208849 [http://reviews.llvm.org/D3629]
MIN(MIN(A, 97), 23) -> MIN(A, 23)
MAX(MAX(A, 23), 97) -> MAX(A, 97)
Differential Revision: http://reviews.llvm.org/D3785
llvm-svn: 209110
2014-05-19 15:08:32 +08:00
|
|
|
|
|
|
|
// MIN(MIN(A, 97), 23) -> MIN(A, 23)
|
|
|
|
// MAX(MAX(A, 23), 97) -> MAX(A, 97)
|
|
|
|
if ((SPF1 == SPF_UMIN && ACB.ugt(ACC)) ||
|
|
|
|
(SPF1 == SPF_SMIN && ACB.sgt(ACC)) ||
|
|
|
|
(SPF1 == SPF_UMAX && ACB.ult(ACC)) ||
|
|
|
|
(SPF1 == SPF_SMAX && ACB.slt(ACC))) {
|
|
|
|
Outer.replaceUsesOfWith(Inner, A);
|
|
|
|
return &Outer;
|
|
|
|
}
|
Added instcombine for 'MIN(MIN(A, 27), 93)' and 'MAX(MAX(A, 93), 27)'
MIN(MIN(A, 23), 97) -> MIN(A, 23)
MAX(MAX(A, 97), 23) -> MAX(A, 97)
Differential Revision: http://reviews.llvm.org/D3629
llvm-svn: 208849
2014-05-15 14:13:40 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2014-06-06 14:54:45 +08:00
|
|
|
|
|
|
|
// ABS(ABS(X)) -> ABS(X)
|
|
|
|
// NABS(NABS(X)) -> NABS(X)
|
|
|
|
if (SPF1 == SPF2 && (SPF1 == SPF_ABS || SPF1 == SPF_NABS)) {
|
|
|
|
return ReplaceInstUsesWith(Outer, Inner);
|
|
|
|
}
|
|
|
|
|
2014-06-12 22:06:00 +08:00
|
|
|
// ABS(NABS(X)) -> ABS(X)
|
|
|
|
// NABS(ABS(X)) -> NABS(X)
|
|
|
|
if ((SPF1 == SPF_ABS && SPF2 == SPF_NABS) ||
|
|
|
|
(SPF1 == SPF_NABS && SPF2 == SPF_ABS)) {
|
|
|
|
SelectInst *SI = cast<SelectInst>(Inner);
|
|
|
|
Value *NewSI = Builder->CreateSelect(
|
|
|
|
SI->getCondition(), SI->getFalseValue(), SI->getTrueValue());
|
|
|
|
return ReplaceInstUsesWith(Outer, NewSI);
|
|
|
|
}
|
2014-04-25 13:29:35 +08:00
|
|
|
return nullptr;
|
2010-01-05 14:03:12 +08:00
|
|
|
}
|
|
|
|
|
2010-12-11 17:42:59 +08:00
|
|
|
/// foldSelectICmpAnd - If one of the constants is zero (we know they can't
|
|
|
|
/// both be) and we have an icmp instruction with zero, and we have an 'and'
|
|
|
|
/// with the non-constant value and a power of two we can turn the select
|
|
|
|
/// into a shift on the result of the 'and'.
|
|
|
|
static Value *foldSelectICmpAnd(const SelectInst &SI, ConstantInt *TrueVal,
|
|
|
|
ConstantInt *FalseVal,
|
|
|
|
InstCombiner::BuilderTy *Builder) {
|
|
|
|
const ICmpInst *IC = dyn_cast<ICmpInst>(SI.getCondition());
|
2013-06-30 05:17:04 +08:00
|
|
|
if (!IC || !IC->isEquality() || !SI.getType()->isIntegerTy())
|
2014-04-25 13:29:35 +08:00
|
|
|
return nullptr;
|
2010-12-11 17:42:59 +08:00
|
|
|
|
2011-03-11 19:37:40 +08:00
|
|
|
if (!match(IC->getOperand(1), m_Zero()))
|
2014-04-25 13:29:35 +08:00
|
|
|
return nullptr;
|
2010-12-11 17:42:59 +08:00
|
|
|
|
|
|
|
ConstantInt *AndRHS;
|
|
|
|
Value *LHS = IC->getOperand(0);
|
2013-06-30 05:17:04 +08:00
|
|
|
if (!match(LHS, m_And(m_Value(), m_ConstantInt(AndRHS))))
|
2014-04-25 13:29:35 +08:00
|
|
|
return nullptr;
|
2010-12-11 17:42:59 +08:00
|
|
|
|
2010-12-11 18:49:22 +08:00
|
|
|
// If both select arms are non-zero see if we have a select of the form
|
|
|
|
// 'x ? 2^n + C : C'. Then we can offset both arms by C, use the logic
|
|
|
|
// for 'x ? 2^n : 0' and fix the thing up at the end.
|
2014-04-25 13:29:35 +08:00
|
|
|
ConstantInt *Offset = nullptr;
|
2010-12-11 18:49:22 +08:00
|
|
|
if (!TrueVal->isZero() && !FalseVal->isZero()) {
|
|
|
|
if ((TrueVal->getValue() - FalseVal->getValue()).isPowerOf2())
|
|
|
|
Offset = FalseVal;
|
|
|
|
else if ((FalseVal->getValue() - TrueVal->getValue()).isPowerOf2())
|
|
|
|
Offset = TrueVal;
|
|
|
|
else
|
2014-04-25 13:29:35 +08:00
|
|
|
return nullptr;
|
2010-12-11 18:49:22 +08:00
|
|
|
|
|
|
|
// Adjust TrueVal and FalseVal to the offset.
|
|
|
|
TrueVal = ConstantInt::get(Builder->getContext(),
|
|
|
|
TrueVal->getValue() - Offset->getValue());
|
|
|
|
FalseVal = ConstantInt::get(Builder->getContext(),
|
|
|
|
FalseVal->getValue() - Offset->getValue());
|
|
|
|
}
|
2010-12-11 17:42:59 +08:00
|
|
|
|
|
|
|
// Make sure the mask in the 'and' and one of the select arms is a power of 2.
|
|
|
|
if (!AndRHS->getValue().isPowerOf2() ||
|
|
|
|
(!TrueVal->getValue().isPowerOf2() &&
|
|
|
|
!FalseVal->getValue().isPowerOf2()))
|
2014-04-25 13:29:35 +08:00
|
|
|
return nullptr;
|
2010-12-11 17:42:59 +08:00
|
|
|
|
|
|
|
// Determine which shift is needed to transform result of the 'and' into the
|
|
|
|
// desired result.
|
|
|
|
ConstantInt *ValC = !TrueVal->isZero() ? TrueVal : FalseVal;
|
|
|
|
unsigned ValZeros = ValC->getValue().logBase2();
|
|
|
|
unsigned AndZeros = AndRHS->getValue().logBase2();
|
|
|
|
|
2013-06-30 05:17:04 +08:00
|
|
|
// If types don't match we can still convert the select by introducing a zext
|
|
|
|
// or a trunc of the 'and'. The trunc case requires that all of the truncated
|
|
|
|
// bits are zero, we can figure that out by looking at the 'and' mask.
|
|
|
|
if (AndZeros >= ValC->getBitWidth())
|
2014-04-25 13:29:35 +08:00
|
|
|
return nullptr;
|
2013-06-30 05:17:04 +08:00
|
|
|
|
|
|
|
Value *V = Builder->CreateZExtOrTrunc(LHS, SI.getType());
|
2010-12-11 17:42:59 +08:00
|
|
|
if (ValZeros > AndZeros)
|
|
|
|
V = Builder->CreateShl(V, ValZeros - AndZeros);
|
|
|
|
else if (ValZeros < AndZeros)
|
|
|
|
V = Builder->CreateLShr(V, AndZeros - ValZeros);
|
|
|
|
|
|
|
|
// Okay, now we know that everything is set up, we just don't know whether we
|
|
|
|
// have a icmp_ne or icmp_eq and whether the true or false val is the zero.
|
|
|
|
bool ShouldNotVal = !TrueVal->isZero();
|
|
|
|
ShouldNotVal ^= IC->getPredicate() == ICmpInst::ICMP_NE;
|
|
|
|
if (ShouldNotVal)
|
|
|
|
V = Builder->CreateXor(V, ValC);
|
2010-12-11 18:49:22 +08:00
|
|
|
|
|
|
|
// Apply an offset if needed.
|
|
|
|
if (Offset)
|
|
|
|
V = Builder->CreateAdd(V, Offset);
|
2010-12-11 17:42:59 +08:00
|
|
|
return V;
|
|
|
|
}
|
2010-01-05 14:03:12 +08:00
|
|
|
|
|
|
|
Instruction *InstCombiner::visitSelectInst(SelectInst &SI) {
|
|
|
|
Value *CondVal = SI.getCondition();
|
|
|
|
Value *TrueVal = SI.getTrueValue();
|
|
|
|
Value *FalseVal = SI.getFalseValue();
|
|
|
|
|
2015-01-04 20:03:27 +08:00
|
|
|
if (Value *V =
|
|
|
|
SimplifySelectInst(CondVal, TrueVal, FalseVal, DL, TLI, DT, AC))
|
2010-04-20 13:32:14 +08:00
|
|
|
return ReplaceInstUsesWith(SI, V);
|
2010-01-05 14:03:12 +08:00
|
|
|
|
2010-02-16 00:12:20 +08:00
|
|
|
if (SI.getType()->isIntegerTy(1)) {
|
2010-01-05 14:03:12 +08:00
|
|
|
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);
|
|
|
|
}
|
2010-04-20 13:32:14 +08:00
|
|
|
// Change: A = select B, false, C --> A = and !B, C
|
2011-05-19 01:31:55 +08:00
|
|
|
Value *NotCond = Builder->CreateNot(CondVal, "not."+CondVal->getName());
|
2010-04-20 13:32:14 +08:00
|
|
|
return BinaryOperator::CreateAnd(NotCond, FalseVal);
|
2013-04-19 09:18:04 +08:00
|
|
|
}
|
|
|
|
if (ConstantInt *C = dyn_cast<ConstantInt>(FalseVal)) {
|
2010-01-05 14:03:12 +08:00
|
|
|
if (C->getZExtValue() == false) {
|
|
|
|
// Change: A = select B, C, false --> A = and B, C
|
|
|
|
return BinaryOperator::CreateAnd(CondVal, TrueVal);
|
|
|
|
}
|
2010-04-20 13:32:14 +08:00
|
|
|
// Change: A = select B, C, true --> A = or !B, C
|
2011-05-19 01:31:55 +08:00
|
|
|
Value *NotCond = Builder->CreateNot(CondVal, "not."+CondVal->getName());
|
2010-04-20 13:32:14 +08:00
|
|
|
return BinaryOperator::CreateOr(NotCond, TrueVal);
|
2010-01-05 14:03:12 +08:00
|
|
|
}
|
2011-01-08 05:33:13 +08:00
|
|
|
|
2010-01-05 14:03:12 +08:00
|
|
|
// select a, b, a -> a&b
|
|
|
|
// select a, a, b -> a|b
|
|
|
|
if (CondVal == TrueVal)
|
|
|
|
return BinaryOperator::CreateOr(CondVal, FalseVal);
|
2013-04-19 09:18:04 +08:00
|
|
|
if (CondVal == FalseVal)
|
2010-01-05 14:03:12 +08:00
|
|
|
return BinaryOperator::CreateAnd(CondVal, TrueVal);
|
2011-12-15 08:56:45 +08:00
|
|
|
|
|
|
|
// select a, ~a, b -> (~a)&b
|
|
|
|
// select a, b, ~a -> (~a)|b
|
|
|
|
if (match(TrueVal, m_Not(m_Specific(CondVal))))
|
|
|
|
return BinaryOperator::CreateAnd(TrueVal, FalseVal);
|
2013-04-19 09:18:04 +08:00
|
|
|
if (match(FalseVal, m_Not(m_Specific(CondVal))))
|
2011-12-15 08:56:45 +08:00
|
|
|
return BinaryOperator::CreateOr(TrueVal, FalseVal);
|
2010-01-05 14:03:12 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// Selecting between two integer constants?
|
|
|
|
if (ConstantInt *TrueValC = dyn_cast<ConstantInt>(TrueVal))
|
|
|
|
if (ConstantInt *FalseValC = dyn_cast<ConstantInt>(FalseVal)) {
|
|
|
|
// select C, 1, 0 -> zext C to int
|
2010-01-24 08:09:49 +08:00
|
|
|
if (FalseValC->isZero() && TrueValC->getValue() == 1)
|
|
|
|
return new ZExtInst(CondVal, SI.getType());
|
|
|
|
|
|
|
|
// select C, -1, 0 -> sext C to int
|
|
|
|
if (FalseValC->isZero() && TrueValC->isAllOnesValue())
|
|
|
|
return new SExtInst(CondVal, SI.getType());
|
2011-01-08 05:33:13 +08:00
|
|
|
|
2010-01-24 08:09:49 +08:00
|
|
|
// select C, 0, 1 -> zext !C to int
|
|
|
|
if (TrueValC->isZero() && FalseValC->getValue() == 1) {
|
|
|
|
Value *NotCond = Builder->CreateNot(CondVal, "not."+CondVal->getName());
|
|
|
|
return new ZExtInst(NotCond, SI.getType());
|
2010-01-05 14:03:12 +08:00
|
|
|
}
|
|
|
|
|
2010-01-24 08:09:49 +08:00
|
|
|
// select C, 0, -1 -> sext !C to int
|
|
|
|
if (TrueValC->isZero() && FalseValC->isAllOnesValue()) {
|
|
|
|
Value *NotCond = Builder->CreateNot(CondVal, "not."+CondVal->getName());
|
|
|
|
return new SExtInst(NotCond, SI.getType());
|
|
|
|
}
|
2010-12-11 17:42:59 +08:00
|
|
|
|
|
|
|
if (Value *V = foldSelectICmpAnd(SI, TrueValC, FalseValC, Builder))
|
|
|
|
return ReplaceInstUsesWith(SI, V);
|
2010-01-05 14:03:12 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// See if we are selecting two values based on a comparison of the two values.
|
|
|
|
if (FCmpInst *FCI = dyn_cast<FCmpInst>(CondVal)) {
|
|
|
|
if (FCI->getOperand(0) == TrueVal && FCI->getOperand(1) == FalseVal) {
|
|
|
|
// Transform (X == Y) ? X : Y -> Y
|
|
|
|
if (FCI->getPredicate() == FCmpInst::FCMP_OEQ) {
|
2011-01-08 05:33:13 +08:00
|
|
|
// This is not safe in general for floating point:
|
2010-01-05 14:03:12 +08:00
|
|
|
// consider X== -0, Y== +0.
|
|
|
|
// It becomes safe if either operand is a nonzero constant.
|
|
|
|
ConstantFP *CFPt, *CFPf;
|
|
|
|
if (((CFPt = dyn_cast<ConstantFP>(TrueVal)) &&
|
|
|
|
!CFPt->getValueAPF().isZero()) ||
|
|
|
|
((CFPf = dyn_cast<ConstantFP>(FalseVal)) &&
|
|
|
|
!CFPf->getValueAPF().isZero()))
|
|
|
|
return ReplaceInstUsesWith(SI, FalseVal);
|
|
|
|
}
|
2010-02-24 01:17:57 +08:00
|
|
|
// Transform (X une Y) ? X : Y -> X
|
|
|
|
if (FCI->getPredicate() == FCmpInst::FCMP_UNE) {
|
2011-01-08 05:33:13 +08:00
|
|
|
// This is not safe in general for floating point:
|
2010-02-24 01:17:57 +08:00
|
|
|
// consider X== -0, Y== +0.
|
|
|
|
// It becomes safe if either operand is a nonzero constant.
|
|
|
|
ConstantFP *CFPt, *CFPf;
|
|
|
|
if (((CFPt = dyn_cast<ConstantFP>(TrueVal)) &&
|
|
|
|
!CFPt->getValueAPF().isZero()) ||
|
|
|
|
((CFPf = dyn_cast<ConstantFP>(FalseVal)) &&
|
|
|
|
!CFPf->getValueAPF().isZero()))
|
2010-01-05 14:03:12 +08:00
|
|
|
return ReplaceInstUsesWith(SI, TrueVal);
|
2010-02-24 01:17:57 +08:00
|
|
|
}
|
2010-01-05 14:03:12 +08:00
|
|
|
|
2014-11-25 07:15:18 +08:00
|
|
|
// Canonicalize to use ordered comparisons by swapping the select
|
|
|
|
// operands.
|
|
|
|
//
|
|
|
|
// e.g.
|
|
|
|
// (X ugt Y) ? X : Y -> (X ole Y) ? Y : X
|
|
|
|
if (FCI->hasOneUse() && FCmpInst::isUnordered(FCI->getPredicate())) {
|
|
|
|
FCmpInst::Predicate InvPred = FCI->getInversePredicate();
|
|
|
|
Value *NewCond = Builder->CreateFCmp(InvPred, TrueVal, FalseVal,
|
|
|
|
FCI->getName() + ".inv");
|
|
|
|
|
|
|
|
return SelectInst::Create(NewCond, FalseVal, TrueVal,
|
|
|
|
SI.getName() + ".p");
|
|
|
|
}
|
|
|
|
|
|
|
|
// NOTE: if we wanted to, this is where to detect MIN/MAX
|
2010-01-05 14:03:12 +08:00
|
|
|
} else if (FCI->getOperand(0) == FalseVal && FCI->getOperand(1) == TrueVal){
|
|
|
|
// Transform (X == Y) ? Y : X -> X
|
|
|
|
if (FCI->getPredicate() == FCmpInst::FCMP_OEQ) {
|
2011-01-08 05:33:13 +08:00
|
|
|
// This is not safe in general for floating point:
|
2010-01-05 14:03:12 +08:00
|
|
|
// consider X== -0, Y== +0.
|
|
|
|
// It becomes safe if either operand is a nonzero constant.
|
|
|
|
ConstantFP *CFPt, *CFPf;
|
|
|
|
if (((CFPt = dyn_cast<ConstantFP>(TrueVal)) &&
|
|
|
|
!CFPt->getValueAPF().isZero()) ||
|
|
|
|
((CFPf = dyn_cast<ConstantFP>(FalseVal)) &&
|
|
|
|
!CFPf->getValueAPF().isZero()))
|
|
|
|
return ReplaceInstUsesWith(SI, FalseVal);
|
|
|
|
}
|
2010-02-24 01:17:57 +08:00
|
|
|
// Transform (X une Y) ? Y : X -> Y
|
|
|
|
if (FCI->getPredicate() == FCmpInst::FCMP_UNE) {
|
2011-01-08 05:33:13 +08:00
|
|
|
// This is not safe in general for floating point:
|
2010-02-24 01:17:57 +08:00
|
|
|
// consider X== -0, Y== +0.
|
|
|
|
// It becomes safe if either operand is a nonzero constant.
|
|
|
|
ConstantFP *CFPt, *CFPf;
|
|
|
|
if (((CFPt = dyn_cast<ConstantFP>(TrueVal)) &&
|
|
|
|
!CFPt->getValueAPF().isZero()) ||
|
|
|
|
((CFPf = dyn_cast<ConstantFP>(FalseVal)) &&
|
|
|
|
!CFPf->getValueAPF().isZero()))
|
|
|
|
return ReplaceInstUsesWith(SI, TrueVal);
|
|
|
|
}
|
2014-11-25 07:15:18 +08:00
|
|
|
|
|
|
|
// Canonicalize to use ordered comparisons by swapping the select
|
|
|
|
// operands.
|
|
|
|
//
|
|
|
|
// e.g.
|
|
|
|
// (X ugt Y) ? X : Y -> (X ole Y) ? X : Y
|
|
|
|
if (FCI->hasOneUse() && FCmpInst::isUnordered(FCI->getPredicate())) {
|
|
|
|
FCmpInst::Predicate InvPred = FCI->getInversePredicate();
|
|
|
|
Value *NewCond = Builder->CreateFCmp(InvPred, FalseVal, TrueVal,
|
|
|
|
FCI->getName() + ".inv");
|
|
|
|
|
|
|
|
return SelectInst::Create(NewCond, FalseVal, TrueVal,
|
|
|
|
SI.getName() + ".p");
|
|
|
|
}
|
|
|
|
|
2010-01-05 14:03:12 +08:00
|
|
|
// NOTE: if we wanted to, this is where to detect MIN/MAX
|
|
|
|
}
|
|
|
|
// NOTE: if we wanted to, this is where to detect ABS
|
|
|
|
}
|
|
|
|
|
|
|
|
// See if we are selecting two values based on a comparison of the two values.
|
|
|
|
if (ICmpInst *ICI = dyn_cast<ICmpInst>(CondVal))
|
|
|
|
if (Instruction *Result = visitSelectInstWithICmp(SI, ICI))
|
|
|
|
return Result;
|
|
|
|
|
|
|
|
if (Instruction *TI = dyn_cast<Instruction>(TrueVal))
|
|
|
|
if (Instruction *FI = dyn_cast<Instruction>(FalseVal))
|
|
|
|
if (TI->hasOneUse() && FI->hasOneUse()) {
|
2014-04-25 13:29:35 +08:00
|
|
|
Instruction *AddOp = nullptr, *SubOp = nullptr;
|
2010-01-05 14:03:12 +08:00
|
|
|
|
|
|
|
// Turn (select C, (op X, Y), (op X, Z)) -> (op X, (select C, Y, Z))
|
|
|
|
if (TI->getOpcode() == FI->getOpcode())
|
|
|
|
if (Instruction *IV = FoldSelectOpOp(SI, TI, FI))
|
|
|
|
return IV;
|
|
|
|
|
|
|
|
// Turn select C, (X+Y), (X-Y) --> (X+(select C, Y, (-Y))). This is
|
|
|
|
// even legal for FP.
|
|
|
|
if ((TI->getOpcode() == Instruction::Sub &&
|
|
|
|
FI->getOpcode() == Instruction::Add) ||
|
|
|
|
(TI->getOpcode() == Instruction::FSub &&
|
|
|
|
FI->getOpcode() == Instruction::FAdd)) {
|
|
|
|
AddOp = FI; SubOp = TI;
|
|
|
|
} else if ((FI->getOpcode() == Instruction::Sub &&
|
|
|
|
TI->getOpcode() == Instruction::Add) ||
|
|
|
|
(FI->getOpcode() == Instruction::FSub &&
|
|
|
|
TI->getOpcode() == Instruction::FAdd)) {
|
|
|
|
AddOp = TI; SubOp = FI;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (AddOp) {
|
2014-04-25 13:29:35 +08:00
|
|
|
Value *OtherAddOp = nullptr;
|
2010-01-05 14:03:12 +08:00
|
|
|
if (SubOp->getOperand(0) == AddOp->getOperand(0)) {
|
|
|
|
OtherAddOp = AddOp->getOperand(1);
|
|
|
|
} else if (SubOp->getOperand(0) == AddOp->getOperand(1)) {
|
|
|
|
OtherAddOp = AddOp->getOperand(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (OtherAddOp) {
|
|
|
|
// So at this point we know we have (Y -> OtherAddOp):
|
|
|
|
// select C, (add X, Y), (sub X, Z)
|
|
|
|
Value *NegVal; // Compute -Z
|
2011-06-24 04:40:23 +08:00
|
|
|
if (SI.getType()->isFPOrFPVectorTy()) {
|
2011-05-19 01:58:37 +08:00
|
|
|
NegVal = Builder->CreateFNeg(SubOp->getOperand(1));
|
2014-01-18 08:48:14 +08:00
|
|
|
if (Instruction *NegInst = dyn_cast<Instruction>(NegVal)) {
|
|
|
|
FastMathFlags Flags = AddOp->getFastMathFlags();
|
|
|
|
Flags &= SubOp->getFastMathFlags();
|
|
|
|
NegInst->setFastMathFlags(Flags);
|
|
|
|
}
|
2010-01-05 14:03:12 +08:00
|
|
|
} else {
|
2011-05-19 01:58:37 +08:00
|
|
|
NegVal = Builder->CreateNeg(SubOp->getOperand(1));
|
2010-01-05 14:03:12 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
Value *NewTrueOp = OtherAddOp;
|
|
|
|
Value *NewFalseOp = NegVal;
|
|
|
|
if (AddOp != TI)
|
|
|
|
std::swap(NewTrueOp, NewFalseOp);
|
2013-04-06 05:20:12 +08:00
|
|
|
Value *NewSel =
|
2011-05-19 01:58:37 +08:00
|
|
|
Builder->CreateSelect(CondVal, NewTrueOp,
|
|
|
|
NewFalseOp, SI.getName() + ".p");
|
2010-01-05 14:03:12 +08:00
|
|
|
|
2014-01-18 08:48:14 +08:00
|
|
|
if (SI.getType()->isFPOrFPVectorTy()) {
|
|
|
|
Instruction *RI =
|
|
|
|
BinaryOperator::CreateFAdd(SubOp->getOperand(0), NewSel);
|
|
|
|
|
|
|
|
FastMathFlags Flags = AddOp->getFastMathFlags();
|
|
|
|
Flags &= SubOp->getFastMathFlags();
|
|
|
|
RI->setFastMathFlags(Flags);
|
|
|
|
return RI;
|
|
|
|
} else
|
2010-10-28 07:45:18 +08:00
|
|
|
return BinaryOperator::CreateAdd(SubOp->getOperand(0), NewSel);
|
2010-01-05 14:03:12 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// See if we can fold the select into one of our operands.
|
2010-02-16 00:12:20 +08:00
|
|
|
if (SI.getType()->isIntegerTy()) {
|
2010-01-05 14:03:12 +08:00
|
|
|
if (Instruction *FoldI = FoldSelectIntoOp(SI, TrueVal, FalseVal))
|
|
|
|
return FoldI;
|
2011-01-08 05:33:13 +08:00
|
|
|
|
2010-01-05 14:03:12 +08:00
|
|
|
// MAX(MAX(a, b), a) -> MAX(a, b)
|
|
|
|
// MIN(MIN(a, b), a) -> MIN(a, b)
|
|
|
|
// MAX(MIN(a, b), a) -> a
|
|
|
|
// MIN(MAX(a, b), a) -> a
|
|
|
|
Value *LHS, *RHS, *LHS2, *RHS2;
|
|
|
|
if (SelectPatternFlavor SPF = MatchSelectPattern(&SI, LHS, RHS)) {
|
|
|
|
if (SelectPatternFlavor SPF2 = MatchSelectPattern(LHS, LHS2, RHS2))
|
2013-04-06 05:20:12 +08:00
|
|
|
if (Instruction *R = FoldSPFofSPF(cast<Instruction>(LHS),SPF2,LHS2,RHS2,
|
2010-01-05 14:03:12 +08:00
|
|
|
SI, SPF, RHS))
|
|
|
|
return R;
|
|
|
|
if (SelectPatternFlavor SPF2 = MatchSelectPattern(RHS, LHS2, RHS2))
|
|
|
|
if (Instruction *R = FoldSPFofSPF(cast<Instruction>(RHS),SPF2,LHS2,RHS2,
|
|
|
|
SI, SPF, LHS))
|
|
|
|
return R;
|
|
|
|
}
|
|
|
|
|
|
|
|
// TODO.
|
|
|
|
// ABS(-X) -> ABS(X)
|
|
|
|
}
|
|
|
|
|
|
|
|
// See if we can fold the select into a phi node if the condition is a select.
|
2011-01-08 05:33:13 +08:00
|
|
|
if (isa<PHINode>(SI.getCondition()))
|
2010-01-05 14:03:12 +08:00
|
|
|
// The true/false values have to be live in the PHI predecessor's blocks.
|
|
|
|
if (CanSelectOperandBeMappingIntoPredBlock(TrueVal, SI) &&
|
|
|
|
CanSelectOperandBeMappingIntoPredBlock(FalseVal, SI))
|
|
|
|
if (Instruction *NV = FoldOpIntoPhi(SI))
|
|
|
|
return NV;
|
|
|
|
|
2011-01-28 11:28:10 +08:00
|
|
|
if (SelectInst *TrueSI = dyn_cast<SelectInst>(TrueVal)) {
|
|
|
|
if (TrueSI->getCondition() == CondVal) {
|
2012-07-28 02:03:57 +08:00
|
|
|
if (SI.getTrueValue() == TrueSI->getTrueValue())
|
2014-04-25 13:29:35 +08:00
|
|
|
return nullptr;
|
2011-01-28 11:28:10 +08:00
|
|
|
SI.setOperand(1, TrueSI->getTrueValue());
|
|
|
|
return &SI;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (SelectInst *FalseSI = dyn_cast<SelectInst>(FalseVal)) {
|
|
|
|
if (FalseSI->getCondition() == CondVal) {
|
2012-07-28 02:03:57 +08:00
|
|
|
if (SI.getFalseValue() == FalseSI->getFalseValue())
|
2014-04-25 13:29:35 +08:00
|
|
|
return nullptr;
|
2011-01-28 11:28:10 +08:00
|
|
|
SI.setOperand(2, FalseSI->getFalseValue());
|
|
|
|
return &SI;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-01-05 14:03:12 +08:00
|
|
|
if (BinaryOperator::isNot(CondVal)) {
|
|
|
|
SI.setOperand(0, BinaryOperator::getNotArgument(CondVal));
|
|
|
|
SI.setOperand(1, FalseVal);
|
|
|
|
SI.setOperand(2, TrueVal);
|
|
|
|
return &SI;
|
|
|
|
}
|
|
|
|
|
2013-05-06 10:39:09 +08:00
|
|
|
if (VectorType* VecTy = dyn_cast<VectorType>(SI.getType())) {
|
2012-07-27 07:10:24 +08:00
|
|
|
unsigned VWidth = VecTy->getNumElements();
|
|
|
|
APInt UndefElts(VWidth, 0);
|
|
|
|
APInt AllOnesEltMask(APInt::getAllOnesValue(VWidth));
|
|
|
|
if (Value *V = SimplifyDemandedVectorElts(&SI, AllOnesEltMask, UndefElts)) {
|
|
|
|
if (V != &SI)
|
|
|
|
return ReplaceInstUsesWith(SI, V);
|
|
|
|
return &SI;
|
|
|
|
}
|
2012-09-27 16:33:56 +08:00
|
|
|
|
2012-09-28 17:33:53 +08:00
|
|
|
if (isa<ConstantAggregateZero>(CondVal)) {
|
|
|
|
return ReplaceInstUsesWith(SI, FalseVal);
|
|
|
|
}
|
2012-07-27 07:10:24 +08:00
|
|
|
}
|
|
|
|
|
2014-04-25 13:29:35 +08:00
|
|
|
return nullptr;
|
2010-01-05 14:03:12 +08:00
|
|
|
}
|