authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-01-21 22:01:24-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-01-21 22:02:13-05:00
logcbe9a51518db6f4e77a4f8c72e8cd9cd02fa7f49
tree9efdeb5bcc24f2cbafec863ee422eede660b2c7c
parent830e0ba2d27b55f999a891d007b24131b790e8c9
signaturelock-open Commit is signed but in an unrecognized format.

don't trust llvm's GetHostCPUName

comment from this commit reproduced here: I have observed the CPU name reported by LLVM being incorrect. On the SourceHut build services, LLVM 9.0 reports the CPU as "athlon-xp", which is a 32-bit CPU, even though the system is 64-bit and the reported CPU features include, among other things, +64bit. So the strategy taken here is that we observe both reported CPU, and the reported CPU features. The features are trusted more; but if the features match exactly the features of the reported CPU, then we trust the reported CPU.

2 files changed, 35 insertions(+), 12 deletions(-)

lib/std/target.zig+4
......@@ -637,6 +637,10 @@ pub const Target = union(enum) {
637637 pub fn asBytes(set: *const Set) *const [byte_count]u8 {
638638 return @ptrCast(*const [byte_count]u8, &set.ints);
639639 }
640
641 pub fn eql(set: Set, other: Set) bool {
642 return mem.eql(usize, &set.ints, &other.ints);
643 }
640644 };
641645
642646 pub fn feature_set_fns(comptime F: type) type {
src-self-hosted/stage1.zig+31-12
......@@ -540,27 +540,25 @@ export fn stage2_progress_update_node(node: *std.Progress.Node, done_count: usiz
540540 node.context.maybeRefresh();
541541}
542542
543/// I have observed the CPU name reported by LLVM being incorrect. On
544/// the SourceHut build services, LLVM 9.0 reports the CPU as "athlon-xp",
545/// which is a 32-bit CPU, even though the system is 64-bit and the reported
546/// CPU features include, among other things, +64bit.
547/// So the strategy taken here is that we observe both reported CPU, and the
548/// reported CPU features. The features are trusted more; but if the features
549/// match exactly the features of the reported CPU, then we trust the reported CPU.
543550fn cpuFeaturesFromLLVM(
544551 arch: Target.Arch,
545552 llvm_cpu_name_z: ?[*:0]const u8,
546553 llvm_cpu_features_opt: ?[*:0]const u8,
547554) !Target.CpuFeatures {
548 if (llvm_cpu_name_z) |cpu_name_z| {
549 const llvm_cpu_name = mem.toSliceConst(u8, cpu_name_z);
550
551 for (arch.allCpus()) |cpu| {
552 const this_llvm_name = cpu.llvm_name orelse continue;
553 if (mem.eql(u8, this_llvm_name, llvm_cpu_name)) {
554 return Target.CpuFeatures{ .cpu = cpu };
555 }
556 }
557 }
558
559555 var set = arch.baselineFeatures();
560556 const llvm_cpu_features = llvm_cpu_features_opt orelse return Target.CpuFeatures{
561557 .features = set,
562558 };
563559
560 const all_features = arch.allFeaturesList();
561
564562 var it = mem.tokenize(mem.toSliceConst(u8, llvm_cpu_features), ",");
565563 while (it.next()) |decorated_llvm_feat| {
566564 var op: enum {
......@@ -577,7 +575,7 @@ fn cpuFeaturesFromLLVM(
577575 } else {
578576 return error.InvalidLlvmCpuFeaturesFormat;
579577 }
580 for (arch.allFeaturesList()) |feature, index| {
578 for (all_features) |feature, index| {
581579 const this_llvm_name = feature.llvm_name orelse continue;
582580 if (mem.eql(u8, llvm_feat, this_llvm_name)) {
583581 switch (op) {
......@@ -588,6 +586,27 @@ fn cpuFeaturesFromLLVM(
588586 }
589587 }
590588 }
589
590 if (llvm_cpu_name_z) |cpu_name_z| {
591 const llvm_cpu_name = mem.toSliceConst(u8, cpu_name_z);
592
593 for (arch.allCpus()) |cpu| {
594 const this_llvm_name = cpu.llvm_name orelse continue;
595 if (mem.eql(u8, this_llvm_name, llvm_cpu_name)) {
596 // Only trust the CPU if the reported features exactly match.
597 var populated_reported_features = set;
598 populated_reported_features.populateDependencies(all_features);
599 var populated_cpu_features = cpu.features;
600 populated_cpu_features.populateDependencies(all_features);
601 if (populated_reported_features.eql(populated_cpu_features)) {
602 return Target.CpuFeatures{ .cpu = cpu };
603 } else {
604 return Target.CpuFeatures{ .features = set };
605 }
606 }
607 }
608 }
609
591610 return Target.CpuFeatures{ .features = set };
592611}
593612