@@ -4739,12 +4739,14 @@ pub const FuncGen = struct {
4739
4739
const err_set_ty = try fg .dg .lowerType (Type .anyerror );
4740
4740
const zero = err_set_ty .constNull ();
4741
4741
if (! payload_has_bits ) {
4742
+ // TODO add alignment to this load
4742
4743
const loaded = if (operand_is_ptr ) fg .builder .buildLoad (err_union , "" ) else err_union ;
4743
4744
break :err fg .builder .buildICmp (.NE , loaded , zero , "" );
4744
4745
}
4745
4746
const err_field_index = errUnionErrorOffset (payload_ty , target );
4746
4747
if (operand_is_ptr or isByRef (err_union_ty )) {
4747
4748
const err_field_ptr = fg .builder .buildStructGEP (err_union , err_field_index , "" );
4749
+ // TODO add alignment to this load
4748
4750
const loaded = fg .builder .buildLoad (err_field_ptr , "" );
4749
4751
break :err fg .builder .buildICmp (.NE , loaded , zero , "" );
4750
4752
}
@@ -4764,13 +4766,22 @@ pub const FuncGen = struct {
4764
4766
if (! payload_has_bits ) {
4765
4767
if (! operand_is_ptr ) return null ;
4766
4768
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.
4768
4771
const res_ptr_ty = try fg .dg .lowerType (result_ty );
4769
4772
return fg .builder .buildBitCast (err_union , res_ptr_ty , "" );
4770
4773
}
4771
4774
const offset = errUnionPayloadOffset (payload_ty , target );
4772
4775
if (operand_is_ptr or isByRef (payload_ty )) {
4773
4776
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 ;
4774
4785
}
4775
4786
return fg .builder .buildExtractValue (err_union , offset , "" );
4776
4787
}
@@ -5794,6 +5805,8 @@ pub const FuncGen = struct {
5794
5805
5795
5806
const ty_op = self .air .instructions .items (.data )[inst ].ty_op ;
5796
5807
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 ;
5797
5810
const result_ty = self .air .typeOfIndex (inst );
5798
5811
const payload_ty = if (operand_is_ptr ) result_ty .childType () else result_ty ;
5799
5812
const target = self .dg .module .getTarget ();
@@ -5808,6 +5821,14 @@ pub const FuncGen = struct {
5808
5821
const offset = errUnionPayloadOffset (payload_ty , target );
5809
5822
if (operand_is_ptr or isByRef (payload_ty )) {
5810
5823
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 ;
5811
5832
}
5812
5833
return self .builder .buildExtractValue (operand , offset , "" );
5813
5834
}
@@ -9330,6 +9351,8 @@ fn ccAbiPromoteInt(
9330
9351
fn isByRef (ty : Type ) bool {
9331
9352
// For tuples and structs, if there are more than this many non-void
9332
9353
// 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
9333
9356
const max_fields_byval = 0 ;
9334
9357
9335
9358
switch (ty .zigTypeTag ()) {
@@ -9384,7 +9407,17 @@ fn isByRef(ty: Type) bool {
9384
9407
return false ;
9385
9408
},
9386
9409
.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
+ },
9388
9421
.Optional = > {
9389
9422
var buf : Type.Payload.ElemType = undefined ;
9390
9423
const payload_ty = ty .optionalChild (& buf );
0 commit comments