@@ -5,6 +5,7 @@ use rustc_middle::mir;
5
5
use rustc_middle:: mir:: interpret:: { InterpResult , Scalar } ;
6
6
use rustc_middle:: ty:: layout:: { LayoutOf , TyAndLayout } ;
7
7
use rustc_middle:: ty:: { self , FloatTy , Ty } ;
8
+ use rustc_target:: abi:: Abi ;
8
9
9
10
use super :: { ImmTy , Immediate , InterpCx , Machine , PlaceTy } ;
10
11
@@ -25,8 +26,21 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
25
26
"type mismatch for result of {:?}" ,
26
27
op,
27
28
) ;
28
- let val = Immediate :: ScalarPair ( val. into ( ) , Scalar :: from_bool ( overflowed) . into ( ) ) ;
29
- self . write_immediate ( val, dest)
29
+ if let Abi :: ScalarPair ( ..) = dest. layout . abi {
30
+ // We can use the optimized path and avoid `place_field` (which might do
31
+ // `force_allocation`).
32
+ let pair = Immediate :: ScalarPair ( val. into ( ) , Scalar :: from_bool ( overflowed) . into ( ) ) ;
33
+ self . write_immediate ( pair, dest) ?;
34
+ } else {
35
+ // With randomized layout, `(int, bool)` might cease to be a `ScalarPair`, so we have to
36
+ // do a component-wise write here. This code path is slower than the above because
37
+ // `place_field` will have to `force_allocate` locals here.
38
+ let val_field = self . place_field ( & dest, 0 ) ?;
39
+ self . write_scalar ( val, & val_field) ?;
40
+ let overflowed_field = self . place_field ( & dest, 1 ) ?;
41
+ self . write_scalar ( Scalar :: from_bool ( overflowed) , & overflowed_field) ?;
42
+ }
43
+ Ok ( ( ) )
30
44
}
31
45
32
46
/// Applies the binary operation `op` to the arguments and writes the result to the
0 commit comments