@@ -5731,12 +5731,7 @@ pub const FuncGen = struct {
57315731 // The payload and the optional are the same value.
57325732 return operand ;
57335733 }
5734- const index_type = self .context .intType (32 );
5735- const indices : [2 ]* const llvm.Value = .{
5736- index_type .constNull (), // dereference the pointer
5737- index_type .constNull (), // first field is the payload
5738- };
5739- return self .builder .buildInBoundsGEP (operand , & indices , indices .len , "" );
5734+ return self .builder .buildStructGEP (operand , 0 , "" );
57405735 }
57415736
57425737 fn airOptionalPayloadPtrSet (self : * FuncGen , inst : Air.Inst.Index ) ! ? * const llvm.Value {
@@ -5760,24 +5755,17 @@ pub const FuncGen = struct {
57605755 // Setting to non-null will be done when the payload is set.
57615756 return operand ;
57625757 }
5763- const index_type = self .context .intType (32 );
5764- {
5765- // First set the non-null bit.
5766- const indices : [2 ]* const llvm.Value = .{
5767- index_type .constNull (), // dereference the pointer
5768- index_type .constInt (1 , .False ), // second field is the non-null bit
5769- };
5770- const non_null_ptr = self .builder .buildInBoundsGEP (operand , & indices , indices .len , "" );
5771- _ = self .builder .buildStore (non_null_bit , non_null_ptr );
5772- }
5758+
5759+ // First set the non-null bit.
5760+ const non_null_ptr = self .builder .buildStructGEP (operand , 1 , "" );
5761+ // TODO set alignment on this store
5762+ _ = self .builder .buildStore (non_null_bit , non_null_ptr );
5763+
57735764 // Then return the payload pointer (only if it's used).
57745765 if (self .liveness .isUnused (inst ))
57755766 return null ;
5776- const indices : [2 ]* const llvm.Value = .{
5777- index_type .constNull (), // dereference the pointer
5778- index_type .constNull (), // first field is the payload
5779- };
5780- return self .builder .buildInBoundsGEP (operand , & indices , indices .len , "" );
5767+
5768+ return self .builder .buildStructGEP (operand , 0 , "" );
57815769 }
57825770
57835771 fn airOptionalPayload (self : * FuncGen , inst : Air.Inst.Index ) ! ? * const llvm.Value {
@@ -5873,16 +5861,11 @@ pub const FuncGen = struct {
58735861 _ = self .builder .buildStore (non_error_val , operand );
58745862 return operand ;
58755863 }
5876- const index_type = self .context .intType (32 );
58775864 const target = self .dg .module .getTarget ();
58785865 {
58795866 const error_offset = errUnionErrorOffset (payload_ty , target );
58805867 // First set the non-error value.
5881- const indices : [2 ]* const llvm.Value = .{
5882- index_type .constNull (), // dereference the pointer
5883- index_type .constInt (error_offset , .False ),
5884- };
5885- const non_null_ptr = self .builder .buildInBoundsGEP (operand , & indices , indices .len , "" );
5868+ const non_null_ptr = self .builder .buildStructGEP (operand , error_offset , "" );
58865869 const store_inst = self .builder .buildStore (non_error_val , non_null_ptr );
58875870 store_inst .setAlignment (Type .anyerror .abiAlignment (target ));
58885871 }
@@ -5891,11 +5874,7 @@ pub const FuncGen = struct {
58915874 return null ;
58925875
58935876 const payload_offset = errUnionPayloadOffset (payload_ty , target );
5894- const indices : [2 ]* const llvm.Value = .{
5895- index_type .constNull (), // dereference the pointer
5896- index_type .constInt (payload_offset , .False ),
5897- };
5898- return self .builder .buildInBoundsGEP (operand , & indices , indices .len , "" );
5877+ return self .builder .buildStructGEP (operand , payload_offset , "" );
58995878 }
59005879
59015880 fn airErrReturnTrace (self : * FuncGen , _ : Air.Inst.Index ) ! ? * const llvm.Value {
@@ -6390,8 +6369,30 @@ pub const FuncGen = struct {
63906369 const overflow_bit = self .builder .buildExtractValue (result_struct , 1 , "" );
63916370
63926371 var ty_buf : Type.Payload.Pointer = undefined ;
6393- const partial = self .builder .buildInsertValue (llvm_dest_ty .getUndef (), result , llvmFieldIndex (dest_ty , 0 , tg , & ty_buf ).? , "" );
6394- return self .builder .buildInsertValue (partial , overflow_bit , llvmFieldIndex (dest_ty , 1 , tg , & ty_buf ).? , "" );
6372+ const result_index = llvmFieldIndex (dest_ty , 0 , tg , & ty_buf ).? ;
6373+ const overflow_index = llvmFieldIndex (dest_ty , 1 , tg , & ty_buf ).? ;
6374+
6375+ if (isByRef (dest_ty )) {
6376+ const target = self .dg .module .getTarget ();
6377+ const alloca_inst = self .buildAlloca (llvm_dest_ty );
6378+ const result_alignment = dest_ty .abiAlignment (target );
6379+ alloca_inst .setAlignment (result_alignment );
6380+ {
6381+ const field_ptr = self .builder .buildStructGEP (alloca_inst , result_index , "" );
6382+ const store_inst = self .builder .buildStore (result , field_ptr );
6383+ store_inst .setAlignment (result_alignment );
6384+ }
6385+ {
6386+ const field_ptr = self .builder .buildStructGEP (alloca_inst , overflow_index , "" );
6387+ const store_inst = self .builder .buildStore (overflow_bit , field_ptr );
6388+ store_inst .setAlignment (1 );
6389+ }
6390+
6391+ return alloca_inst ;
6392+ }
6393+
6394+ const partial = self .builder .buildInsertValue (llvm_dest_ty .getUndef (), result , result_index , "" );
6395+ return self .builder .buildInsertValue (partial , overflow_bit , overflow_index , "" );
63956396 }
63966397
63976398 fn buildElementwiseCall (
@@ -6720,8 +6721,30 @@ pub const FuncGen = struct {
67206721 const overflow_bit = self .builder .buildICmp (.NE , lhs , reconstructed , "" );
67216722
67226723 var ty_buf : Type.Payload.Pointer = undefined ;
6723- const partial = self .builder .buildInsertValue (llvm_dest_ty .getUndef (), result , llvmFieldIndex (dest_ty , 0 , tg , & ty_buf ).? , "" );
6724- return self .builder .buildInsertValue (partial , overflow_bit , llvmFieldIndex (dest_ty , 1 , tg , & ty_buf ).? , "" );
6724+ const result_index = llvmFieldIndex (dest_ty , 0 , tg , & ty_buf ).? ;
6725+ const overflow_index = llvmFieldIndex (dest_ty , 1 , tg , & ty_buf ).? ;
6726+
6727+ if (isByRef (dest_ty )) {
6728+ const target = self .dg .module .getTarget ();
6729+ const alloca_inst = self .buildAlloca (llvm_dest_ty );
6730+ const result_alignment = dest_ty .abiAlignment (target );
6731+ alloca_inst .setAlignment (result_alignment );
6732+ {
6733+ const field_ptr = self .builder .buildStructGEP (alloca_inst , result_index , "" );
6734+ const store_inst = self .builder .buildStore (result , field_ptr );
6735+ store_inst .setAlignment (result_alignment );
6736+ }
6737+ {
6738+ const field_ptr = self .builder .buildStructGEP (alloca_inst , overflow_index , "" );
6739+ const store_inst = self .builder .buildStore (overflow_bit , field_ptr );
6740+ store_inst .setAlignment (1 );
6741+ }
6742+
6743+ return alloca_inst ;
6744+ }
6745+
6746+ const partial = self .builder .buildInsertValue (llvm_dest_ty .getUndef (), result , result_index , "" );
6747+ return self .builder .buildInsertValue (partial , overflow_bit , overflow_index , "" );
67256748 }
67266749
67276750 fn airAnd (self : * FuncGen , inst : Air.Inst.Index ) ! ? * const llvm.Value {
@@ -8332,14 +8355,7 @@ pub const FuncGen = struct {
83328355 /// Assumes the optional is not pointer-like and payload has bits.
83338356 fn optIsNonNull (self : * FuncGen , opt_handle : * const llvm.Value , is_by_ref : bool ) * const llvm.Value {
83348357 if (is_by_ref ) {
8335- const index_type = self .context .intType (32 );
8336-
8337- const indices : [2 ]* const llvm.Value = .{
8338- index_type .constNull (),
8339- index_type .constInt (1 , .False ),
8340- };
8341-
8342- const field_ptr = self .builder .buildInBoundsGEP (opt_handle , & indices , indices .len , "" );
8358+ const field_ptr = self .builder .buildStructGEP (opt_handle , 1 , "" );
83438359 return self .builder .buildLoad (field_ptr , "" );
83448360 }
83458361
@@ -8357,12 +8373,7 @@ pub const FuncGen = struct {
83578373
83588374 if (isByRef (opt_ty )) {
83598375 // We have a pointer and we need to return a pointer to the first field.
8360- const index_type = fg .context .intType (32 );
8361- const indices : [2 ]* const llvm.Value = .{
8362- index_type .constNull (), // dereference the pointer
8363- index_type .constNull (), // first field is the payload
8364- };
8365- const payload_ptr = fg .builder .buildInBoundsGEP (opt_handle , & indices , indices .len , "" );
8376+ const payload_ptr = fg .builder .buildStructGEP (opt_handle , 0 , "" );
83668377
83678378 if (isByRef (payload_ty )) {
83688379 return payload_ptr ;
@@ -8392,22 +8403,13 @@ pub const FuncGen = struct {
83928403 const payload_alignment = optional_ty .abiAlignment (target );
83938404 alloca_inst .setAlignment (payload_alignment );
83948405
8395- const index_type = self .context .intType (32 );
83968406 {
8397- const indices : [2 ]* const llvm.Value = .{
8398- index_type .constNull (), // dereference the pointer
8399- index_type .constNull (), // first field is the payload
8400- };
8401- const field_ptr = self .builder .buildInBoundsGEP (alloca_inst , & indices , indices .len , "" );
8407+ const field_ptr = self .builder .buildStructGEP (alloca_inst , 0 , "" );
84028408 const store_inst = self .builder .buildStore (payload , field_ptr );
84038409 store_inst .setAlignment (payload_alignment );
84048410 }
84058411 {
8406- const indices : [2 ]* const llvm.Value = .{
8407- index_type .constNull (), // dereference the pointer
8408- index_type .constInt (1 , .False ), // second field is the non-null bit
8409- };
8410- const field_ptr = self .builder .buildInBoundsGEP (alloca_inst , & indices , indices .len , "" );
8412+ const field_ptr = self .builder .buildStructGEP (alloca_inst , 1 , "" );
84118413 const store_inst = self .builder .buildStore (non_null_bit , field_ptr );
84128414 store_inst .setAlignment (1 );
84138415 }
@@ -9328,7 +9330,7 @@ fn ccAbiPromoteInt(
93289330fn isByRef (ty : Type ) bool {
93299331 // For tuples and structs, if there are more than this many non-void
93309332 // fields, then we make it byref, otherwise byval.
9331- const max_fields_byval = 2 ;
9333+ const max_fields_byval = 0 ;
93329334
93339335 switch (ty .zigTypeTag ()) {
93349336 .Type ,
0 commit comments