Commit 9b45dc1608

Jacob Young <jacobly0@users.noreply.github.com>
2022-10-14 12:29:24
stage2: fix emitting asm and bin at the same time
This logic is copied from stage1. Fixes #12800
1 parent cb257d5
Changed files (4)
src
codegen
test
standalone
emit_asm_and_bin
src/codegen/llvm.zig
@@ -780,7 +780,7 @@ pub const Object = struct {
             null;
 
         const emit_asm_path = try locPath(arena, comp.emit_asm, cache_dir);
-        const emit_llvm_ir_path = try locPath(arena, comp.emit_llvm_ir, cache_dir);
+        var emit_llvm_ir_path = try locPath(arena, comp.emit_llvm_ir, cache_dir);
         const emit_llvm_bc_path = try locPath(arena, comp.emit_llvm_bc, cache_dir);
 
         const emit_asm_msg = emit_asm_path orelse "(none)";
@@ -791,7 +791,34 @@ pub const Object = struct {
             emit_asm_msg, emit_bin_msg, emit_llvm_ir_msg, emit_llvm_bc_msg,
         });
 
+        // Unfortunately, LLVM shits the bed when we ask for both binary and assembly.
+        // So we call the entire pipeline multiple times if this is requested.
         var error_message: [*:0]const u8 = undefined;
+        if (emit_asm_path != null and emit_bin_path != null) {
+            if (self.target_machine.emitToFile(
+                self.llvm_module,
+                &error_message,
+                comp.bin_file.options.optimize_mode == .Debug,
+                comp.bin_file.options.optimize_mode == .ReleaseSmall,
+                comp.time_report,
+                comp.bin_file.options.tsan,
+                comp.bin_file.options.lto,
+                null,
+                emit_bin_path,
+                emit_llvm_ir_path,
+                null,
+            )) {
+                defer llvm.disposeMessage(error_message);
+
+                log.err("LLVM failed to emit bin={s} ir={s}: {s}", .{
+                    emit_bin_msg, emit_llvm_ir_msg, error_message,
+                });
+                return error.FailedToEmit;
+            }
+            emit_bin_path = null;
+            emit_llvm_ir_path = null;
+        }
+
         if (self.target_machine.emitToFile(
             self.llvm_module,
             &error_message,
test/standalone/emit_asm_and_bin/build.zig
@@ -0,0 +1,11 @@
+const Builder = @import("std").build.Builder;
+
+pub fn build(b: *Builder) void {
+    const main = b.addTest("main.zig");
+    main.setBuildMode(b.standardReleaseOptions());
+    main.emit_asm = .{ .emit_to = b.pathFromRoot("main.s") };
+    main.emit_bin = .{ .emit_to = b.pathFromRoot("main") };
+
+    const test_step = b.step("test", "Run test");
+    test_step.dependOn(&main.step);
+}
test/standalone/emit_asm_and_bin/main.zig
@@ -0,0 +1,1 @@
+pub fn main() void {}
test/standalone.zig
@@ -99,4 +99,5 @@ pub fn addCases(cases: *tests.StandaloneContext) void {
     //cases.add("tools/update_spirv_features.zig");
 
     cases.addBuildFile("test/standalone/issue_13030/build.zig", .{ .build_modes = true });
+    cases.addBuildFile("test/standalone/emit_asm_and_bin/build.zig", .{});
 }