Stephen Canon via llvm-dev
2017-Mar-20 16:14 UTC
[llvm-dev] Is it a valid fp transformation?
I agree. There’s implementation-defined behavior on the conversion of (arg*58) to int, but that shouldn’t be at issue here. The transform of (float)x + 1 => (float)(x + 1) is bogus.> On Mar 20, 2017, at 10:41 AM, Sanjay Patel via llvm-dev <llvm-dev at lists.llvm.org> wrote: > > Looks broken to me; I don't think there's UB in the original program. > > The fold in visitFAdd() should check if the sitofp is guaranteed to produce an exact result? Ie, if the int value input to the sitofp could possibly be different when converted back using fptosi, then the transform does not work. > > define float @test(i32 %x) { > %mul = mul i32 %x, 58 > %conv = sitofp i32 %mul to float > %add = fadd float %conv, 1.0 > ret float %add > } > > > On Mon, Mar 20, 2017 at 4:25 AM, Artur Pilipenko <apilipenko at azul.com <mailto:apilipenko at azul.com>> wrote: > This C program produces different results with -O0 and -O3 optimization levels. > > #include <stdio.h> > float test(unsigned int arg) { > return (float)((int)(arg * 58)) + 1; > } > int main() { > printf("%d\n", (int)test((unsigned int)-831710640)); > } > > O0 result is -994576896 > O3 result is -994576832 > > It happens because LLVM (specifically instcombine) does the following transformation: > (float)x + 1.0 => (float)(x + 1) > > For some values the expression before and after yield different results: > x = -994576864 > (float)x = -994576896.000000 > (float)x + 1.0 = -994576896.000000 > (float)(x + 1) = -994576832.000000 > > I’m curious if this is a correct transformation and why. > > Artur > > > _______________________________________________ > LLVM Developers mailing list > llvm-dev at lists.llvm.org > http://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/20170320/75914f8b/attachment.html>
Artur Pilipenko via llvm-dev
2017-Mar-20 16:49 UTC
[llvm-dev] Is it a valid fp transformation?
It looks like we already have a bug filed for this problem: https://bugs.llvm.org//show_bug.cgi?id=27036 Artur On 20 Mar 2017, at 19:14, Stephen Canon <scanon at apple.com<mailto:scanon at apple.com>> wrote: I agree. There’s implementation-defined behavior on the conversion of (arg*58) to int, but that shouldn’t be at issue here. The transform of (float)x + 1 => (float)(x + 1) is bogus. On Mar 20, 2017, at 10:41 AM, Sanjay Patel via llvm-dev <llvm-dev at lists.llvm.org<mailto:llvm-dev at lists.llvm.org>> wrote: Looks broken to me; I don't think there's UB in the original program. The fold in visitFAdd() should check if the sitofp is guaranteed to produce an exact result? Ie, if the int value input to the sitofp could possibly be different when converted back using fptosi, then the transform does not work. define float @test(i32 %x) { %mul = mul i32 %x, 58 %conv = sitofp i32 %mul to float %add = fadd float %conv, 1.0 ret float %add } On Mon, Mar 20, 2017 at 4:25 AM, Artur Pilipenko <apilipenko at azul.com<mailto:apilipenko at azul.com>> wrote: This C program produces different results with -O0 and -O3 optimization levels. #include <stdio.h> float test(unsigned int arg) { return (float)((int)(arg * 58)) + 1; } int main() { printf("%d\n", (int)test((unsigned int)-831710640)); } O0 result is -994576896 O3 result is -994576832 It happens because LLVM (specifically instcombine) does the following transformation: (float)x + 1.0 => (float)(x + 1) For some values the expression before and after yield different results: x = -994576864 (float)x = -994576896.000000 (float)x + 1.0 = -994576896.000000 (float)(x + 1) = -994576832.000000 I’m curious if this is a correct transformation and why. Artur _______________________________________________ LLVM Developers mailing list llvm-dev at lists.llvm.org<mailto:llvm-dev at lists.llvm.org> http://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/20170320/c5e13b84/attachment.html>
Artur Pilipenko via llvm-dev
2017-Mar-21 12:01 UTC
[llvm-dev] Is it a valid fp transformation?
I posted a review with a simple fix to this transform: https://reviews.llvm.org/D31182 Artur On 20 Mar 2017, at 19:49, Artur Pilipenko via llvm-dev <llvm-dev at lists.llvm.org<mailto:llvm-dev at lists.llvm.org>> wrote: It looks like we already have a bug filed for this problem: https://bugs.llvm.org//show_bug.cgi?id=27036 Artur On 20 Mar 2017, at 19:14, Stephen Canon <scanon at apple.com<mailto:scanon at apple.com>> wrote: I agree. There’s implementation-defined behavior on the conversion of (arg*58) to int, but that shouldn’t be at issue here. The transform of (float)x + 1 => (float)(x + 1) is bogus. On Mar 20, 2017, at 10:41 AM, Sanjay Patel via llvm-dev <llvm-dev at lists.llvm.org<mailto:llvm-dev at lists.llvm.org>> wrote: Looks broken to me; I don't think there's UB in the original program. The fold in visitFAdd() should check if the sitofp is guaranteed to produce an exact result? Ie, if the int value input to the sitofp could possibly be different when converted back using fptosi, then the transform does not work. define float @test(i32 %x) { %mul = mul i32 %x, 58 %conv = sitofp i32 %mul to float %add = fadd float %conv, 1.0 ret float %add } On Mon, Mar 20, 2017 at 4:25 AM, Artur Pilipenko <apilipenko at azul.com<mailto:apilipenko at azul.com>> wrote: This C program produces different results with -O0 and -O3 optimization levels. #include <stdio.h> float test(unsigned int arg) { return (float)((int)(arg * 58)) + 1; } int main() { printf("%d\n", (int)test((unsigned int)-831710640)); } O0 result is -994576896 O3 result is -994576832 It happens because LLVM (specifically instcombine) does the following transformation: (float)x + 1.0 => (float)(x + 1) For some values the expression before and after yield different results: x = -994576864 (float)x = -994576896.000000 (float)x + 1.0 = -994576896.000000 (float)(x + 1) = -994576832.000000 I’m curious if this is a correct transformation and why. Artur _______________________________________________ LLVM Developers mailing list llvm-dev at lists.llvm.org<mailto:llvm-dev at lists.llvm.org> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev _______________________________________________ LLVM Developers mailing list llvm-dev at lists.llvm.org<mailto:llvm-dev at lists.llvm.org> http://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/20170321/9c6bd434/attachment.html>