[llvm-dev] Speculative execution of FP divide Instructions - Call-Graph Simplify
Sanjay Patel via llvm-dev
llvm-dev at lists.llvm.org
Wed Mar 15 08:16:21 PDT 2017
> - is there any target for which fp division does not have side effects?
Yes - all of them. This goes back to the fact that clang/llvm do not
support changing the FPENV:
https://bugs.llvm.org/show_bug.cgi?id=8100
There has been some effort to change that recently, so maybe this is
(partly) fixed? (cc'ing Andy Kaylor)
These reports may also provide info / answers / work-arounds:
https://bugs.llvm.org/show_bug.cgi?id=6050
https://bugs.llvm.org/show_bug.cgi?id=24343
https://bugs.llvm.org/show_bug.cgi?id=24818
On Wed, Mar 15, 2017 at 3:41 AM, Samuel Antão via llvm-dev <
llvm-dev at lists.llvm.org> wrote:
> Hi all,
>
> I came across an issue caused by the Call-Graph Simplify Pass. Here is a a
> small repro:
>
> ```
> define double @foo(double %a1, double %a2, double %a3) #0 {
> entry:
> %a_mul = fmul double %a1, %a2
> %a_cmp = fcmp ogt double %a3, %a_mul
> br i1 %a_cmp, label %a.then, label %a.end
>
> a.then:
> %a_div = fdiv double %a_mul, %a3
> br label %a.end
>
> a.end:
> %a_factor = phi double [ %a_div, %a.then ], [ 1.000000e+00, %entry ]
> ret double %a_factor
> }
> ```
> Here, the conditional is guarding a possible division by zero. However if
> I run CGSimplify on this I get:
> ```
> define double @foo(double %a1, double %a2, double %a3) local_unnamed_addr
> #0 {
> entry:
> %a_mul = fmul double %a1, %a2
> %a_cmp = fcmp olt double %a_mul, %a3
> %a_div = fdiv double %a_mul, %a3
> %a_factor = select i1 %a_cmp, double %a_div, double 1.000000e+00
> ret double %a_factor
> }
> ```
> This will cause a FP arithmetic exception, and the application will get a
> SIGFPE signal. The code that drives the change in the optimizer relies on
> `llvm::isSafeToSpeculativelyExecute` to decide whether the division
> should be performed speculatively. Right now, this function returns true.
> One could do something similar to integer divisions and add a case there
> (this solved the issue for me):
> ```
> diff --git a/lib/Analysis/ValueTracking.cpp b/lib/Analysis/ValueTracking.c
> pp
> index 1761dac..c61fefd 100644
> --- a/lib/Analysis/ValueTracking.cpp
> +++ b/lib/Analysis/ValueTracking.cpp
> @@ -3352,6 +3352,21 @@ bool llvm::isSafeToSpeculativelyExecute(const
> Value *V,
> // The numerator *might* be MinSignedValue.
> return false;
> }
> + case Instruction::FDiv:
> + case Instruction::FRem:{
> + const Value *Denominator = Inst->getOperand(1);
> + // x / y is undefined if y == 0
> + // The denominator is not a constant, so there is nothing we can do
> to prove
> + // it is non-zero.
> + if (auto *VV = dyn_cast<ConstantVector>(Denominator))
> + Denominator = VV->getSplatValue();
> + if (!isa<ConstantFP>(Denominator))
> + return false;
> + // The denominator is a zero constant - we can't speculate here.
> + if (m_AnyZero().match(Denominator))
> + return false;
> + return true;
> + }
> case Instruction::Load: {
> const LoadInst *LI = cast<LoadInst>(Inst);
> if (!LI->isUnordered() ||
> ```
> I did my tests using a powerpc64le target, but I couldn't find any target
> specific login involved in this transform. In any case, I wanted to drop
> the questions:
>
> - is there any target that would benefit from speculative fp divisions?
> - is there any target for which fp division does not have side effects?
>
> If not, I can go ahead and post the patch above for review.
>
> Many thanks!
> Sam
>
> _______________________________________________
> LLVM Developers mailing list
> llvm-dev at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20170315/ed01cd79/attachment.html>
More information about the llvm-dev
mailing list