sema: add float coercion in calls and param type resolution; enable 12 corpus tests
- Add float→float coercion (fpext/fptrunc) to semaCoerce for runtime values - Extract param types from callee's ZIR param instructions and coerce call arguments to match (f16→f32 fpext for __divhf3 calling __divsf3) - Fix param type resolution to read break_inline operand from type body - Enable divhf3, floatdihf, floatdixf, floatsihf, floatsixf, fixunshfdi, fixunshfsi, fixunsxfdi, fixunsxfsi, floatundihf, floatundixf, floatunsixf Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -442,11 +442,12 @@ static bool declIdIsExport(uint32_t id) {
|
||||
|| id == 29;
|
||||
}
|
||||
|
||||
// Forward declaration for recursive call from zirStructDecl.
|
||||
// Forward declarations.
|
||||
static bool analyzeBodyInner(
|
||||
Sema* sema, SemaBlock* block, const uint32_t* body, uint32_t body_len);
|
||||
static uint8_t analyzeBodyRuntimeBreak(
|
||||
Sema* sema, SemaBlock* block, const uint32_t* body, uint32_t body_len);
|
||||
static uint16_t floatBits(TypeIndex ty);
|
||||
|
||||
// getParamBody: extract param body from a param_block ZIR instruction.
|
||||
// Ported from lib/std/zig/Zir.zig getParamBody.
|
||||
@@ -719,6 +720,21 @@ static AirInstRef semaCoerce(
|
||||
data.ty_op.operand = ref;
|
||||
return semaAddInst(block, tag, data);
|
||||
}
|
||||
// Runtime float→float coercion: emit fpext or fptrunc.
|
||||
// Ported from src/Sema.zig coerce for float types.
|
||||
if (AIR_REF_IS_INST(ref)) {
|
||||
uint16_t src_fbits = floatBits(src_ty);
|
||||
uint16_t tgt_fbits = floatBits(target_ty);
|
||||
if (src_fbits > 0 && tgt_fbits > 0 && src_fbits != tgt_fbits) {
|
||||
AirInstTag ftag
|
||||
= (tgt_fbits > src_fbits) ? AIR_INST_FPEXT : AIR_INST_FPTRUNC;
|
||||
AirInstData data;
|
||||
memset(&data, 0, sizeof(data));
|
||||
data.ty_op.ty_ref = AIR_REF_FROM_IP(target_ty);
|
||||
data.ty_op.operand = ref;
|
||||
return semaAddInst(block, ftag, data);
|
||||
}
|
||||
}
|
||||
// For unsupported type combinations (e.g. type→void during comptime
|
||||
// analysis of generic functions), return the operand unchanged.
|
||||
// This is safe because these paths don't produce runtime AIR.
|
||||
@@ -3533,15 +3549,52 @@ static AirInstRef zirCall(
|
||||
// Dummy allocs for generic runtime params are now emitted
|
||||
// interleaved in the arg evaluation loop above (Fix A).
|
||||
|
||||
// Count runtime params (skip comptime type params).
|
||||
// Count runtime params (skip comptime type params) and coerce
|
||||
// arguments to callee's parameter types.
|
||||
// Ported from src/Sema.zig analyzeCall (Sema.zig:7575-7601).
|
||||
uint32_t runtime_args_count = 0;
|
||||
AirInstRef runtime_arg_refs[16];
|
||||
uint32_t pi = 0;
|
||||
for (uint32_t p = 0; p < param_body_len; p++) {
|
||||
ZirInstTag ptag = sema->code.inst_tags[param_body[p]];
|
||||
if (ptag == ZIR_INST_PARAM || ptag == ZIR_INST_PARAM_ANYTYPE) {
|
||||
if (pi < args_len)
|
||||
runtime_arg_refs[runtime_args_count++] = arg_refs[pi];
|
||||
if (pi < args_len) {
|
||||
AirInstRef arg = arg_refs[pi];
|
||||
// For typed params, coerce arg to the param type.
|
||||
// Param extra: {name(u32), type(u32={body_len:31,
|
||||
// is_generic:1}), body_inst...}
|
||||
if (ptag == ZIR_INST_PARAM) {
|
||||
uint32_t param_pl = sema->code.inst_datas[
|
||||
param_body[p]]
|
||||
.pl_tok.payload_index;
|
||||
uint32_t type_raw
|
||||
= sema->code.extra[param_pl + 1];
|
||||
uint32_t type_body_len = type_raw & 0x7FFFFFFF;
|
||||
if (type_body_len >= 1) {
|
||||
// The type body contains ZIR instruction
|
||||
// indices. The last instruction should be a
|
||||
// break_inline whose operand is the type ref.
|
||||
uint32_t last_type_inst
|
||||
= sema->code
|
||||
.extra[param_pl + 2
|
||||
+ type_body_len - 1];
|
||||
if (last_type_inst < sema->code.inst_len
|
||||
&& sema->code.inst_tags[last_type_inst]
|
||||
== ZIR_INST_BREAK_INLINE) {
|
||||
ZirInstRef type_ref
|
||||
= sema->code.inst_datas
|
||||
[last_type_inst]
|
||||
.break_data.operand;
|
||||
if (type_ref < ZIR_REF_START_INDEX) {
|
||||
TypeIndex param_ty = type_ref;
|
||||
arg = semaCoerce(
|
||||
sema, block, param_ty, arg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
runtime_arg_refs[runtime_args_count++] = arg;
|
||||
}
|
||||
pi++;
|
||||
} else if (ptag == ZIR_INST_PARAM_COMPTIME
|
||||
|| ptag == ZIR_INST_PARAM_ANYTYPE_COMPTIME) {
|
||||
|
||||
@@ -132,18 +132,18 @@ const corpus_files = .{
|
||||
"../lib/compiler_rt/unordhf2.zig", // 341
|
||||
"../lib/compiler_rt/unordxf2.zig", // 341
|
||||
"../lib/std/crypto/pcurves/secp256k1/field.zig", // 343
|
||||
//"../lib/compiler_rt/divhf3.zig", // 344
|
||||
//"../lib/compiler_rt/floatdihf.zig", // 347
|
||||
//"../lib/compiler_rt/floatdixf.zig", // 347
|
||||
//"../lib/compiler_rt/floatsihf.zig", // 347
|
||||
//"../lib/compiler_rt/floatsixf.zig", // 347
|
||||
//"../lib/compiler_rt/fixunshfdi.zig", // 350
|
||||
//"../lib/compiler_rt/fixunshfsi.zig", // 350
|
||||
//"../lib/compiler_rt/fixunsxfdi.zig", // 350
|
||||
//"../lib/compiler_rt/fixunsxfsi.zig", // 350
|
||||
//"../lib/compiler_rt/floatundihf.zig", // 353
|
||||
//"../lib/compiler_rt/floatundixf.zig", // 353
|
||||
//"../lib/compiler_rt/floatunsixf.zig", // 353
|
||||
"../lib/compiler_rt/divhf3.zig", // 344
|
||||
"../lib/compiler_rt/floatdihf.zig", // 347
|
||||
"../lib/compiler_rt/floatdixf.zig", // 347
|
||||
"../lib/compiler_rt/floatsihf.zig", // 347
|
||||
"../lib/compiler_rt/floatsixf.zig", // 347
|
||||
"../lib/compiler_rt/fixunshfdi.zig", // 350
|
||||
"../lib/compiler_rt/fixunshfsi.zig", // 350
|
||||
"../lib/compiler_rt/fixunsxfdi.zig", // 350
|
||||
"../lib/compiler_rt/fixunsxfsi.zig", // 350
|
||||
"../lib/compiler_rt/floatundihf.zig", // 353
|
||||
"../lib/compiler_rt/floatundixf.zig", // 353
|
||||
"../lib/compiler_rt/floatunsixf.zig", // 353
|
||||
//"../lib/compiler_rt/truncxfhf2.zig", // 356
|
||||
//"../lib/compiler_rt/floatunsihf.zig", // 357
|
||||
//"../lib/compiler_rt/trunctfhf2.zig", // 359
|
||||
|
||||
Reference in New Issue
Block a user