@@ -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(
93309351fn 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