authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-07-18 21:27:40-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-07-19 11:26:19-07:00
log74fb65fb424a0fbb2eb00109fe4cee17aa2646c2
tree0ea0f6373ac13f9a6596503099a070c2f083809e
parentbab570a22540c2acb15c19e1d080a80d355407e3

LLVM: lower all error unions as byref=true

Same reasoning as previous commit.

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

src/codegen/llvm.zig+35-2
......@@ -4740,12 +4740,14 @@ pub const FuncGen = struct {
47404740 const err_set_ty = try fg.dg.lowerType(Type.anyerror);
47414741 const zero = err_set_ty.constNull();
47424742 if (!payload_has_bits) {
4743 // TODO add alignment to this load
47434744 const loaded = if (operand_is_ptr) fg.builder.buildLoad(err_union, "") else err_union;
47444745 break :err fg.builder.buildICmp(.NE, loaded, zero, "");
47454746 }
47464747 const err_field_index = errUnionErrorOffset(payload_ty, target);
47474748 if (operand_is_ptr or isByRef(err_union_ty)) {
47484749 const err_field_ptr = fg.builder.buildStructGEP(err_union, err_field_index, "");
4750 // TODO add alignment to this load
47494751 const loaded = fg.builder.buildLoad(err_field_ptr, "");
47504752 break :err fg.builder.buildICmp(.NE, loaded, zero, "");
47514753 }
......@@ -4765,13 +4767,22 @@ pub const FuncGen = struct {
47654767 if (!payload_has_bits) {
47664768 if (!operand_is_ptr) return null;
47674769
4768 // TODO once we update to LLVM 14 this bitcast won't be necessary.
4770 // TODO once we update to an LLVM version with opaque pointers
4771 // this bitcast won't be necessary.
47694772 const res_ptr_ty = try fg.dg.lowerType(result_ty);
47704773 return fg.builder.buildBitCast(err_union, res_ptr_ty, "");
47714774 }
47724775 const offset = errUnionPayloadOffset(payload_ty, target);
47734776 if (operand_is_ptr or isByRef(payload_ty)) {
47744777 return fg.builder.buildStructGEP(err_union, offset, "");
4778 } else if (isByRef(err_union_ty)) {
4779 const payload_ptr = fg.builder.buildStructGEP(err_union, offset, "");
4780 if (isByRef(payload_ty)) {
4781 return payload_ptr;
4782 }
4783 const load_inst = fg.builder.buildLoad(payload_ptr, "");
4784 load_inst.setAlignment(payload_ty.abiAlignment(target));
4785 return load_inst;
47754786 }
47764787 return fg.builder.buildExtractValue(err_union, offset, "");
47774788 }
......@@ -5795,6 +5806,8 @@ pub const FuncGen = struct {
57955806
57965807 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
57975808 const operand = try self.resolveInst(ty_op.operand);
5809 const operand_ty = self.air.typeOf(ty_op.operand);
5810 const err_union_ty = if (operand_is_ptr) operand_ty.childType() else operand_ty;
57985811 const result_ty = self.air.typeOfIndex(inst);
57995812 const payload_ty = if (operand_is_ptr) result_ty.childType() else result_ty;
58005813 const target = self.dg.module.getTarget();
......@@ -5809,6 +5822,14 @@ pub const FuncGen = struct {
58095822 const offset = errUnionPayloadOffset(payload_ty, target);
58105823 if (operand_is_ptr or isByRef(payload_ty)) {
58115824 return self.builder.buildStructGEP(operand, offset, "");
5825 } else if (isByRef(err_union_ty)) {
5826 const payload_ptr = self.builder.buildStructGEP(operand, offset, "");
5827 if (isByRef(payload_ty)) {
5828 return payload_ptr;
5829 }
5830 const load_inst = self.builder.buildLoad(payload_ptr, "");
5831 load_inst.setAlignment(payload_ty.abiAlignment(target));
5832 return load_inst;
58125833 }
58135834 return self.builder.buildExtractValue(operand, offset, "");
58145835 }
......@@ -9338,6 +9359,8 @@ fn ccAbiPromoteInt(
93389359fn isByRef(ty: Type) bool {
93399360 // For tuples and structs, if there are more than this many non-void
93409361 // fields, then we make it byref, otherwise byval.
9362 // TODO we actually want to set this to 2, however it is tripping an LLVM 14 regression:
9363 // https://github.com/llvm/llvm-project/issues/56585
93419364 const max_fields_byval = 0;
93429365
93439366 switch (ty.zigTypeTag()) {
......@@ -9392,7 +9415,17 @@ fn isByRef(ty: Type) bool {
93929415 return false;
93939416 },
93949417 .Union => return ty.hasRuntimeBits(),
9395 .ErrorUnion => return isByRef(ty.errorUnionPayload()),
9418 .ErrorUnion => {
9419 const payload_ty = ty.errorUnionPayload();
9420 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {
9421 return false;
9422 }
9423 return true;
9424 // TODO we actually want this logic:
9425 // however it is tripping an LLVM 14 regression:
9426 // https://github.com/llvm/llvm-project/issues/56585
9427 //return isByRef(payload_ty);
9428 },
93969429 .Optional => {
93979430 var buf: Type.Payload.ElemType = undefined;
93989431 const payload_ty = ty.optionalChild(&buf);