aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Sema.zig4
-rw-r--r--src/codegen/llvm.zig35
-rw-r--r--src/zig_llvm.cpp1
3 files changed, 30 insertions, 10 deletions
diff --git a/src/Sema.zig b/src/Sema.zig
index f7d8aef12d..550f51d7c5 100644
--- a/src/Sema.zig
+++ b/src/Sema.zig
@@ -7096,6 +7096,7 @@ fn funcCommon(
if (param.ty.tag() == .generic_poison) is_generic = true;
}
+ var destroy_fn_on_error = false;
const new_func: *Module.Fn = new_func: {
if (!has_body) break :new_func undefined;
if (sema.comptime_args_fn_inst == func_inst) {
@@ -7103,9 +7104,10 @@ fn funcCommon(
sema.preallocated_new_func = null; // take ownership
break :new_func new_func;
}
+ destroy_fn_on_error = true;
break :new_func try sema.gpa.create(Module.Fn);
};
- errdefer if (has_body) sema.gpa.destroy(new_func);
+ errdefer if (destroy_fn_on_error) sema.gpa.destroy(new_func);
var maybe_inferred_error_set_node: ?*Module.Fn.InferredErrorSetListNode = null;
errdefer if (maybe_inferred_error_set_node) |node| sema.gpa.destroy(node);
diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig
index 4275a1b69d..8857c96bc1 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;
}
@@ -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.
@@ -6988,7 +7007,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 +9274,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;
}
diff --git a/src/zig_llvm.cpp b/src/zig_llvm.cpp
index abb1eb0a99..52c202fded 100644
--- a/src/zig_llvm.cpp
+++ b/src/zig_llvm.cpp
@@ -1134,6 +1134,7 @@ void ZigLLVMAddModuleDebugInfoFlag(LLVMModuleRef module) {
}
void ZigLLVMAddModuleCodeViewFlag(LLVMModuleRef module) {
+ unwrap(module)->addModuleFlag(Module::Warning, "Debug Info Version", DEBUG_METADATA_VERSION);
unwrap(module)->addModuleFlag(Module::Warning, "CodeView", 1);
}