本文整理汇总了C++中SelectInst::getCondition方法的典型用法代码示例。如果您正苦于以下问题:C++ SelectInst::getCondition方法的具体用法?C++ SelectInst::getCondition怎么用?C++ SelectInst::getCondition使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类SelectInst
的用法示例。
在下文中一共展示了SelectInst::getCondition方法的14个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: visitSelectInst
SizeOffsetEvalType ObjectSizeOffsetEvaluator::visitSelectInst(SelectInst &I) {
SizeOffsetEvalType TrueSide = compute_(I.getTrueValue());
SizeOffsetEvalType FalseSide = compute_(I.getFalseValue());
if (!bothKnown(TrueSide) || !bothKnown(FalseSide))
return unknown();
if (TrueSide == FalseSide)
return TrueSide;
Value *Size = Builder.CreateSelect(I.getCondition(), TrueSide.first,
FalseSide.first);
Value *Offset = Builder.CreateSelect(I.getCondition(), TrueSide.second,
FalseSide.second);
return std::make_pair(Size, Offset);
}
示例2: CanSelectOperandBeMappingIntoPredBlock
/// 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);
if (!I) return true;
// 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());
if (const PHINode *VP = dyn_cast<PHINode>(I))
if (VP->getParent() == CondPHI->getParent())
return true;
// 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;
// Otherwise we have a 'hard' case and we can't tell without doing more
// detailed dominator based analysis, punt.
return false;
}
示例3: instrumentOneSelectInst
void SelectInstVisitor::instrumentOneSelectInst(SelectInst &SI) {
Module *M = F.getParent();
IRBuilder<> Builder(&SI);
Type *Int64Ty = Builder.getInt64Ty();
Type *I8PtrTy = Builder.getInt8PtrTy();
auto *Step = Builder.CreateZExt(SI.getCondition(), Int64Ty);
Builder.CreateCall(
Intrinsic::getDeclaration(M, Intrinsic::instrprof_increment_step),
{llvm::ConstantExpr::getBitCast(FuncNameVar, I8PtrTy),
Builder.getInt64(FuncHash),
Builder.getInt32(TotalNumCtrs), Builder.getInt32(*CurCtrIdx), Step});
++(*CurCtrIdx);
}
示例4: visitSelectInst
void TracingNoGiri::visitSelectInst(SelectInst &SI) {
instrumentLock(&SI);
// Cast the predicate (boolean) value into an 8-bit value.
Value *Predicate = SI.getCondition();
Predicate = castTo(Predicate, Int8Type, Predicate->getName(), &SI);
// Get the ID of the load instruction.
Value *SelectID = ConstantInt::get(Int32Type, lsNumPass->getID(&SI));
// Create the call to the run-time to record the load instruction.
std::vector<Value *> args=make_vector<Value *>(SelectID, Predicate, 0);
CallInst::Create(RecordSelect, args, "", &SI);
instrumentUnlock(&SI);
++NumSelects; // Update statistics
}
示例5: switch
/// 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);
if (SI == 0) return SPF_UNKNOWN;
ICmpInst *ICI = dyn_cast<ICmpInst>(SI->getCondition());
if (ICI == 0) return SPF_UNKNOWN;
LHS = ICI->getOperand(0);
RHS = ICI->getOperand(1);
// (icmp X, Y) ? X : Y
if (SI->getTrueValue() == ICI->getOperand(0) &&
SI->getFalseValue() == ICI->getOperand(1)) {
switch (ICI->getPredicate()) {
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;
}
}
// (icmp X, Y) ? Y : X
if (SI->getTrueValue() == ICI->getOperand(1) &&
SI->getFalseValue() == ICI->getOperand(0)) {
switch (ICI->getPredicate()) {
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;
}
}
// TODO: (X > 4) ? X : 5 --> (X >= 5) ? X : 5 --> MAX(X, 5)
return SPF_UNKNOWN;
}
示例6: visitSelectInst
void SelectInstVisitor::visitSelectInst(SelectInst &SI) {
if (!PGOInstrSelect)
return;
// FIXME: do not handle this yet.
if (SI.getCondition()->getType()->isVectorTy())
return;
NSIs++;
switch (Mode) {
case VM_counting:
return;
case VM_instrument:
instrumentOneSelectInst(SI);
return;
case VM_annotate:
annotateOneSelectInst(SI);
return;
}
llvm_unreachable("Unknown visiting mode");
}
示例7: InstDesc
/// Returns true if the select instruction has users in the compare-and-add
/// reduction pattern below. The select instruction argument is the last one
/// in the sequence.
///
/// %sum.1 = phi ...
/// ...
/// %cmp = fcmp pred %0, %CFP
/// %add = fadd %0, %sum.1
/// %sum.2 = select %cmp, %add, %sum.1
RecurrenceDescriptor::InstDesc
RecurrenceDescriptor::isConditionalRdxPattern(
RecurrenceKind Kind, Instruction *I) {
SelectInst *SI = dyn_cast<SelectInst>(I);
if (!SI)
return InstDesc(false, I);
CmpInst *CI = dyn_cast<CmpInst>(SI->getCondition());
// Only handle single use cases for now.
if (!CI || !CI->hasOneUse())
return InstDesc(false, I);
Value *TrueVal = SI->getTrueValue();
Value *FalseVal = SI->getFalseValue();
// Handle only when either of operands of select instruction is a PHI
// node for now.
if ((isa<PHINode>(*TrueVal) && isa<PHINode>(*FalseVal)) ||
(!isa<PHINode>(*TrueVal) && !isa<PHINode>(*FalseVal)))
return InstDesc(false, I);
Instruction *I1 =
isa<PHINode>(*TrueVal) ? dyn_cast<Instruction>(FalseVal)
: dyn_cast<Instruction>(TrueVal);
if (!I1 || !I1->isBinaryOp())
return InstDesc(false, I);
Value *Op1, *Op2;
if ((m_FAdd(m_Value(Op1), m_Value(Op2)).match(I1) ||
m_FSub(m_Value(Op1), m_Value(Op2)).match(I1)) &&
I1->isFast())
return InstDesc(Kind == RK_FloatAdd, SI);
if (m_FMul(m_Value(Op1), m_Value(Op2)).match(I1) && (I1->isFast()))
return InstDesc(Kind == RK_FloatMult, SI);
return InstDesc(false, I);
}
示例8: CheckAndInstrument
bool SelectInstrumenter::CheckAndInstrument(Instruction* inst) {
SelectInst* selectInst = dyn_cast<SelectInst>(inst);
if (selectInst != NULL) {
safe_assert(parent_ != NULL);
count_++;
InstrPtrVector instrs;
Constant* iidC = IID_CONSTANT(selectInst);
Constant* inxC = computeIndex(selectInst);
Value* condition = KVALUE_VALUE(selectInst->getCondition(), instrs, NOSIGN);
if(condition == NULL) return false;
Value* tvalue = KVALUE_VALUE(selectInst->getTrueValue(), instrs, NOSIGN);
if(tvalue == NULL) return false;
Value* fvalue = KVALUE_VALUE(selectInst->getFalseValue(), instrs, NOSIGN);
if(fvalue == NULL) return false;
Instruction* call = CALL_IID_KVALUE_KVALUE_KVALUE_INT("llvm_select", iidC, condition, tvalue, fvalue, inxC);
instrs.push_back(call);
// instrument
InsertAllBefore(instrs, selectInst);
return true;
}
return false;
}
示例9: visitSelectInst
/*
* Instrument select instructions similar to how we instrument branches.
*/
void PandaInstrumentVisitor::visitSelectInst(SelectInst &I){
BinaryOperator *BO;
ZExtInst *ZEI;
CallInst *CI;
std::vector<Value*> argValues;
Value *condition;
Function *F = mod->getFunction("log_dynval");
if (!F) {
printf("Instrumentation function not found\n");
assert(1==0);
}
condition = I.getCondition();
BO = static_cast<BinaryOperator*>(IRB.CreateNot(condition));
ZEI = static_cast<ZExtInst*>(IRB.CreateZExt(BO, wordType));
argValues.push_back(ConstantInt::get(ptrType,
(uintptr_t)dynval_buffer));
argValues.push_back(ConstantInt::get(intType, SELECTENTRY));
argValues.push_back(ConstantInt::get(intType, SELECT));
argValues.push_back(static_cast<Value*>(ZEI));
CI = IRB.CreateCall(F, ArrayRef<Value*>(argValues));
CI->insertBefore(static_cast<Instruction*>(&I));
ZEI->insertBefore(static_cast<Instruction*>(CI));
BO->insertBefore(static_cast<Instruction*>(ZEI));
}
示例10: getInstructionCost
unsigned CostModelAnalysis::getInstructionCost(Instruction *I) const {
if (!VTTI)
return -1;
switch (I->getOpcode()) {
case Instruction::Ret:
case Instruction::PHI:
case Instruction::Br: {
return VTTI->getCFInstrCost(I->getOpcode());
}
case Instruction::Add:
case Instruction::FAdd:
case Instruction::Sub:
case Instruction::FSub:
case Instruction::Mul:
case Instruction::FMul:
case Instruction::UDiv:
case Instruction::SDiv:
case Instruction::FDiv:
case Instruction::URem:
case Instruction::SRem:
case Instruction::FRem:
case Instruction::Shl:
case Instruction::LShr:
case Instruction::AShr:
case Instruction::And:
case Instruction::Or:
case Instruction::Xor: {
return VTTI->getArithmeticInstrCost(I->getOpcode(), I->getType());
}
case Instruction::Select: {
SelectInst *SI = cast<SelectInst>(I);
Type *CondTy = SI->getCondition()->getType();
return VTTI->getCmpSelInstrCost(I->getOpcode(), I->getType(), CondTy);
}
case Instruction::ICmp:
case Instruction::FCmp: {
Type *ValTy = I->getOperand(0)->getType();
return VTTI->getCmpSelInstrCost(I->getOpcode(), ValTy);
}
case Instruction::Store: {
StoreInst *SI = cast<StoreInst>(I);
Type *ValTy = SI->getValueOperand()->getType();
return VTTI->getMemoryOpCost(I->getOpcode(), ValTy,
SI->getAlignment(),
SI->getPointerAddressSpace());
}
case Instruction::Load: {
LoadInst *LI = cast<LoadInst>(I);
return VTTI->getMemoryOpCost(I->getOpcode(), I->getType(),
LI->getAlignment(),
LI->getPointerAddressSpace());
}
case Instruction::ZExt:
case Instruction::SExt:
case Instruction::FPToUI:
case Instruction::FPToSI:
case Instruction::FPExt:
case Instruction::PtrToInt:
case Instruction::IntToPtr:
case Instruction::SIToFP:
case Instruction::UIToFP:
case Instruction::Trunc:
case Instruction::FPTrunc:
case Instruction::BitCast: {
Type *SrcTy = I->getOperand(0)->getType();
return VTTI->getCastInstrCost(I->getOpcode(), I->getType(), SrcTy);
}
case Instruction::ExtractElement: {
ExtractElementInst * EEI = cast<ExtractElementInst>(I);
ConstantInt *CI = dyn_cast<ConstantInt>(I->getOperand(1));
unsigned Idx = -1;
if (CI)
Idx = CI->getZExtValue();
return VTTI->getVectorInstrCost(I->getOpcode(),
EEI->getOperand(0)->getType(), Idx);
}
case Instruction::InsertElement: {
InsertElementInst * IE = cast<InsertElementInst>(I);
ConstantInt *CI = dyn_cast<ConstantInt>(IE->getOperand(2));
unsigned Idx = -1;
if (CI)
Idx = CI->getZExtValue();
return VTTI->getVectorInstrCost(I->getOpcode(),
IE->getType(), Idx);
}
default:
// We don't have any information on this instruction.
return -1;
}
}
示例11: processPHI
bool CorrelatedValuePropagation::processPHI(PHINode *P) {
bool Changed = false;
BasicBlock *BB = P->getParent();
for (unsigned i = 0, e = P->getNumIncomingValues(); i < e; ++i) {
Value *Incoming = P->getIncomingValue(i);
if (isa<Constant>(Incoming)) continue;
Value *V = LVI->getConstantOnEdge(Incoming, P->getIncomingBlock(i), BB, P);
// Look if the incoming value is a select with a scalar condition for which
// LVI can tells us the value. In that case replace the incoming value with
// the appropriate value of the select. This often allows us to remove the
// select later.
if (!V) {
SelectInst *SI = dyn_cast<SelectInst>(Incoming);
if (!SI) continue;
Value *Condition = SI->getCondition();
if (!Condition->getType()->isVectorTy()) {
if (Constant *C = LVI->getConstantOnEdge(
Condition, P->getIncomingBlock(i), BB, P)) {
if (C->isOneValue()) {
V = SI->getTrueValue();
} else if (C->isZeroValue()) {
V = SI->getFalseValue();
}
// Once LVI learns to handle vector types, we could also add support
// for vector type constants that are not all zeroes or all ones.
}
}
// Look if the select has a constant but LVI tells us that the incoming
// value can never be that constant. In that case replace the incoming
// value with the other value of the select. This often allows us to
// remove the select later.
if (!V) {
Constant *C = dyn_cast<Constant>(SI->getFalseValue());
if (!C) continue;
if (LVI->getPredicateOnEdge(ICmpInst::ICMP_EQ, SI, C,
P->getIncomingBlock(i), BB, P) !=
LazyValueInfo::False)
continue;
V = SI->getTrueValue();
}
DEBUG(dbgs() << "CVP: Threading PHI over " << *SI << '\n');
}
P->setIncomingValue(i, V);
Changed = true;
}
// FIXME: Provide TLI, DT, AT to SimplifyInstruction.
const DataLayout &DL = BB->getModule()->getDataLayout();
if (Value *V = SimplifyInstruction(P, DL)) {
P->replaceAllUsesWith(V);
P->eraseFromParent();
Changed = true;
}
if (Changed)
++NumPhis;
return Changed;
}
示例12: ReplaceInstUsesWith
//.........这里部分代码省略.........
if (W == Y) {
Value *NewAdd = Builder->CreateAdd(X, Z, LHS->getName());
return BinaryOperator::CreateMul(W, NewAdd);
}
}
}
if (ConstantInt *CRHS = dyn_cast<ConstantInt>(RHS)) {
Value *X = 0;
if (match(LHS, m_Not(m_Value(X)))) // ~X + C --> (C-1) - X
return BinaryOperator::CreateSub(SubOne(CRHS), X);
// (X & FF00) + xx00 -> (X+xx00) & FF00
if (LHS->hasOneUse() &&
match(LHS, m_And(m_Value(X), m_ConstantInt(C2))) &&
CRHS->getValue() == (CRHS->getValue() & C2->getValue())) {
// See if all bits from the first bit set in the Add RHS up are included
// in the mask. First, get the rightmost bit.
const APInt &AddRHSV = CRHS->getValue();
// Form a mask of all bits from the lowest bit added through the top.
APInt AddRHSHighBits(~((AddRHSV & -AddRHSV)-1));
// See if the and mask includes all of these bits.
APInt AddRHSHighBitsAnd(AddRHSHighBits & C2->getValue());
if (AddRHSHighBits == AddRHSHighBitsAnd) {
// Okay, the xform is safe. Insert the new add pronto.
Value *NewAdd = Builder->CreateAdd(X, CRHS, LHS->getName());
return BinaryOperator::CreateAnd(NewAdd, C2);
}
}
// Try to fold constant add into select arguments.
if (SelectInst *SI = dyn_cast<SelectInst>(LHS))
if (Instruction *R = FoldOpIntoSelect(I, SI))
return R;
}
// add (select X 0 (sub n A)) A --> select X A n
{
SelectInst *SI = dyn_cast<SelectInst>(LHS);
Value *A = RHS;
if (!SI) {
SI = dyn_cast<SelectInst>(RHS);
A = LHS;
}
if (SI && SI->hasOneUse()) {
Value *TV = SI->getTrueValue();
Value *FV = SI->getFalseValue();
Value *N;
// Can we fold the add into the argument of the select?
// We check both true and false select arguments for a matching subtract.
if (match(FV, m_Zero()) && match(TV, m_Sub(m_Value(N), m_Specific(A))))
// Fold the add into the true select value.
return SelectInst::Create(SI->getCondition(), N, A);
if (match(TV, m_Zero()) && match(FV, m_Sub(m_Value(N), m_Specific(A))))
// Fold the add into the false select value.
return SelectInst::Create(SI->getCondition(), A, N);
}
}
// Check for (add (sext x), y), see if we can merge this into an
// integer add followed by a sext.
if (SExtInst *LHSConv = dyn_cast<SExtInst>(LHS)) {
// (add (sext x), cst) --> (sext (add x, cst'))
if (ConstantInt *RHSC = dyn_cast<ConstantInt>(RHS)) {
Constant *CI =
ConstantExpr::getTrunc(RHSC, LHSConv->getOperand(0)->getType());
if (LHSConv->hasOneUse() &&
ConstantExpr::getSExt(CI, I.getType()) == RHSC &&
WillNotOverflowSignedAdd(LHSConv->getOperand(0), CI)) {
// Insert the new, smaller add.
Value *NewAdd = Builder->CreateNSWAdd(LHSConv->getOperand(0),
CI, "addconv");
return new SExtInst(NewAdd, I.getType());
}
}
// (add (sext x), (sext y)) --> (sext (add int x, y))
if (SExtInst *RHSConv = dyn_cast<SExtInst>(RHS)) {
// Only do this if x/y have the same type, if at last one of them has a
// single use (so we don't increase the number of sexts), and if the
// integer add will not overflow.
if (LHSConv->getOperand(0)->getType()==RHSConv->getOperand(0)->getType()&&
(LHSConv->hasOneUse() || RHSConv->hasOneUse()) &&
WillNotOverflowSignedAdd(LHSConv->getOperand(0),
RHSConv->getOperand(0))) {
// Insert the new integer add.
Value *NewAdd = Builder->CreateNSWAdd(LHSConv->getOperand(0),
RHSConv->getOperand(0), "addconv");
return new SExtInst(NewAdd, I.getType());
}
}
}
return Changed ? &I : 0;
}
示例13: ReplaceInstUsesWith
/// FoldSPFofSPF - We have an SPF (e.g. a min or max) of an SPF of the form:
/// SPF2(SPF1(A, B), C)
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);
// 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);
}
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();
// MIN(MIN(A, 23), 97) -> MIN(A, 23)
// MAX(MAX(A, 97), 23) -> MAX(A, 97)
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);
// 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;
}
}
}
}
// ABS(ABS(X)) -> ABS(X)
// NABS(NABS(X)) -> NABS(X)
if (SPF1 == SPF2 && (SPF1 == SPF_ABS || SPF1 == SPF_NABS)) {
return ReplaceInstUsesWith(Outer, Inner);
}
// 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);
}
return nullptr;
}
示例14: switch
/// 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);
if (!SI) return SPF_UNKNOWN;
ICmpInst *ICI = dyn_cast<ICmpInst>(SI->getCondition());
if (!ICI) return SPF_UNKNOWN;
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;
// (icmp X, Y) ? X : Y
if (TrueVal == CmpLHS && FalseVal == CmpRHS) {
switch (Pred) {
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;
}
}
// (icmp X, Y) ? Y : X
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;
}
}
}
// TODO: (X > 4) ? X : 5 --> (X >= 5) ? X : 5 --> MAX(X, 5)
return SPF_UNKNOWN;
}