[llvm-dev] Why does FPBinOp(X, undef) -> NaN?

Roman Lebedev via llvm-dev llvm-dev at lists.llvm.org
Fri Feb 7 10:47:27 PST 2020


On Fri, Feb 7, 2020 at 9:28 PM Cameron McInally via llvm-dev
<llvm-dev at lists.llvm.org> wrote:
>
> 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
For these 4 - because divisor 'undef' can be defined to any value, including 0,
but divisor can't be 0..

> What's the reasoning behind folding to undef here? Would that fall
> into the same "any value can't produce some value" bin?

----------------------------------------
define i8 @t0(i8 %a) {
%0:
  %t0 = udiv i8 %a, undef
  ret i8 %t0
}
=>
define i8 @t0(i8 %a) {
%0:
  ret i8 undef
}
Transformation seems to be correct!

Summary:
  1 correct transformations
  0 incorrect transformations
  0 errors

----------------------------------------
define i8 @t0(i8 %a) {
%0:
  %t0 = sdiv i8 %a, undef
  ret i8 %t0
}
=>
define i8 @t0(i8 %a) {
%0:
  ret i8 undef
}
Transformation seems to be correct!

Summary:
  1 correct transformations
  0 incorrect transformations
  0 errors

----------------------------------------
define i8 @t0(i8 %a) {
%0:
  %t0 = urem i8 %a, undef
  ret i8 %t0
}
=>
define i8 @t0(i8 %a) {
%0:
  ret i8 undef
}
Transformation seems to be correct!

Summary:
  1 correct transformations
  0 incorrect transformations
  0 errors

----------------------------------------
define i8 @t0(i8 %a) {
%0:
  %t0 = srem i8 %a, undef
  ret i8 %t0
}
=>
define i8 @t0(i8 %a) {
%0:
  ret i8 undef
}
Transformation seems to be correct!

Summary:
  1 correct transformations
  0 incorrect transformations
  0 errors

----------------------------------------
define i8 @t0(i8 %a) {
%0:
  %t0 = add i8 %a, undef
  ret i8 %t0
}
=>
define i8 @t0(i8 %a) {
%0:
  ret i8 undef
}
Transformation seems to be correct!

Summary:
  1 correct transformations
  0 incorrect transformations
  0 errors

----------------------------------------
define i8 @t0(i8 %a) {
%0:
  %t0 = sub i8 %a, undef
  ret i8 %t0
}
=>
define i8 @t0(i8 %a) {
%0:
  ret i8 undef
}
Transformation seems to be correct!

Summary:
  1 correct transformations
  0 incorrect transformations
  0 errors


> _______________________________________________
> LLVM Developers mailing list
> llvm-dev at lists.llvm.org
> https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev


More information about the llvm-dev mailing list