Commit 13541bc1c0

Ali Cheraghi <alichraghi@proton.me>
2025-04-19 19:03:03
Module: ignore `xnack` and `sramecc` features on some gpu models
1 parent f01833e
Changed files (3)
src/Package/Module.zig
@@ -335,6 +335,10 @@ pub fn create(arena: Allocator, options: CreateOptions) !*Package.Module {
         // Append disabled features after enabled ones, so that their effects aren't overwritten.
         for (target.cpu.arch.allFeaturesList()) |feature| {
             if (feature.llvm_name) |llvm_name| {
+                // Ignore these until we figure out how to handle the concept of omitting features.
+                // See https://github.com/ziglang/zig/issues/23539
+                if (target_util.isDynamicAMDGCNFeature(target, feature)) continue;
+
                 const is_enabled = target.cpu.features.isEnabled(feature.index);
 
                 if (is_enabled) {
src/Compilation.zig
@@ -5989,6 +5989,10 @@ pub fn addCCArgs(
                         std.mem.startsWith(u8, llvm_name, "hard-float"))
                         continue;
 
+                    // Ignore these until we figure out how to handle the concept of omitting features.
+                    // See https://github.com/ziglang/zig/issues/23539
+                    if (target_util.isDynamicAMDGCNFeature(target, feature)) continue;
+
                     argv.appendSliceAssumeCapacity(&[_][]const u8{ "-Xclang", "-target-feature", "-Xclang" });
                     const plus_or_minus = "-+"[@intFromBool(is_enabled)];
                     const arg = try std.fmt.allocPrint(arena, "{c}{s}", .{ plus_or_minus, llvm_name });
src/target.zig
@@ -486,6 +486,54 @@ pub fn arePointersLogical(target: std.Target, as: AddressSpace) bool {
     };
 }
 
+pub fn isDynamicAMDGCNFeature(target: std.Target, feature: std.Target.Cpu.Feature) bool {
+    if (target.cpu.arch != .amdgcn) return false;
+
+    const sramecc_only = &[_]*const std.Target.Cpu.Model{
+        &std.Target.amdgcn.cpu.gfx1010,
+        &std.Target.amdgcn.cpu.gfx1011,
+        &std.Target.amdgcn.cpu.gfx1012,
+        &std.Target.amdgcn.cpu.gfx1013,
+    };
+    const xnack_or_sramecc = &[_]*const std.Target.Cpu.Model{
+        &std.Target.amdgcn.cpu.gfx1030,
+        &std.Target.amdgcn.cpu.gfx1031,
+        &std.Target.amdgcn.cpu.gfx1032,
+        &std.Target.amdgcn.cpu.gfx1033,
+        &std.Target.amdgcn.cpu.gfx1034,
+        &std.Target.amdgcn.cpu.gfx1035,
+        &std.Target.amdgcn.cpu.gfx1036,
+        &std.Target.amdgcn.cpu.gfx1100,
+        &std.Target.amdgcn.cpu.gfx1101,
+        &std.Target.amdgcn.cpu.gfx1102,
+        &std.Target.amdgcn.cpu.gfx1103,
+        &std.Target.amdgcn.cpu.gfx1150,
+        &std.Target.amdgcn.cpu.gfx1151,
+        &std.Target.amdgcn.cpu.gfx1152,
+        &std.Target.amdgcn.cpu.gfx1153,
+        &std.Target.amdgcn.cpu.gfx1200,
+        &std.Target.amdgcn.cpu.gfx1201,
+    };
+    const feature_tag: std.Target.amdgcn.Feature = @enumFromInt(feature.index);
+
+    if (feature_tag == .sramecc) {
+        if (std.mem.indexOfScalar(
+            *const std.Target.Cpu.Model,
+            sramecc_only ++ xnack_or_sramecc,
+            target.cpu.model,
+        )) |_| return true;
+    }
+    if (feature_tag == .xnack) {
+        if (std.mem.indexOfScalar(
+            *const std.Target.Cpu.Model,
+            xnack_or_sramecc,
+            target.cpu.model,
+        )) |_| return true;
+    }
+
+    return false;
+}
+
 pub fn llvmMachineAbi(target: std.Target) ?[:0]const u8 {
     // LLD does not support ELFv1. Rather than having LLVM produce ELFv1 code and then linking it
     // into a broken ELFv2 binary, just force LLVM to use ELFv2 as well. This will break when glibc