Fix pattern that was rewriting func(! var, var) as func(1).
authorGeorge Koehler <xkernigh@netscape.net>
Sun, 29 Oct 2017 18:53:33 +0000 (14:53 -0400)
committerGeorge Koehler <xkernigh@netscape.net>
Sun, 29 Oct 2017 18:53:33 +0000 (14:53 -0400)
Bug reported by Rune, see
 - https://sourceforge.net/p/tack/mailman/message/35809953/
 - https://github.com/davidgiven/ack/issues/62

In EM code, beq and bne pop 2 values and compare them, but teq and tne
pop only 1 value and compare it with zero.  We need cms to compare 2
values; other patterns may convert cmi or cmu to cms.

tests/plat/bugs/bug-62-notvar_var_e.c [new file with mode: 0644]
tests/plat/build.lua
util/opt/patterns

diff --git a/tests/plat/bugs/bug-62-notvar_var_e.c b/tests/plat/bugs/bug-62-notvar_var_e.c
new file mode 100644 (file)
index 0000000..d3813bb
--- /dev/null
@@ -0,0 +1,49 @@
+#include "test.h"
+
+/*
+ * Function a() comes from this mail by Rune to tack-devel:
+ * https://sourceforge.net/p/tack/mailman/message/35809953/
+ *
+ * The peephole optimiser (util/opt) had a bug that rewrote
+ * xx(! i, i) as xx(1).  It was confused with xx(i == i).
+ */
+
+void xx(int xfal, int x1234) {
+  ASSERT(xfal == 0);
+  ASSERT(x1234 == 1234);
+}
+
+void a(void) {
+  int i = 1234;
+  xx(! i, i);
+}
+
+void xxxx(int x2005, int xfal, int xn567, int x2017) {
+  ASSERT(x2005 == 2005);
+  ASSERT(xfal == 0);
+  ASSERT(xn567 == -567);
+  ASSERT(x2017 == 2017);
+}
+
+/* Like a(), but with surrounding arguments. */
+void b(void) {
+  int i = -567;
+  xxxx(2005, ! i, i, 2017);
+}
+
+/*
+ * In c(), the fixed peephole optimiser may
+ * rewrite i == i as 1 and i != i as 0.
+ */
+void c(int i, int tru, int fal) {
+  ASSERT((i == i) == tru);
+  ASSERT((i != i) == fal);
+}
+
+/* Bypasses the CRT. */
+void _m_a_i_n(void) {
+  a();
+  b();
+  c(62, 1, 0);
+  finished();
+}
index b689ea5..1261171 100644 (file)
@@ -13,7 +13,8 @@ definerule("plat_testsuite",
                        "tests/plat/*.e",
                        "tests/plat/*.p",
                        "tests/plat/b/*.b",
-                       "tests/plat/bugs/*.mod"
+                       "tests/plat/bugs/bug-22-inn_mod.mod",
+                       "tests/plat/bugs/bug-62-notvar_var_e.c"
                )
 
                acklibrary {
index 8d949df..34bcc76 100644 (file)
@@ -641,13 +641,13 @@ lol lol bne $1==$2 :
 loe loe bne $1==$2 :
 lil lil bne $1==$2 :
 
-lol lol teq $1==$2 : loc 1
-loe loe teq $1==$2 : loc 1
-lil lil teq $1==$2 : loc 1
+lol lol cms teq $1==$2 && $3==w : loc 1
+loe loe cms teq $1==$2 && $3==w : loc 1
+lil lil cms teq $1==$2 && $3==w : loc 1
 
-lol lol tne $1==$2 : loc 0
-loe loe tne $1==$2 : loc 0
-lil lil tne $1==$2 : loc 0
+lol lol cms tne $1==$2 && $3==w : loc 0
+loe loe cms tne $1==$2 && $3==w : loc 0
+lil lil cms tne $1==$2 && $3==w : loc 0
 
 lol loc CBO stl $3==w && $1==$4 : loc $2 lol $1 CBO w stl $4
 lol loe CBO stl $3==w && $1==$4 : loe $2 lol $1 CBO w stl $4