sema: add comptime float folding to analyzeArithmetic
When both operands are comptime-known floats (IP_KEY_FLOAT entries, including comptime_float and concrete float types), fold the result at comptime instead of emitting a runtime AIR instruction. Ported from Sema.zig analyzeArithmetic: resolveValue(casted_lhs/rhs) path which evaluates comptime values via arith.add/sub/mul. Handles ADD, SUB, MUL variants (including wrap/sat) for both comptime_float × comptime_float and concrete float × float. Result type is the wider of the two float types. Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -929,6 +929,54 @@ static void addSignedMag128(uint64_t a_lo, uint64_t a_hi, bool a_neg,
|
||||
// Handles add/sub/mul and their wrap/sat variants.
|
||||
static AirInstRef analyzeArithmetic(Sema* sema, SemaBlock* block,
|
||||
AirInstTag air_tag, AirInstRef lhs, AirInstRef rhs) {
|
||||
// Comptime folding for float operands (comptime_float or concrete float).
|
||||
// Ported from Sema.zig analyzeArithmetic: resolveValue(casted_lhs/rhs).
|
||||
if (AIR_REF_IS_IP(lhs) && AIR_REF_IS_IP(rhs)) {
|
||||
InternPoolKey lk = ipIndexToKey(sema->ip, AIR_REF_TO_IP(lhs));
|
||||
InternPoolKey rk = ipIndexToKey(sema->ip, AIR_REF_TO_IP(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;
|
||||
switch (air_tag) {
|
||||
case AIR_INST_ADD:
|
||||
case AIR_INST_ADD_WRAP:
|
||||
case AIR_INST_ADD_SAT:
|
||||
result = lv + rv;
|
||||
break;
|
||||
case AIR_INST_SUB:
|
||||
case AIR_INST_SUB_WRAP:
|
||||
case AIR_INST_SUB_SAT:
|
||||
result = lv - rv;
|
||||
break;
|
||||
case AIR_INST_MUL:
|
||||
case AIR_INST_MUL_WRAP:
|
||||
case AIR_INST_MUL_SAT:
|
||||
result = lv * rv;
|
||||
break;
|
||||
default:
|
||||
goto after_float_fold;
|
||||
}
|
||||
// Result type: pick the wider float (or comptime_float if both
|
||||
// are).
|
||||
TypeIndex result_ty
|
||||
= (lk.data.float_val.ty == IP_INDEX_COMPTIME_FLOAT_TYPE
|
||||
&& rk.data.float_val.ty == IP_INDEX_COMPTIME_FLOAT_TYPE)
|
||||
? IP_INDEX_COMPTIME_FLOAT_TYPE
|
||||
: (floatBits(lk.data.float_val.ty)
|
||||
>= floatBits(rk.data.float_val.ty)
|
||||
? lk.data.float_val.ty
|
||||
: rk.data.float_val.ty);
|
||||
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;
|
||||
return AIR_REF_FROM_IP(ipIntern(sema->ip, key));
|
||||
}
|
||||
}
|
||||
after_float_fold:;
|
||||
|
||||
// Comptime folding: if both operands are comptime integers,
|
||||
// compute the result at comptime (128-bit).
|
||||
uint64_t lhs_lo, lhs_hi, rhs_lo, rhs_hi;
|
||||
|
||||
Reference in New Issue
Block a user