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?
Roman Lebedev via llvm-dev
2020-Feb-07 18:47 UTC
[llvm-dev] Why does FPBinOp(X, undef) -> NaN?
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) -> undefFor 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
Cameron McInally via llvm-dev
2020-Feb-07 19:12 UTC
[llvm-dev] Why does FPBinOp(X, undef) -> NaN?
On Fri, Feb 7, 2020 at 1:48 PM Roman Lebedev <lebedev.ri at gmail.com> wrote:> > 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..That makes sense. It's undefined behavior, so the "some value" as output is fine. The ADD and SUB I don't understand. Perhaps it's because there's no single value for undef that will always give one defined result? Is that a requirement?