// Calculate Edge Weights using "Pointer Heuristics". Predict a comparsion // between two pointer or pointer and NULL will fail. bool BranchProbabilityInfo::calcPointerHeuristics(const BasicBlock *BB) { const BranchInst *BI = dyn_cast<BranchInst>(BB->getTerminator()); if (!BI || !BI->isConditional()) return false; Value *Cond = BI->getCondition(); ICmpInst *CI = dyn_cast<ICmpInst>(Cond); if (!CI || !CI->isEquality()) return false; Value *LHS = CI->getOperand(0); if (!LHS->getType()->isPointerTy()) return false; assert(CI->getOperand(1)->getType()->isPointerTy()); // p != 0 -> isProb = true // p == 0 -> isProb = false // p != q -> isProb = true // p == q -> isProb = false; unsigned TakenIdx = 0, NonTakenIdx = 1; bool isProb = CI->getPredicate() == ICmpInst::ICMP_NE; if (!isProb) std::swap(TakenIdx, NonTakenIdx); BranchProbability TakenProb(PH_TAKEN_WEIGHT, PH_TAKEN_WEIGHT + PH_NONTAKEN_WEIGHT); setEdgeProbability(BB, TakenIdx, TakenProb); setEdgeProbability(BB, NonTakenIdx, TakenProb.getCompl()); return true; }
// Calculate Edge Weights using "Pointer Heuristics". Predict a comparsion // between two pointer or pointer and NULL will fail. bool BranchProbabilityAnalysis::calcPointerHeuristics(BasicBlock *BB) { BranchInst * BI = dyn_cast<BranchInst>(BB->getTerminator()); if (!BI || !BI->isConditional()) return false; Value *Cond = BI->getCondition(); ICmpInst *CI = dyn_cast<ICmpInst>(Cond); if (!CI || !CI->isEquality()) return false; Value *LHS = CI->getOperand(0); if (!LHS->getType()->isPointerTy()) return false; assert(CI->getOperand(1)->getType()->isPointerTy()); BasicBlock *Taken = BI->getSuccessor(0); BasicBlock *NonTaken = BI->getSuccessor(1); // p != 0 -> isProb = true // p == 0 -> isProb = false // p != q -> isProb = true // p == q -> isProb = false; bool isProb = CI->getPredicate() == ICmpInst::ICMP_NE; if (!isProb) std::swap(Taken, NonTaken); BP->setEdgeWeight(BB, Taken, PH_TAKEN_WEIGHT); BP->setEdgeWeight(BB, NonTaken, PH_NONTAKEN_WEIGHT); return true; }
bool BranchProbabilityInfo::calcZeroHeuristics(BasicBlock *BB) { BranchInst * BI = dyn_cast<BranchInst>(BB->getTerminator()); if (!BI || !BI->isConditional()) return false; Value *Cond = BI->getCondition(); ICmpInst *CI = dyn_cast<ICmpInst>(Cond); if (!CI) return false; Value *RHS = CI->getOperand(1); ConstantInt *CV = dyn_cast<ConstantInt>(RHS); if (!CV) return false; bool isProb; if (CV->isZero()) { switch (CI->getPredicate()) { case CmpInst::ICMP_EQ: // X == 0 -> Unlikely isProb = false; break; case CmpInst::ICMP_NE: // X != 0 -> Likely isProb = true; break; case CmpInst::ICMP_SLT: // X < 0 -> Unlikely isProb = false; break; case CmpInst::ICMP_SGT: // X > 0 -> Likely isProb = true; break; default: return false; } } else if (CV->isOne() && CI->getPredicate() == CmpInst::ICMP_SLT) { // InstCombine canonicalizes X <= 0 into X < 1. // X <= 0 -> Unlikely isProb = false; } else if (CV->isAllOnesValue() && CI->getPredicate() == CmpInst::ICMP_SGT) { // InstCombine canonicalizes X >= 0 into X > -1. // X >= 0 -> Likely isProb = true; } else { return false; } unsigned TakenIdx = 0, NonTakenIdx = 1; if (!isProb) std::swap(TakenIdx, NonTakenIdx); setEdgeWeight(BB, TakenIdx, ZH_TAKEN_WEIGHT); setEdgeWeight(BB, NonTakenIdx, ZH_NONTAKEN_WEIGHT); return true; }
/// Given a LoadInst LI this adds assume(LI != null) after it. static void addAssumeNonNull(AssumptionCache *AC, LoadInst *LI) { Function *AssumeIntrinsic = Intrinsic::getDeclaration(LI->getModule(), Intrinsic::assume); ICmpInst *LoadNotNull = new ICmpInst(ICmpInst::ICMP_NE, LI, Constant::getNullValue(LI->getType())); LoadNotNull->insertAfter(LI); CallInst *CI = CallInst::Create(AssumeIntrinsic, {LoadNotNull}); CI->insertAfter(LoadNotNull); AC->registerAssumption(CI); }
void IndVarSimplify::EliminateIVComparisons() { // Look for ICmp users. for (IVUsers::iterator I = IU->begin(), E = IU->end(); I != E; ++I) { IVStrideUse &UI = *I; ICmpInst *ICmp = dyn_cast<ICmpInst>(UI.getUser()); if (!ICmp) continue; bool Swapped = UI.getOperandValToReplace() == ICmp->getOperand(1); ICmpInst::Predicate Pred = ICmp->getPredicate(); if (Swapped) Pred = ICmpInst::getSwappedPredicate(Pred); // Get the SCEVs for the ICmp operands. const SCEV *S = IU->getReplacementExpr(UI); const SCEV *X = SE->getSCEV(ICmp->getOperand(!Swapped)); // Simplify unnecessary loops away. const Loop *ICmpLoop = LI->getLoopFor(ICmp->getParent()); S = SE->getSCEVAtScope(S, ICmpLoop); X = SE->getSCEVAtScope(X, ICmpLoop); // If the condition is always true or always false, replace it with // a constant value. if (SE->isKnownPredicate(Pred, S, X)) ICmp->replaceAllUsesWith(ConstantInt::getTrue(ICmp->getContext())); else if (SE->isKnownPredicate(ICmpInst::getInversePredicate(Pred), S, X)) ICmp->replaceAllUsesWith(ConstantInt::getFalse(ICmp->getContext())); else continue; DEBUG(dbgs() << "INDVARS: Eliminated comparison: " << *ICmp << '\n'); DeadInsts.push_back(ICmp); } }
bool AMDGPUCodeGenPrepare::promoteUniformOpToI32(ICmpInst &I) const { assert(needsPromotionToI32(I.getOperand(0)->getType()) && "I does not need promotion to i32"); IRBuilder<> Builder(&I); Builder.SetCurrentDebugLocation(I.getDebugLoc()); Type *I32Ty = getI32Ty(Builder, I.getOperand(0)->getType()); Value *ExtOp0 = nullptr; Value *ExtOp1 = nullptr; Value *NewICmp = nullptr; if (I.isSigned()) { ExtOp0 = Builder.CreateSExt(I.getOperand(0), I32Ty); ExtOp1 = Builder.CreateSExt(I.getOperand(1), I32Ty); } else { ExtOp0 = Builder.CreateZExt(I.getOperand(0), I32Ty); ExtOp1 = Builder.CreateZExt(I.getOperand(1), I32Ty); } NewICmp = Builder.CreateICmp(I.getPredicate(), ExtOp0, ExtOp1); I.replaceAllUsesWith(NewICmp); I.eraseFromParent(); return true; }
bool BranchProbabilityAnalysis::calcZeroHeuristics(BasicBlock *BB) { BranchInst * BI = dyn_cast<BranchInst>(BB->getTerminator()); if (!BI || !BI->isConditional()) return false; Value *Cond = BI->getCondition(); ICmpInst *CI = dyn_cast<ICmpInst>(Cond); if (!CI) return false; Value *RHS = CI->getOperand(1); ConstantInt *CV = dyn_cast<ConstantInt>(RHS); if (!CV || !CV->isZero()) return false; bool isProb; switch (CI->getPredicate()) { case CmpInst::ICMP_EQ: // Equal to zero is not expected to be taken. isProb = false; break; case CmpInst::ICMP_NE: // Not equal to zero is expected. isProb = true; break; case CmpInst::ICMP_SLT: // Less or equal to zero is not expected. // X < 0 -> Unlikely isProb = false; break; case CmpInst::ICMP_UGT: case CmpInst::ICMP_SGT: // Greater or equal to zero is expected. // X > 0 -> Likely isProb = true; break; default: return false; }; BasicBlock *Taken = BI->getSuccessor(0); BasicBlock *NonTaken = BI->getSuccessor(1); if (!isProb) std::swap(Taken, NonTaken); BP->setEdgeWeight(BB, Taken, ZH_TAKEN_WEIGHT); BP->setEdgeWeight(BB, NonTaken, ZH_NONTAKEN_WEIGHT); return true; }
bool LowerExpectIntrinsic::HandleIfExpect(BranchInst *BI) { if (BI->isUnconditional()) return false; // Handle non-optimized IR code like: // %expval = call i64 @llvm.expect.i64(i64 %conv1, i64 1) // %tobool = icmp ne i64 %expval, 0 // br i1 %tobool, label %if.then, label %if.end // // Or the following simpler case: // %expval = call i1 @llvm.expect.i1(i1 %cmp, i1 1) // br i1 %expval, label %if.then, label %if.end CallInst *CI; ICmpInst *CmpI = dyn_cast<ICmpInst>(BI->getCondition()); if (!CmpI) { CI = dyn_cast<CallInst>(BI->getCondition()); } else { if (CmpI->getPredicate() != CmpInst::ICMP_NE) return false; CI = dyn_cast<CallInst>(CmpI->getOperand(0)); } if (!CI) return false; Function *Fn = CI->getCalledFunction(); if (!Fn || Fn->getIntrinsicID() != Intrinsic::expect) return false; Value *ArgValue = CI->getArgOperand(0); ConstantInt *ExpectedValue = dyn_cast<ConstantInt>(CI->getArgOperand(1)); if (!ExpectedValue) return false; MDBuilder MDB(CI->getContext()); MDNode *Node; // If expect value is equal to 1 it means that we are more likely to take // branch 0, in other case more likely is branch 1. if (ExpectedValue->isOne()) Node = MDB.createBranchWeights(LikelyBranchWeight, UnlikelyBranchWeight); else Node = MDB.createBranchWeights(UnlikelyBranchWeight, LikelyBranchWeight); BI->setMetadata(LLVMContext::MD_prof, Node); if (CmpI) CmpI->setOperand(0, ArgValue); else BI->setCondition(ArgValue); return true; }
void TempScopInfo::buildAffineCondition(Value &V, bool inverted, Comparison **Comp, TempScop &Scop) const { Region &R = Scop.getMaxRegion(); ParamSetType &Params = Scop.getParamSet(); if (ConstantInt *C = dyn_cast<ConstantInt>(&V)) { // If this is always true condition, we will create 1 >= 0, // otherwise we will create 1 == 0. SCEVAffFunc *AffLHS = new SCEVAffFunc(SE->getConstant(C->getType(), 0), SCEVAffFunc::Eq, R, Params, LI, SE); SCEVAffFunc *AffRHS = new SCEVAffFunc(SE->getConstant(C->getType(), 1), SCEVAffFunc::Eq, R, Params, LI, SE); if (C->isOne() == inverted) *Comp = new Comparison(AffRHS, AffLHS, ICmpInst::ICMP_NE); else *Comp = new Comparison(AffLHS, AffLHS, ICmpInst::ICMP_EQ); return; } ICmpInst *ICmp = dyn_cast<ICmpInst>(&V); assert(ICmp && "Only ICmpInst of constant as condition supported!"); const SCEV *LHS = SE->getSCEV(ICmp->getOperand(0)), *RHS = SE->getSCEV(ICmp->getOperand(1)); ICmpInst::Predicate Pred = ICmp->getPredicate(); // Invert the predicate if needed. if (inverted) Pred = ICmpInst::getInversePredicate(Pred); SCEVAffFunc *AffLHS = new SCEVAffFunc(LHS, SCEVAffFunc::Eq, R, Params, LI, SE); SCEVAffFunc *AffRHS = new SCEVAffFunc(RHS, SCEVAffFunc::Eq, R, Params, LI, SE); switch (Pred) { case ICmpInst::ICMP_UGT: case ICmpInst::ICMP_UGE: case ICmpInst::ICMP_ULT: case ICmpInst::ICMP_ULE: // TODO: At the moment we need to see everything as signed. This is an // correctness issue that needs to be solved. //AffLHS->setUnsigned(); //AffRHS->setUnsigned(); break; default: break; } *Comp = new Comparison(AffLHS, AffRHS, Pred); }
bool visitICmpInst(ICmpInst& inst) { // errs() << "got icmp instruction! " << inst << '\n'; bool changed = false; if (inst.getPredicate() == CmpInst::ICMP_EQ) { assert(inst.getNumOperands() == 2); if (inst.getOperand(1) == processing) { inst.swapOperands(); changed = true; any_changes = true; } assert(dyn_cast<Instruction>(inst.getOperand(0)) == processing); Value* other = inst.getOperand(1); if (isa<ConstantPointerNull>(other)) { if (VERBOSITY("opt") >= 2) { errs() << inst << '\n'; errs() << "replacing with false!\n"; } Value* new_value = ConstantInt::getFalse(other->getContext()); inst.replaceAllUsesWith(new_value); inst.eraseFromParent(); changed = true; any_changes = true; } } return changed; }
/// restrictLoopBound - Op dominates loop body. Op compares an IV based value /// with a loop invariant value. Update loop's lower and upper bound based on /// the loop invariant value. bool LoopIndexSplit::restrictLoopBound(ICmpInst &Op) { bool Sign = Op.isSigned(); Instruction *PHTerm = L->getLoopPreheader()->getTerminator(); if (IVisGT(*ExitCondition) || IVisGE(*ExitCondition)) { BranchInst *EBR = cast<BranchInst>(ExitCondition->getParent()->getTerminator()); ExitCondition->setPredicate(ExitCondition->getInversePredicate()); BasicBlock *T = EBR->getSuccessor(0); EBR->setSuccessor(0, EBR->getSuccessor(1)); EBR->setSuccessor(1, T); } LLVMContext &Context = Op.getContext(); // New upper and lower bounds. Value *NLB = NULL; Value *NUB = NULL; if (Value *V = IVisLT(Op)) { // Restrict upper bound. if (IVisLE(*ExitCondition)) V = getMinusOne(V, Sign, PHTerm, Context); NUB = getMin(V, IVExitValue, Sign, PHTerm); } else if (Value *V = IVisLE(Op)) { // Restrict upper bound. if (IVisLT(*ExitCondition)) V = getPlusOne(V, Sign, PHTerm, Context); NUB = getMin(V, IVExitValue, Sign, PHTerm); } else if (Value *V = IVisGT(Op)) { // Restrict lower bound. V = getPlusOne(V, Sign, PHTerm, Context); NLB = getMax(V, IVStartValue, Sign, PHTerm); } else if (Value *V = IVisGE(Op)) // Restrict lower bound. NLB = getMax(V, IVStartValue, Sign, PHTerm); if (!NLB && !NUB) return false; if (NLB) { unsigned i = IndVar->getBasicBlockIndex(L->getLoopPreheader()); IndVar->setIncomingValue(i, NLB); } if (NUB) { unsigned i = (ExitCondition->getOperand(0) != IVExitValue); ExitCondition->setOperand(i, NUB); } return true; }
/// Creates the graphs for this function. /// It will look for all comparators used in branches, and create them. /// These comparators will create constraints for any instruction as an /// operand. void ABCD::executeABCD(Function &F) { for (Function::iterator begin = F.begin(), end = F.end(); begin != end; ++begin) { BasicBlock *BB = begin; TerminatorInst *TI = BB->getTerminator(); if (TI->getNumOperands() == 0) continue; ICmpInst *ICI = dyn_cast<ICmpInst>(TI->getOperand(0)); if (!ICI || !isa<IntegerType>(ICI->getOperand(0)->getType())) continue; createConstraintCmpInst(ICI, TI); seekRedundancy(ICI, TI); } }
void TempScopInfo::buildAffineCondition(Value &V, bool inverted, Comparison **Comp) const { if (ConstantInt *C = dyn_cast<ConstantInt>(&V)) { // If this is always true condition, we will create 0 <= 1, // otherwise we will create 0 >= 1. const SCEV *LHS = SE->getConstant(C->getType(), 0); const SCEV *RHS = SE->getConstant(C->getType(), 1); if (C->isOne() == inverted) *Comp = new Comparison(LHS, RHS, ICmpInst::ICMP_SLE); else *Comp = new Comparison(LHS, RHS, ICmpInst::ICMP_SGE); return; } ICmpInst *ICmp = dyn_cast<ICmpInst>(&V); assert(ICmp && "Only ICmpInst of constant as condition supported!"); Loop *L = LI->getLoopFor(ICmp->getParent()); const SCEV *LHS = SE->getSCEVAtScope(ICmp->getOperand(0), L); const SCEV *RHS = SE->getSCEVAtScope(ICmp->getOperand(1), L); ICmpInst::Predicate Pred = ICmp->getPredicate(); // Invert the predicate if needed. if (inverted) Pred = ICmpInst::getInversePredicate(Pred); switch (Pred) { case ICmpInst::ICMP_UGT: case ICmpInst::ICMP_UGE: case ICmpInst::ICMP_ULT: case ICmpInst::ICMP_ULE: // TODO: At the moment we need to see everything as signed. This is an // correctness issue that needs to be solved. // AffLHS->setUnsigned(); // AffRHS->setUnsigned(); break; default: break; } *Comp = new Comparison(LHS, RHS, Pred); }
bool AMDGPUCodeGenPrepare::visitICmpInst(ICmpInst &I) { bool Changed = false; if (ST->has16BitInsts() && needsPromotionToI32(I.getOperand(0)->getType()) && DA->isUniform(&I)) Changed |= promoteUniformOpToI32(I); return Changed; }
/// If From has a conditional jump to To, add the condition to Conditions, /// if it is relevant to any argument at CS. static void recordCondition(CallSite CS, BasicBlock *From, BasicBlock *To, ConditionsTy &Conditions) { auto *BI = dyn_cast<BranchInst>(From->getTerminator()); if (!BI || !BI->isConditional()) return; CmpInst::Predicate Pred; Value *Cond = BI->getCondition(); if (!match(Cond, m_ICmp(Pred, m_Value(), m_Constant()))) return; ICmpInst *Cmp = cast<ICmpInst>(Cond); if (Pred == ICmpInst::ICMP_EQ || Pred == ICmpInst::ICMP_NE) if (isCondRelevantToAnyCallArgument(Cmp, CS)) Conditions.push_back({Cmp, From->getTerminator()->getSuccessor(0) == To ? Pred : Cmp->getInversePredicate()}); }
bool LowerExpectIntrinsic::HandleIfExpect(BranchInst *BI) { if (BI->isUnconditional()) return false; // Handle non-optimized IR code like: // %expval = call i64 @llvm.expect.i64.i64(i64 %conv1, i64 1) // %tobool = icmp ne i64 %expval, 0 // br i1 %tobool, label %if.then, label %if.end ICmpInst *CmpI = dyn_cast<ICmpInst>(BI->getCondition()); if (!CmpI || CmpI->getPredicate() != CmpInst::ICMP_NE) return false; CallInst *CI = dyn_cast<CallInst>(CmpI->getOperand(0)); if (!CI) return false; Function *Fn = CI->getCalledFunction(); if (!Fn || Fn->getIntrinsicID() != Intrinsic::expect) return false; Value *ArgValue = CI->getArgOperand(0); ConstantInt *ExpectedValue = dyn_cast<ConstantInt>(CI->getArgOperand(1)); if (!ExpectedValue) return false; LLVMContext &Context = CI->getContext(); const Type *Int32Ty = Type::getInt32Ty(Context); bool Likely = ExpectedValue->isOne(); // If expect value is equal to 1 it means that we are more likely to take // branch 0, in other case more likely is branch 1. Value *Ops[] = { MDString::get(Context, "branch_weights"), ConstantInt::get(Int32Ty, Likely ? LikelyBranchWeight : UnlikelyBranchWeight), ConstantInt::get(Int32Ty, Likely ? UnlikelyBranchWeight : LikelyBranchWeight) }; MDNode *WeightsNode = MDNode::get(Context, Ops); BI->setMetadata(LLVMContext::MD_prof, WeightsNode); CmpI->setOperand(0, ArgValue); return true; }
/// MatchPointerHeuristic - Predict that a comparison of a pointer against /// null or of two pointers will fail. /// @returns a Prediction that is a pair in which the first element is the /// successor taken, and the second the successor not taken. Prediction BranchHeuristicsInfo::MatchPointerHeuristic(BasicBlock *root) const { // Last instruction of basic block. TerminatorInst *TI = root->getTerminator(); // Basic block successors. True and False branches. BasicBlock *trueSuccessor = TI->getSuccessor(0); BasicBlock *falseSuccessor = TI->getSuccessor(1); // Is the last instruction a Branch Instruction? BranchInst *BI = dyn_cast<BranchInst>(TI); if (!BI || !BI->isConditional()) return empty; // Conditional instruction. Value *cond = BI->getCondition(); // Pointer comparisons are integer comparisons. ICmpInst *II = dyn_cast<ICmpInst>(cond); if (!II) return empty; // An integer comparison has always two operands. Value *operand1 = II->getOperand(0); Value *operand2 = II->getOperand(1); // Obtain the type of comparison. enum ICmpInst::Predicate signedPred = II->getSignedPredicate(); // The heuristic states that it must be compared against null, // but in LLVM, null is also a PointerType, so it only requires // to test if there is a comparison between two pointers. if (signedPred == ICmpInst::ICMP_EQ && isa<PointerType>(operand1->getType()) && // NULL is a pointer type too isa<PointerType>(operand2->getType())) { // NULL is a pointer type too return std::make_pair(falseSuccessor, trueSuccessor); } else if (signedPred != ICmpInst::ICMP_EQ && isa<PointerType>(operand1->getType()) && isa<PointerType>(operand2->getType())) { return std::make_pair(trueSuccessor, falseSuccessor); } return empty; }
// createSigmasForCondBranch void Redefinition::createSigmasForCondBranch(BranchInst *BI) { assert(BI->isConditional() && "Expected conditional branch"); ICmpInst *ICI = dyn_cast<ICmpInst>(BI->getCondition()); if (!ICI || !ICI->getOperand(0)->getType()->isIntegerTy()) return; RDEF_DEBUG(dbgs() << "createSigmasForCondBranch: " << *BI << "\n"); Value *Left = ICI->getOperand(0); Value *Right = ICI->getOperand(1); BasicBlock *TB = BI->getSuccessor(0); BasicBlock *FB = BI->getSuccessor(1); bool HasSinglePredTB = TB->getSinglePredecessor() != NULL; bool HasSinglePredFB = FB->getSinglePredecessor() != NULL; bool IsRedefinableRight = IsRedefinable(Right); bool SameBranchOperands = Left == Right; //errs() << HasSinglePredTB << ", " << HasSinglePredFB << "\n"; //errs() << IsRedefinable(Left) << ", " << IsRedefinableRight << "\n"; if (IsRedefinable(Left)) { // We don't want to place extranius definitions of a value, so the only // place the sigma once if the branch operands are the same. Value *Second = SameBranchOperands && IsRedefinableRight ? Right : NULL; if (HasSinglePredTB) createSigmaNodesForValueAt(Left, Second, TB); if (HasSinglePredFB) createSigmaNodesForValueAt(Left, Second, FB); } // Left isn't definable down here. else if (IsRedefinable(Right)) { if (HasSinglePredTB) createSigmaNodesForValueAt(Right, NULL, TB); if (HasSinglePredFB) createSigmaNodesForValueAt(Right, NULL, FB); } }
void IndVarSimplify::EliminateIVComparisons() { SmallVector<WeakVH, 16> DeadInsts; // Look for ICmp users. for (IVUsers::iterator I = IU->begin(), E = IU->end(); I != E; ++I) { IVStrideUse &UI = *I; ICmpInst *ICmp = dyn_cast<ICmpInst>(UI.getUser()); if (!ICmp) continue; bool Swapped = UI.getOperandValToReplace() == ICmp->getOperand(1); ICmpInst::Predicate Pred = ICmp->getPredicate(); if (Swapped) Pred = ICmpInst::getSwappedPredicate(Pred); // Get the SCEVs for the ICmp operands. const SCEV *S = IU->getReplacementExpr(UI); const SCEV *X = SE->getSCEV(ICmp->getOperand(!Swapped)); // Simplify unnecessary loops away. const Loop *ICmpLoop = LI->getLoopFor(ICmp->getParent()); S = SE->getSCEVAtScope(S, ICmpLoop); X = SE->getSCEVAtScope(X, ICmpLoop); // If the condition is always true or always false, replace it with // a constant value. if (SE->isKnownPredicate(Pred, S, X)) ICmp->replaceAllUsesWith(ConstantInt::getTrue(ICmp->getContext())); else if (SE->isKnownPredicate(ICmpInst::getInversePredicate(Pred), S, X)) ICmp->replaceAllUsesWith(ConstantInt::getFalse(ICmp->getContext())); else continue; DEBUG(dbgs() << "INDVARS: Eliminated comparison: " << *ICmp << '\n'); DeadInsts.push_back(ICmp); } // Now that we're done iterating through lists, clean up any instructions // which are now dead. while (!DeadInsts.empty()) if (Instruction *Inst = dyn_cast_or_null<Instruction>(&*DeadInsts.pop_back_val())) RecursivelyDeleteTriviallyDeadInstructions(Inst); }
/// 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; }
int BranchProbabilities::CheckPointerHeuristic() { // Heuristic fails if the last instruction is not a conditional branch BranchInst *BI = dyn_cast<BranchInst>(_TI); if ((!BI) || (BI->isUnconditional())) return -1; // All pointer comparisons are done with the icmp instruction ICmpInst *icmp = dyn_cast<ICmpInst>(BI->getCondition()); if (!icmp) return -1; Value *v[2]; v[0] = icmp->getOperand(0); v[1] = icmp->getOperand(1); // Make sure we're comparing pointers if (isa<PointerType>(v[0]->getType())) { assert(isa<PointerType>(v[1]->getType()) && "v[1] is not a pointer!"); // Choose the prefered branch depending on if this is an eq or neq comp switch (icmp->getPredicate()) { case ICmpInst::ICMP_EQ: return 1; case ICmpInst::ICMP_NE: return 0; default: assert("non-equality comparison of pointers"); return -1; } } return -1; }
bool CallAnalyzer::visitICmp(ICmpInst &I) { Value *LHS = I.getOperand(0), *RHS = I.getOperand(1); // First try to handle simplified comparisons. if (!isa<Constant>(LHS)) if (Constant *SimpleLHS = SimplifiedValues.lookup(LHS)) LHS = SimpleLHS; if (!isa<Constant>(RHS)) if (Constant *SimpleRHS = SimplifiedValues.lookup(RHS)) RHS = SimpleRHS; if (Constant *CLHS = dyn_cast<Constant>(LHS)) if (Constant *CRHS = dyn_cast<Constant>(RHS)) if (Constant *C = ConstantExpr::getICmp(I.getPredicate(), CLHS, CRHS)) { SimplifiedValues[&I] = C; return true; } // Otherwise look for a comparison between constant offset pointers with // a common base. Value *LHSBase, *RHSBase; APInt LHSOffset, RHSOffset; llvm::tie(LHSBase, LHSOffset) = ConstantOffsetPtrs.lookup(LHS); if (LHSBase) { llvm::tie(RHSBase, RHSOffset) = ConstantOffsetPtrs.lookup(RHS); if (RHSBase && LHSBase == RHSBase) { // We have common bases, fold the icmp to a constant based on the // offsets. Constant *CLHS = ConstantInt::get(LHS->getContext(), LHSOffset); Constant *CRHS = ConstantInt::get(RHS->getContext(), RHSOffset); if (Constant *C = ConstantExpr::getICmp(I.getPredicate(), CLHS, CRHS)) { SimplifiedValues[&I] = C; ++NumConstantPtrCmps; return true; } } } // If the comparison is an equality comparison with null, we can simplify it // for any alloca-derived argument. if (I.isEquality() && isa<ConstantPointerNull>(I.getOperand(1))) if (isAllocaDerivedArg(I.getOperand(0))) { // We can actually predict the result of comparisons between an // alloca-derived value and null. Note that this fires regardless of // SROA firing. bool IsNotEqual = I.getPredicate() == CmpInst::ICMP_NE; SimplifiedValues[&I] = IsNotEqual ? ConstantInt::getTrue(I.getType()) : ConstantInt::getFalse(I.getType()); return true; } // Finally check for SROA candidates in comparisons. Value *SROAArg; DenseMap<Value *, int>::iterator CostIt; if (lookupSROAArgAndCost(I.getOperand(0), SROAArg, CostIt)) { if (isa<ConstantPointerNull>(I.getOperand(1))) { accumulateSROACost(CostIt, InlineConstants::InstrCost); return true; } disableSROA(CostIt); } return false; }
bool BranchProbabilityInfo::calcZeroHeuristics(BasicBlock *BB) { BranchInst * BI = dyn_cast<BranchInst>(BB->getTerminator()); if (!BI || !BI->isConditional()) return false; Value *Cond = BI->getCondition(); ICmpInst *CI = dyn_cast<ICmpInst>(Cond); if (!CI) return false; Value *RHS = CI->getOperand(1); ConstantInt *CV = dyn_cast<ConstantInt>(RHS); if (!CV) return false; // If the LHS is the result of AND'ing a value with a single bit bitmask, // we don't have information about probabilities. if (Instruction *LHS = dyn_cast<Instruction>(CI->getOperand(0))) if (LHS->getOpcode() == Instruction::And) if (ConstantInt *AndRHS = dyn_cast<ConstantInt>(LHS->getOperand(1))) if (AndRHS->getUniqueInteger().isPowerOf2()) return false; bool isProb; if (CV->isZero()) { switch (CI->getPredicate()) { case CmpInst::ICMP_EQ: // X == 0 -> Unlikely isProb = false; break; case CmpInst::ICMP_NE: // X != 0 -> Likely isProb = true; break; case CmpInst::ICMP_SLT: // X < 0 -> Unlikely isProb = false; break; case CmpInst::ICMP_SGT: // X > 0 -> Likely isProb = true; break; default: return false; } } else if (CV->isOne() && CI->getPredicate() == CmpInst::ICMP_SLT) { // InstCombine canonicalizes X <= 0 into X < 1. // X <= 0 -> Unlikely isProb = false; } else if (CV->isAllOnesValue()) { switch (CI->getPredicate()) { case CmpInst::ICMP_EQ: // X == -1 -> Unlikely isProb = false; break; case CmpInst::ICMP_NE: // X != -1 -> Likely isProb = true; break; case CmpInst::ICMP_SGT: // InstCombine canonicalizes X >= 0 into X > -1. // X >= 0 -> Likely isProb = true; break; default: return false; } } else { return false; } unsigned TakenIdx = 0, NonTakenIdx = 1; if (!isProb) std::swap(TakenIdx, NonTakenIdx); BranchProbability TakenProb(ZH_TAKEN_WEIGHT, ZH_TAKEN_WEIGHT + ZH_NONTAKEN_WEIGHT); setEdgeProbability(BB, TakenIdx, TakenProb); setEdgeProbability(BB, NonTakenIdx, TakenProb.getCompl()); return true; }
bool LoopIndexSplit::splitLoop() { SplitCondition = NULL; if (ExitCondition->getPredicate() == ICmpInst::ICMP_NE || ExitCondition->getPredicate() == ICmpInst::ICMP_EQ) return false; BasicBlock *Header = L->getHeader(); BasicBlock *Latch = L->getLoopLatch(); BranchInst *SBR = NULL; // Split Condition Branch BranchInst *EBR = cast<BranchInst>(ExitCondition->getParent()->getTerminator()); // If Exiting block includes loop variant instructions then this // loop may not be split safely. BasicBlock *ExitingBlock = ExitCondition->getParent(); if (!cleanBlock(ExitingBlock)) return false; LLVMContext &Context = Header->getContext(); for (Loop::block_iterator I = L->block_begin(), E = L->block_end(); I != E; ++I) { BranchInst *BR = dyn_cast<BranchInst>((*I)->getTerminator()); if (!BR || BR->isUnconditional()) continue; ICmpInst *CI = dyn_cast<ICmpInst>(BR->getCondition()); if (!CI || CI == ExitCondition || CI->getPredicate() == ICmpInst::ICMP_NE || CI->getPredicate() == ICmpInst::ICMP_EQ) continue; // Unable to handle triangle loops at the moment. // In triangle loop, split condition is in header and one of the // the split destination is loop latch. If split condition is EQ // then such loops are already handle in processOneIterationLoop(). if (Header == (*I) && (Latch == BR->getSuccessor(0) || Latch == BR->getSuccessor(1))) continue; // If the block does not dominate the latch then this is not a diamond. // Such loop may not benefit from index split. if (!DT->dominates((*I), Latch)) continue; // If split condition branches heads do not have single predecessor, // SplitCondBlock, then is not possible to remove inactive branch. if (!BR->getSuccessor(0)->getSinglePredecessor() || !BR->getSuccessor(1)->getSinglePredecessor()) return false; // If the merge point for BR is not loop latch then skip this condition. if (BR->getSuccessor(0) != Latch) { DominanceFrontier::iterator DF0 = DF->find(BR->getSuccessor(0)); assert (DF0 != DF->end() && "Unable to find dominance frontier"); if (!DF0->second.count(Latch)) continue; } if (BR->getSuccessor(1) != Latch) { DominanceFrontier::iterator DF1 = DF->find(BR->getSuccessor(1)); assert (DF1 != DF->end() && "Unable to find dominance frontier"); if (!DF1->second.count(Latch)) continue; } SplitCondition = CI; SBR = BR; break; } if (!SplitCondition) return false; // If the predicate sign does not match then skip. if (ExitCondition->isSigned() != SplitCondition->isSigned()) return false; unsigned EVOpNum = (ExitCondition->getOperand(1) == IVExitValue); unsigned SVOpNum = IVBasedValues.count(SplitCondition->getOperand(0)); Value *SplitValue = SplitCondition->getOperand(SVOpNum); if (!L->isLoopInvariant(SplitValue)) return false; if (!IVBasedValues.count(SplitCondition->getOperand(!SVOpNum))) return false; // Normalize loop conditions so that it is easier to calculate new loop // bounds. if (IVisGT(*ExitCondition) || IVisGE(*ExitCondition)) { ExitCondition->setPredicate(ExitCondition->getInversePredicate()); BasicBlock *T = EBR->getSuccessor(0); EBR->setSuccessor(0, EBR->getSuccessor(1)); EBR->setSuccessor(1, T); } if (IVisGT(*SplitCondition) || IVisGE(*SplitCondition)) { SplitCondition->setPredicate(SplitCondition->getInversePredicate()); BasicBlock *T = SBR->getSuccessor(0); SBR->setSuccessor(0, SBR->getSuccessor(1)); SBR->setSuccessor(1, T); } //[*] Calculate new loop bounds. Value *AEV = SplitValue; Value *BSV = SplitValue; bool Sign = SplitCondition->isSigned(); Instruction *PHTerm = L->getLoopPreheader()->getTerminator(); if (IVisLT(*ExitCondition)) { if (IVisLT(*SplitCondition)) { /* Do nothing */ } else if (IVisLE(*SplitCondition)) { AEV = getPlusOne(SplitValue, Sign, PHTerm, Context); BSV = getPlusOne(SplitValue, Sign, PHTerm, Context); } else { assert (0 && "Unexpected split condition!"); } } else if (IVisLE(*ExitCondition)) { if (IVisLT(*SplitCondition)) { AEV = getMinusOne(SplitValue, Sign, PHTerm, Context); } else if (IVisLE(*SplitCondition)) { BSV = getPlusOne(SplitValue, Sign, PHTerm, Context); } else { assert (0 && "Unexpected split condition!"); } } else { assert (0 && "Unexpected exit condition!"); } AEV = getMin(AEV, IVExitValue, Sign, PHTerm); BSV = getMax(BSV, IVStartValue, Sign, PHTerm); // [*] Clone Loop DenseMap<const Value *, Value *> ValueMap; Loop *BLoop = CloneLoop(L, LPM, LI, ValueMap, this); Loop *ALoop = L; // [*] ALoop's exiting edge enters BLoop's header. // ALoop's original exit block becomes BLoop's exit block. PHINode *B_IndVar = cast<PHINode>(ValueMap[IndVar]); BasicBlock *A_ExitingBlock = ExitCondition->getParent(); BranchInst *A_ExitInsn = dyn_cast<BranchInst>(A_ExitingBlock->getTerminator()); assert (A_ExitInsn && "Unable to find suitable loop exit branch"); BasicBlock *B_ExitBlock = A_ExitInsn->getSuccessor(1); BasicBlock *B_Header = BLoop->getHeader(); if (ALoop->contains(B_ExitBlock)) { B_ExitBlock = A_ExitInsn->getSuccessor(0); A_ExitInsn->setSuccessor(0, B_Header); } else A_ExitInsn->setSuccessor(1, B_Header); // [*] Update ALoop's exit value using new exit value. ExitCondition->setOperand(EVOpNum, AEV); // [*] Update BLoop's header phi nodes. Remove incoming PHINode's from // original loop's preheader. Add incoming PHINode values from // ALoop's exiting block. Update BLoop header's domiantor info. // Collect inverse map of Header PHINodes. DenseMap<Value *, Value *> InverseMap; for (BasicBlock::iterator BI = ALoop->getHeader()->begin(), BE = ALoop->getHeader()->end(); BI != BE; ++BI) { if (PHINode *PN = dyn_cast<PHINode>(BI)) { PHINode *PNClone = cast<PHINode>(ValueMap[PN]); InverseMap[PNClone] = PN; } else break; } BasicBlock *A_Preheader = ALoop->getLoopPreheader(); for (BasicBlock::iterator BI = B_Header->begin(), BE = B_Header->end(); BI != BE; ++BI) { if (PHINode *PN = dyn_cast<PHINode>(BI)) { // Remove incoming value from original preheader. PN->removeIncomingValue(A_Preheader); // Add incoming value from A_ExitingBlock. if (PN == B_IndVar) PN->addIncoming(BSV, A_ExitingBlock); else { PHINode *OrigPN = cast<PHINode>(InverseMap[PN]); Value *V2 = NULL; // If loop header is also loop exiting block then // OrigPN is incoming value for B loop header. if (A_ExitingBlock == ALoop->getHeader()) V2 = OrigPN; else V2 = OrigPN->getIncomingValueForBlock(A_ExitingBlock); PN->addIncoming(V2, A_ExitingBlock); } } else break; } DT->changeImmediateDominator(B_Header, A_ExitingBlock); DF->changeImmediateDominator(B_Header, A_ExitingBlock, DT); // [*] Update BLoop's exit block. Its new predecessor is BLoop's exit // block. Remove incoming PHINode values from ALoop's exiting block. // Add new incoming values from BLoop's incoming exiting value. // Update BLoop exit block's dominator info.. BasicBlock *B_ExitingBlock = cast<BasicBlock>(ValueMap[A_ExitingBlock]); for (BasicBlock::iterator BI = B_ExitBlock->begin(), BE = B_ExitBlock->end(); BI != BE; ++BI) { if (PHINode *PN = dyn_cast<PHINode>(BI)) { PN->addIncoming(ValueMap[PN->getIncomingValueForBlock(A_ExitingBlock)], B_ExitingBlock); PN->removeIncomingValue(A_ExitingBlock); } else break; } DT->changeImmediateDominator(B_ExitBlock, B_ExitingBlock); DF->changeImmediateDominator(B_ExitBlock, B_ExitingBlock, DT); //[*] Split ALoop's exit edge. This creates a new block which // serves two purposes. First one is to hold PHINode defnitions // to ensure that ALoop's LCSSA form. Second use it to act // as a preheader for BLoop. BasicBlock *A_ExitBlock = SplitEdge(A_ExitingBlock, B_Header, this); //[*] Preserve ALoop's LCSSA form. Create new forwarding PHINodes // in A_ExitBlock to redefine outgoing PHI definitions from ALoop. for(BasicBlock::iterator BI = B_Header->begin(), BE = B_Header->end(); BI != BE; ++BI) { if (PHINode *PN = dyn_cast<PHINode>(BI)) { Value *V1 = PN->getIncomingValueForBlock(A_ExitBlock); PHINode *newPHI = PHINode::Create(PN->getType(), PN->getName()); newPHI->addIncoming(V1, A_ExitingBlock); A_ExitBlock->getInstList().push_front(newPHI); PN->removeIncomingValue(A_ExitBlock); PN->addIncoming(newPHI, A_ExitBlock); } else break; } //[*] Eliminate split condition's inactive branch from ALoop. BasicBlock *A_SplitCondBlock = SplitCondition->getParent(); BranchInst *A_BR = cast<BranchInst>(A_SplitCondBlock->getTerminator()); BasicBlock *A_InactiveBranch = NULL; BasicBlock *A_ActiveBranch = NULL; A_ActiveBranch = A_BR->getSuccessor(0); A_InactiveBranch = A_BR->getSuccessor(1); A_BR->setUnconditionalDest(A_ActiveBranch); removeBlocks(A_InactiveBranch, L, A_ActiveBranch); //[*] Eliminate split condition's inactive branch in from BLoop. BasicBlock *B_SplitCondBlock = cast<BasicBlock>(ValueMap[A_SplitCondBlock]); BranchInst *B_BR = cast<BranchInst>(B_SplitCondBlock->getTerminator()); BasicBlock *B_InactiveBranch = NULL; BasicBlock *B_ActiveBranch = NULL; B_ActiveBranch = B_BR->getSuccessor(1); B_InactiveBranch = B_BR->getSuccessor(0); B_BR->setUnconditionalDest(B_ActiveBranch); removeBlocks(B_InactiveBranch, BLoop, B_ActiveBranch); BasicBlock *A_Header = ALoop->getHeader(); if (A_ExitingBlock == A_Header) return true; //[*] Move exit condition into split condition block to avoid // executing dead loop iteration. ICmpInst *B_ExitCondition = cast<ICmpInst>(ValueMap[ExitCondition]); Instruction *B_IndVarIncrement = cast<Instruction>(ValueMap[IVIncrement]); ICmpInst *B_SplitCondition = cast<ICmpInst>(ValueMap[SplitCondition]); moveExitCondition(A_SplitCondBlock, A_ActiveBranch, A_ExitBlock, ExitCondition, cast<ICmpInst>(SplitCondition), IndVar, IVIncrement, ALoop, EVOpNum); moveExitCondition(B_SplitCondBlock, B_ActiveBranch, B_ExitBlock, B_ExitCondition, B_SplitCondition, B_IndVar, B_IndVarIncrement, BLoop, EVOpNum); NumIndexSplit++; return true; }
/// HandleFloatingPointIV - If the loop has floating induction variable /// then insert corresponding integer induction variable if possible. /// For example, /// for(double i = 0; i < 10000; ++i) /// bar(i) /// is converted into /// for(int i = 0; i < 10000; ++i) /// bar((double)i); /// void IndVarSimplify::HandleFloatingPointIV(Loop *L, PHINode *PN) { unsigned IncomingEdge = L->contains(PN->getIncomingBlock(0)); unsigned BackEdge = IncomingEdge^1; // Check incoming value. ConstantFP *InitValueVal = dyn_cast<ConstantFP>(PN->getIncomingValue(IncomingEdge)); int64_t InitValue; if (!InitValueVal || !ConvertToSInt(InitValueVal->getValueAPF(), InitValue)) return; // Check IV increment. Reject this PN if increment operation is not // an add or increment value can not be represented by an integer. BinaryOperator *Incr = dyn_cast<BinaryOperator>(PN->getIncomingValue(BackEdge)); if (Incr == 0 || Incr->getOpcode() != Instruction::FAdd) return; // If this is not an add of the PHI with a constantfp, or if the constant fp // is not an integer, bail out. ConstantFP *IncValueVal = dyn_cast<ConstantFP>(Incr->getOperand(1)); int64_t IncValue; if (IncValueVal == 0 || Incr->getOperand(0) != PN || !ConvertToSInt(IncValueVal->getValueAPF(), IncValue)) return; // Check Incr uses. One user is PN and the other user is an exit condition // used by the conditional terminator. Value::use_iterator IncrUse = Incr->use_begin(); Instruction *U1 = cast<Instruction>(IncrUse++); if (IncrUse == Incr->use_end()) return; Instruction *U2 = cast<Instruction>(IncrUse++); if (IncrUse != Incr->use_end()) return; // Find exit condition, which is an fcmp. If it doesn't exist, or if it isn't // only used by a branch, we can't transform it. FCmpInst *Compare = dyn_cast<FCmpInst>(U1); if (!Compare) Compare = dyn_cast<FCmpInst>(U2); if (Compare == 0 || !Compare->hasOneUse() || !isa<BranchInst>(Compare->use_back())) return; BranchInst *TheBr = cast<BranchInst>(Compare->use_back()); // We need to verify that the branch actually controls the iteration count // of the loop. If not, the new IV can overflow and no one will notice. // The branch block must be in the loop and one of the successors must be out // of the loop. assert(TheBr->isConditional() && "Can't use fcmp if not conditional"); if (!L->contains(TheBr->getParent()) || (L->contains(TheBr->getSuccessor(0)) && L->contains(TheBr->getSuccessor(1)))) return; // If it isn't a comparison with an integer-as-fp (the exit value), we can't // transform it. ConstantFP *ExitValueVal = dyn_cast<ConstantFP>(Compare->getOperand(1)); int64_t ExitValue; if (ExitValueVal == 0 || !ConvertToSInt(ExitValueVal->getValueAPF(), ExitValue)) return; // Find new predicate for integer comparison. CmpInst::Predicate NewPred = CmpInst::BAD_ICMP_PREDICATE; switch (Compare->getPredicate()) { default: return; // Unknown comparison. case CmpInst::FCMP_OEQ: case CmpInst::FCMP_UEQ: NewPred = CmpInst::ICMP_EQ; break; case CmpInst::FCMP_ONE: case CmpInst::FCMP_UNE: NewPred = CmpInst::ICMP_NE; break; case CmpInst::FCMP_OGT: case CmpInst::FCMP_UGT: NewPred = CmpInst::ICMP_SGT; break; case CmpInst::FCMP_OGE: case CmpInst::FCMP_UGE: NewPred = CmpInst::ICMP_SGE; break; case CmpInst::FCMP_OLT: case CmpInst::FCMP_ULT: NewPred = CmpInst::ICMP_SLT; break; case CmpInst::FCMP_OLE: case CmpInst::FCMP_ULE: NewPred = CmpInst::ICMP_SLE; break; } // We convert the floating point induction variable to a signed i32 value if // we can. This is only safe if the comparison will not overflow in a way // that won't be trapped by the integer equivalent operations. Check for this // now. // TODO: We could use i64 if it is native and the range requires it. // The start/stride/exit values must all fit in signed i32. if (!isInt<32>(InitValue) || !isInt<32>(IncValue) || !isInt<32>(ExitValue)) return; // If not actually striding (add x, 0.0), avoid touching the code. if (IncValue == 0) return; // Positive and negative strides have different safety conditions. if (IncValue > 0) { // If we have a positive stride, we require the init to be less than the // exit value and an equality or less than comparison. if (InitValue >= ExitValue || NewPred == CmpInst::ICMP_SGT || NewPred == CmpInst::ICMP_SGE) return; uint32_t Range = uint32_t(ExitValue-InitValue); if (NewPred == CmpInst::ICMP_SLE) { // Normalize SLE -> SLT, check for infinite loop. if (++Range == 0) return; // Range overflows. } unsigned Leftover = Range % uint32_t(IncValue); // If this is an equality comparison, we require that the strided value // exactly land on the exit value, otherwise the IV condition will wrap // around and do things the fp IV wouldn't. if ((NewPred == CmpInst::ICMP_EQ || NewPred == CmpInst::ICMP_NE) && Leftover != 0) return; // If the stride would wrap around the i32 before exiting, we can't // transform the IV. if (Leftover != 0 && int32_t(ExitValue+IncValue) < ExitValue) return; } else { // If we have a negative stride, we require the init to be greater than the // exit value and an equality or greater than comparison. if (InitValue >= ExitValue || NewPred == CmpInst::ICMP_SLT || NewPred == CmpInst::ICMP_SLE) return; uint32_t Range = uint32_t(InitValue-ExitValue); if (NewPred == CmpInst::ICMP_SGE) { // Normalize SGE -> SGT, check for infinite loop. if (++Range == 0) return; // Range overflows. } unsigned Leftover = Range % uint32_t(-IncValue); // If this is an equality comparison, we require that the strided value // exactly land on the exit value, otherwise the IV condition will wrap // around and do things the fp IV wouldn't. if ((NewPred == CmpInst::ICMP_EQ || NewPred == CmpInst::ICMP_NE) && Leftover != 0) return; // If the stride would wrap around the i32 before exiting, we can't // transform the IV. if (Leftover != 0 && int32_t(ExitValue+IncValue) > ExitValue) return; } const IntegerType *Int32Ty = Type::getInt32Ty(PN->getContext()); // Insert new integer induction variable. PHINode *NewPHI = PHINode::Create(Int32Ty, PN->getName()+".int", PN); NewPHI->addIncoming(ConstantInt::get(Int32Ty, InitValue), PN->getIncomingBlock(IncomingEdge)); Value *NewAdd = BinaryOperator::CreateAdd(NewPHI, ConstantInt::get(Int32Ty, IncValue), Incr->getName()+".int", Incr); NewPHI->addIncoming(NewAdd, PN->getIncomingBlock(BackEdge)); ICmpInst *NewCompare = new ICmpInst(TheBr, NewPred, NewAdd, ConstantInt::get(Int32Ty, ExitValue), Compare->getName()); // In the following deletions, PN may become dead and may be deleted. // Use a WeakVH to observe whether this happens. WeakVH WeakPH = PN; // Delete the old floating point exit comparison. The branch starts using the // new comparison. NewCompare->takeName(Compare); Compare->replaceAllUsesWith(NewCompare); RecursivelyDeleteTriviallyDeadInstructions(Compare); // Delete the old floating point increment. Incr->replaceAllUsesWith(UndefValue::get(Incr->getType())); RecursivelyDeleteTriviallyDeadInstructions(Incr); // If the FP induction variable still has uses, this is because something else // in the loop uses its value. In order to canonicalize the induction // variable, we chose to eliminate the IV and rewrite it in terms of an // int->fp cast. // // We give preference to sitofp over uitofp because it is faster on most // platforms. if (WeakPH) { Value *Conv = new SIToFPInst(NewPHI, PN->getType(), "indvar.conv", PN->getParent()->getFirstNonPHI()); PN->replaceAllUsesWith(Conv); RecursivelyDeleteTriviallyDeadInstructions(PN); } // Add a new IVUsers entry for the newly-created integer PHI. IU->AddUsersIfInteresting(NewPHI); }
bool IndVarSimplify::runOnLoop(Loop *L, LPPassManager &LPM) { IU = &getAnalysis<IVUsers>(); LI = &getAnalysis<LoopInfo>(); SE = &getAnalysis<ScalarEvolution>(); DT = &getAnalysis<DominatorTree>(); Changed = false; // If there are any floating-point recurrences, attempt to // transform them to use integer recurrences. RewriteNonIntegerIVs(L); BasicBlock *ExitingBlock = L->getExitingBlock(); // may be null const SCEV *BackedgeTakenCount = SE->getBackedgeTakenCount(L); // Create a rewriter object which we'll use to transform the code with. SCEVExpander Rewriter(*SE); // Check to see if this loop has a computable loop-invariant execution count. // If so, this means that we can compute the final value of any expressions // that are recurrent in the loop, and substitute the exit values from the // loop into any instructions outside of the loop that use the final values of // the current expressions. // if (!isa<SCEVCouldNotCompute>(BackedgeTakenCount)) RewriteLoopExitValues(L, Rewriter); // Compute the type of the largest recurrence expression, and decide whether // a canonical induction variable should be inserted. const Type *LargestType = 0; bool NeedCannIV = false; if (!isa<SCEVCouldNotCompute>(BackedgeTakenCount)) { LargestType = BackedgeTakenCount->getType(); LargestType = SE->getEffectiveSCEVType(LargestType); // If we have a known trip count and a single exit block, we'll be // rewriting the loop exit test condition below, which requires a // canonical induction variable. if (ExitingBlock) NeedCannIV = true; } for (IVUsers::const_iterator I = IU->begin(), E = IU->end(); I != E; ++I) { const Type *Ty = SE->getEffectiveSCEVType(I->getOperandValToReplace()->getType()); if (!LargestType || SE->getTypeSizeInBits(Ty) > SE->getTypeSizeInBits(LargestType)) LargestType = Ty; NeedCannIV = true; } // Now that we know the largest of the induction variable expressions // in this loop, insert a canonical induction variable of the largest size. Value *IndVar = 0; if (NeedCannIV) { // Check to see if the loop already has any canonical-looking induction // variables. If any are present and wider than the planned canonical // induction variable, temporarily remove them, so that the Rewriter // doesn't attempt to reuse them. SmallVector<PHINode *, 2> OldCannIVs; while (PHINode *OldCannIV = L->getCanonicalInductionVariable()) { if (SE->getTypeSizeInBits(OldCannIV->getType()) > SE->getTypeSizeInBits(LargestType)) OldCannIV->removeFromParent(); else break; OldCannIVs.push_back(OldCannIV); } IndVar = Rewriter.getOrInsertCanonicalInductionVariable(L, LargestType); ++NumInserted; Changed = true; DEBUG(dbgs() << "INDVARS: New CanIV: " << *IndVar << '\n'); // Now that the official induction variable is established, reinsert // any old canonical-looking variables after it so that the IR remains // consistent. They will be deleted as part of the dead-PHI deletion at // the end of the pass. while (!OldCannIVs.empty()) { PHINode *OldCannIV = OldCannIVs.pop_back_val(); OldCannIV->insertBefore(L->getHeader()->getFirstNonPHI()); } } // If we have a trip count expression, rewrite the loop's exit condition // using it. We can currently only handle loops with a single exit. ICmpInst *NewICmp = 0; if (!isa<SCEVCouldNotCompute>(BackedgeTakenCount) && !BackedgeTakenCount->isZero() && ExitingBlock) { assert(NeedCannIV && "LinearFunctionTestReplace requires a canonical induction variable"); // Can't rewrite non-branch yet. if (BranchInst *BI = dyn_cast<BranchInst>(ExitingBlock->getTerminator())) NewICmp = LinearFunctionTestReplace(L, BackedgeTakenCount, IndVar, ExitingBlock, BI, Rewriter); } // Rewrite IV-derived expressions. Clears the rewriter cache. RewriteIVExpressions(L, Rewriter); // The Rewriter may not be used from this point on. // Loop-invariant instructions in the preheader that aren't used in the // loop may be sunk below the loop to reduce register pressure. SinkUnusedInvariants(L); // For completeness, inform IVUsers of the IV use in the newly-created // loop exit test instruction. if (NewICmp) IU->AddUsersIfInteresting(cast<Instruction>(NewICmp->getOperand(0))); // Clean up dead instructions. Changed |= DeleteDeadPHIs(L->getHeader()); // Check a post-condition. assert(L->isLCSSAForm(*DT) && "Indvars did not leave the loop in lcssa form!"); return Changed; }
string esp::parseName(Value *value){ // has existed if(names.find(value) != names.end()) return names[value]; string name = ""; Value *current = value; /* bool continueFlag = true; do{ if(isa<Instruction > (current)){ Instruction* inst = dyn_cast<Instruction>(current); unsigned op = inst->getOpcode(); switch(op){ case Instruction::Ret :{ break; } case Instruction::Br :{ break; } case Instruction::Switch :{ break; } case Instruction::Call :{ CallInst *callinst = (CallInst*) current; if (((CallInst*) current)->getCalledFunction() != NULL) { name += string("@")+((CallInst*) current)->getCalledFunction()->getNameStr() + "("; } else { name += string("@[funcPTR]("); name += ((CallInst*) current)->getCalledValue()->getNameStr(); } for (unsigned i = 1; i < callinst->getNumOperands(); i++) { name += esp::parseName(callinst->getOperand(i)); } name += string(")"); continueFlag = false; break; } case Instruction::PHI :{ name += string("PHI["); name += current->getNameStr(); PHINode *phi = (PHINode*) current; for (unsigned i = 0; i < phi->getNumIncomingValues(); i++) { Value *incoming = phi->getIncomingValue(i); if (i != 0) name += ","; if (!hasLoop(incoming)) { if (!incoming->hasName()) { name += esp::parseName(incoming); } else { name += incoming->getNameStr(); } } } name += std::string("]"); continueFlag = false; break; } case Instruction::Select :{ break; } case Instruction::Add :{ name += "+"; name += parseBinaryOpName(inst); break; } case Instruction::Sub :{ name += "-"; name += parseBinaryOpName(inst); break; } case Instruction::Mul :{ name += "*"; name += parseBinaryOpName(inst); break; } case Instruction::UDiv :{ name += "/"; name += parseBinaryOpName(inst); break; } case Instruction::SDiv :{ name += "//"; name += parseBinaryOpName(inst); break; } case Instruction::And :{ name += "&"; name += parseBinaryOpName(inst); break; } case Instruction::Or :{ name += "|"; name += parseBinaryOpName(inst); break; } case Instruction::Xor :{ name += "^"; name += parseBinaryOpName(inst); break; } case Instruction::Shl :{ name += "<<"; name += parseBinaryOpName(inst); break; } case Instruction::LShr :{ name += ">>"; name += parseBinaryOpName(inst); break; } case Instruction::AShr :{ name += ">>>"; name += parseBinaryOpName(inst); break; } case Instruction::ICmp :{ ICmpInst * icmp = dyn_cast<ICmpInst>(current); if (isa<Constant>(icmp->getOperand(0))) { name += esp::parseName(icmp->getOperand(1)); continueFlag = false; } else { name += esp::parseName(icmp->getOperand(0)); continueFlag = false; } break; } case Instruction::Alloca :{ name += current->getNameStr(); break; } case Instruction::Load :{ if (((LoadInst*) inst)->isVolatile()) name += std::string("@VolatileLoad"); name += "*"; name += esp::parseName(inst->getOperand(0)); continueFlag = false; break; } case Instruction::Store :{ // need to handle continueFlag = false; break; } case Instruction::GetElementPtr :{ GetElementPtrInst * gep = dyn_cast<GetElementPtrInst>(current); unsigned ops = gep->getNumOperands(); name += "["; for (unsigned i = 1; i < ops; i++) { Value *v = gep->getOperand(i); if (ConstantInt * ci = dyn_cast<ConstantInt>(v)) { if (i == 1 && ci->equalsInt(0)) continue; name += "."; name += ci->getValue().toString(10, false); } else { name += "."; name += esp::parseName(v); } } name += "]"; name += esp::parseName(gep->getOperand(0)); continueFlag = false; break; } case Instruction::BitCast:{ name += esp::parseName(inst->getOperand(0)); continueFlag = false; break; } default :{ // Illegal or unsupported instruction name += current->getNameStr(); break; } } }else if(isa<Argument>(current)){ if (arguments.find(current) != arguments.end()) name += std::string("$") + current->getNameStr(); }else if(isa<GlobalValue>(current)){ name += std::string("@") + current->getNameStr(); }else if(isa<ConstantInt>(current)){ ConstantInt * cint = dyn_cast<ConstantInt > (current); name += cint->getValue().toString(10, true); }else if (isa<Constant > (current)) { Constant *c = dyn_cast<Constant > (current); if (c->isNullValue()) { name += "null"; } }else{ // Illegal format } if(!continueFlag) break; current = parents[current]; }while(current); */ //Refactor do { if (isa<LoadInst > (current)) { name += "*"; if (parents[current] == NULL) name += (((LoadInst*) current)->getOperand(0))->getNameStr(); if (((LoadInst*) current)->isVolatile()) name += std::string("@VolatileLoad"); } else if (dyn_cast<GetElementPtrInst > (current)) { GetElementPtrInst * gep = dyn_cast<GetElementPtrInst > (current); unsigned ops = gep->getNumOperands(); name += "["; for (unsigned i = 1; i < ops; i++) { Value *v = gep->getOperand(i); if (dyn_cast<ConstantInt > (current)) { ConstantInt * ci = dyn_cast<ConstantInt > (current); if (i == 1 && ci->equalsInt(0)) continue; name += "."; name += ci->getValue().toString(10, false); } else { name += "."; name += parseName(v); } } name += "]"; name += parseName(gep->getOperand(0)); break; } else if (isa<AllocaInst > (current)) { name += current->getNameStr(); } else if (isa<Argument > (current)) { if (arguments.find(current) != arguments.end()) name += std::string("$") + current->getNameStr(); } else if (isa<GlobalValue > (current)) { name += std::string("@") + current->getNameStr(); } else if (isa<CallInst > (current)) { CallInst *callinst = (CallInst*) current; if (((CallInst*) current)->getCalledFunction() != NULL) { name += std::string("@")+((CallInst*) current)->getCalledFunction()->getNameStr() + "("; } else { name += std::string("@[funcPTR]("); name += ((CallInst*) current)->getCalledValue()->getNameStr(); } for (unsigned i = 1; i < callinst->getNumOperands(); i++) { name += parseName(callinst->getOperand(i)); } name += std::string(")"); break; } else if (isa<CastInst > (current)) { } else if (isa<PHINode > (current)) { /* name += std::string("PHI["); s += parent->getNameStr(); PHINode *phi = (PHINode*) parent; for (unsigned i = 0; i < phi->getNumIncomingValues(); i++) { //s+=phi->getIncomingBlock(i)->getNameStr(); Value *incoming = phi->getIncomingValue(i); if (i != 0) s += ","; if (!hasLoop(incoming)) { DEBUG(errs() << "incoming#" << i << " no loop(i rather doubt it)\n"); if (!incoming->hasName()) { s += parseName(incoming); } else { s += incoming->getNameStr(); } } } // PHI nodes...ugh s += std::string("]"); break; */ } else if (isa<BinaryOperator > (current)) { BinaryOperator *bo = dyn_cast<BinaryOperator > (current); Instruction::BinaryOps opcode = bo->getOpcode(); if (opcode == Instruction::Add) { name.append("+"); } else if (opcode == Instruction::Sub) { name.append("-"); } else if (opcode == Instruction::Or) { name.append("||"); } else if (opcode == Instruction::Mul) { name.append("*"); } else if (opcode == Instruction::Xor) { name.append("^"); } else if (opcode == Instruction::And) { name.append("&&"); } else if (opcode == Instruction::Shl) { name.append("<<"); } else if (opcode == Instruction::AShr) { name.append(">>"); } else if (opcode == Instruction::LShr) { name.append(">>>"); } Value *v0 = bo->getOperand(0); Value *v1 = bo->getOperand(1); if (isa<ConstantInt > (v0)) { name += ((ConstantInt*) v0)->getValue().toString(10, false); } else if (isa<ConstantInt > (v1)) { name += ((ConstantInt*) v1)->getValue().toString(10, false); } else { printDebugMsg("Binary Operation between non-constants\n"); } } else if (dyn_cast<GEPOperator > (current)) { GEPOperator * gep = dyn_cast<GEPOperator > (current); unsigned ops = gep->getNumOperands(); name += "["; for (unsigned i = 1; i < ops; i++) { Value *v = gep->getOperand(i); if (dyn_cast<ConstantInt > (v)) { ConstantInt * ci = dyn_cast<ConstantInt > (v); if (i == 1 && ci->equalsInt(0)) continue; name += "."; name += ci->getValue().toString(10, false); } } name += "]"; name += parseName(gep->getOperand(0)); break; } else if (dyn_cast<ICmpInst > (current)) { ICmpInst * icmp = dyn_cast<ICmpInst > (current); if (isa<Constant > (icmp->getOperand(0))) { name += parseName(icmp->getOperand(1)); break; } else { name += parseName(icmp->getOperand(0)); break; } } else if (dyn_cast<ConstantInt > (current)) { ConstantInt * cint = dyn_cast<ConstantInt > (current); name += cint->getValue().toString(10, true); } else { name += current->getNameStr(); // might not work } } while ((current = parents[current])); names[value] = name; return name; }
bool GambasPass::runOnFunction(Function &F){ IRBuilder<> Builder(F.getContext()); bool changed = false; for(Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB) { for(BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ){ ICmpInst* ICI = dyn_cast<ICmpInst>(I); CallInst* CI = dyn_cast<CallInst>(I++); if (ICI && ICI->hasMetadata() && ICI->getMetadata("unref_slt") && dyn_cast<LoadInst>(ICI->getOperand(0))){ ICI->replaceAllUsesWith(ConstantInt::get(ICI->getType(), false)); ICI->eraseFromParent(); changed = true; continue; } if (!CI) continue; Function* callee = CI->getCalledFunction(); if (callee == NULL || !callee->isDeclaration()) continue; StringRef name = callee->getName(); if (name == "JR_release_variant" || name == "JR_borrow_variant"){ ConstantInt* vtype_int = dyn_cast<ConstantInt>(CI->getArgOperand(0)); if (!vtype_int) continue; uint64_t vtype = vtype_int->getZExtValue(); if (TYPE_is_string(vtype) || TYPE_is_object(vtype)) continue; CI->eraseFromParent(); changed = true; } else if (name == FUNCTION_NAME(__finite)){ ConstantFP* op = dyn_cast<ConstantFP>(CI->getArgOperand(0)); if (!op) continue; int val = __finite(op->getValueAPF().convertToDouble()); Constant* res = ConstantInt::get(CI->getType(), val); CI->replaceAllUsesWith(res); CI->eraseFromParent(); changed = true; } else if (name == FUNCTION_NAME(__isnan)){ ConstantFP* op = dyn_cast<ConstantFP>(CI->getArgOperand(0)); if (!op) continue; int val = __isnan(op->getValueAPF().convertToDouble()); Constant* res = ConstantInt::get(CI->getType(), val); CI->replaceAllUsesWith(res); CI->eraseFromParent(); changed = true; } else if (name == FUNCTION_NAME(__isinf)){ ConstantFP* op = dyn_cast<ConstantFP>(CI->getArgOperand(0)); if (!op) continue; int val = __isinf(op->getValueAPF().convertToDouble()); Constant* res = ConstantInt::get(CI->getType(), val); CI->replaceAllUsesWith(res); CI->eraseFromParent(); changed = true; } } } return changed; }
void CPFlowFunction::visitBranchInst(BranchInst &BI) { CPLatticePoint* result = new CPLatticePoint(*(info_in_casted.back())); info_in_casted.pop_back(); BranchInst* current = &BI; if (BI.isConditional()) { Value* cond = BI.getCondition(); if (isa<ICmpInst>(cond)) { std::pair<Use*, Use *> branches = helper::getOps(BI); Use* true_branch = branches.first; Use* false_branch = branches.second; ICmpInst* cmp = dyn_cast<ICmpInst>(cond); std::pair<Use*, Use *> operands = helper::getOps(*cmp); Use* rhs = operands.second; Use* lhs = operands.first; ConstantInt* rhs_const = NULL; ConstantInt* lhs_const = NULL; // get the rhs/lhs as a constant int if (isa<ConstantInt>(rhs)) { rhs_const = dyn_cast<ConstantInt>(rhs); } else if (result->representation.count(rhs->get()) > 0) { rhs_const = result->representation[rhs->get()]; } else { rhs_const = ConstantInt::get(context, llvm::APInt(32, 0, true)); } if (isa<ConstantInt>(lhs)) { lhs_const = dyn_cast<ConstantInt>(lhs->get()); } else if (result->representation.count(lhs->get()) > 0) { lhs_const = result->representation[lhs->get()]; } else { lhs_const = ConstantInt::get(context, llvm::APInt(32, 0, true)); } // Create successors CPLatticePoint* true_branchCLP = new CPLatticePoint(false, false, std::map<Value*,ConstantInt*>(result->representation)); CPLatticePoint* false_branchCLP = new CPLatticePoint(false, false, std::map<Value*,ConstantInt*>(result->representation)); // get the predicate int predicate = 0; predicate = cmp->isSigned() ? cmp->getSignedPredicate() : cmp->getUnsignedPredicate(); if (predicate == CmpInst::ICMP_EQ) { if (isa<ConstantInt>(lhs)) { true_branchCLP->representation[rhs->get()] = lhs_const; } else if (isa<ConstantInt>(rhs)) { true_branchCLP->representation[lhs->get()] = rhs_const; } out_map[true_branch->get()] = true_branchCLP; out_map[false_branch->get()] = false_branchCLP; } else if (predicate == CmpInst::ICMP_NE) { if (isa<ConstantInt>(lhs)) { false_branchCLP->representation[rhs->get()] = lhs_const; } else if (isa<ConstantInt>(rhs)) { false_branchCLP->representation[lhs->get()] = rhs_const; } out_map[true_branch->get()] = true_branchCLP; out_map[false_branch->get()] = false_branchCLP; } else { for (std::map<Value *, LatticePoint *>::iterator it=out_map.begin(); it != out_map.end(); ++it){ Value* elm = it->first; out_map[elm] = new CPLatticePoint(*result); } } } else { for (std::map<Value *, LatticePoint *>::iterator it=out_map.begin(); it != out_map.end(); ++it){ Value* elm = it->first; out_map[elm] = new CPLatticePoint(*result); } } } else { for (std::map<Value *, LatticePoint *>::iterator it=out_map.begin(); it != out_map.end(); ++it){ Value* elm = it->first; out_map[elm] = new CPLatticePoint(*result); } } }
/// 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; }