Skip to content

Commit 400ec54

Browse files
committed
Add safety guards for division and modulo optimizations
Implement zero-check guards to prevent undefined behavior in: - x / x = 1 optimization (only when x is provably non-zero) - x % x = 0 optimization (only when x is provably non-zero) - x / 1 = x and x % 1 = 0 (always safe) These guards ensure correctness by only applying optimizations when operands are compile-time constants with non-zero values, addressing reviewer concerns about potential division by zero.
1 parent a06e3c6 commit 400ec54

File tree

1 file changed

+35
-1
lines changed

1 file changed

+35
-1
lines changed

src/ssa.c

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1884,7 +1884,41 @@ void optimize(void)
18841884
}
18851885
}
18861886

1887-
/* TODO: Dead load elimination */
1887+
/* Safety guards for division and modulo optimizations */
1888+
if (insn->rs1 && insn->rs2 && insn->rs1 == insn->rs2) {
1889+
/* x / x = 1 (with zero-check guard) */
1890+
if (insn->opcode == OP_div && insn->rd) {
1891+
/* Only optimize if we can prove x is non-zero */
1892+
bool is_safe = false;
1893+
if (insn->rs1->is_const && insn->rs1->init_val != 0) {
1894+
is_safe = true;
1895+
}
1896+
1897+
if (is_safe) {
1898+
insn->opcode = OP_load_constant;
1899+
insn->rd->is_const = true;
1900+
insn->rd->init_val = 1;
1901+
insn->rs1 = NULL;
1902+
insn->rs2 = NULL;
1903+
}
1904+
}
1905+
/* x % x = 0 (with zero-check guard) */
1906+
else if (insn->opcode == OP_mod && insn->rd) {
1907+
/* Only optimize if we can prove x is non-zero */
1908+
bool is_safe = false;
1909+
if (insn->rs1->is_const && insn->rs1->init_val != 0) {
1910+
is_safe = true;
1911+
}
1912+
1913+
if (is_safe) {
1914+
insn->opcode = OP_load_constant;
1915+
insn->rd->is_const = true;
1916+
insn->rd->init_val = 0;
1917+
insn->rs1 = NULL;
1918+
insn->rs2 = NULL;
1919+
}
1920+
}
1921+
}
18881922

18891923
/* more optimizations */
18901924
}

0 commit comments

Comments
 (0)