@@ -149,6 +149,26 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'a, 'tcx> {
149149 }
150150 }
151151 }
152+
153+ // Generate sideeffect intrinsic if jumping to any of the targets can form
154+ // a loop.
155+ fn maybe_sideeffect < ' b , ' tcx2 : ' b , Bx : BuilderMethods < ' b , ' tcx2 > > (
156+ & self ,
157+ mir : & ' b mir:: Body < ' tcx > ,
158+ bx : & mut Bx ,
159+ targets : & [ mir:: BasicBlock ] ,
160+ ) {
161+ if bx. tcx ( ) . sess . opts . debugging_opts . insert_sideeffect {
162+ if targets. iter ( ) . any ( |target| {
163+ * target <= * self . bb
164+ && target
165+ . start_location ( )
166+ . is_predecessor_of ( self . bb . start_location ( ) , mir)
167+ } ) {
168+ bx. sideeffect ( ) ;
169+ }
170+ }
171+ }
152172}
153173
154174/// Codegen implementations for some terminator variants.
@@ -197,6 +217,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
197217 let lltrue = helper. llblock ( self , targets[ 0 ] ) ;
198218 let llfalse = helper. llblock ( self , targets[ 1 ] ) ;
199219 if switch_ty == bx. tcx ( ) . types . bool {
220+ helper. maybe_sideeffect ( self . mir , & mut bx, targets. as_slice ( ) ) ;
200221 // Don't generate trivial icmps when switching on bool
201222 if let [ 0 ] = values[ ..] {
202223 bx. cond_br ( discr. immediate ( ) , llfalse, lltrue) ;
@@ -210,9 +231,11 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
210231 ) ;
211232 let llval = bx. const_uint_big ( switch_llty, values[ 0 ] ) ;
212233 let cmp = bx. icmp ( IntPredicate :: IntEQ , discr. immediate ( ) , llval) ;
234+ helper. maybe_sideeffect ( self . mir , & mut bx, targets. as_slice ( ) ) ;
213235 bx. cond_br ( cmp, lltrue, llfalse) ;
214236 }
215237 } else {
238+ helper. maybe_sideeffect ( self . mir , & mut bx, targets. as_slice ( ) ) ;
216239 let ( otherwise, targets) = targets. split_last ( ) . unwrap ( ) ;
217240 bx. switch (
218241 discr. immediate ( ) ,
@@ -308,6 +331,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
308331
309332 if let ty:: InstanceDef :: DropGlue ( _, None ) = drop_fn. def {
310333 // we don't actually need to drop anything.
334+ helper. maybe_sideeffect ( self . mir , & mut bx, & [ target] ) ;
311335 helper. funclet_br ( self , & mut bx, target) ;
312336 return
313337 }
@@ -338,6 +362,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
338362 FnType :: of_instance ( & bx, drop_fn) )
339363 }
340364 } ;
365+ helper. maybe_sideeffect ( self . mir , & mut bx, & [ target] ) ;
341366 helper. do_call ( self , & mut bx, fn_ty, drop_fn, args,
342367 Some ( ( ReturnDest :: Nothing , target) ) ,
343368 unwind) ;
@@ -373,6 +398,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
373398
374399 // Don't codegen the panic block if success if known.
375400 if const_cond == Some ( expected) {
401+ helper. maybe_sideeffect ( self . mir , & mut bx, & [ target] ) ;
376402 helper. funclet_br ( self , & mut bx, target) ;
377403 return ;
378404 }
@@ -383,6 +409,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
383409 // Create the failure block and the conditional branch to it.
384410 let lltarget = helper. llblock ( self , target) ;
385411 let panic_block = self . new_block ( "panic" ) ;
412+ helper. maybe_sideeffect ( self . mir , & mut bx, & [ target] ) ;
386413 if expected {
387414 bx. cond_br ( cond, lltarget, panic_block. llbb ( ) ) ;
388415 } else {
@@ -486,6 +513,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
486513 if let Some ( destination_ref) = destination. as_ref ( ) {
487514 let & ( ref dest, target) = destination_ref;
488515 self . codegen_transmute ( & mut bx, & args[ 0 ] , dest) ;
516+ helper. maybe_sideeffect ( self . mir , & mut bx, & [ target] ) ;
489517 helper. funclet_br ( self , & mut bx, target) ;
490518 } else {
491519 // If we are trying to transmute to an uninhabited type,
@@ -513,6 +541,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
513541 Some ( ty:: InstanceDef :: DropGlue ( _, None ) ) => {
514542 // Empty drop glue; a no-op.
515543 let & ( _, target) = destination. as_ref ( ) . unwrap ( ) ;
544+ helper. maybe_sideeffect ( self . mir , & mut bx, & [ target] ) ;
516545 helper. funclet_br ( self , & mut bx, target) ;
517546 return ;
518547 }
@@ -549,6 +578,9 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
549578 let fn_ty = FnType :: of_instance ( & bx, instance) ;
550579 let llfn = bx. get_fn ( instance) ;
551580
581+ if let Some ( ( _, target) ) = destination. as_ref ( ) {
582+ helper. maybe_sideeffect ( self . mir , & mut bx, & [ * target] ) ;
583+ }
552584 // Codegen the actual panic invoke/call.
553585 helper. do_call (
554586 self ,
@@ -561,7 +593,9 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
561593 ) ;
562594 } else {
563595 // a NOP
564- helper. funclet_br ( self , & mut bx, destination. as_ref ( ) . unwrap ( ) . 1 )
596+ let target = destination. as_ref ( ) . unwrap ( ) . 1 ;
597+ helper. maybe_sideeffect ( self . mir , & mut bx, & [ target] ) ;
598+ helper. funclet_br ( self , & mut bx, target) ;
565599 }
566600 return ;
567601 }
@@ -670,6 +704,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
670704 }
671705
672706 if let Some ( ( _, target) ) = * destination {
707+ helper. maybe_sideeffect ( self . mir , & mut bx, & [ target] ) ;
673708 helper. funclet_br ( self , & mut bx, target) ;
674709 } else {
675710 bx. unreachable ( ) ;
@@ -762,6 +797,9 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
762797 _ => span_bug ! ( span, "no llfn for call" ) ,
763798 } ;
764799
800+ if let Some ( ( _, target) ) = destination. as_ref ( ) {
801+ helper. maybe_sideeffect ( self . mir , & mut bx, & [ * target] ) ;
802+ }
765803 helper. do_call ( self , & mut bx, fn_ty, fn_ptr, & llargs,
766804 destination. as_ref ( ) . map ( |& ( _, target) | ( ret_dest, target) ) ,
767805 cleanup) ;
@@ -811,6 +849,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
811849 }
812850
813851 mir:: TerminatorKind :: Goto { target } => {
852+ helper. maybe_sideeffect ( self . mir , & mut bx, & [ target] ) ;
814853 helper. funclet_br ( self , & mut bx, target) ;
815854 }
816855
0 commit comments