Skip to content

Folding select into operand for "fadd", "fmul", "fsub", "fdiv" not safe for precise math (?) #82726

Open
@michele-scandale

Description

@michele-scandale

With 9cd7c53 InstCombine is able to fold select into binary floating point operation operands. For example the following code:

 %C = fadd %A, %B
 %D = select %cond, %C, %A

is transformed into:

%C = select %cond, %B, -0.000000e+00
%D = fadd %A, %C

From the commit message there were Alive2 verification links -- which at the time were timing out:

However today they report the transformation seems not semantic preserving in the cases of NaNs -- e.g.


----------------------------------------
define half @src(i1 %cond, half %A, half %B) {
#0:
  %C = fsub half %A, %B
  %D = select i1 %cond, half %C, half %A
  ret half %D
}
=>
define half @tgt(i1 %cond, half %A, half %B) {
#0:
  %C = select i1 %cond, half %B, half 0x0000
  %D = fsub half %A, %C
  ret half %D
}
Transformation doesn't verify!

ERROR: Value mismatch

Example:
i1 %cond = #x0 (0)
half %A = #xfc80 (SNaN)
half %B = #x0000 (+0.0)

Source:
half %C = #x7e00 (QNaN)
half %D = #xfc80 (SNaN)

Target:
half %C = #x0000 (+0.0)
half %D = #x7c80 (SNaN)
Source value: #xfc80 (SNaN)
Target value: #x7c80 (SNaN)

The counter example reported above suggests that the transformation is not sound w.r.t. NaNs.
It is not clear to me if according to https://llvm.org/docs/LangRef.html#behavior-of-floating-point-nan-values select is considered a floating point operation or not, hence I wonder if the transformation should be allowed only when nnan is being on the select instruction.

@spatel @huihzhang any comment?

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions