commit: 2ea9c3293333d90a5fae667f2d30cbb7aa7e6ebb
parent eca93027e7f76e074e3fa8f46ace287cc8212976
Author: Michael Forney <mforney@mforney.org>
Date: Tue, 2 Jul 2019 21:21:26 -0700
qbe: Add a few patches to fix various things
Diffstat:
4 files changed, 165 insertions(+), 1 deletion(-)
diff --git a/pkg/qbe/patch/0009-amd64-Fix-floating-point-equality-check-with-NaN.patch b/pkg/qbe/patch/0009-amd64-Fix-floating-point-equality-check-with-NaN.patch
@@ -0,0 +1,73 @@
+From d4d5e44e1064cff4f6b3c25b174ec53d294c6e09 Mon Sep 17 00:00:00 2001
+From: Michael Forney <mforney@mforney.org>
+Date: Fri, 24 May 2019 18:56:12 -0700
+Subject: [PATCH] amd64: Fix floating-point equality check with NaN
+
+arm64 does not have the same issue, and the added test passes there
+as well.
+---
+ amd64/isel.c | 15 +++++++++++++++
+ test/isel2.ssa | 25 +++++++++++++++++++++++++
+ 2 files changed, 40 insertions(+)
+ create mode 100644 test/isel2.ssa
+
+diff --git a/amd64/isel.c b/amd64/isel.c
+index 56e4cf3..9bf5c74 100644
+--- a/amd64/isel.c
++++ b/amd64/isel.c
+@@ -327,6 +327,21 @@ Emit:
+ if (isload(i.op))
+ goto case_Oload;
+ if (iscmp(i.op, &kc, &x)) {
++ /* ZF is set when operands are unordered, so we
++ * may have to check PF as well.
++ */
++ switch (x) {
++ case NCmpI+Cfeq:
++ r0 = newtmp("isel", Kw, fn);
++ emit(Oand, Kw, i.to, i.to, r0);
++ emit(Oflagfo, k, r0, R, R);
++ break;
++ case NCmpI+Cfne:
++ r0 = newtmp("isel", Kw, fn);
++ emit(Oor, Kw, i.to, i.to, r0);
++ emit(Oflagfuo, k, r0, R, R);
++ break;
++ }
+ emit(Oflag+x, k, i.to, R, R);
+ i1 = curi;
+ if (selcmp(i.arg, kc, fn))
+diff --git a/test/isel2.ssa b/test/isel2.ssa
+new file mode 100644
+index 0000000..d6e009c
+--- /dev/null
++++ b/test/isel2.ssa
+@@ -0,0 +1,25 @@
++# tests that floating point equality works
++# on amd64, which requires additional
++# instructions to check that the operands
++# are ordered.
++
++export function w $eq(s %x, s %y) {
++@start
++ %r =w ceqs %x, %y
++ ret %r
++}
++
++export function w $ne(s %x, s %y) {
++@start
++ %r =w cnes %x, %y
++ ret %r
++}
++
++# >>> driver
++# #include <math.h>
++# extern int eq(float, float);
++# extern int ne(float, float);
++# int main() {
++# return !(eq(NAN, NAN) == 0 && ne(NAN, NAN) == 1);
++# }
++# <<<
+--
+2.22.0
+
diff --git a/pkg/qbe/patch/0010-Increase-NString-to-96.patch b/pkg/qbe/patch/0010-Increase-NString-to-96.patch
@@ -0,0 +1,25 @@
+From b391a6bdf819585cd956107b2346cd939b48ce41 Mon Sep 17 00:00:00 2001
+From: Michael Forney <mforney@mforney.org>
+Date: Fri, 31 May 2019 13:31:04 -0700
+Subject: [PATCH] Increase NString to 96
+
+---
+ all.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/all.h b/all.h
+index 5f67e81..8819e85 100644
+--- a/all.h
++++ b/all.h
+@@ -31,7 +31,7 @@ typedef struct Dat Dat;
+ typedef struct Target Target;
+
+ enum {
+- NString = 64,
++ NString = 96,
+ NPred = 63,
+ NIns = 1 << 20,
+ NAlign = 3,
+--
+2.22.0
+
diff --git a/pkg/qbe/patch/0011-fold-Don-t-fold-invalid-addition-subtraction-rather-.patch b/pkg/qbe/patch/0011-fold-Don-t-fold-invalid-addition-subtraction-rather-.patch
@@ -0,0 +1,66 @@
+From 264b07e0cb0ce869cfcdab0a3e66c92a99de5dee Mon Sep 17 00:00:00 2001
+From: Michael Forney <mforney@mforney.org>
+Date: Sun, 16 Jun 2019 01:38:27 -0700
+Subject: [PATCH] fold: Don't fold invalid addition/subtraction rather than
+ failing
+
+This may happen in a branch QBE doesn't realize is unreachable,
+for example (simplified from real code found in ncurses)
+
+ data $str = { b "abcdef", b 0 }
+ function l $f(w %x) {
+ @start
+ %.1 =w ceqw %x, 0
+ jnz %.1, @logic_join, @logic_right
+ @logic_right
+ %p =l call $strchr(l $str, w %x)
+ %.2 =w ceql %p, 0
+ @logic_join
+ %.3 =w phi @start %.1, @logic_right %.2
+ jnz %.3, @fail, @return
+ @fail
+ ret 0
+ @return
+ %.4 =l sub %p, $str
+ ret %.4
+ }
+---
+ fold.c | 11 ++++-------
+ 1 file changed, 4 insertions(+), 7 deletions(-)
+
+diff --git a/fold.c b/fold.c
+index 0a3945f..9e1a12d 100644
+--- a/fold.c
++++ b/fold.c
+@@ -343,7 +343,7 @@ foldint(Con *res, int op, int w, Con *cl, Con *cr)
+ if (op == Oadd) {
+ if (cl->type == CAddr) {
+ if (cr->type == CAddr)
+- err("undefined addition (addr + addr)");
++ return 1;
+ lab = cl->label;
+ typ = CAddr;
+ }
+@@ -358,16 +358,13 @@ foldint(Con *res, int op, int w, Con *cl, Con *cr)
+ lab = cl->label;
+ typ = CAddr;
+ } else if (cl->label != cr->label)
+- err("undefined substraction (addr1 - addr2)");
++ return 1;
+ }
+ else if (cr->type == CAddr)
+- err("undefined substraction (num - addr)");
+- }
+- else if (cl->type == CAddr || cr->type == CAddr) {
+- if (Ocmpl <= op && op <= Ocmpl1)
+ return 1;
+- err("invalid address operand for '%s'", optab[op].name);
+ }
++ else if (cl->type == CAddr || cr->type == CAddr)
++ return 1;
+ switch (op) {
+ case Oadd: x = l.u + r.u; break;
+ case Osub: x = l.u - r.u; break;
+--
+2.22.0
+
diff --git a/pkg/qbe/ver b/pkg/qbe/ver
@@ -1 +1 @@
-acc3af4733 r0
+acc3af4733 r1