Skip to content

Commit 346b978

Browse files
committed
Add tests designed for wasm32, but that can be general
1 parent 7043d05 commit 346b978

14 files changed

Lines changed: 602 additions & 0 deletions

tests/wasm/coalesce_arith.c

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/* Test: basic block coalescing — straight-line arithmetic
2+
* Multiple consecutive non-branching ops should be merged into a
3+
* single br_table case. This tests that straight-line arithmetic
4+
* produces correct results after coalescing. */
5+
6+
int main(void)
7+
{
8+
int err = 0;
9+
10+
/* 1. Long chain of integer ops (should coalesce into one block) */
11+
int a = 10;
12+
int b = 20;
13+
int c = a + b; /* 30 */
14+
int d = c * 3; /* 90 */
15+
int e = d - a; /* 80 */
16+
int f = e / 4; /* 20 */
17+
int g = f + b + c; /* 70 */
18+
if (g != 70)
19+
err |= 1;
20+
21+
/* 2. Floating-point chain (should coalesce into one block) */
22+
double x = 2.5;
23+
double y = 3.0;
24+
double z = x * y; /* 7.5 */
25+
double w = z + 1.5; /* 9.0 */
26+
double v = w * 2.0 - 1.0; /* 17.0 */
27+
if (v < 16.99 || v > 17.01)
28+
err |= 2;
29+
30+
/* 3. Mixed int/float chain */
31+
int n = 7;
32+
double r = (double)n * 1.5; /* 10.5 */
33+
if (r < 10.49 || r > 10.51)
34+
err |= 4;
35+
36+
/* 4. Chained stores and loads */
37+
int arr[4];
38+
arr[0] = 100;
39+
arr[1] = arr[0] + 1; /* 101 */
40+
arr[2] = arr[1] + 1; /* 102 */
41+
arr[3] = arr[2] + 1; /* 103 */
42+
if (arr[3] != 103)
43+
err |= 8;
44+
45+
return err;
46+
}

tests/wasm/coalesce_arith.expect

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
0

tests/wasm/coalesce_branch.c

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
/* Test: basic block coalescing — conditionals and multi-way branches
2+
* Tests if/else chains, ternary expressions, and nested conditionals
3+
* to exercise the block boundary detection at JMP_CMP targets. */
4+
5+
static int abs_val(int x)
6+
{
7+
if (x < 0)
8+
return -x;
9+
return x;
10+
}
11+
12+
static int clamp(int x, int lo, int hi)
13+
{
14+
if (x < lo)
15+
return lo;
16+
if (x > hi)
17+
return hi;
18+
return x;
19+
}
20+
21+
static int classify(int x)
22+
{
23+
/* Multi-branch: chain of if/else if */
24+
if (x < 0)
25+
return -1;
26+
else if (x == 0)
27+
return 0;
28+
else if (x < 10)
29+
return 1;
30+
else if (x < 100)
31+
return 2;
32+
else
33+
return 3;
34+
}
35+
36+
static int ternary_chain(int a, int b)
37+
{
38+
/* Ternary expressions generate JMP/JMP_CMP patterns */
39+
int max = (a > b) ? a : b;
40+
int min = (a < b) ? a : b;
41+
return max - min;
42+
}
43+
44+
int main(void)
45+
{
46+
int err = 0;
47+
48+
/* 1. Simple if/else */
49+
if (abs_val(-42) != 42)
50+
err |= 1;
51+
if (abs_val(17) != 17)
52+
err |= 1;
53+
54+
/* 2. Multi-way clamp */
55+
if (clamp(5, 0, 10) != 5)
56+
err |= 2;
57+
if (clamp(-3, 0, 10) != 0)
58+
err |= 2;
59+
if (clamp(15, 0, 10) != 10)
60+
err |= 2;
61+
62+
/* 3. If/else-if chain */
63+
if (classify(-5) != -1)
64+
err |= 4;
65+
if (classify(0) != 0)
66+
err |= 4;
67+
if (classify(7) != 1)
68+
err |= 4;
69+
if (classify(50) != 2)
70+
err |= 4;
71+
if (classify(200) != 3)
72+
err |= 4;
73+
74+
/* 4. Ternary */
75+
if (ternary_chain(10, 3) != 7)
76+
err |= 8;
77+
if (ternary_chain(3, 10) != 7)
78+
err |= 8;
79+
80+
/* 5. Nested conditionals */
81+
{
82+
int a = 5, b = 10, c = 3;
83+
int result;
84+
if (a > b) {
85+
if (a > c) result = a;
86+
else result = c;
87+
} else {
88+
if (b > c) result = b;
89+
else result = c;
90+
}
91+
if (result != 10)
92+
err |= 16;
93+
}
94+
95+
return err;
96+
}

