From 4b78dbe068445eb37cb28f2f8d1faf5836dc1175 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20R=C3=B8nne=20Petersen?= Date: Wed, 16 Oct 2024 06:07:13 +0200 Subject: [PATCH 01/12] Compilation: Omit Clang CPU model flags for some targets. --- src/Compilation.zig | 10 ++++++---- src/target.zig | 14 ++++++++++++++ 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/src/Compilation.zig b/src/Compilation.zig index 73185a91ea8ea178436ef58cb83dde0b97a9bb47..f83bac1e1998045b026336f05eee738656470b56 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -5371,10 +5371,12 @@ pub fn addCCArgs( try argv.append(include_dir); } - if (target.cpu.model.llvm_name) |llvm_name| { - try argv.appendSlice(&[_][]const u8{ - "-Xclang", "-target-cpu", "-Xclang", llvm_name, - }); + if (target_util.clangSupportsTargetCpuArg(target)) { + if (target.cpu.model.llvm_name) |llvm_name| { + try argv.appendSlice(&[_][]const u8{ + "-Xclang", "-target-cpu", "-Xclang", llvm_name, + }); + } } // It would be really nice if there was a more compact way to communicate this info to Clang. diff --git a/src/target.zig b/src/target.zig index 1f8a567f03c95f1f9268fd611c8507fae406e025..f0ef89d4e9baccd809edc2e924b41939aa25f9d2 100644 --- a/src/target.zig +++ b/src/target.zig @@ -315,6 +315,20 @@ pub fn clangAssemblerSupportsMcpuArg(target: std.Target) bool { }; } +/// Some experimental or poorly-maintained LLVM targets do not properly process CPU models in their +/// Clang driver code. For these, we should omit the `-Xclang -target-cpu -Xclang ` flags. +pub fn clangSupportsTargetCpuArg(target: std.Target) bool { + return switch (target.cpu.arch) { + .arc, + .msp430, + .ve, + .xcore, + .xtensa, + => false, + else => true, + }; +} + pub fn clangSupportsFloatAbiArg(target: std.Target) bool { return switch (target.cpu.arch) { .arm, -- 2.54.0 From 8282f3be960137e74c44827aea2436d3ff9fec30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20R=C3=B8nne=20Petersen?= Date: Thu, 17 Oct 2024 01:48:37 +0200 Subject: [PATCH 02/12] std.Target: Add doc comments for Cpu.Arch.generic() and baseline(). --- lib/std/Target.zig | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/lib/std/Target.zig b/lib/std/Target.zig index def304bc6c8496aa9e60a6f0aea8f4e4ccc6b1f1..b17cb81fbfb8beaa16dcb71393298b0218a321cf 100644 --- a/lib/std/Target.zig +++ b/lib/std/Target.zig @@ -1785,6 +1785,9 @@ pub const Cpu = struct { }; } + /// Returns the most bare-bones CPU model that is valid for `arch`. Note that this function + /// can return CPU models that are understood by LLVM, but *not* understood by Clang. If + /// Clang compatibility is important, consider using `baseline` instead. pub fn generic(arch: Arch) *const Model { const S = struct { const generic_model = Model{ @@ -1835,6 +1838,14 @@ pub const Cpu = struct { }; } + /// Returns a conservative CPU model for `arch` that is expected to be compatible with the + /// vast majority of hardware available. This function is guaranteed to return CPU models + /// that are understood by both LLVM and Clang, unlike `generic`. + /// + /// For certain `os` values, this function will additionally bump the baseline higher than + /// the baseline would be for `arch` in isolation; for example, for `aarch64-macos`, the + /// baseline is considered to be `apple_m1`. To avoid this behavior entirely, pass + /// `Os.Tag.freestanding`. pub fn baseline(arch: Arch, os: Os) *const Model { return switch (arch) { .arm, .armeb, .thumb, .thumbeb => &arm.cpu.baseline, -- 2.54.0 From 73b4cb6314690b179800a3959a5e94ae469fcc0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20R=C3=B8nne=20Petersen?= Date: Wed, 16 Oct 2024 05:59:13 +0200 Subject: [PATCH 03/12] std.Target: Use ck810 as the baseline CPU model for csky. --- lib/std/Target.zig | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/std/Target.zig b/lib/std/Target.zig index b17cb81fbfb8beaa16dcb71393298b0218a321cf..ce0bb10953a35dd601b0adb1849dad94feb4f8c4 100644 --- a/lib/std/Target.zig +++ b/lib/std/Target.zig @@ -1856,6 +1856,7 @@ pub const Cpu = struct { .watchos => &aarch64.cpu.apple_s4, else => generic(arch), }, + .csky => &csky.cpu.ck810, // gcc/clang do not have a generic csky model. .hexagon => &hexagon.cpu.hexagonv60, // gcc/clang do not have a generic hexagon model. .riscv32 => &riscv.cpu.baseline_rv32, .riscv64 => &riscv.cpu.baseline_rv64, -- 2.54.0 From c50fb583073ccae245fae9018e09ef0c2d2211c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20R=C3=B8nne=20Petersen?= Date: Wed, 16 Oct 2024 06:07:00 +0200 Subject: [PATCH 04/12] std.Target: Use v11 as the baseline CPU model for lanai. --- lib/std/Target.zig | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/std/Target.zig b/lib/std/Target.zig index ce0bb10953a35dd601b0adb1849dad94feb4f8c4..d57fac4c078df43247df149b7d2f788251b49b9c 100644 --- a/lib/std/Target.zig +++ b/lib/std/Target.zig @@ -1858,13 +1858,14 @@ pub const Cpu = struct { }, .csky => &csky.cpu.ck810, // gcc/clang do not have a generic csky model. .hexagon => &hexagon.cpu.hexagonv60, // gcc/clang do not have a generic hexagon model. + .lanai => &lanai.cpu.v11, // clang does not have a generic lanai model. + .loongarch64 => &loongarch.cpu.loongarch64, .riscv32 => &riscv.cpu.baseline_rv32, .riscv64 => &riscv.cpu.baseline_rv64, - .x86 => &x86.cpu.pentium4, .nvptx, .nvptx64 => &nvptx.cpu.sm_20, .s390x => &s390x.cpu.arch8, // gcc/clang do not have a generic s390x model. .sparc => &sparc.cpu.v9, // glibc does not work with 'plain' v8. - .loongarch64 => &loongarch.cpu.loongarch64, + .x86 => &x86.cpu.pentium4, else => generic(arch), }; -- 2.54.0 From 8062bdba9aa2dd5c4f63106a952df5d75c4f4ccb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20R=C3=B8nne=20Petersen?= Date: Thu, 17 Oct 2024 01:49:27 +0200 Subject: [PATCH 05/12] std.Target: Use avr1 as the generic CPU model for avr. avr2 remains the baseline CPU model. --- lib/std/Target.zig | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/std/Target.zig b/lib/std/Target.zig index d57fac4c078df43247df149b7d2f788251b49b9c..c1714629bf1c3d08cbb66465c91732aa16b3f66f 100644 --- a/lib/std/Target.zig +++ b/lib/std/Target.zig @@ -1800,7 +1800,7 @@ pub const Cpu = struct { .arc => &arc.cpu.generic, .arm, .armeb, .thumb, .thumbeb => &arm.cpu.generic, .aarch64, .aarch64_be => &aarch64.cpu.generic, - .avr => &avr.cpu.avr2, + .avr => &avr.cpu.avr1, .bpfel, .bpfeb => &bpf.cpu.generic, .csky => &csky.cpu.generic, .hexagon => &hexagon.cpu.generic, @@ -1856,6 +1856,7 @@ pub const Cpu = struct { .watchos => &aarch64.cpu.apple_s4, else => generic(arch), }, + .avr => &avr.cpu.avr2, .csky => &csky.cpu.ck810, // gcc/clang do not have a generic csky model. .hexagon => &hexagon.cpu.hexagonv60, // gcc/clang do not have a generic hexagon model. .lanai => &lanai.cpu.v11, // clang does not have a generic lanai model. -- 2.54.0 From 51dc4b05494e5b6ddf32ce38cca70b1af54b091d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20R=C3=B8nne=20Petersen?= Date: Thu, 17 Oct 2024 01:50:36 +0200 Subject: [PATCH 06/12] std.Target: Use ppc64 as the generic CPU model for powerpc64le. ppc64le remains the baseline CPU model. Note that there's nothing about little endian, 64-bit PowerPC that requires the features in the ppc64le model; the reason it exists is that 64-bit PowerPC wasn't really used in little endian mode prior to those features being commonplace. That makes the ppc64le model a good baseline model, but not the right choice for a generic model. --- lib/std/Target.zig | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/lib/std/Target.zig b/lib/std/Target.zig index c1714629bf1c3d08cbb66465c91732aa16b3f66f..d73612e77bda29a5a11443c520fce9d6f0e7ace2 100644 --- a/lib/std/Target.zig +++ b/lib/std/Target.zig @@ -1811,10 +1811,8 @@ pub const Cpu = struct { .mips, .mipsel => &mips.cpu.mips32, .mips64, .mips64el => &mips.cpu.mips64, .msp430 => &msp430.cpu.generic, - .powerpc => &powerpc.cpu.ppc, - .powerpcle => &powerpc.cpu.ppc, - .powerpc64 => &powerpc.cpu.ppc64, - .powerpc64le => &powerpc.cpu.ppc64le, + .powerpc, .powerpcle => &powerpc.cpu.ppc, + .powerpc64, .powerpc64le => &powerpc.cpu.ppc64, .propeller1 => &propeller.cpu.generic, .propeller2 => &propeller.cpu.generic, .amdgcn => &amdgpu.cpu.generic, @@ -1861,6 +1859,7 @@ pub const Cpu = struct { .hexagon => &hexagon.cpu.hexagonv60, // gcc/clang do not have a generic hexagon model. .lanai => &lanai.cpu.v11, // clang does not have a generic lanai model. .loongarch64 => &loongarch.cpu.loongarch64, + .powerpc64le => &powerpc.cpu.ppc64le, .riscv32 => &riscv.cpu.baseline_rv32, .riscv64 => &riscv.cpu.baseline_rv64, .nvptx, .nvptx64 => &nvptx.cpu.sm_20, -- 2.54.0 From 5b7eba95bae1a954b7737aec301280cc4a63b677 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20R=C3=B8nne=20Petersen?= Date: Thu, 17 Oct 2024 01:54:10 +0200 Subject: [PATCH 07/12] std.Target: Use gfx600 as the generic CPU model for amdgcn. This is the first model that was actually in the GCN family. --- lib/std/Target.zig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/std/Target.zig b/lib/std/Target.zig index d73612e77bda29a5a11443c520fce9d6f0e7ace2..762778af2b47bf3d64dbade6665cce06ff4ac1d7 100644 --- a/lib/std/Target.zig +++ b/lib/std/Target.zig @@ -1797,6 +1797,7 @@ pub const Cpu = struct { }; }; return switch (arch) { + .amdgcn => &amdgpu.cpu.gfx600, .arc => &arc.cpu.generic, .arm, .armeb, .thumb, .thumbeb => &arm.cpu.generic, .aarch64, .aarch64_be => &aarch64.cpu.generic, @@ -1815,7 +1816,6 @@ pub const Cpu = struct { .powerpc64, .powerpc64le => &powerpc.cpu.ppc64, .propeller1 => &propeller.cpu.generic, .propeller2 => &propeller.cpu.generic, - .amdgcn => &amdgpu.cpu.generic, .riscv32 => &riscv.cpu.generic_rv32, .riscv64 => &riscv.cpu.generic_rv64, .spirv, .spirv32, .spirv64 => &spirv.cpu.generic, -- 2.54.0 From 2d22cc9f61ea2a721b16417e9b8acfcf32067818 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20R=C3=B8nne=20Petersen?= Date: Thu, 17 Oct 2024 01:56:22 +0200 Subject: [PATCH 08/12] std.Target: Use gfx906 as the baseline CPU model for amdgcn. This matches Clang's default. --- lib/std/Target.zig | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/std/Target.zig b/lib/std/Target.zig index 762778af2b47bf3d64dbade6665cce06ff4ac1d7..d02dbb0bcc556f1ace6ae5c092cc172b6fa92e8c 100644 --- a/lib/std/Target.zig +++ b/lib/std/Target.zig @@ -1846,6 +1846,7 @@ pub const Cpu = struct { /// `Os.Tag.freestanding`. pub fn baseline(arch: Arch, os: Os) *const Model { return switch (arch) { + .amdgcn => &amdgpu.cpu.gfx906, .arm, .armeb, .thumb, .thumbeb => &arm.cpu.baseline, .aarch64 => switch (os.tag) { .bridgeos, .driverkit, .macos => &aarch64.cpu.apple_m1, -- 2.54.0 From 385f586605aaf8abe303bf64f9c40209088e874e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20R=C3=B8nne=20Petersen?= Date: Thu, 17 Oct 2024 01:57:10 +0200 Subject: [PATCH 09/12] std.Target: Use sm_52 as the baseline CPU model for nvptx. This matches Clang's default. --- lib/std/Target.zig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/std/Target.zig b/lib/std/Target.zig index d02dbb0bcc556f1ace6ae5c092cc172b6fa92e8c..c60c6fee971ebaa96257b5476887b46c0a7b9e59 100644 --- a/lib/std/Target.zig +++ b/lib/std/Target.zig @@ -1860,10 +1860,10 @@ pub const Cpu = struct { .hexagon => &hexagon.cpu.hexagonv60, // gcc/clang do not have a generic hexagon model. .lanai => &lanai.cpu.v11, // clang does not have a generic lanai model. .loongarch64 => &loongarch.cpu.loongarch64, + .nvptx, .nvptx64 => &nvptx.cpu.sm_52, .powerpc64le => &powerpc.cpu.ppc64le, .riscv32 => &riscv.cpu.baseline_rv32, .riscv64 => &riscv.cpu.baseline_rv64, - .nvptx, .nvptx64 => &nvptx.cpu.sm_20, .s390x => &s390x.cpu.arch8, // gcc/clang do not have a generic s390x model. .sparc => &sparc.cpu.v9, // glibc does not work with 'plain' v8. .x86 => &x86.cpu.pentium4, -- 2.54.0 From e26b64a87dd4170a46aec317e958ee617bc26e8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20R=C3=B8nne=20Petersen?= Date: Thu, 17 Oct 2024 01:59:53 +0200 Subject: [PATCH 10/12] std.Target: Use mips32r2/mips64r2 as the baseline CPU models for mips/mips64. This matches Clang's defaults. That also means these CPU models tend to get more testing, so they're a safer baseline choice. Anecdotally, the oldest MIPS hardware that I've seen anyone run Zig on was also r2. --- lib/std/Target.zig | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/std/Target.zig b/lib/std/Target.zig index c60c6fee971ebaa96257b5476887b46c0a7b9e59..63bac883311bc406c9309ed37fe12382ea667b0f 100644 --- a/lib/std/Target.zig +++ b/lib/std/Target.zig @@ -1860,6 +1860,8 @@ pub const Cpu = struct { .hexagon => &hexagon.cpu.hexagonv60, // gcc/clang do not have a generic hexagon model. .lanai => &lanai.cpu.v11, // clang does not have a generic lanai model. .loongarch64 => &loongarch.cpu.loongarch64, + .mips, .mipsel => &mips.cpu.mips32r2, + .mips64, .mips64el => &mips.cpu.mips64r2, .nvptx, .nvptx64 => &nvptx.cpu.sm_52, .powerpc64le => &powerpc.cpu.ppc64le, .riscv32 => &riscv.cpu.baseline_rv32, -- 2.54.0 From ea987faa85ea57db89167a220853e0c0936c7d43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20R=C3=B8nne=20Petersen?= Date: Thu, 17 Oct 2024 02:03:02 +0200 Subject: [PATCH 11/12] std.Target: Use explicit baseline CPU models for bpf, m68k, msp430, and xcore. This makes no difference presently, but if LLVM ever starts modeling features for these, we would not get them by default for our baseline if we use the generic model. --- lib/std/Target.zig | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/std/Target.zig b/lib/std/Target.zig index 63bac883311bc406c9309ed37fe12382ea667b0f..75d5603f310a2abe3730b23c7219f3046c8fd933 100644 --- a/lib/std/Target.zig +++ b/lib/std/Target.zig @@ -1856,12 +1856,15 @@ pub const Cpu = struct { else => generic(arch), }, .avr => &avr.cpu.avr2, + .bpfel, .bpfeb => &bpf.cpu.v1, .csky => &csky.cpu.ck810, // gcc/clang do not have a generic csky model. .hexagon => &hexagon.cpu.hexagonv60, // gcc/clang do not have a generic hexagon model. .lanai => &lanai.cpu.v11, // clang does not have a generic lanai model. .loongarch64 => &loongarch.cpu.loongarch64, + .m68k => &m68k.cpu.M68000, .mips, .mipsel => &mips.cpu.mips32r2, .mips64, .mips64el => &mips.cpu.mips64r2, + .msp430 => &msp430.cpu.msp430, .nvptx, .nvptx64 => &nvptx.cpu.sm_52, .powerpc64le => &powerpc.cpu.ppc64le, .riscv32 => &riscv.cpu.baseline_rv32, @@ -1869,6 +1872,7 @@ pub const Cpu = struct { .s390x => &s390x.cpu.arch8, // gcc/clang do not have a generic s390x model. .sparc => &sparc.cpu.v9, // glibc does not work with 'plain' v8. .x86 => &x86.cpu.pentium4, + .xcore => &xcore.cpu.xs1b_generic, else => generic(arch), }; -- 2.54.0 From 79717740bdce162caa34936040cd774dbe4c15a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20R=C3=B8nne=20Petersen?= Date: Thu, 17 Oct 2024 02:05:37 +0200 Subject: [PATCH 12/12] std.Target: Pick better baseline CPU models for darwin and ps4/ps5 on x86_64. These are sourced from getX86TargetCPU() in Clang. --- lib/std/Target.zig | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/lib/std/Target.zig b/lib/std/Target.zig index 75d5603f310a2abe3730b23c7219f3046c8fd933..3cdbf88aaf9e19bf4b6bb2406ec999b55ccf6b69 100644 --- a/lib/std/Target.zig +++ b/lib/std/Target.zig @@ -1872,6 +1872,13 @@ pub const Cpu = struct { .s390x => &s390x.cpu.arch8, // gcc/clang do not have a generic s390x model. .sparc => &sparc.cpu.v9, // glibc does not work with 'plain' v8. .x86 => &x86.cpu.pentium4, + .x86_64 => switch (os.tag) { + .driverkit => &x86.cpu.nehalem, + .ios, .macos, .tvos, .visionos, .watchos => &x86.cpu.core2, + .ps4 => &x86.cpu.btver2, + .ps5 => &x86.cpu.znver2, + else => generic(arch), + }, .xcore => &xcore.cpu.xs1b_generic, else => generic(arch), -- 2.54.0