Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot compile on x86_64 with SSE/SSE2 disabled #7285

Closed
BinaryWarlock opened this issue Dec 3, 2020 · 6 comments
Closed

Cannot compile on x86_64 with SSE/SSE2 disabled #7285

BinaryWarlock opened this issue Dec 3, 2020 · 6 comments
Milestone

Comments

@BinaryWarlock
Copy link

I'm trying to disable SSE/SSE2/MMX for a freestanding x86_64 target, but it fails.

test.zig:

pub fn main() void { }
$ zig build-exe -mcpu=x86_64-sse-sse2 test.zig 
error: extendXfYf2.zig:23:5: in function __gnu_h2f_ieee float (i16): SSE register return with SSE disabled

In addition, if you don't include -sse:

$ zig build-exe -mcpu=x86_64-sse2 test.zig 
LLVM ERROR: Access past stack top!
Aborted (core dumped)

I expected there to be something like GCC/Clang's -mno-sse to disable emitting SSE code.

Perhaps the compiler_rt should test for the SSE feature set on x86_64 too?

Any tips for getting this to work?

@xackus
Copy link
Contributor

xackus commented Dec 3, 2020

According to Wikipedia:

The original AMD64 architecture adopted Intel's SSE and SSE2 as core instructions.

@FireFox317
Copy link
Contributor

Could you trying specifying a -target? Currently you did not do that so Zig will take advantage of all the powers that your own cpu has.

@BinaryWarlock
Copy link
Author

BinaryWarlock commented Dec 3, 2020

Sure, it doesn't change the output:

$ zig build-exe -target x86_64-freestanding -mcpu=x86_64-sse-sse2 test.zig 
error: extendXfYf2.zig:23:5: in function __gnu_h2f_ieee float (i16): SSE register return with SSE disabled

@xackus
x86_64 does indeed require SSE/SSE2, however the Zig compiler should support disabling generating SSE/SSE2 code.

A core use case for this (and the one I'm running into) is OS kernels, who generally want to avoid preserving SIMD registers for performance reasons. It's also easier to read the (dis)assembly without them, IMHO, when debugging.

C supports this use case pretty well by compilers offering -mno-sse / -mno-sse2.

@LemonBoy
Copy link
Contributor

LemonBoy commented Dec 3, 2020

Some parts of the standard runtime, such as compiler-rt.zig and c.zig, require some kind of support for floating point types.
Using -mcpu=x86_64-sse-sse2+soft_float should solve your problem.

C supports this use case pretty well by compilers offering -mno-sse / -mno-sse2.

But they don't rebuild the libgcc/compiler-rt objects with those flags, that's why they "work".

@BinaryWarlock
Copy link
Author

Cheers @LemonBoy, that seems to work fine. I feel like this should be documented somewhere, or perhaps give an error saying what you did (the runtime requires some kind of float support).

Thanks, besides that I don't think this is an issue.

@andrewrk andrewrk added this to the 0.8.0 milestone Jan 3, 2021
@cdecompilador
Copy link

I suggest reopening this issue as this still fails with float support on windows.

Here is the command:

zig build-exe -femit-asm=output.s -target x86_64-windows-gnu -mcpu=x86_64-sse-sse2+soft_float src/main.zig

And here is the error:

error: lld-link: undefined symbol: __gnu_h2f_ieee
    note: referenced by compiler_rt.lib(compiler_rt.lib.obj):(math.ldexp.ldexp__anon_3705)
    note: referenced by compiler_rt.lib(compiler_rt.lib.obj):(.weak.__subhf3.default._alloca)
    note: referenced by compiler_rt.lib(compiler_rt.lib.obj):(.weak.__subhf3.default._alloca)
    note: referenced 107 more times
error: lld-link: undefined symbol: __gnu_f2h_ieee
    note: referenced by compiler_rt.lib(compiler_rt.lib.obj):(.weak.__subhf3.default._alloca)
    note: referenced by compiler_rt.lib(compiler_rt.lib.obj):(.weak.__divhf3.default._alloca)
    note: referenced by compiler_rt.lib(compiler_rt.lib.obj):(.weak.__powihf2.default._alloca)
    note: referenced 63 more times

And if I remove either the -sse or -sse2 it fails silently without producing any executable, doing it with a build.zig it fails sometimes and other it use sse/sse2 :( here is the build.zig

const std = @import("std");
const print = std.debug.print;
const CrossTarget = std.zig.CrossTarget;

pub fn build(b: *std.Build) !void {
    // Create target and optimize level
    var target = b.standardTargetOptions(.{});
    var features = (try CrossTarget.parse(.{
        .arch_os_abi = "x86_64-windows-gnu",
        .cpu_features = "baseline-sse-sse2+soft_float",
    })).getCpuFeatures();
    target.updateCpuFeatures(&features);
    const optimize = b.standardOptimizeOption(.{});

    // Create executable
    const exe = b.addExecutable(.{
        .name = "benching",
        // In this case the main source file is merely a path, however, in more
        // complicated build scripts, this could be a generated file.
        .root_source_file = .{ .path = "src/main.zig" },
        .target = target,
        .optimize = optimize,
    });
    
    // For checking no sse/sse2
    exe.emit_asm = .{ .emit_to = "output.s" };

    // Avoid windows bug
    if (optimize == std.builtin.OptimizeMode.ReleaseSmall) exe.strip = false;

    // Make executable and its run command
    exe.install();
    const run_cmd = exe.run();
    run_cmd.step.dependOn(b.getInstallStep());
    const run_step = b.step("run", "Launch");
    run_step.dependOn(&run_cmd.step);

    // Allow passing args to function
    if (b.args) |args| {
        run_cmd.addArgs(args);
    }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants