Cameron McInally via llvm-dev
2020-Feb-07 17:20 UTC
[llvm-dev] Why does FPBinOp(X, undef) -> NaN?
I came across this comment in SelectionDAG.cpp:
case ISD::FADD:
case ISD::FSUB:
case ISD::FMUL:
case ISD::FDIV:
case ISD::FREM:
// If both operands are undef, the result is undef. If 1 operand is undef,
// the result is NaN. This should match the behavior of the IR optimizer.
That isn't intuitive to me. I would have expected a binary FP
operation with one undef operand to fold to undef. Does anyone know
the reasoning behind that decision? I don't see the value added in
returning a NaN here.
Thx,
Cameron
Nuno Lopes via llvm-dev
2020-Feb-07 17:29 UTC
[llvm-dev] Why does FPBinOp(X, undef) -> NaN?
It's not correct (output of Alive2):
define half @fn(half %a) {
%b = fadd half %a, undef
ret half %b
}
=>
define half @fn(half %a) {
ret half undef
}
Transformation doesn't verify!
ERROR: Value mismatch
Example:
half %a = #x0e02 (0.000366687774?)
Source:
half %b = NaN [based on undef value]
Target:
Source value: NaN
Target value: #x8000 (-0.0)
Essentially, for some inputs, doing an operation with any value can't
produce some value, as the example above shows.
Nuno
Quoting Cameron McInally via llvm-dev <llvm-dev at lists.llvm.org>:
> I came across this comment in SelectionDAG.cpp:
>
> case ISD::FADD:
> case ISD::FSUB:
> case ISD::FMUL:
> case ISD::FDIV:
> case ISD::FREM:
> // If both operands are undef, the result is undef. If 1 operand
> is undef,
> // the result is NaN. This should match the behavior of the IR
optimizer.
>
> That isn't intuitive to me. I would have expected a binary FP
> operation with one undef operand to fold to undef. Does anyone know
> the reasoning behind that decision? I don't see the value added in
> returning a NaN here.
>
> Thx,
> Cameron
Sanjay Patel via llvm-dev
2020-Feb-07 18:01 UTC
[llvm-dev] Why does FPBinOp(X, undef) -> NaN?
For reference, the IR side of this was: On Fri, Feb 7, 2020 at 12:30 PM Nuno Lopes via llvm-dev < llvm-dev at lists.llvm.org> wrote:> It's not correct (output of Alive2): > > define half @fn(half %a) { > %b = fadd half %a, undef > ret half %b > } > => > define half @fn(half %a) { > ret half undef > } > Transformation doesn't verify! > ERROR: Value mismatch > > Example: > half %a = #x0e02 (0.000366687774?) > > Source: > half %b = NaN [based on undef value] > > Target: > Source value: NaN > Target value: #x8000 (-0.0) > > > Essentially, for some inputs, doing an operation with any value can't > produce some value, as the example above shows. > > Nuno > > > > Quoting Cameron McInally via llvm-dev <llvm-dev at lists.llvm.org>: > > > I came across this comment in SelectionDAG.cpp: > > > > case ISD::FADD: > > case ISD::FSUB: > > case ISD::FMUL: > > case ISD::FDIV: > > case ISD::FREM: > > // If both operands are undef, the result is undef. If 1 operand > > is undef, > > // the result is NaN. This should match the behavior of the IR > optimizer. > > > > That isn't intuitive to me. I would have expected a binary FP > > operation with one undef operand to fold to undef. Does anyone know > > the reasoning behind that decision? I don't see the value added in > > returning a NaN here. > > > > Thx, > > Cameron > > _______________________________________________ > LLVM Developers mailing list > llvm-dev at lists.llvm.org > https://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/20200207/c91aee23/attachment.html>
Cameron McInally via llvm-dev
2020-Feb-07 18:27 UTC
[llvm-dev] Why does FPBinOp(X, undef) -> NaN?
On Fri, Feb 7, 2020 at 12:29 PM Nuno Lopes <nunoplopes at sapo.pt> wrote:> > It's not correct (output of Alive2): > > define half @fn(half %a) { > %b = fadd half %a, undef > ret half %b > } > => > define half @fn(half %a) { > ret half undef > } > Transformation doesn't verify! > ERROR: Value mismatch > > Example: > half %a = #x0e02 (0.000366687774?) > > Source: > half %b = NaN [based on undef value] > > Target: > Source value: NaN > Target value: #x8000 (-0.0) > > > Essentially, for some inputs, doing an operation with any value can't > produce some value, as the example above shows.Ok, I can buy that. We're picking NaN for the value of the undef operand since the result will always be a NaN. So a few lines below this, we have something similar for integer operations: case ISD::ADD: case ISD::SUB: case ISD::UDIV: case ISD::SDIV: case ISD::UREM: case ISD::SREM: return getUNDEF(VT); // fold op(arg1, undef) -> undef What's the reasoning behind folding to undef here? Would that fall into the same "any value can't produce some value" bin?