diff options
| author | Sanjay Patel <spatel@rotateright.com> | 2018-02-14 23:04:17 +0000 | 
|---|---|---|
| committer | Sanjay Patel <spatel@rotateright.com> | 2018-02-14 23:04:17 +0000 | 
| commit | b39bcc0437e3c1b4160363298b935260c656e1b3 (patch) | |
| tree | 4488811cee56efc15dc3587164999258dd808dc8 /llvm/lib/Transforms | |
| parent | 0e88dbe3e68050620666c60ca6a39b491aad2739 (diff) | |
| download | bcm5719-llvm-b39bcc0437e3c1b4160363298b935260c656e1b3.tar.gz bcm5719-llvm-b39bcc0437e3c1b4160363298b935260c656e1b3.zip | |
[InstCombine] clean up fold for X / C -> X * (1.0/C); NFCI
This should work with vector constants too, but it's currently limited to scalar.
llvm-svn: 325187
Diffstat (limited to 'llvm/lib/Transforms')
| -rw-r--r-- | llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp | 61 | 
1 files changed, 27 insertions, 34 deletions
| diff --git a/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp b/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp index 4cc2cbc493f..5457f19d7f4 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp @@ -1317,33 +1317,34 @@ Instruction *InstCombiner::visitSDiv(BinaryOperator &I) {    return nullptr;  } -/// CvtFDivConstToReciprocal tries to convert X/C into X*1/C if C not a special -/// FP value and: -///    1) 1/C is exact, or -///    2) reciprocal is allowed. -/// If the conversion was successful, the simplified expression "X * 1/C" is -/// returned; otherwise, nullptr is returned. -static Instruction *CvtFDivConstToReciprocal(Value *Dividend, Constant *Divisor, -                                             bool AllowReciprocal) { -  if (!isa<ConstantFP>(Divisor)) // TODO: handle vectors. +/// Try to convert X/C into X * (1/C). +static Instruction *foldFDivConstantDivisor(BinaryOperator &FDiv) { +  // TODO: Handle vector constants. +  ConstantFP *CFP; +  if (!match(FDiv.getOperand(1), m_ConstantFP(CFP)))      return nullptr; -  const APFloat &FpVal = cast<ConstantFP>(Divisor)->getValueAPF(); +  const APFloat &FpVal = CFP->getValueAPF();    APFloat Reciprocal(FpVal.getSemantics()); -  bool Cvt = FpVal.getExactInverse(&Reciprocal); -  if (!Cvt && AllowReciprocal && FpVal.isFiniteNonZero()) { +  // This returns false if the inverse would be a denormal. +  bool HasRecip = FpVal.getExactInverse(&Reciprocal); +  // If the inverse is not exact, we may still be able to convert if we are +  // not operating with strict math. +  if (!HasRecip && FDiv.hasAllowReciprocal() && FpVal.isFiniteNonZero()) {      Reciprocal = APFloat(FpVal.getSemantics(), 1.0f); -    (void)Reciprocal.divide(FpVal, APFloat::rmNearestTiesToEven); -    Cvt = !Reciprocal.isDenormal(); +    Reciprocal.divide(FpVal, APFloat::rmNearestTiesToEven); +    // Disallow denormal constants because we don't know what would happen +    // on all targets. +    // TODO: Function attributes can tell us that denorms are flushed? +    HasRecip = !Reciprocal.isDenormal();    } -  if (!Cvt) +  if (!HasRecip)      return nullptr; -  ConstantFP *R; -  R = ConstantFP::get(Dividend->getType()->getContext(), Reciprocal); -  return BinaryOperator::CreateFMul(Dividend, R); +  auto *RecipCFP = ConstantFP::get(FDiv.getContext(), Reciprocal); +  return BinaryOperator::CreateFMul(FDiv.getOperand(0), RecipCFP);  }  Instruction *InstCombiner::visitFDiv(BinaryOperator &I) { @@ -1356,14 +1357,17 @@ Instruction *InstCombiner::visitFDiv(BinaryOperator &I) {                                    SQ.getWithInstruction(&I)))      return replaceInstUsesWith(I, V); +  if (Instruction *FMul = foldFDivConstantDivisor(I)) { +    FMul->copyFastMathFlags(&I); +    return FMul; +  } +    if (isa<Constant>(Op0))      if (SelectInst *SI = dyn_cast<SelectInst>(Op1))        if (Instruction *R = FoldOpIntoSelect(I, SI))          return R;    bool AllowReassociate = I.isFast(); -  bool AllowReciprocal = I.hasAllowReciprocal(); -    if (Constant *Op1C = dyn_cast<Constant>(Op1)) {      if (SelectInst *SI = dyn_cast<SelectInst>(Op0))        if (Instruction *R = FoldOpIntoSelect(I, SI)) @@ -1377,18 +1381,14 @@ Instruction *InstCombiner::visitFDiv(BinaryOperator &I) {        if (match(Op0, m_FMul(m_Value(X), m_Constant(C1)))) {          // (X*C1)/C2 => X * (C1/C2) -        //          Constant *C = ConstantExpr::getFDiv(C1, C2);          if (isNormalFp(C))            Res = BinaryOperator::CreateFMul(X, C);        } else if (match(Op0, m_FDiv(m_Value(X), m_Constant(C1)))) { -        // (X/C1)/C2 => X /(C2*C1) [=> X * 1/(C2*C1) if reciprocal is allowed] +        // (X/C1)/C2 => X /(C2*C1)          Constant *C = ConstantExpr::getFMul(C1, C2); -        if (isNormalFp(C)) { -          Res = CvtFDivConstToReciprocal(X, C, AllowReciprocal); -          if (!Res) -            Res = BinaryOperator::CreateFDiv(X, C); -        } +        if (isNormalFp(C)) +          Res = BinaryOperator::CreateFDiv(X, C);        }        if (Res) { @@ -1396,13 +1396,6 @@ Instruction *InstCombiner::visitFDiv(BinaryOperator &I) {          return Res;        }      } - -    // X / C => X * 1/C -    if (Instruction *T = CvtFDivConstToReciprocal(Op0, Op1C, AllowReciprocal)) { -      T->copyFastMathFlags(&I); -      return T; -    } -      return nullptr;    } | 

