summaryrefslogtreecommitdiffstats
path: root/results/classifier/mode-deepseek-r1:32b/output/user/616
diff options
context:
space:
mode:
Diffstat (limited to 'results/classifier/mode-deepseek-r1:32b/output/user/616')
-rw-r--r--results/classifier/mode-deepseek-r1:32b/output/user/616109
1 files changed, 109 insertions, 0 deletions
diff --git a/results/classifier/mode-deepseek-r1:32b/output/user/616 b/results/classifier/mode-deepseek-r1:32b/output/user/616
new file mode 100644
index 00000000..4bd3bac2
--- /dev/null
+++ b/results/classifier/mode-deepseek-r1:32b/output/user/616
@@ -0,0 +1,109 @@
+
+
+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)