aboutsummaryrefslogtreecommitdiff
path: root/src/codegen/llvm.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/codegen/llvm.zig')
-rw-r--r--src/codegen/llvm.zig52
1 files changed, 47 insertions, 5 deletions
diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig
index 0da0ef18e2..a629624c58 100644
--- a/src/codegen/llvm.zig
+++ b/src/codegen/llvm.zig
@@ -988,6 +988,25 @@ pub const Object = struct {
args.appendAssumeCapacity(load_inst);
}
},
+ .byref_mut => {
+ const param_ty = fn_info.param_types[it.zig_index - 1];
+ const param_llvm_ty = try dg.lowerType(param_ty);
+ const param = llvm_func.getParam(llvm_arg_i);
+ const alignment = param_ty.abiAlignment(target);
+
+ dg.addArgAttr(llvm_func, llvm_arg_i, "noundef");
+ llvm_arg_i += 1;
+
+ try args.ensureUnusedCapacity(1);
+
+ if (isByRef(param_ty)) {
+ args.appendAssumeCapacity(param);
+ } else {
+ const load_inst = builder.buildLoad(param_llvm_ty, param, "");
+ load_inst.setAlignment(alignment);
+ args.appendAssumeCapacity(load_inst);
+ }
+ },
.abi_sized_int => {
assert(!it.byval_attr);
const param_ty = fn_info.param_types[it.zig_index - 1];
@@ -2583,6 +2602,9 @@ pub const DeclGen = struct {
const alignment = param_ty.abiAlignment(target);
dg.addByRefParamAttrs(llvm_fn, it.llvm_index - 1, alignment, it.byval_attr, param_llvm_ty);
},
+ .byref_mut => {
+ dg.addArgAttr(llvm_fn, it.llvm_index - 1, "noundef");
+ },
// No attributes needed for these.
.no_bits,
.abi_sized_int,
@@ -3101,7 +3123,7 @@ pub const DeclGen = struct {
const param_ty = fn_info.param_types[it.zig_index - 1];
try llvm_params.append(try dg.lowerType(param_ty));
},
- .byref => {
+ .byref, .byref_mut => {
const param_ty = fn_info.param_types[it.zig_index - 1];
const raw_llvm_ty = try dg.lowerType(param_ty);
try llvm_params.append(raw_llvm_ty.pointerType(0));
@@ -4726,6 +4748,27 @@ pub const FuncGen = struct {
try llvm_args.append(arg_ptr);
}
},
+ .byref_mut => {
+ const arg = args[it.zig_index - 1];
+ const param_ty = self.air.typeOf(arg);
+ const llvm_arg = try self.resolveInst(arg);
+
+ const alignment = param_ty.abiAlignment(target);
+ const param_llvm_ty = try self.dg.lowerType(param_ty);
+ const arg_ptr = self.buildAlloca(param_llvm_ty, alignment);
+ if (isByRef(param_ty)) {
+ const load_inst = self.builder.buildLoad(param_llvm_ty, llvm_arg, "");
+ load_inst.setAlignment(alignment);
+
+ const store_inst = self.builder.buildStore(load_inst, arg_ptr);
+ store_inst.setAlignment(alignment);
+ try llvm_args.append(arg_ptr);
+ } else {
+ const store_inst = self.builder.buildStore(llvm_arg, arg_ptr);
+ store_inst.setAlignment(alignment);
+ try llvm_args.append(arg_ptr);
+ }
+ },
.abi_sized_int => {
const arg = args[it.zig_index - 1];
const param_ty = self.air.typeOf(arg);
@@ -10384,6 +10427,7 @@ const ParamTypeIterator = struct {
no_bits,
byval,
byref,
+ byref_mut,
abi_sized_int,
multiple_llvm_types,
slice,
@@ -10547,7 +10591,7 @@ const ParamTypeIterator = struct {
it.zig_index += 1;
it.llvm_index += 1;
switch (aarch64_c_abi.classifyType(ty, it.target)) {
- .memory => return .byref,
+ .memory => return .byref_mut,
.float_array => |len| return Lowering{ .float_array = len },
.byval => return .byval,
.integer => {
@@ -10578,9 +10622,7 @@ const ParamTypeIterator = struct {
return .as_u16;
}
switch (riscv_c_abi.classifyType(ty, it.target)) {
- .memory => {
- return .byref;
- },
+ .memory => return .byref_mut,
.byval => return .byval,
.integer => return .abi_sized_int,
.double_integer => return Lowering{ .i64_array = 2 },