[llvm] r228432 - [InstSimplify] Add SimplifyFPBinOp function.

Michael Zolotukhin mzolotukhin at apple.com
Mon Feb 9 14:22:13 PST 2015


Hi Chandler, Chad,

Could you please take a look at the attached testcase?



Is it ok to commit it?

Thanks,
Michael

> On Feb 6, 2015, at 12:23 PM, Michael Zolotukhin <mzolotukhin at apple.com> wrote:
> 
>> On Feb 6, 2015, at 12:10 PM, Chad Rosier <mcrosier at codeaurora.org <mailto:mcrosier at codeaurora.org>> wrote:
>> 
>> testcase?
> I’ll follow up shortly with that.
> 
> Thanks,
> Michael
> 
>> 
>>> Author: mzolotukhin
>>> Date: Fri Feb  6 14:02:51 2015
>>> New Revision: 228432
>>> 
>>> URL: http://llvm.org/viewvc/llvm-project?rev=228432&view=rev
>>> Log:
>>> [InstSimplify] Add SimplifyFPBinOp function.
>>> 
>>> It is a variation of SimplifyBinOp, but it takes into account
>>> FastMathFlags.
>>> 
>>> It is needed in inliner and loop-unroller to accurately predict the
>>> transformation's outcome (previously we dropped the flags and were too
>>> conservative in some cases).
>>> 
>>> Example:
>>> float foo(float *a, float b) {
>>> float r;
>>> if (a[1] * b)
>>>  r = /* a lot of expensive computations */;
>>> else
>>>  r = 1;
>>> return r;
>>> }
>>> float boo(float *a) {
>>> return foo(a, 0.0);
>>> }
>>> 
>>> Without this patch, we don't inline 'foo' into 'boo'.
>>> 
>>> Modified:
>>>   llvm/trunk/include/llvm/Analysis/InstructionSimplify.h
>>>   llvm/trunk/lib/Analysis/IPA/InlineCost.cpp
>>>   llvm/trunk/lib/Analysis/InstructionSimplify.cpp
>>>   llvm/trunk/lib/Transforms/Scalar/LoopUnrollPass.cpp
>>> 
>>> Modified: llvm/trunk/include/llvm/Analysis/InstructionSimplify.h
>>> URL:
>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/InstructionSimplify.h?rev=228432&r1=228431&r2=228432&view=diff
>>> ==============================================================================
>>> --- llvm/trunk/include/llvm/Analysis/InstructionSimplify.h (original)
>>> +++ llvm/trunk/include/llvm/Analysis/InstructionSimplify.h Fri Feb  6
>>> 14:02:51 2015
>>> @@ -277,6 +277,17 @@ namespace llvm {
>>>                       const DominatorTree *DT = nullptr,
>>>                       AssumptionCache *AC = nullptr,
>>>                       const Instruction *CxtI = nullptr);
>>> +  /// SimplifyFPBinOp - Given operands for a BinaryOperator, see if we
>>> can
>>> +  /// fold the result.  If not, this returns null.
>>> +  /// In contrast to SimplifyBinOp, try to use FastMathFlag when folding
>>> the
>>> +  /// result. In case we don't need FastMathFlags, simply fall to
>>> SimplifyBinOp.
>>> +  Value *SimplifyFPBinOp(unsigned Opcode, Value *LHS, Value *RHS,
>>> +                         const FastMathFlags &FMF,
>>> +                         const DataLayout *TD = nullptr,
>>> +                         const TargetLibraryInfo *TLI = nullptr,
>>> +                         const DominatorTree *DT = nullptr,
>>> +                         AssumptionCache *AC = nullptr,
>>> +                         const Instruction *CxtI = nullptr);
>>> 
>>>  /// \brief Given a function and iterators over arguments, see if we can
>>> fold
>>>  /// the result.
>>> 
>>> Modified: llvm/trunk/lib/Analysis/IPA/InlineCost.cpp
>>> URL:
>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/IPA/InlineCost.cpp?rev=228432&r1=228431&r2=228432&view=diff
>>> ==============================================================================
>>> --- llvm/trunk/lib/Analysis/IPA/InlineCost.cpp (original)
>>> +++ llvm/trunk/lib/Analysis/IPA/InlineCost.cpp Fri Feb  6 14:02:51 2015
>>> @@ -601,7 +601,13 @@ bool CallAnalyzer::visitBinaryOperator(B
>>>  if (!isa<Constant>(RHS))
>>>    if (Constant *SimpleRHS = SimplifiedValues.lookup(RHS))
>>>      RHS = SimpleRHS;
>>> -  Value *SimpleV = SimplifyBinOp(I.getOpcode(), LHS, RHS, DL);
>>> +  Value *SimpleV = nullptr;
>>> +  if (auto FI = dyn_cast<FPMathOperator>(&I))
>>> +    SimpleV =
>>> +        SimplifyFPBinOp(I.getOpcode(), LHS, RHS, FI->getFastMathFlags(),
>>> DL);
>>> +  else
>>> +    SimpleV = SimplifyBinOp(I.getOpcode(), LHS, RHS, DL);
>>> +
>>>  if (Constant *C = dyn_cast_or_null<Constant>(SimpleV)) {
>>>    SimplifiedValues[&I] = C;
>>>    return true;
>>> 
>>> Modified: llvm/trunk/lib/Analysis/InstructionSimplify.cpp
>>> URL:
>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/InstructionSimplify.cpp?rev=228432&r1=228431&r2=228432&view=diff
>>> ==============================================================================
>>> --- llvm/trunk/lib/Analysis/InstructionSimplify.cpp (original)
>>> +++ llvm/trunk/lib/Analysis/InstructionSimplify.cpp Fri Feb  6 14:02:51
>>> 2015
>>> @@ -61,6 +61,8 @@ struct Query {
>>> static Value *SimplifyAndInst(Value *, Value *, const Query &, unsigned);
>>> static Value *SimplifyBinOp(unsigned, Value *, Value *, const Query &,
>>>                            unsigned);
>>> +static Value *SimplifyFPBinOp(unsigned, Value *, Value *, const
>>> FastMathFlags &,
>>> +                              const Query &, unsigned);
>>> static Value *SimplifyCmpInst(unsigned, Value *, Value *, const Query &,
>>>                              unsigned);
>>> static Value *SimplifyOrInst(Value *, Value *, const Query &, unsigned);
>>> @@ -3465,6 +3467,25 @@ static Value *SimplifyBinOp(unsigned Opc
>>>  }
>>> }
>>> 
>>> +/// SimplifyFPBinOp - Given operands for a BinaryOperator, see if we can
>>> +/// fold the result.  If not, this returns null.
>>> +/// In contrast to SimplifyBinOp, try to use FastMathFlag when folding
>>> the
>>> +/// result. In case we don't need FastMathFlags, simply fall to
>>> SimplifyBinOp.
>>> +static Value *SimplifyFPBinOp(unsigned Opcode, Value *LHS, Value *RHS,
>>> +                              const FastMathFlags &FMF, const Query &Q,
>>> +                              unsigned MaxRecurse) {
>>> +  switch (Opcode) {
>>> +  case Instruction::FAdd:
>>> +    return SimplifyFAddInst(LHS, RHS, FMF, Q, MaxRecurse);
>>> +  case Instruction::FSub:
>>> +    return SimplifyFSubInst(LHS, RHS, FMF, Q, MaxRecurse);
>>> +  case Instruction::FMul:
>>> +    return SimplifyFMulInst(LHS, RHS, FMF, Q, MaxRecurse);
>>> +  default:
>>> +    return SimplifyBinOp(Opcode, LHS, RHS, Q, MaxRecurse);
>>> +  }
>>> +}
>>> +
>>> Value *llvm::SimplifyBinOp(unsigned Opcode, Value *LHS, Value *RHS,
>>>                           const DataLayout *DL, const TargetLibraryInfo
>>> *TLI,
>>>                           const DominatorTree *DT, AssumptionCache *AC,
>>> @@ -3473,6 +3494,15 @@ Value *llvm::SimplifyBinOp(unsigned Opco
>>>                         RecursionLimit);
>>> }
>>> 
>>> +Value *llvm::SimplifyFPBinOp(unsigned Opcode, Value *LHS, Value *RHS,
>>> +                             const FastMathFlags &FMF, const DataLayout
>>> *DL,
>>> +                             const TargetLibraryInfo *TLI,
>>> +                             const DominatorTree *DT, AssumptionCache
>>> *AC,
>>> +                             const Instruction *CxtI) {
>>> +  return ::SimplifyFPBinOp(Opcode, LHS, RHS, FMF, Query(DL, TLI, DT, AC,
>>> CxtI),
>>> +                           RecursionLimit);
>>> +}
>>> +
>>> /// SimplifyCmpInst - Given operands for a CmpInst, see if we can
>>> /// fold the result.
>>> static Value *SimplifyCmpInst(unsigned Predicate, Value *LHS, Value *RHS,
>>> 
>>> Modified: llvm/trunk/lib/Transforms/Scalar/LoopUnrollPass.cpp
>>> URL:
>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopUnrollPass.cpp?rev=228432&r1=228431&r2=228432&view=diff
>>> ==============================================================================
>>> --- llvm/trunk/lib/Transforms/Scalar/LoopUnrollPass.cpp (original)
>>> +++ llvm/trunk/lib/Transforms/Scalar/LoopUnrollPass.cpp Fri Feb  6
>>> 14:02:51 2015
>>> @@ -311,7 +311,12 @@ class UnrollAnalyzer : public InstVisito
>>>    if (!isa<Constant>(RHS))
>>>      if (Constant *SimpleRHS = SimplifiedValues.lookup(RHS))
>>>        RHS = SimpleRHS;
>>> -    Value *SimpleV = SimplifyBinOp(I.getOpcode(), LHS, RHS);
>>> +    Value *SimpleV = nullptr;
>>> +    if (auto FI = dyn_cast<FPMathOperator>(&I))
>>> +      SimpleV =
>>> +          SimplifyFPBinOp(I.getOpcode(), LHS, RHS,
>>> FI->getFastMathFlags());
>>> +    else
>>> +      SimpleV = SimplifyBinOp(I.getOpcode(), LHS, RHS);
>>> 
>>>    if (SimpleV && CountedInsns.insert(&I).second)
>>>      NumberOfOptimizedInstructions += TTI.getUserCost(&I);
>>> 
>>> 
>>> _______________________________________________
>>> llvm-commits mailing list
>>> llvm-commits at cs.uiuc.edu
>>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>>> 
>> 
>> 
> 
> 
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu <mailto:llvm-commits at cs.uiuc.edu>
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits <http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20150209/fe457384/attachment.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: inline-fast-math-flags.ll
Type: application/octet-stream
Size: 1086 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20150209/fe457384/attachment.obj>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20150209/fe457384/attachment-0001.html>


More information about the llvm-commits mailing list