@@ -8,7 +8,7 @@ use rustc_middle::ty::{self, Instance, Ty, TyCtxt};
8
8
use rustc_middle:: { bug, mir, span_bug} ;
9
9
use rustc_session:: config:: OptLevel ;
10
10
use rustc_span:: { DUMMY_SP , Span } ;
11
- use tracing:: { debug, instrument} ;
11
+ use tracing:: { debug, instrument, trace } ;
12
12
13
13
use super :: FunctionCx ;
14
14
use super :: operand:: { OperandRef , OperandValue } ;
@@ -93,6 +93,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
93
93
return ;
94
94
}
95
95
96
+ // If `v` is an integer constant whose value is just a single byte repeated N times,
97
+ // emit a `memset` filling the entire `dest` with that byte.
96
98
let try_init_all_same = |bx : & mut Bx , v| {
97
99
let start = dest. val . llval ;
98
100
let size = bx. const_usize ( dest. layout . size . bytes ( ) ) ;
@@ -117,13 +119,33 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
117
119
false
118
120
} ;
119
121
122
+ trace ! ( ?cg_elem. val) ;
120
123
match cg_elem. val {
121
124
OperandValue :: Immediate ( v) => {
122
125
if try_init_all_same ( bx, v) {
123
126
return ;
124
127
}
125
128
}
126
- _ => ( ) ,
129
+ OperandValue :: Pair ( a, b) => {
130
+ let a_is_undef = bx. cx ( ) . is_undef ( a) ;
131
+ match ( a_is_undef, bx. cx ( ) . is_undef ( b) ) {
132
+ // Can happen for uninit unions
133
+ ( true , true ) => {
134
+ // FIXME: can we produce better output here?
135
+ }
136
+ ( false , true ) | ( true , false ) => {
137
+ let val = if a_is_undef { b } else { a } ;
138
+ if try_init_all_same ( bx, val) {
139
+ return ;
140
+ }
141
+ }
142
+ ( false , false ) => {
143
+ // FIXME: if both are the same value, use try_init_all_same
144
+ }
145
+ }
146
+ }
147
+ OperandValue :: ZeroSized => unreachable ! ( "checked above" ) ,
148
+ OperandValue :: Ref ( ..) => { }
127
149
}
128
150
129
151
let count = self
0 commit comments