llvm / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
http://llvm.org
Other
27.21k stars 11.14k forks source link

Wrong optimization with ppc_fp128: 1 - 1 -> -0 #44556

Open llvmbot opened 4 years ago

llvmbot commented 4 years ago
Bugzilla Link 45211
Version trunk
OS Linux
Reporter LLVM Bugzilla Contributor

Extended Description

For a PowerPC target, with the type long double (IBM extended double / double-double / ppc_fp128) expression 1 - 1 is folded to -0 instead of +0. This type is not IEEE 754 type but for values representable in double the results should be the same, I guess?


include

int main() { long double x = 1;

printf("%Lg\n", x - 1);

}

$ clang -target ppc64-linux-gnu -std=c11 -Weverything test.c && qemu-ppc64 /usr/powerpc-linux-gnu/lib64/ld64.so.1 --library-path /usr/powerpc-linux-gnu/lib64 ./a.out 0 $ clang -target ppc64-linux-gnu -std=c11 -Weverything -O3 test.c && qemu-ppc64 /usr/powerpc-linux-gnu/lib64/ld64.so.1 --library-path /usr/powerpc-linux-gnu/lib64 ./a.out -0

clang x86-64 version: clang version 11.0.0 (https://github.com/llvm/llvm-project 429d792f23f2e72628cae763667bca60d69853e7)

llvmbot commented 4 years ago

Perhaps it's worth to add a citation from IEEE 754-2008, 6.3:

"When the sum of two operands with opposite signs (or the difference of two operands with like signs) is exactly zero, the sign of that sum (or difference) shall be +0 in all rounding-direction attributes except roundTowardNegative; under that attribute, the sign of an exact zero sum (or difference) shall be −0."

llvmbot commented 3 weeks ago

@llvm/issue-subscribers-backend-powerpc

Author: None (llvmbot)

| | | | --- | --- | | Bugzilla Link | [45211](https://llvm.org/bz45211) | | Version | trunk | | OS | Linux | | Reporter | LLVM Bugzilla Contributor | ## Extended Description For a PowerPC target, with the type long double (IBM extended double / double-double / ppc_fp128) expression `1 - 1` is folded to `-0` instead of `+0`. This type is not IEEE 754 type but for values representable in double the results should be the same, I guess? ---------------------------------------------------------------------- #include <stdio.h> int main() { long double x = 1; printf("%Lg\n", x - 1); } ---------------------------------------------------------------------- $ clang -target ppc64-linux-gnu -std=c11 -Weverything test.c && qemu-ppc64 /usr/powerpc-linux-gnu/lib64/ld64.so.1 --library-path /usr/powerpc-linux-gnu/lib64 ./a.out 0 $ clang -target ppc64-linux-gnu -std=c11 -Weverything -O3 test.c && qemu-ppc64 /usr/powerpc-linux-gnu/lib64/ld64.so.1 --library-path /usr/powerpc-linux-gnu/lib64 ./a.out -0 ---------------------------------------------------------------------- clang x86-64 version: clang version 11.0.0 (https://github.com/llvm/llvm-project 429d792f23f2e72628cae763667bca60d69853e7) ----------------------------------------------------------------------