From 0d164f9a25f05a2917f4e1d4eb21c85b3279b47b Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Mon, 11 Jul 2022 16:44:09 -0700 Subject: LLVM: broaden aarch64-windows f16 debug variable workaround LLVM does not properly handle debug info for f16 on the aarch64-windows target, causing "fatal error: unknown codeview register H1". The previous workaround checked only for f16 but was still vulnerable if a type was a byval struct or tuple which had an f16 field in it. Now I have filed an upstream issue (see https://github.com/llvm/llvm-project/issues/56484) and broadened the workaround to always skip debug values for this target. --- src/codegen/llvm.zig | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) (limited to 'src/codegen') diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig index 4275a1b69d..4333b34d98 100644 --- a/src/codegen/llvm.zig +++ b/src/codegen/llvm.zig @@ -5244,7 +5244,7 @@ pub const FuncGen = struct { const operand_ty = self.air.typeOf(pl_op.operand); const name = self.air.nullTerminatedString(pl_op.payload); - if (needDbgVarWorkaround(self.dg, operand_ty)) { + if (needDbgVarWorkaround(self.dg)) { return null; } @@ -6988,7 +6988,7 @@ pub const FuncGen = struct { const inst_ty = self.air.typeOfIndex(inst); if (self.dg.object.di_builder) |dib| { - if (needDbgVarWorkaround(self.dg, inst_ty)) { + if (needDbgVarWorkaround(self.dg)) { return arg_val; } @@ -9255,13 +9255,11 @@ const AnnotatedDITypePtr = enum(usize) { const lt_errors_fn_name = "__zig_lt_errors_len"; /// Without this workaround, LLVM crashes with "unknown codeview register H1" -/// TODO use llvm-reduce and file upstream LLVM bug for this. -fn needDbgVarWorkaround(dg: *DeclGen, ty: Type) bool { - if (ty.tag() == .f16) { - const target = dg.module.getTarget(); - if (target.os.tag == .windows and target.cpu.arch == .aarch64) { - return true; - } +/// https://github.com/llvm/llvm-project/issues/56484 +fn needDbgVarWorkaround(dg: *DeclGen) bool { + const target = dg.module.getTarget(); + if (target.os.tag == .windows and target.cpu.arch == .aarch64) { + return true; } return false; } -- cgit v1.2.3 From 8324a93f2e382036b3a923f4ac869cf0d80438a2 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Mon, 11 Jul 2022 18:41:59 -0700 Subject: LLVM: always add some clobbers for some architectures For some targets, Clang unconditionally adds some clobbers to all inline assembly. While this is probably not strictly necessary, if we don't follow Clang's lead here then we may risk tripping LLVM bugs since anything not used by Clang tends to be buggy and regress often. --- src/codegen/llvm.zig | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'src/codegen') diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig index 4333b34d98..8857c96bc1 100644 --- a/src/codegen/llvm.zig +++ b/src/codegen/llvm.zig @@ -5432,6 +5432,25 @@ pub const FuncGen = struct { total_i += 1; } } + + // For some targets, Clang unconditionally adds some clobbers to all inline assembly. + // While this is probably not strictly necessary, if we don't follow Clang's lead + // here then we may risk tripping LLVM bugs since anything not used by Clang tends + // to be buggy and regress often. + switch (target.cpu.arch) { + .x86_64, .i386 => { + if (total_i != 0) try llvm_constraints.append(self.gpa, ','); + try llvm_constraints.appendSlice(self.gpa, "~{dirflag},~{fpsr},~{flags}"); + total_i += 3; + }, + .mips, .mipsel, .mips64, .mips64el => { + if (total_i != 0) try llvm_constraints.append(self.gpa, ','); + try llvm_constraints.appendSlice(self.gpa, "~{$1}"); + total_i += 1; + }, + else => {}, + } + const asm_source = std.mem.sliceAsBytes(self.air.extra[extra_i..])[0..extra.data.source_len]; // hackety hacks until stage2 has proper inline asm in the frontend. -- cgit v1.2.3