lebedev.ri updated this revision to Diff 310855. lebedev.ri added a comment. This revision is now accepted and ready to land.
Partial rebase (without updating test coverage) Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D87188/new/ https://reviews.llvm.org/D87188 Files: llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
Index: llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp =================================================================== --- llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp +++ llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp @@ -1048,89 +1048,28 @@ return &Sel; } -/// There are many select variants for each of ABS/NABS. -/// In matchSelectPattern(), there are different compare constants, compare -/// predicates/operands and select operands. -/// In isKnownNegation(), there are different formats of negated operands. -/// Canonicalize all these variants to 1 pattern. -/// This makes CSE more likely. static Instruction *canonicalizeAbsNabs(SelectInst &Sel, ICmpInst &Cmp, InstCombinerImpl &IC) { if (!Cmp.hasOneUse() || !isa<Constant>(Cmp.getOperand(1))) return nullptr; - // Choose a sign-bit check for the compare (likely simpler for codegen). - // ABS: (X <s 0) ? -X : X - // NABS: (X <s 0) ? X : -X Value *LHS, *RHS; SelectPatternFlavor SPF = matchSelectPattern(&Sel, LHS, RHS).Flavor; if (SPF != SelectPatternFlavor::SPF_ABS && SPF != SelectPatternFlavor::SPF_NABS) return nullptr; - Value *TVal = Sel.getTrueValue(); - Value *FVal = Sel.getFalseValue(); - assert(isKnownNegation(TVal, FVal) && - "Unexpected result from matchSelectPattern"); + bool IntMinIsPoison = match(RHS, m_NSWNeg(m_Specific(LHS))); + Constant *IntMinIsPoisonC = + ConstantInt::get(Type::getInt1Ty(Sel.getContext()), IntMinIsPoison); + Instruction *Abs = + IC.Builder.CreateBinaryIntrinsic(Intrinsic::abs, LHS, IntMinIsPoisonC); - // The compare may use the negated abs()/nabs() operand, or it may use - // negation in non-canonical form such as: sub A, B. - bool CmpUsesNegatedOp = match(Cmp.getOperand(0), m_Neg(m_Specific(TVal))) || - match(Cmp.getOperand(0), m_Neg(m_Specific(FVal))); + if (SPF == SelectPatternFlavor::SPF_NABS) + return IntMinIsPoison ? BinaryOperator::CreateNSWNeg(Abs) + : BinaryOperator::CreateNeg(Abs); - bool CmpCanonicalized = !CmpUsesNegatedOp && - match(Cmp.getOperand(1), m_ZeroInt()) && - Cmp.getPredicate() == ICmpInst::ICMP_SLT; - bool RHSCanonicalized = match(RHS, m_Neg(m_Specific(LHS))); - - // Is this already canonical? - if (CmpCanonicalized && RHSCanonicalized) - return nullptr; - - // If RHS is not canonical but is used by other instructions, don't - // canonicalize it and potentially increase the instruction count. - if (!RHSCanonicalized) - if (!(RHS->hasOneUse() || (RHS->hasNUses(2) && CmpUsesNegatedOp))) - return nullptr; - - // Create the canonical compare: icmp slt LHS 0. - if (!CmpCanonicalized) { - Cmp.setPredicate(ICmpInst::ICMP_SLT); - Cmp.setOperand(1, ConstantInt::getNullValue(Cmp.getOperand(0)->getType())); - if (CmpUsesNegatedOp) - Cmp.setOperand(0, LHS); - } - - // Create the canonical RHS: RHS = sub (0, LHS). - if (!RHSCanonicalized) { - assert(RHS->hasOneUse() && "RHS use number is not right"); - RHS = IC.Builder.CreateNeg(LHS); - if (TVal == LHS) { - // Replace false value. - IC.replaceOperand(Sel, 2, RHS); - FVal = RHS; - } else { - // Replace true value. - IC.replaceOperand(Sel, 1, RHS); - TVal = RHS; - } - } - - // If the select operands do not change, we're done. - if (SPF == SelectPatternFlavor::SPF_NABS) { - if (TVal == LHS) - return &Sel; - assert(FVal == LHS && "Unexpected results from matchSelectPattern"); - } else { - if (FVal == LHS) - return &Sel; - assert(TVal == LHS && "Unexpected results from matchSelectPattern"); - } - - // We are swapping the select operands, so swap the metadata too. - Sel.swapValues(); - Sel.swapProfMetadata(); - return &Sel; + return IC.replaceInstUsesWith(Sel, Abs); } /// If we have a select with an equality comparison, then we know the value in
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits