diff options
| author | 2026-03-22 10:45:22 +0100 | |
|---|---|---|
| committer | 2026-03-22 10:49:30 +0100 | |
| commit | f9e3a52eaa6ae91388aa247182da6df3cc8d5a05 (patch) | |
| tree | 0fa1b5604ebeaf4a1efbcb5242cf8bb07b4f1d76 /test | |
| parent | 79874c83bf76a5b3efd3d558933b90d9b53b829e (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.c | 24 |
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"); +} |