@@ -759,8 +759,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
759
759
if const_offset == Some ( Size :: ZERO ) {
760
760
trace ! ( "ptr_offset_strided: strategy 1 picked: offset 0 => pointer cast" ) ;
761
761
762
- // FIXME(eddyb) could this just `return ptr;`? what even breaks?
763
- return self . pointercast ( ptr, self . type_ptr_to ( stride_elem_ty ) ) ;
762
+ // FIXME(eddyb) replace docs to remove mentions of pointer casting.
763
+ return ptr;
764
764
}
765
765
766
766
// Strategy 2: try recovering an `OpAccessChain` from a constant offset.
@@ -3261,6 +3261,7 @@ impl<'a, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'tcx> {
3261
3261
Bitcast ( ID , ID ) ,
3262
3262
CompositeExtract ( ID , ID , u32 ) ,
3263
3263
InBoundsAccessChain ( ID , ID , u32 ) ,
3264
+ InBoundsAccessChain2 ( ID , ID , u32 , u32 ) ,
3264
3265
Store ( ID , ID ) ,
3265
3266
Load ( ID , ID ) ,
3266
3267
CopyMemory ( ID , ID ) ,
@@ -3317,6 +3318,13 @@ impl<'a, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'tcx> {
3317
3318
Inst :: Unsupported ( inst. class . opcode )
3318
3319
}
3319
3320
}
3321
+ ( Op :: InBoundsAccessChain , Some ( r) , & [ p, i, j] ) => {
3322
+ if let [ Some ( i) , Some ( j) ] = [ i, j] . map ( const_as_u32) {
3323
+ Inst :: InBoundsAccessChain2 ( r, p, i, j)
3324
+ } else {
3325
+ Inst :: Unsupported ( inst. class . opcode )
3326
+ }
3327
+ }
3320
3328
( Op :: Store , None , & [ p, v] ) => Inst :: Store ( p, v) ,
3321
3329
( Op :: Load , Some ( r) , & [ p] ) => Inst :: Load ( r, p) ,
3322
3330
( Op :: CopyMemory , None , & [ a, b] ) => Inst :: CopyMemory ( a, b) ,
@@ -3508,20 +3516,45 @@ impl<'a, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'tcx> {
3508
3516
3509
3517
let rev_copies_to_rt_args_array_src_ptrs: SmallVec < [ _ ; 4 ] > =
3510
3518
( 0 ..rt_args_count) . rev ( ) . map ( |rt_arg_idx| {
3511
- let copy_to_rt_args_array_insts = try_rev_take ( 4 ) . ok_or_else ( || {
3519
+ let mut copy_to_rt_args_array_insts = try_rev_take ( 3 ) . ok_or_else ( || {
3512
3520
FormatArgsNotRecognized (
3513
3521
"[fmt::rt::Argument; N] copy: ran out of instructions" . into ( ) ,
3514
3522
)
3515
3523
} ) ?;
3524
+
3525
+ // HACK(eddyb) account for both the split and combined
3526
+ // access chain cases that `inbounds_gep` can now cause.
3527
+ if let Inst :: InBoundsAccessChain ( dst_field_ptr, dst_base_ptr, 0 ) =
3528
+ copy_to_rt_args_array_insts[ 0 ]
3529
+ {
3530
+ if let Some ( mut prev_insts) = try_rev_take ( 1 ) {
3531
+ assert_eq ! ( prev_insts. len( ) , 1 ) ;
3532
+ let prev_inst = prev_insts. pop ( ) . unwrap ( ) ;
3533
+
3534
+ match prev_inst {
3535
+ Inst :: InBoundsAccessChain (
3536
+ array_elem_ptr,
3537
+ array_ptr,
3538
+ idx,
3539
+ ) if dst_base_ptr == array_elem_ptr => {
3540
+ copy_to_rt_args_array_insts[ 0 ] =
3541
+ Inst :: InBoundsAccessChain2 ( dst_field_ptr, array_ptr, idx, 0 ) ;
3542
+ }
3543
+ _ => {
3544
+ // HACK(eddyb) don't lose the taken `prev_inst`.
3545
+ copy_to_rt_args_array_insts. insert ( 0 , prev_inst) ;
3546
+ }
3547
+ }
3548
+ }
3549
+ }
3550
+
3516
3551
match copy_to_rt_args_array_insts[ ..] {
3517
3552
[
3518
- Inst :: InBoundsAccessChain ( array_slot, array_base, array_idx) ,
3519
- Inst :: InBoundsAccessChain ( dst_field_ptr, dst_base_ptr, 0 ) ,
3553
+ Inst :: InBoundsAccessChain2 ( dst_field_ptr, dst_array_base_ptr, array_idx, 0 ) ,
3520
3554
Inst :: InBoundsAccessChain ( src_field_ptr, src_base_ptr, 0 ) ,
3521
3555
Inst :: CopyMemory ( copy_dst, copy_src) ,
3522
- ] if array_base == rt_args_array_ptr_id
3556
+ ] if dst_array_base_ptr == rt_args_array_ptr_id
3523
3557
&& array_idx as usize == rt_arg_idx
3524
- && dst_base_ptr == array_slot
3525
3558
&& ( copy_dst, copy_src) == ( dst_field_ptr, src_field_ptr) =>
3526
3559
{
3527
3560
Ok ( src_base_ptr)
0 commit comments