zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

commit 4e623e11101dc7f900580772393c3d7855634291 (tree)
parent 2f1303d0dbdb1447997f6e692073f609319af4c9
Author: Motiejus <motiejus@jakstys.lt>
Date:   Sat,  7 Mar 2026 09:24:32 +0000

sema: add comptime float folding to zirMinMax

When both @min/@max operands are comptime-known floats (IP_KEY_FLOAT),
fold the result at compile time. Result type is the wider of the two
float types, or comptime_float if both are comptime_float.

Ported from Sema.zig analyzeMinMax → Value.numberMin/Max.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>

Diffstat:
Mstage0/sema.c | 27+++++++++++++++++++++++++++
1 file changed, 27 insertions(+), 0 deletions(-)

diff --git a/stage0/sema.c b/stage0/sema.c @@ -10253,6 +10253,33 @@ static AirInstRef zirMinMax(Sema* sema, SemaBlock* block, uint32_t inst) { result_ty = semaTypeOf(sema, min_rhs); return internComptimeInt(sema, result_ty, r_lo, r_hi, r_neg); } + + // Comptime folding for float operands. + // Ported from Sema.zig analyzeMinMax → Value.numberMin/Max for floats. + if (AIR_REF_IS_IP(min_lhs) && AIR_REF_IS_IP(min_rhs)) { + InternPoolKey lk = ipIndexToKey(sema->ip, AIR_REF_TO_IP(min_lhs)); + InternPoolKey rk = ipIndexToKey(sema->ip, AIR_REF_TO_IP(min_rhs)); + if (lk.tag == IP_KEY_FLOAT && rk.tag == IP_KEY_FLOAT) { + double lv = lk.data.float_val.val; + double rv = rk.data.float_val.val; + double result_val + = is_max ? (lv > rv ? lv : rv) : (lv < rv ? lv : rv); + TypeIndex result_ty = (floatBits(lk.data.float_val.ty) + >= floatBits(rk.data.float_val.ty)) + ? lk.data.float_val.ty + : rk.data.float_val.ty; + if (lk.data.float_val.ty == IP_INDEX_COMPTIME_FLOAT_TYPE + && rk.data.float_val.ty == IP_INDEX_COMPTIME_FLOAT_TYPE) + result_ty = IP_INDEX_COMPTIME_FLOAT_TYPE; + InternPoolKey key; + memset(&key, 0, sizeof(key)); + key.tag = IP_KEY_FLOAT; + key.data.float_val.ty = result_ty; + key.data.float_val.val = result_val; + return AIR_REF_FROM_IP(ipIntern(sema->ip, key)); + } + } + TypeIndex peer_ty = resolvePeerTypes(sema, min_lhs, min_rhs); AirInstRef c_lhs = semaCoerce(sema, block, peer_ty, min_lhs); AirInstRef c_rhs = semaCoerce(sema, block, peer_ty, min_rhs);