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 73185a91ea..f83bac1e19 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 1f8a567f03..f0ef89d4e9 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, 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 def304bc6c..b17cb81fbf 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, 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 b17cb81fbf..ce0bb10953 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, 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 ce0bb10953..d57fac4c07 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), }; 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 d57fac4c07..c1714629bf 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. 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 c1714629bf..d73612e77b 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, 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 d73612e77b..762778af2b 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, 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 762778af2b..d02dbb0bcc 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, 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 d02dbb0bcc..c60c6fee97 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, 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 c60c6fee97..63bac88331 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, 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 63bac88331..75d5603f31 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), }; 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 75d5603f31..3cdbf88aaf 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),