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