Skip to content

Commit 3140f57

Browse files
committed
LLVM: lower all error unions as byref=true
Same reasoning as previous commit.
1 parent a628e7f commit 3140f57

File tree

1 file changed

+35
-2
lines changed

1 file changed

+35
-2
lines changed

src/codegen/llvm.zig

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -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(
93389359
fn 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);

0 commit comments

Comments
 (0)