commit 99fea1e21174b18ccbd947787bea91140fd802e8
parent 26c1c30b7d96d2170195970a8cdb3b024ba7421a
Author: Quentin Carbonneaux <quentin@c9x.me>
Date: Tue, 13 Dec 2022 10:50:27 +0100
bugfix in load elimination
When checking if two slices represent
the same range of memory we must check
that offsets match.
The bug was revealed by a harec test.
Diffstat:
2 files changed, 52 insertions(+), 0 deletions(-)
diff --git a/load.c b/load.c
@@ -248,6 +248,7 @@ def(Slice sl, bits msk, Blk *b, Ins *i, Loc *il)
} else if (i->op == Oblit1) {
assert(rtype(i->arg[0]) == RInt);
sz = abs(rsval(i->arg[0]));
+ assert(i > b->ins);
--i;
assert(i->op == Oblit0);
r1 = i->arg[1];
@@ -321,6 +322,7 @@ def(Slice sl, bits msk, Blk *b, Ins *i, Loc *il)
for (ist=ilog; ist<&ilog[nlog]; ++ist)
if (ist->isphi && ist->bid == b->id)
if (req(ist->new.phi.m.ref, sl.ref))
+ if (ist->new.phi.m.off == sl.off)
if (ist->new.phi.m.sz == sl.sz) {
r = ist->new.phi.p->to;
if (msk != msks)
diff --git a/test/load3.ssa b/test/load3.ssa
@@ -0,0 +1,50 @@
+# regression test for load()
+# see comment below
+
+function w $rand() {
+@start
+ ret 0
+}
+
+function w $chk(w %a, w %b) {
+@start
+ %ok =w ceqw %a, 1
+ %ok1 =w ceqw %b, 0
+ %ok2 =w and %ok, %ok1
+ %ret =w xor %ok2, 1
+ ret %ret
+}
+
+export
+function w $main() {
+@start
+ %s0 =l alloc4 8
+ %s1 =l alloc4 8
+
+ storew 1, %s0
+ %s04 =l add 4, %s0
+ storew 0, %s04
+
+ %rnd =w call $rand()
+ jnz %rnd, @tt, @ff
+@tt
+ jmp @blit
+@ff
+ jmp @blit
+
+@blit
+ # we make sure def() checks
+ # offsets correctly when
+ # processing inserted phis;
+ # if not, %w1 will bogusly
+ # have the same value as %w0
+
+ blit %s0, %s1, 8
+
+ %w0 =w load %s1
+ %s14 =l add 4, %s1
+ %w1 =w load %s14
+
+ %ret =w call $chk(w %w0, w %w1)
+ ret %ret
+}