aboutsummaryrefslogtreecommitdiffhomepage
path: root/test
diff options
context:
space:
mode:
authorlemon <lsof@mailbox.org>2026-03-22 10:45:22 +0100
committerlemon <lsof@mailbox.org>2026-03-22 10:49:30 +0100
commitf9e3a52eaa6ae91388aa247182da6df3cc8d5a05 (patch)
tree0fa1b5604ebeaf4a1efbcb5242cf8bb07b4f1d76 /test
parent79874c83bf76a5b3efd3d558933b90d9b53b829e (diff)
mem2reg: fix rare edge case with weird control flow
mem2reg was assuming alloca's appeared before all their uses. When this didn't happen it broke the logic re. sealed blocks. Normally this doesn't happen in most natural code. Even with gotos, RPO would assure this in most cases, the exception I found is a goto that jumps into a loop past a variable declaration that is earlier in the loop. Then even RPO would keep the alloca itself past the first uses, breaking things.
Diffstat (limited to 'test')
-rw-r--r--test/18-goto2.c24
1 files changed, 24 insertions, 0 deletions
diff --git a/test/18-goto2.c b/test/18-goto2.c
new file mode 100644
index 0000000..8742d35
--- /dev/null
+++ b/test/18-goto2.c
@@ -0,0 +1,24 @@
+/* EXPECT:
+ok
+*/
+
+void h(int x){}
+
+/* isolated mem2reg bug from something in regalloc: the goto into the loop past
+ * the `int nqueue` declaration caused a miscompilation */
+void test(void) {
+ int curi = 5;
+ goto start2;
+ for (curi; curi >= 0; curi--) {
+ int nqueue;
+ start2:
+ for (nqueue = 2; nqueue > 0; ) {
+ h(nqueue--);
+ }
+ }
+}
+int puts(const char *);
+int main(void) {
+ test();
+ puts("ok");
+}