From 3d6ee435cf6ebf94dbd3ba9ea0eca4070e5eff65 Mon Sep 17 00:00:00 2001 From: George Koehler Date: Sun, 29 Oct 2017 14:53:33 -0400 Subject: [PATCH] Fix pattern that was rewriting func(! var, var) as func(1). 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 | 49 +++++++++++++++++++++++++++ tests/plat/build.lua | 3 +- util/opt/patterns | 12 +++---- 3 files changed, 57 insertions(+), 7 deletions(-) create mode 100644 tests/plat/bugs/bug-62-notvar_var_e.c 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 index 000000000..d3813bb91 --- /dev/null +++ b/tests/plat/bugs/bug-62-notvar_var_e.c @@ -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(); +} diff --git a/tests/plat/build.lua b/tests/plat/build.lua index b689ea5f6..12611711a 100644 --- a/tests/plat/build.lua +++ b/tests/plat/build.lua @@ -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 { diff --git a/util/opt/patterns b/util/opt/patterns index 8d949dfd8..34bcc760a 100644 --- a/util/opt/patterns +++ b/util/opt/patterns @@ -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