@@ -4740,12 +4740,14 @@ pub const FuncGen = struct {
4740
4740
const err_set_ty = try fg .dg .lowerType (Type .anyerror );
4741
4741
const zero = err_set_ty .constNull ();
4742
4742
if (! payload_has_bits ) {
4743
+ // TODO add alignment to this load
4743
4744
const loaded = if (operand_is_ptr ) fg .builder .buildLoad (err_union , "" ) else err_union ;
4744
4745
break :err fg .builder .buildICmp (.NE , loaded , zero , "" );
4745
4746
}
4746
4747
const err_field_index = errUnionErrorOffset (payload_ty , target );
4747
4748
if (operand_is_ptr or isByRef (err_union_ty )) {
4748
4749
const err_field_ptr = fg .builder .buildStructGEP (err_union , err_field_index , "" );
4750
+ // TODO add alignment to this load
4749
4751
const loaded = fg .builder .buildLoad (err_field_ptr , "" );
4750
4752
break :err fg .builder .buildICmp (.NE , loaded , zero , "" );
4751
4753
}
@@ -4765,13 +4767,22 @@ pub const FuncGen = struct {
4765
4767
if (! payload_has_bits ) {
4766
4768
if (! operand_is_ptr ) return null ;
4767
4769
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.
4769
4772
const res_ptr_ty = try fg .dg .lowerType (result_ty );
4770
4773
return fg .builder .buildBitCast (err_union , res_ptr_ty , "" );
4771
4774
}
4772
4775
const offset = errUnionPayloadOffset (payload_ty , target );
4773
4776
if (operand_is_ptr or isByRef (payload_ty )) {
4774
4777
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 ;
4775
4786
}
4776
4787
return fg .builder .buildExtractValue (err_union , offset , "" );
4777
4788
}
@@ -5795,6 +5806,8 @@ pub const FuncGen = struct {
5795
5806
5796
5807
const ty_op = self .air .instructions .items (.data )[inst ].ty_op ;
5797
5808
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 ;
5798
5811
const result_ty = self .air .typeOfIndex (inst );
5799
5812
const payload_ty = if (operand_is_ptr ) result_ty .childType () else result_ty ;
5800
5813
const target = self .dg .module .getTarget ();
@@ -5809,6 +5822,14 @@ pub const FuncGen = struct {
5809
5822
const offset = errUnionPayloadOffset (payload_ty , target );
5810
5823
if (operand_is_ptr or isByRef (payload_ty )) {
5811
5824
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 ;
5812
5833
}
5813
5834
return self .builder .buildExtractValue (operand , offset , "" );
5814
5835
}
@@ -9338,6 +9359,8 @@ fn ccAbiPromoteInt(
9338
9359
fn isByRef (ty : Type ) bool {
9339
9360
// For tuples and structs, if there are more than this many non-void
9340
9361
// 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
9341
9364
const max_fields_byval = 0 ;
9342
9365
9343
9366
switch (ty .zigTypeTag ()) {
@@ -9392,7 +9415,17 @@ fn isByRef(ty: Type) bool {
9392
9415
return false ;
9393
9416
},
9394
9417
.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
+ },
9396
9429
.Optional = > {
9397
9430
var buf : Type.Payload.ElemType = undefined ;
9398
9431
const payload_ty = ty .optionalChild (& buf );
0 commit comments