Merge pull request #7372 from kalsprite/abs_constant_range

check_builtin: range-check the constant `abs` folds
This commit is contained in:
gingerBill
2026-08-18 12:05:28 +02:00
committed by GitHub
2 changed files with 40 additions and 1 deletions

View File

@@ -4612,6 +4612,11 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As
}
GB_ASSERT(!is_type_complex_or_quaternion(operand->type));
if (operand->mode == Addressing_Constant) {
operand->expr = call;
check_is_expressible(c, operand, operand->type);
}
break;
}

View File

@@ -210,4 +210,38 @@ bit_set_subset_folding_selects_the_right_when_arm :: proc(t: ^testing.T) {
testing.expect_value(t, W2, 1)
testing.expect_value(t, W3, 1)
testing.expect_value(t, W4, 1)
}
}
// `abs` folds with `mp_abs`, which is arbitrary precision, so the magnitude of a signed minimum
// leaves the type's range. Enusre the are the neighbors are not refused
@(test)
abs_constant_folding_matches_runtime :: proc(t: ^testing.T) {
{
a, b, c, d := i8(-127), i16(-32767), i32(-2147483647), i64(-9223372036854775807)
testing.expect_value(t, abs(i8(-127)), abs(a))
testing.expect_value(t, abs(i16(-32767)), abs(b))
testing.expect_value(t, abs(i32(-2147483647)), abs(c))
testing.expect_value(t, abs(i64(-9223372036854775807)), abs(d))
testing.expect_value(t, abs(i32(-2147483647)), 2147483647)
}
{
a, b := i32(2147483647), u32(4294967295)
testing.expect_value(t, abs(i32(2147483647)), abs(a))
testing.expect_value(t, abs(u32(4294967295)), abs(b))
}
{
a, b := f32(-1.5), f64(-2.5)
testing.expect_value(t, abs(f32(-1.5)), abs(a))
testing.expect_value(t, abs(f64(-2.5)), abs(b))
}
{
a := complex(f64(3), f64(-4))
b := quaternion(w = f64(1), x = f64(2), y = f64(2), z = f64(4))
testing.expect_value(t, abs(complex(f64(3), f64(-4))), abs(a))
testing.expect_value(t, abs(complex(f64(3), f64(-4))), 5)
testing.expect_value(t, abs(quaternion(w = f64(1), x = f64(2), y = f64(2), z = f64(4))), abs(b))
}
// the folded value still selects the right `when` arm
when abs(i32(-2147483647)) == 2147483647 { W :: 1 } else { W :: 0 }
testing.expect_value(t, W, 1)
}