@@ -149,6 +149,18 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'a, 'tcx> {
149149 }
150150 }
151151 }
152+
153+ // Generate sideeffect intrinsic if any of the targets' index is not
154+ // greater than that of the current block.
155+ fn maybe_sideeffect < ' b , ' tcx2 : ' b , Bx : BuilderMethods < ' b , ' tcx2 > > (
156+ & self ,
157+ bx : & mut Bx ,
158+ targets : & [ mir:: BasicBlock ] ,
159+ ) {
160+ if targets. iter ( ) . any ( |target| target <= self . bb ) {
161+ bx. sideeffect ( ) ;
162+ }
163+ }
152164}
153165
154166/// Codegen implementations for some terminator variants.
@@ -197,6 +209,7 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
197209 let lltrue = helper. llblock ( self , targets[ 0 ] ) ;
198210 let llfalse = helper. llblock ( self , targets[ 1 ] ) ;
199211 if switch_ty == bx. tcx ( ) . types . bool {
212+ helper. maybe_sideeffect ( & mut bx, targets. as_slice ( ) ) ;
200213 // Don't generate trivial icmps when switching on bool
201214 if let [ 0 ] = values[ ..] {
202215 bx. cond_br ( discr. immediate ( ) , llfalse, lltrue) ;
@@ -210,9 +223,11 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
210223 ) ;
211224 let llval = bx. const_uint_big ( switch_llty, values[ 0 ] ) ;
212225 let cmp = bx. icmp ( IntPredicate :: IntEQ , discr. immediate ( ) , llval) ;
226+ helper. maybe_sideeffect ( & mut bx, targets. as_slice ( ) ) ;
213227 bx. cond_br ( cmp, lltrue, llfalse) ;
214228 }
215229 } else {
230+ helper. maybe_sideeffect ( & mut bx, targets. as_slice ( ) ) ;
216231 let ( otherwise, targets) = targets. split_last ( ) . unwrap ( ) ;
217232 bx. switch (
218233 discr. immediate ( ) ,
@@ -307,6 +322,7 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
307322
308323 if let ty:: InstanceDef :: DropGlue ( _, None ) = drop_fn. def {
309324 // we don't actually need to drop anything.
325+ helper. maybe_sideeffect ( & mut bx, & [ target] ) ;
310326 helper. funclet_br ( self , & mut bx, target) ;
311327 return
312328 }
@@ -337,6 +353,7 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
337353 bx. fn_type_of_instance ( & drop_fn) )
338354 }
339355 } ;
356+ bx. sideeffect ( ) ;
340357 helper. do_call ( self , & mut bx, fn_ty, drop_fn, args,
341358 Some ( ( ReturnDest :: Nothing , target) ) ,
342359 unwind) ;
@@ -372,6 +389,7 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
372389
373390 // Don't codegen the panic block if success if known.
374391 if const_cond == Some ( expected) {
392+ helper. maybe_sideeffect ( & mut bx, & [ target] ) ;
375393 helper. funclet_br ( self , & mut bx, target) ;
376394 return ;
377395 }
@@ -382,6 +400,7 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
382400 // Create the failure block and the conditional branch to it.
383401 let lltarget = helper. llblock ( self , target) ;
384402 let panic_block = self . new_block ( "panic" ) ;
403+ helper. maybe_sideeffect ( & mut bx, & [ target] ) ;
385404 if expected {
386405 bx. cond_br ( cond, lltarget, panic_block. llbb ( ) ) ;
387406 } else {
@@ -435,6 +454,7 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
435454 let fn_ty = bx. fn_type_of_instance ( & instance) ;
436455 let llfn = bx. get_fn ( instance) ;
437456
457+ bx. sideeffect ( ) ;
438458 // Codegen the actual panic invoke/call.
439459 helper. do_call ( self , & mut bx, fn_ty, llfn, & args, None , cleanup) ;
440460 }
@@ -486,6 +506,7 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
486506 if let Some ( destination_ref) = destination. as_ref ( ) {
487507 let & ( ref dest, target) = destination_ref;
488508 self . codegen_transmute ( & mut bx, & args[ 0 ] , dest) ;
509+ helper. maybe_sideeffect ( & mut bx, & [ target] ) ;
489510 helper. funclet_br ( self , & mut bx, target) ;
490511 } else {
491512 // If we are trying to transmute to an uninhabited type,
@@ -516,6 +537,7 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
516537 Some ( ty:: InstanceDef :: DropGlue ( _, None ) ) => {
517538 // Empty drop glue; a no-op.
518539 let & ( _, target) = destination. as_ref ( ) . unwrap ( ) ;
540+ helper. maybe_sideeffect ( & mut bx, & [ target] ) ;
519541 helper. funclet_br ( self , & mut bx, target) ;
520542 return ;
521543 }
@@ -552,6 +574,7 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
552574 let fn_ty = bx. fn_type_of_instance ( & instance) ;
553575 let llfn = bx. get_fn ( instance) ;
554576
577+ bx. sideeffect ( ) ;
555578 // Codegen the actual panic invoke/call.
556579 helper. do_call (
557580 self ,
@@ -564,7 +587,9 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
564587 ) ;
565588 } else {
566589 // a NOP
567- helper. funclet_br ( self , & mut bx, destination. as_ref ( ) . unwrap ( ) . 1 )
590+ let target = destination. as_ref ( ) . unwrap ( ) . 1 ;
591+ helper. maybe_sideeffect ( & mut bx, & [ target] ) ;
592+ helper. funclet_br ( self , & mut bx, target) ;
568593 }
569594 return ;
570595 }
@@ -668,6 +693,7 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
668693 }
669694
670695 if let Some ( ( _, target) ) = * destination {
696+ helper. maybe_sideeffect ( & mut bx, & [ target] ) ;
671697 helper. funclet_br ( self , & mut bx, target) ;
672698 } else {
673699 bx. unreachable ( ) ;
@@ -790,6 +816,7 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
790816 _ => span_bug ! ( span, "no llfn for call" ) ,
791817 } ;
792818
819+ bx. sideeffect ( ) ;
793820 helper. do_call ( self , & mut bx, fn_ty, fn_ptr, & llargs,
794821 destination. as_ref ( ) . map ( |& ( _, target) | ( ret_dest, target) ) ,
795822 cleanup) ;
@@ -839,6 +866,7 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
839866 }
840867
841868 mir:: TerminatorKind :: Goto { target } => {
869+ helper. maybe_sideeffect ( & mut bx, & [ target] ) ;
842870 helper. funclet_br ( self , & mut bx, target) ;
843871 }
844872
0 commit comments