diff --git a/tests/plat/bugs/bug-203-ego-sr_c-O3.c b/tests/plat/bugs/bug-203-ego-sr_c-O3.c new file mode 100644 index 000000000..9e851effb --- /dev/null +++ b/tests/plat/bugs/bug-203-ego-sr_c-O3.c @@ -0,0 +1,47 @@ +#include "test.h" + +/* + * https://github.com/davidgiven/ack/issues/203 was a bug in the + * strength reduction (SR) phase of ego. To cause the bug: + * + * 1. SR must run; it runs at `ack -O3` and higher. + * + * 2. SR must find a loop with an induction variable, and SR must + * find at least 2 different expressions using the variable, like + * i << 1, (i + 1) << 1, or 3 * i, 5 * i. + * + * 3. There is no basic block to act as a loop header, so SR must + * create the block. One way is to put if (one) { ... } around + * the loop, so the loop is just after a conditional branch. + */ + +/* + * Global variables prevent optimizations: + * if (one) { ... } caused the bug, if (1) { ... } didn't. + */ +int zero = 0; +int one = 1; +short ary[] = {8, 8, 8, 8, 8, 9}; + +int left_shift(int i) { + if (one) { + /* EM will use i << 1, (i + 1) << 1 here. */ + while (ary[i] == ary[i + 1]) + i++; + } + return i; +} + +int multiply(int i) { + if (one) { + while (((3 * i) & (5 * i)) < 40) + i++; + } + return i; +} + +int main(void) { + ASSERT(left_shift(zero) == 4); + ASSERT(multiply(zero) == 21); + finished(); +} diff --git a/tests/plat/build.lua b/tests/plat/build.lua index e5318eae4..0ae4a5c19 100644 --- a/tests/plat/build.lua +++ b/tests/plat/build.lua @@ -5,7 +5,7 @@ definerule("plat_testsuite", { plat = { type="string" }, method = { type="string" }, - -- added long-long/llswitch_e.c + -- added bugs/bug-203-ego-sr_c-O3.c sets = { type="table", default={"core", "b", "bugs", "m2", "floats", "long-long"}}, skipsets = { type="table", default={}}, tests = { type="targets", default={} }, @@ -48,6 +48,14 @@ definerule("plat_testsuite", lang = "e" end + -- If lang is "c-O3", then build with -O3. + local _, _, optimize = lang:find("(-O[^-]*)$") + if optimize then + lang = lang:sub(1, -1 - #optimize) + else + optimize = "-O0" + end + local bin = ackprogram { name = fs.."_bin", srcs = { f }, @@ -55,7 +63,7 @@ definerule("plat_testsuite", vars = { plat = e.plat, lang = lang, - ackcflags = "-O0 -Bmain" + ackcflags = optimize.." -Bmain" } }