tests/wasm/coalesce_branch.expect

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
0

tests/wasm/coalesce_directbr.c

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
/*
2+
* Test direct br / br_if optimisation (Phase B2).
3+
*
4+
* Exercises:
5+
* - JMP forward (becomes br <depth>)
6+
* - JMP_CMP both-forward (becomes br_if <depth_taken> / br <depth_not_taken>)
7+
* - JMP_CMP forward-taken, backward-not-taken (br_if <depth>; fallback dispatch)
8+
* - JMP backward (must still go through loop dispatch)
9+
* - Deeply nested forward jumps (depth > 1)
10+
* - Single-block functions (halt depth = 0)
11+
*/
12+
13+
/* ---- helpers ----------------------------------------------------------- */
14+
static int g_acc; /* global accumulator */
15+
16+
/* Single-block function: only RET, no jumps */
17+
static int identity(int x) { return x; }
18+
19+
/* Backward jump: simple loop (while) */
20+
static int sum_to(int n)
21+
{
22+
int s = 0;
23+
while (n > 0) { s += n; n--; }
24+
return s;
25+
}
26+
27+
/* Forward JMP_CMP: if / else */
28+
static int abs_val(int x)
29+
{
30+
if (x < 0) return -x;
31+
return x;
32+
}
33+
34+
/* Deeply nested forward jumps: short-circuit || chain */
35+
static int any_nonzero(int a, int b, int c, int d, int e)
36+
{
37+
if (a != 0 || b != 0 || c != 0 || d != 0 || e != 0)
38+
return 1;
39+
return 0;
40+
}
41+
42+
/* Mixed forward / backward: loop with early break */
43+
static int first_ge(const int *arr, int n, int thresh)
44+
{
45+
int i;
46+
for (i = 0; i < n; i++) {
47+
if (arr[i] >= thresh)
48+
return arr[i];
49+
}
50+
return -1;
51+
}
52+
53+
/* Cascaded if/else-if producing many forward jumps */
54+
static int classify(int x)
55+
{
56+
if (x < 0) return -1;
57+
if (x == 0) return 0;
58+
if (x < 10) return 1;
59+
if (x < 100) return 2;
60+
return 3;
61+
}
62+
63+
/* Nested loops with break + continue (backward + forward mix) */
64+
static int nested_loop(void)
65+
{
66+
int total = 0;
67+
int i, j;
68+
for (i = 0; i < 5; i++) {
69+
if (i == 3) continue; /* forward jump */
70+
for (j = 0; j < 4; j++) {
71+
if (j == 2) break; /* forward jump */
72+
total += i * 10 + j;
73+
}
74+
}
75+
return total;
76+
}
77+
78+
/* ---- main -------------------------------------------------------------- */
79+
int main(void)
80+
{
81+
int err = 0;
82+
static int arr[] = { 3, 7, 1, 9, 5 };
83+
84+
/* single-block function */
85+
if (identity(42) != 42) err |= 1;
86+
87+
/* backward loop */
88+
if (sum_to(10) != 55) err |= 2;
89+
90+
/* forward branch (if/else) */
91+
if (abs_val(-7) != 7 || abs_val(7) != 7) err |= 4;
92+
93+
/* deeply nested forward (short-circuit ||) */
94+
if (any_nonzero(0,0,0,0,0) != 0) err |= 8;
95+
if (any_nonzero(0,0,0,0,1) != 1) err |= 16;
96+
if (any_nonzero(1,0,0,0,0) != 1) err |= 32;
97+
98+
/* loop with early break (forward + backward) */
99+
if (first_ge(arr, 5, 8) != 9) err |= 64;
100+
if (first_ge(arr, 5, 99) != -1) err |= 128;
101+
102+
/* cascaded if/else-if */
103+
if (classify(-5) != -1) err |= 256;
104+
if (classify(0) != 0) err |= 512;
105+
if (classify(5) != 1) err |= 1024;
106+
if (classify(50) != 2) err |= 2048;
107+
if (classify(500)!= 3) err |= 4096;
108+
109+
/* nested loop with break + continue */
110+
if (nested_loop() != 144) err |= 8192;
111+
112+
return err;
113+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
0

tests/wasm/coalesce_loops.c

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
/* Test: basic block coalescing — loops and branches
2+
* Loops create multiple basic blocks (condition, body, increment).
3+
* This tests that block boundaries are correctly identified at
4+
* jump targets and after jumps. */
5+
6+
int main(void)
7+
{
8+
int err = 0;
9+
10+
/* 1. Simple for loop — sum 1..10 */
11+
{
12+
int sum = 0;
13+
int i;
14+
for (i = 1; i <= 10; i++)
15+
sum += i;
16+
if (sum != 55)
17+
err |= 1;
18+
}
19+
20+
/* 2. Nested loops */
21+
{
22+
int total = 0;
23+
int i, j;
24+
for (i = 0; i < 5; i++)
25+
for (j = 0; j < 3; j++)
26+
total++;
27+
if (total != 15)
28+
err |= 2;
29+
}
30+
31+
/* 3. While loop with early break */
32+
{
33+
int count = 0;
34+
int k = 0;
35+
while (k < 100) {
36+
count++;
37+
k += 7;
38+
if (k > 30)
39+
break;
40+
}
41+
/* k goes: 7, 14, 21, 28, 35 -> break at 35, count=5 */
42+
if (count != 5)
43+
err |= 4;
44+
}
45+
46+
/* 4. Do-while loop */
47+
{
48+
int val = 1;
49+
int iter = 0;
50+
do {
51+
val *= 2;
52+
iter++;
53+
} while (val < 64);
54+
/* val: 2, 4, 8, 16, 32, 64 -> iter=6, val=64 */
55+
if (val != 64 || iter != 6)
56+
err |= 8;
57+
}
58+
59+
/* 5. Loop with continue */
60+
{
61+
int sum = 0;
62+
int i;
63+
for (i = 0; i < 10; i++) {
64+
if (i % 2 == 0)
65+
continue;
66+
sum += i;
67+
}
68+
/* sum = 1+3+5+7+9 = 25 */
69+
if (sum != 25)
70+
err |= 16;
71+
}
72+
73+
return err;
74+
}

tests/wasm/coalesce_loops.expect

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
0

tests/wasm/coalesce_mandel.c

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/* Test: basic block coalescing — compute-heavy kernel
2+
* A simplified mandelbrot-style computation that exercises tight loops
3+
* with many arithmetic ops per iteration — the key scenario for
4+
* coalescing speedups. */
5+
6+
static int mandelbrot_pixel(double cx, double cy, int max_iter)
7+
{
8+
double zx = 0.0, zy = 0.0;
9+
int iter = 0;
10+
while (iter < max_iter) {
11+
/* These ops should all coalesce into one block */
12+
double zx2 = zx * zx;
13+
double zy2 = zy * zy;
14+
if (zx2 + zy2 > 4.0)
15+
break;
16+
double new_zx = zx2 - zy2 + cx;
17+
zy = 2.0 * zx * zy + cy;
18+
zx = new_zx;
19+
iter++;
20+
}
21+
return iter;
22+
}
23+
24+
int main(void)
25+
{
26+
int err = 0;
27+
28+
/* Point inside the set: (-0.5, 0) — should reach max_iter */
29+
if (mandelbrot_pixel(-0.5, 0.0, 100) != 100)
30+
err |= 1;
31+
32+
/* Point outside the set: (2.0, 0) — should escape quickly */
33+
{
34+
int n = mandelbrot_pixel(2.0, 0.0, 100);
35+
if (n >= 100 || n < 1)
36+
err |= 2;
37+
}
38+
39+
/* Point on boundary: (0.25, 0) — should take many iterations */
40+
{
41+
int n = mandelbrot_pixel(0.25, 0.0, 200);
42+
if (n < 50)
43+
err |= 4;
44+
}
45+
46+
/* Known escape point: (1, 1) — escapes in a few iterations */
47+
{
48+
int n = mandelbrot_pixel(1.0, 1.0, 100);
49+
if (n > 10)
50+
err |= 8;
51+
}
52+
53+
return err;
54+
}

tests/wasm/coalesce_mandel.expect

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
0

0 commit comments

Comments
 (0)