@@ -5730,12 +5730,7 @@ pub const FuncGen = struct {
57305730 // The payload and the optional are the same value.
57315731 return operand ;
57325732 }
5733- const index_type = self .context .intType (32 );
5734- const indices : [2 ]* const llvm.Value = .{
5735- index_type .constNull (), // dereference the pointer
5736- index_type .constNull (), // first field is the payload
5737- };
5738- return self .builder .buildInBoundsGEP (operand , & indices , indices .len , "" );
5733+ return self .builder .buildStructGEP (operand , 0 , "" );
57395734 }
57405735
57415736 fn airOptionalPayloadPtrSet (self : * FuncGen , inst : Air.Inst.Index ) ! ? * const llvm.Value {
@@ -5761,24 +5756,17 @@ pub const FuncGen = struct {
57615756 // Setting to non-null will be done when the payload is set.
57625757 return operand ;
57635758 }
5764- const index_type = self .context .intType (32 );
5765- {
5766- // First set the non-null bit.
5767- const indices : [2 ]* const llvm.Value = .{
5768- index_type .constNull (), // dereference the pointer
5769- index_type .constInt (1 , .False ), // second field is the non-null bit
5770- };
5771- const non_null_ptr = self .builder .buildInBoundsGEP (operand , & indices , indices .len , "" );
5772- _ = self .builder .buildStore (non_null_bit , non_null_ptr );
5773- }
5759+
5760+ // First set the non-null bit.
5761+ const non_null_ptr = self .builder .buildStructGEP (operand , 1 , "" );
5762+ // TODO set alignment on this store
5763+ _ = self .builder .buildStore (non_null_bit , non_null_ptr );
5764+
57745765 // Then return the payload pointer (only if it's used).
57755766 if (self .liveness .isUnused (inst ))
57765767 return null ;
5777- const indices : [2 ]* const llvm.Value = .{
5778- index_type .constNull (), // dereference the pointer
5779- index_type .constNull (), // first field is the payload
5780- };
5781- return self .builder .buildInBoundsGEP (operand , & indices , indices .len , "" );
5768+
5769+ return self .builder .buildStructGEP (operand , 0 , "" );
57825770 }
57835771
57845772 fn airOptionalPayload (self : * FuncGen , inst : Air.Inst.Index ) ! ? * const llvm.Value {
@@ -5874,16 +5862,11 @@ pub const FuncGen = struct {
58745862 _ = self .builder .buildStore (non_error_val , operand );
58755863 return operand ;
58765864 }
5877- const index_type = self .context .intType (32 );
58785865 const target = self .dg .module .getTarget ();
58795866 {
58805867 const error_offset = errUnionErrorOffset (payload_ty , target );
58815868 // First set the non-error value.
5882- const indices : [2 ]* const llvm.Value = .{
5883- index_type .constNull (), // dereference the pointer
5884- index_type .constInt (error_offset , .False ),
5885- };
5886- const non_null_ptr = self .builder .buildInBoundsGEP (operand , & indices , indices .len , "" );
5869+ const non_null_ptr = self .builder .buildStructGEP (operand , error_offset , "" );
58875870 const store_inst = self .builder .buildStore (non_error_val , non_null_ptr );
58885871 store_inst .setAlignment (Type .anyerror .abiAlignment (target ));
58895872 }
@@ -5892,11 +5875,7 @@ pub const FuncGen = struct {
58925875 return null ;
58935876
58945877 const payload_offset = errUnionPayloadOffset (payload_ty , target );
5895- const indices : [2 ]* const llvm.Value = .{
5896- index_type .constNull (), // dereference the pointer
5897- index_type .constInt (payload_offset , .False ),
5898- };
5899- return self .builder .buildInBoundsGEP (operand , & indices , indices .len , "" );
5878+ return self .builder .buildStructGEP (operand , payload_offset , "" );
59005879 }
59015880
59025881 fn airErrReturnTrace (self : * FuncGen , _ : Air.Inst.Index ) ! ? * const llvm.Value {
@@ -6391,8 +6370,30 @@ pub const FuncGen = struct {
63916370 const overflow_bit = self .builder .buildExtractValue (result_struct , 1 , "" );
63926371
63936372 var ty_buf : Type.Payload.Pointer = undefined ;
6394- const partial = self .builder .buildInsertValue (llvm_dest_ty .getUndef (), result , llvmFieldIndex (dest_ty , 0 , tg , & ty_buf ).? , "" );
6395- return self .builder .buildInsertValue (partial , overflow_bit , llvmFieldIndex (dest_ty , 1 , tg , & ty_buf ).? , "" );
6373+ const result_index = llvmFieldIndex (dest_ty , 0 , tg , & ty_buf ).? ;
6374+ const overflow_index = llvmFieldIndex (dest_ty , 1 , tg , & ty_buf ).? ;
6375+
6376+ if (isByRef (dest_ty )) {
6377+ const target = self .dg .module .getTarget ();
6378+ const alloca_inst = self .buildAlloca (llvm_dest_ty );
6379+ const result_alignment = dest_ty .abiAlignment (target );
6380+ alloca_inst .setAlignment (result_alignment );
6381+ {
6382+ const field_ptr = self .builder .buildStructGEP (alloca_inst , result_index , "" );
6383+ const store_inst = self .builder .buildStore (result , field_ptr );
6384+ store_inst .setAlignment (result_alignment );
6385+ }
6386+ {
6387+ const field_ptr = self .builder .buildStructGEP (alloca_inst , overflow_index , "" );
6388+ const store_inst = self .builder .buildStore (overflow_bit , field_ptr );
6389+ store_inst .setAlignment (1 );
6390+ }
6391+
6392+ return alloca_inst ;
6393+ }
6394+
6395+ const partial = self .builder .buildInsertValue (llvm_dest_ty .getUndef (), result , result_index , "" );
6396+ return self .builder .buildInsertValue (partial , overflow_bit , overflow_index , "" );
63966397 }
63976398
63986399 fn buildElementwiseCall (
@@ -6721,8 +6722,30 @@ pub const FuncGen = struct {
67216722 const overflow_bit = self .builder .buildICmp (.NE , lhs , reconstructed , "" );
67226723
67236724 var ty_buf : Type.Payload.Pointer = undefined ;
6724- const partial = self .builder .buildInsertValue (llvm_dest_ty .getUndef (), result , llvmFieldIndex (dest_ty , 0 , tg , & ty_buf ).? , "" );
6725- return self .builder .buildInsertValue (partial , overflow_bit , llvmFieldIndex (dest_ty , 1 , tg , & ty_buf ).? , "" );
6725+ const result_index = llvmFieldIndex (dest_ty , 0 , tg , & ty_buf ).? ;
6726+ const overflow_index = llvmFieldIndex (dest_ty , 1 , tg , & ty_buf ).? ;
6727+
6728+ if (isByRef (dest_ty )) {
6729+ const target = self .dg .module .getTarget ();
6730+ const alloca_inst = self .buildAlloca (llvm_dest_ty );
6731+ const result_alignment = dest_ty .abiAlignment (target );
6732+ alloca_inst .setAlignment (result_alignment );
6733+ {
6734+ const field_ptr = self .builder .buildStructGEP (alloca_inst , result_index , "" );
6735+ const store_inst = self .builder .buildStore (result , field_ptr );
6736+ store_inst .setAlignment (result_alignment );
6737+ }
6738+ {
6739+ const field_ptr = self .builder .buildStructGEP (alloca_inst , overflow_index , "" );
6740+ const store_inst = self .builder .buildStore (overflow_bit , field_ptr );
6741+ store_inst .setAlignment (1 );
6742+ }
6743+
6744+ return alloca_inst ;
6745+ }
6746+
6747+ const partial = self .builder .buildInsertValue (llvm_dest_ty .getUndef (), result , result_index , "" );
6748+ return self .builder .buildInsertValue (partial , overflow_bit , overflow_index , "" );
67266749 }
67276750
67286751 fn airAnd (self : * FuncGen , inst : Air.Inst.Index ) ! ? * const llvm.Value {
@@ -8336,17 +8359,9 @@ pub const FuncGen = struct {
83368359 fn optIsNonNull (self : * FuncGen , opt_handle : * const llvm.Value , is_by_ref : bool ) * const llvm.Value {
83378360 const field = b : {
83388361 if (is_by_ref ) {
8339- const index_type = self .context .intType (32 );
8340-
8341- const indices : [2 ]* const llvm.Value = .{
8342- index_type .constNull (),
8343- index_type .constInt (1 , .False ),
8344- };
8345-
8346- const field_ptr = self .builder .buildInBoundsGEP (opt_handle , & indices , indices .len , "" );
8362+ const field_ptr = self .builder .buildStructGEP (opt_handle , 1 , "" );
83478363 break :b self .builder .buildLoad (field_ptr , "" );
83488364 }
8349-
83508365 break :b self .builder .buildExtractValue (opt_handle , 1 , "" );
83518366 };
83528367 comptime assert (optional_layout_version == 3 );
@@ -8365,12 +8380,7 @@ pub const FuncGen = struct {
83658380
83668381 if (isByRef (opt_ty )) {
83678382 // We have a pointer and we need to return a pointer to the first field.
8368- const index_type = fg .context .intType (32 );
8369- const indices : [2 ]* const llvm.Value = .{
8370- index_type .constNull (), // dereference the pointer
8371- index_type .constNull (), // first field is the payload
8372- };
8373- const payload_ptr = fg .builder .buildInBoundsGEP (opt_handle , & indices , indices .len , "" );
8383+ const payload_ptr = fg .builder .buildStructGEP (opt_handle , 0 , "" );
83748384
83758385 if (isByRef (payload_ty )) {
83768386 return payload_ptr ;
@@ -8401,22 +8411,13 @@ pub const FuncGen = struct {
84018411 const payload_alignment = optional_ty .abiAlignment (target );
84028412 alloca_inst .setAlignment (payload_alignment );
84038413
8404- const index_type = self .context .intType (32 );
84058414 {
8406- const indices : [2 ]* const llvm.Value = .{
8407- index_type .constNull (), // dereference the pointer
8408- index_type .constNull (), // first field is the payload
8409- };
8410- const field_ptr = self .builder .buildInBoundsGEP (alloca_inst , & indices , indices .len , "" );
8415+ const field_ptr = self .builder .buildStructGEP (alloca_inst , 0 , "" );
84118416 const store_inst = self .builder .buildStore (payload , field_ptr );
84128417 store_inst .setAlignment (payload_alignment );
84138418 }
84148419 {
8415- const indices : [2 ]* const llvm.Value = .{
8416- index_type .constNull (), // dereference the pointer
8417- index_type .constInt (1 , .False ), // second field is the non-null bit
8418- };
8419- const field_ptr = self .builder .buildInBoundsGEP (alloca_inst , & indices , indices .len , "" );
8420+ const field_ptr = self .builder .buildStructGEP (alloca_inst , 1 , "" );
84208421 const store_inst = self .builder .buildStore (non_null_field , field_ptr );
84218422 store_inst .setAlignment (1 );
84228423 }
@@ -9337,7 +9338,7 @@ fn ccAbiPromoteInt(
93379338fn isByRef (ty : Type ) bool {
93389339 // For tuples and structs, if there are more than this many non-void
93399340 // fields, then we make it byref, otherwise byval.
9340- const max_fields_byval = 2 ;
9341+ const max_fields_byval = 0 ;
93419342
93429343 switch (ty .zigTypeTag ()) {
93439344 .Type ,
0 commit comments