diff options
Diffstat (limited to 'results/classifier/qwen3:32b/output/instruction/616')
| -rw-r--r-- | results/classifier/qwen3:32b/output/instruction/616 | 110 |
1 files changed, 110 insertions, 0 deletions
diff --git a/results/classifier/qwen3:32b/output/instruction/616 b/results/classifier/qwen3:32b/output/instruction/616 new file mode 100644 index 00000000..3aa0af14 --- /dev/null +++ b/results/classifier/qwen3:32b/output/instruction/616 @@ -0,0 +1,110 @@ + + + +overflow condition code determined incorrectly after addition on s390x +Description of problem: +The following program foo.c +[foo.c](/uploads/78f5f799af6e3c400a6a42634f3f0e63/foo.c) + +``` +#include <stdio.h> + +int overflow_32 (int x, int y) +{ + int sum; + return ! __builtin_add_overflow (x, y, &sum); +} + +int overflow_64 (long long x, long long y) +{ + long sum; + return ! __builtin_add_overflow (x, y, &sum); +} + +int a1 = -2147483648; +int b1 = -2147483648; +long long a2 = -9223372036854775808L; +long long b2 = -9223372036854775808L; + +int main () +{ + { + int a = a1; + int b = b1; + printf ("a = 0x%x, b = 0x%x\n", a, b); + printf ("no_overflow = %d\n", overflow_32 (a, b)); + } + { + long long a = a2; + long long b = b2; + printf ("a = 0x%llx, b = 0x%llx\n", a, b); + printf ("no_overflow = %d\n", overflow_64 (a, b)); + } +} +``` + +should print + +``` +a = 0x80000000, b = 0x80000000 +no_overflow = 0 +a = 0x8000000000000000, b = 0x8000000000000000 +no_overflow = 0 +``` + +However, when compiled as an s390x program and executed through +qemu 6.1.0 (Linux user-mode), it prints 'no_overflow = 1' twice. + +``` +$ s390x-linux-gnu-gcc-10 --version +s390x-linux-gnu-gcc-10 (Ubuntu 10.3.0-1ubuntu1~20.04) 10.3.0 +``` + +``` +$ s390x-linux-gnu-gcc-10 -static foo.c +$ ~/inst-qemu/6.1.0/bin/qemu-s390x a.out +a = 0x80000000, b = 0x80000000 +no_overflow = 1 +a = 0x8000000000000000, b = 0x8000000000000000 +no_overflow = 1 +``` + +``` +$ s390x-linux-gnu-gcc-10 -O2 -static foo.c +$ ~/inst-qemu/6.1.0/bin/qemu-s390x a.out +a = 0x80000000, b = 0x80000000 +no_overflow = 1 +a = 0x8000000000000000, b = 0x8000000000000000 +no_overflow = 1 +``` + +The code generated by 's390x-linux-gnu-gcc-10 -O2' makes use of the +'o' (overflow / ones) condition code: + +``` +overflow_64: + lgr %r1,%r2 ;; copy a into %r1 + lghi %r2,0 + agr %r1,%r3 ;; add a and b + bnor %r14 ;; if no overflow, return %r2 = 0 + lghi %r2,1 + br %r14 ;; otherwise, return %r2 = 1 +``` + +Either the bug is in GCC, that is, GCC produces code that uses the CPU's +overflow condition code when it shouldn't. + +Or the bug is in QEMU, that is, QEMU does not set the overflow condition +code correctly. + +This can be decided by running the above program on real Linux/s390x hardware +(to which I don't have access). +Steps to reproduce: +[foo.static.s390x](/uploads/ac41abf4c54baf9ca96ba82d75a24ad6/foo.static.s390x) +(foo.static.s390x is attached, the result of "s390x-linux-gnu-gcc-10 -static -O2 foo.c -o foo.static.s390x") + +1. `qemu-s390x foo.static.s390x` +Additional information: +If the bug is really in QEMU, the attached patch fixes it. + +[0001-s390x-Fix-determination-of-overflow-condition-code-a.patch](/uploads/552917079ccd25f1861d682fc9dee3e8/0001-s390x-Fix-determination-of-overflow-condition-code-a.patch) |