[llvm-dev] how to simplify FP ops with an undef operand?

Ralf Jung via llvm-dev llvm-dev at lists.llvm.org
Tue Mar 6 01:55:50 PST 2018


Hi,

> *Hopefully uncontroversial points:*
> 
>  - Floating point operations are represented in LLVM IR in two ways: the
> fdiv/fmul/fadd etc /instructions/, and the llvm.experimental.constrained.*
> /intrinsic/ forms.
> 
>  - The instruction forms are modeled as having no side effects.  fdiv/frem trap
> on divide by zero, but are otherwise defined on the same set of inputs as
> fadd/fmul/etc.
> 
> - Because they have no side effects, these instructions can be reordered freely
> (though for fdiv/frem, see footnote [1] below).  For example, it is legal to
> transform this:
> 
>    foo(x,y)
>    tmp = a+b
> 
> into:
> 
>    tmp = a+b
>    foo(x,y)
> 
> This can occur for many reasons: for example, because the compiler decides it is
> profitable (e.g. hoisting a loop invariant computation out of a loop), as a side
> effect of instruction scheduling, selection dag not having chain nodes on the
> ISD nodes, etc.

[snip]

> - Because the LLVM instructions are not defined on SNaNs, SNaNs are outside of
> their domain, and thus the LLVM instructions are undefined on these inputs.  As
> such, it would be perfectly reasonable to “constant fold” an "fadd SNaN, 42”
> instruction into unreachable and delete all the code after it, or turn it into a
> call to formatHardDrive().  [2]

Isn't "possibly raises UB" in contradiction with "does not have side-effects"?
In your reordering example quoted below, if `foo` never returns but `a+b` raises
UB, then doing the reordering could introduce UB into the program.  Returning
undef or poison should be fine, but raising UB or calling formatHardDrive()
seems to be incompatible with desired optimizations.  Did I miss something?

Kind regards,
Ralf


More information about the llvm-dev mailing list