Skip to content

support f128 arguments in riscv self-hosted backend #23375

@rootbeer

Description

@rootbeer

Zig Version

0.15.0-dev.131+3b25bf47d

Steps to Reproduce and Observed Behavior

Create a test.zig:

fn op(f: f128) u128 {
    return @bitCast(f);
}

pub fn main() !void {
    _ = op(1.0);
}

Compile with:

$ zig build-exe test.zig -target riscv64-linux-musl -fno-llvm

Get something like:

thread 1159684 panic: reached unreachable code
/home/pat/projects/ziglang/zig/src/arch/riscv64/abi.zig:152:13: 0x78ddecd in classifySystem (zig)
            unreachable; // support split float args
            ^
/home/pat/projects/ziglang/zig/src/arch/riscv64/CodeGen.zig:8301:64: 0x7d347ab in resolveCallingConventionValues (zig)
                const classes = mem.sliceTo(&abi.classifySystem(ty, zcu), .none);
                                                               ^
/home/pat/projects/ziglang/zig/src/arch/riscv64/CodeGen.zig:829:60: 0x7a2c554 in generate (zig)
    var call_info = function.resolveCallingConventionValues(fn_info, &.{}) catch |err| switch (err) {
                                                           ^
/home/pat/projects/ziglang/zig/src/codegen.zig:69:51: 0x76e59ff in generateFunction (zig)
            return importBackend(backend).generate(lf, pt, src_loc, func_index, air, liveness, code, debug_output);
                                                  ^
/home/pat/projects/ziglang/zig/src/link/Elf/ZigObject.zig:1440:33: 0x76e6212 in updateFunc (zig)
    try codegen.generateFunction(
                                ^
/home/pat/projects/ziglang/zig/src/link/Elf.zig:2380:44: 0x729cf27 in updateFunc (zig)
    return self.zigObjectPtr().?.updateFunc(self, pt, func_index, air, liveness);

The unreachable is:

        .float => {
            const target = zcu.getTarget();
            const features = target.cpu.features;

            const float_bits = ty.floatBits(zcu.getTarget());
            const float_reg_size: u32 = if (std.Target.riscv.featureSetHas(features, .d)) 64 else 32;
            if (float_bits <= float_reg_size) {
                result[0] = .float;
                return result;
            }
            unreachable; // support split float args
        },

In classifySystem.

Changing the f128 to f64 avoids the crash. As does inlining the code in main. Or dropping the -fno-llvm option. Or switching the targe to x86_64-linux-musl. The aarch64-linux-musl also crashes the compiler (different reason, I think?).

I ran into this on #23357 (see https://github.com/ziglang/zig/actions/runs/14071605497/job/39406816135?pr=23357). That PR has changes to isInf that caused the pre-existing "comptime fixed-width float non-zero divided by zero produces signed Inf" test in floatop.zig to start failing. Not clear to me why the existing code (which has an f128 @bitCast too) wasn't triggering this.

Expected Behavior

Compiles the code without crashing.

Metadata

Metadata

Assignees

No one assigned

    Labels

    arch-riscv6464-bit RISC-Vbackend-self-hostedbugObserved behavior contradicts documented or intended behavior

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions