Commit e19886a898

Andrew Kelley <andrew@ziglang.org>
2025-06-04 19:42:30
Compilation.Config: prefer_llvm depends on pie
1 parent d6b1ff7
Changed files (1)
src
Compilation
src/Compilation/Config.zig
@@ -191,95 +191,6 @@ pub fn resolve(options: Options) ResolveError!Config {
 
     const root_optimize_mode = options.root_optimize_mode orelse .Debug;
 
-    // Make a decision on whether to use LLVM backend for machine code generation.
-    // Note that using the LLVM backend does not necessarily mean using LLVM libraries.
-    // For example, Zig can emit .bc and .ll files directly, and this is still considered
-    // using "the LLVM backend".
-    const prefer_llvm = b: {
-        // If emitting to LLVM bitcode object format, must use LLVM backend.
-        if (options.emit_llvm_ir or options.emit_llvm_bc) {
-            if (options.use_llvm == false)
-                return error.EmittingLlvmModuleRequiresLlvmBackend;
-            if (!target_util.hasLlvmSupport(target, target.ofmt))
-                return error.LlvmLacksTargetSupport;
-
-            break :b true;
-        }
-
-        // If LLVM does not support the target, then we can't use it.
-        if (!target_util.hasLlvmSupport(target, target.ofmt)) {
-            if (options.use_llvm == true) return error.LlvmLacksTargetSupport;
-            break :b false;
-        }
-
-        // If Zig does not support the target, then we can't use it.
-        if (target_util.zigBackend(target, false) == .other) {
-            if (options.use_llvm == false) return error.ZigLacksTargetSupport;
-            break :b true;
-        }
-
-        if (options.use_llvm) |x| break :b x;
-
-        // If we cannot use LLVM libraries, then our own backends will be a
-        // better default since the LLVM backend can only produce bitcode
-        // and not an object file or executable.
-        if (!use_lib_llvm and options.emit_bin) break :b false;
-
-        // Prefer LLVM for release builds.
-        if (root_optimize_mode != .Debug) break :b true;
-
-        // At this point we would prefer to use our own self-hosted backend,
-        // because the compilation speed is better than LLVM. But only do it if
-        // we are confident in the robustness of the backend.
-        break :b !target_util.selfHostedBackendIsAsRobustAsLlvm(target);
-    };
-
-    const use_llvm = b: {
-        // If we have no zig code to compile, no need for LLVM.
-        if (!options.have_zcu) break :b false;
-
-        break :b prefer_llvm;
-    };
-
-    if (options.emit_bin and options.have_zcu) {
-        if (!use_lib_llvm and use_llvm) {
-            // Explicit request to use LLVM to produce an object file, but without
-            // using LLVM libraries. Impossible.
-            return error.EmittingBinaryRequiresLlvmLibrary;
-        }
-
-        if (target_util.zigBackend(target, use_llvm) == .other) {
-            // There is no compiler backend available for this target.
-            return error.ZigLacksTargetSupport;
-        }
-    }
-
-    // Make a decision on whether to use LLD or our own linker.
-    const use_lld = b: {
-        if (!target_util.hasLldSupport(target.ofmt)) {
-            if (options.use_lld == true) return error.LldIncompatibleObjectFormat;
-            break :b false;
-        }
-
-        if (!build_options.have_llvm) {
-            if (options.use_lld == true) return error.LldUnavailable;
-            break :b false;
-        }
-
-        if (options.lto != null and options.lto != .none) {
-            if (options.use_lld == false) return error.LtoRequiresLld;
-            break :b true;
-        }
-
-        if (options.use_llvm == false) {
-            if (options.use_lld == true) return error.LldCannotIncrementallyLink;
-            break :b false;
-        }
-
-        if (options.use_lld) |x| break :b x;
-        break :b prefer_llvm;
-    };
-
     // Make a decision on whether to use Clang or Aro for translate-c and compiling C files.
     const c_frontend: CFrontend = b: {
         if (!build_options.have_llvm) {
@@ -292,19 +203,6 @@ pub fn resolve(options: Options) ResolveError!Config {
         break :b .clang;
     };
 
-    const lto: std.zig.LtoMode = b: {
-        if (!use_lld) {
-            // zig ld LTO support is tracked by
-            // https://github.com/ziglang/zig/issues/8680
-            if (options.lto != null and options.lto != .none) return error.LtoRequiresLld;
-            break :b .none;
-        }
-
-        if (options.lto) |x| break :b x;
-
-        break :b .none;
-    };
-
     const link_libcpp = b: {
         if (options.link_libcpp == true) break :b true;
         if (options.any_sanitize_thread) {
@@ -447,6 +345,112 @@ pub fn resolve(options: Options) ResolveError!Config {
         } else false;
     };
 
+    // Make a decision on whether to use LLVM backend for machine code generation.
+    // Note that using the LLVM backend does not necessarily mean using LLVM libraries.
+    // For example, Zig can emit .bc and .ll files directly, and this is still considered
+    // using "the LLVM backend".
+    const prefer_llvm = b: {
+        // If emitting to LLVM bitcode object format, must use LLVM backend.
+        if (options.emit_llvm_ir or options.emit_llvm_bc) {
+            if (options.use_llvm == false)
+                return error.EmittingLlvmModuleRequiresLlvmBackend;
+            if (!target_util.hasLlvmSupport(target, target.ofmt))
+                return error.LlvmLacksTargetSupport;
+
+            break :b true;
+        }
+
+        // If LLVM does not support the target, then we can't use it.
+        if (!target_util.hasLlvmSupport(target, target.ofmt)) {
+            if (options.use_llvm == true) return error.LlvmLacksTargetSupport;
+            break :b false;
+        }
+
+        // If Zig does not support the target, then we can't use it.
+        if (target_util.zigBackend(target, false) == .other) {
+            if (options.use_llvm == false) return error.ZigLacksTargetSupport;
+            break :b true;
+        }
+
+        if (options.use_llvm) |x| break :b x;
+
+        // If we cannot use LLVM libraries, then our own backends will be a
+        // better default since the LLVM backend can only produce bitcode
+        // and not an object file or executable.
+        if (!use_lib_llvm and options.emit_bin) break :b false;
+
+        // Prefer LLVM for release builds.
+        if (root_optimize_mode != .Debug) break :b true;
+
+        // Self-hosted backends can't handle the inline assembly in std.pie yet
+        // https://github.com/ziglang/zig/issues/24046
+        if (pie) break :b true;
+
+        // At this point we would prefer to use our own self-hosted backend,
+        // because the compilation speed is better than LLVM. But only do it if
+        // we are confident in the robustness of the backend.
+        break :b !target_util.selfHostedBackendIsAsRobustAsLlvm(target);
+    };
+
+    const use_llvm = b: {
+        // If we have no zig code to compile, no need for LLVM.
+        if (!options.have_zcu) break :b false;
+
+        break :b prefer_llvm;
+    };
+
+    if (options.emit_bin and options.have_zcu) {
+        if (!use_lib_llvm and use_llvm) {
+            // Explicit request to use LLVM to produce an object file, but without
+            // using LLVM libraries. Impossible.
+            return error.EmittingBinaryRequiresLlvmLibrary;
+        }
+
+        if (target_util.zigBackend(target, use_llvm) == .other) {
+            // There is no compiler backend available for this target.
+            return error.ZigLacksTargetSupport;
+        }
+    }
+
+    // Make a decision on whether to use LLD or our own linker.
+    const use_lld = b: {
+        if (!target_util.hasLldSupport(target.ofmt)) {
+            if (options.use_lld == true) return error.LldIncompatibleObjectFormat;
+            break :b false;
+        }
+
+        if (!build_options.have_llvm) {
+            if (options.use_lld == true) return error.LldUnavailable;
+            break :b false;
+        }
+
+        if (options.lto != null and options.lto != .none) {
+            if (options.use_lld == false) return error.LtoRequiresLld;
+            break :b true;
+        }
+
+        if (options.use_llvm == false) {
+            if (options.use_lld == true) return error.LldCannotIncrementallyLink;
+            break :b false;
+        }
+
+        if (options.use_lld) |x| break :b x;
+        break :b prefer_llvm;
+    };
+
+    const lto: std.zig.LtoMode = b: {
+        if (!use_lld) {
+            // zig ld LTO support is tracked by
+            // https://github.com/ziglang/zig/issues/8680
+            if (options.lto != null and options.lto != .none) return error.LtoRequiresLld;
+            break :b .none;
+        }
+
+        if (options.lto) |x| break :b x;
+
+        break :b .none;
+    };
+
     const root_strip = b: {
         if (options.root_strip) |x| break :b x;
         if (root_optimize_mode == .ReleaseSmall) break :b true;