From f51aba22e0650032815ef791acb492220e3da7a4 Mon Sep 17 00:00:00 2001 From: Quentin Carbonneaux Date: Sun, 12 Mar 2023 22:32:57 +0100 Subject: refresh stale Tmp.link before use During coalescing, the resizing/ reordering of the sl[] array invalidates the indices stored in the 'visit' field of temps; we need to reset it before we can use it again. --- mem.c | 5 +++++ test/mem3.ssa | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+) create mode 100644 test/mem3.ssa diff --git a/mem.c b/mem.c index 8bde4be..36359a0 100644 --- a/mem.c +++ b/mem.c @@ -406,6 +406,11 @@ coalesce(Fn *fn) /* substitute fused slots */ for (s=sl; s<&sl[nsl]; s++) { t = &fn->tmp[s->t]; + /* the visit link is stale, + * reset it before the slot() + * calls below + */ + t->visit = s-sl; assert(t->ndef == 1 && t->def); if (s->s == s) continue; diff --git a/test/mem3.ssa b/test/mem3.ssa new file mode 100644 index 0000000..a6cafd2 --- /dev/null +++ b/test/mem3.ssa @@ -0,0 +1,48 @@ +# Ember Sawady reported this bug +# in stack-slot coalescing + +type :type.3 = align 8 { l 1, l 1 } +type :tags.2 = { { :type.3 1 } } +type :type.1 = align 8 { w 1, :tags.2 1 } +type :tags.9 = { { w 1 } } +type :type.8 = align 4 { w 1, :tags.9 1 } + +function :type.1 $func() { +@start.0 + %object.5 =l alloc8 24 + %object.7 =l alloc4 8 + %binding.21 =l alloc8 16 + %object.23 =l alloc8 24 +@body.4 + %.10 =l add %object.7, 4 + jnz 1, @matches.13, @next.14 +@matches.13 + # binding.21 gets fused with object.23 + storel 1, %binding.21 + %value.22 =l add %binding.21, 8 + storel 2, %value.22 + %.24 =l add %object.23, 8 + # but the blit direction is not set correctly + blit %binding.21, %.24, 16 + ret %object.23 +@next.14 + storew 2543892678, %object.5 + ret %object.5 +} + +export function w $main() { +@start.27 + %object.43 =l alloc8 24 + %object.49 =l alloc8 24 +@body.28 + %returns.34 =:type.1 call $func() + %value.47 =l add %returns.34, 16 + %load.48 =l loadl %value.47 + %.33 =w ceql %load.48, 2 + jnz %.33, @passed.32, @failed.31 +@failed.31 + call $abort() +@passed.32 + ret 0 +} + -- cgit 1.4.1