@@ -8,7 +8,7 @@ use rustc_middle::ty::{self, Instance, Ty, TyCtxt};
88use rustc_middle:: { bug, mir, span_bug} ;
99use rustc_session:: config:: OptLevel ;
1010use rustc_span:: { DUMMY_SP , Span } ;
11- use tracing:: { debug, instrument} ;
11+ use tracing:: { debug, instrument, trace } ;
1212
1313use super :: operand:: { OperandRef , OperandValue } ;
1414use super :: place:: PlaceRef ;
@@ -93,6 +93,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
9393 return ;
9494 }
9595
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.
9698 let try_init_all_same = |bx : & mut Bx , v| {
9799 let start = dest. val . llval ;
98100 let size = bx. const_usize ( dest. layout . size . bytes ( ) ) ;
@@ -117,13 +119,33 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
117119 false
118120 } ;
119121
122+ trace ! ( ?cg_elem. val) ;
120123 match cg_elem. val {
121124 OperandValue :: Immediate ( v) => {
122125 if try_init_all_same ( bx, v) {
123126 return ;
124127 }
125128 }
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 ( ..) => { }
127149 }
128150
129151 let count = self
0 commit comments