commit ba3703764da428d800257c7ce5b760386a9ed5e7
parent 4934c27ff80eca5aedb33bb589ddc42bdd9973ee
Author: Ryan Sepassi <rsepassi@gmail.com>
Date: Mon, 11 May 2026 12:49:21 -0700
test/cg q05: accumulate into r_int to fit x64 INT pool
test_main was alloc_reg'ing 7 concurrent INT vals, one past the x64
pool (RBX, R12..R15, R10). At -O0 the 7th alloc returned REG_NONE,
whose low nibble collided with R15 holding r_zero; at -O1
opt_cgtarget's replay allocates one phys reg per Val with no
liveness, hitting the same exhaustion. Reusing r_int as the sum
accumulator keeps the concurrent count at 6.
Diffstat:
1 file changed, 10 insertions(+), 5 deletions(-)
diff --git a/test/cg/harness/cases_q.c b/test/cg/harness/cases_q.c
@@ -269,12 +269,17 @@ void build_q05_distinct_signatures(CgTestCtx* ctx) {
Reg r_long_lo = T->alloc_reg(T, RC_INT, I32);
T->convert(T, CV_TRUNC, REG_op(r_long_lo, I32), REG_op(r_long, I64));
- Reg s = T->alloc_reg(T, RC_INT, I32);
- T->binop(T, BO_IADD, REG_op(s, I32), REG_op(r_int, I32),
+ /* Accumulate into r_int rather than allocating a fresh sum reg — keeps
+ * concurrent Val count at 6, matching the x64 INT pool (RBX, R12..R15,
+ * R10). A 7th alloc would return REG_NONE here, and opt_cgtarget's
+ * replay alloc-on-first-use exhausts the same pool at -O1. */
+ T->binop(T, BO_IADD, REG_op(r_int, I32), REG_op(r_int, I32),
REG_op(r_long_lo, I32));
- T->binop(T, BO_IADD, REG_op(s, I32), REG_op(s, I32), REG_op(r_void, I32));
- T->binop(T, BO_IADD, REG_op(s, I32), REG_op(s, I32), REG_op(r_zero, I32));
- cgtest_ret_reg(tf, s, I32);
+ T->binop(T, BO_IADD, REG_op(r_int, I32), REG_op(r_int, I32),
+ REG_op(r_void, I32));
+ T->binop(T, BO_IADD, REG_op(r_int, I32), REG_op(r_int, I32),
+ REG_op(r_zero, I32));
+ cgtest_ret_reg(tf, r_int, I32);
cgtest_end(tf);
}