Skip to content

Commit 5aa9b6f

Browse files
committed
LLVM: lower all error unions as byref=true
Same reasoning as previous commit.
1 parent a74b6ad commit 5aa9b6f

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
@@ -4739,12 +4739,14 @@ pub const FuncGen = struct {
47394739
const err_set_ty = try fg.dg.lowerType(Type.anyerror);
47404740
const zero = err_set_ty.constNull();
47414741
if (!payload_has_bits) {
4742+
// TODO add alignment to this load
47424743
const loaded = if (operand_is_ptr) fg.builder.buildLoad(err_union, "") else err_union;
47434744
break :err fg.builder.buildICmp(.NE, loaded, zero, "");
47444745
}
47454746
const err_field_index = errUnionErrorOffset(payload_ty, target);
47464747
if (operand_is_ptr or isByRef(err_union_ty)) {
47474748
const err_field_ptr = fg.builder.buildStructGEP(err_union, err_field_index, "");
4749+
// TODO add alignment to this load
47484750
const loaded = fg.builder.buildLoad(err_field_ptr, "");
47494751
break :err fg.builder.buildICmp(.NE, loaded, zero, "");
47504752
}
@@ -4764,13 +4766,22 @@ pub const FuncGen = struct {
47644766
if (!payload_has_bits) {
47654767
if (!operand_is_ptr) return null;
47664768

4767-
// TODO once we update to LLVM 14 this bitcast won't be necessary.
4769+
// TODO once we update to an LLVM version with opaque pointers
4770+
// this bitcast won't be necessary.
47684771
const res_ptr_ty = try fg.dg.lowerType(result_ty);
47694772
return fg.builder.buildBitCast(err_union, res_ptr_ty, "");
47704773
}
47714774
const offset = errUnionPayloadOffset(payload_ty, target);
47724775
if (operand_is_ptr or isByRef(payload_ty)) {
47734776
return fg.builder.buildStructGEP(err_union, offset, "");
4777+
} else if (isByRef(err_union_ty)) {
4778+
const payload_ptr = fg.builder.buildStructGEP(err_union, offset, "");
4779+
if (isByRef(payload_ty)) {
4780+
return payload_ptr;
4781+
}
4782+
const load_inst = fg.builder.buildLoad(payload_ptr, "");
4783+
load_inst.setAlignment(payload_ty.abiAlignment(target));
4784+
return load_inst;
47744785
}
47754786
return fg.builder.buildExtractValue(err_union, offset, "");
47764787
}
@@ -5794,6 +5805,8 @@ pub const FuncGen = struct {
57945805

57955806
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
57965807
const operand = try self.resolveInst(ty_op.operand);
5808+
const operand_ty = self.air.typeOf(ty_op.operand);
5809+
const err_union_ty = if (operand_is_ptr) operand_ty.childType() else operand_ty;
57975810
const result_ty = self.air.typeOfIndex(inst);
57985811
const payload_ty = if (operand_is_ptr) result_ty.childType() else result_ty;
57995812
const target = self.dg.module.getTarget();
@@ -5808,6 +5821,14 @@ pub const FuncGen = struct {
58085821
const offset = errUnionPayloadOffset(payload_ty, target);
58095822
if (operand_is_ptr or isByRef(payload_ty)) {
58105823
return self.builder.buildStructGEP(operand, offset, "");
5824+
} else if (isByRef(err_union_ty)) {
5825+
const payload_ptr = self.builder.buildStructGEP(operand, offset, "");
5826+
if (isByRef(payload_ty)) {
5827+
return payload_ptr;
5828+
}
5829+
const load_inst = self.builder.buildLoad(payload_ptr, "");
5830+
load_inst.setAlignment(payload_ty.abiAlignment(target));
5831+
return load_inst;
58115832
}
58125833
return self.builder.buildExtractValue(operand, offset, "");
58135834
}
@@ -9330,6 +9351,8 @@ fn ccAbiPromoteInt(
93309351
fn isByRef(ty: Type) bool {
93319352
// For tuples and structs, if there are more than this many non-void
93329353
// fields, then we make it byref, otherwise byval.
9354+
// TODO we actually want to set this to 2, however it is tripping an LLVM 14 regression:
9355+
// https://github.com/llvm/llvm-project/issues/56585
93339356
const max_fields_byval = 0;
93349357

93359358
switch (ty.zigTypeTag()) {
@@ -9384,7 +9407,17 @@ fn isByRef(ty: Type) bool {
93849407
return false;
93859408
},
93869409
.Union => return ty.hasRuntimeBits(),
9387-
.ErrorUnion => return isByRef(ty.errorUnionPayload()),
9410+
.ErrorUnion => {
9411+
const payload_ty = ty.errorUnionPayload();
9412+
if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {
9413+
return false;
9414+
}
9415+
return true;
9416+
// TODO we actually want this logic:
9417+
// however it is tripping an LLVM 14 regression:
9418+
// https://github.com/llvm/llvm-project/issues/56585
9419+
//return isByRef(payload_ty);
9420+
},
93889421
.Optional => {
93899422
var buf: Type.Payload.ElemType = undefined;
93909423
const payload_ty = ty.optionalChild(&buf);

0 commit comments

Comments
 (0)