@@ -148,6 +148,24 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'a, 'tcx> {
148
148
}
149
149
}
150
150
}
151
+
152
+ // Generate sideeffect intrinsic if jumping to any of the targets can form
153
+ // a loop.
154
+ fn maybe_sideeffect < ' b , ' tcx2 : ' b , Bx : BuilderMethods < ' b , ' tcx2 > > (
155
+ & self ,
156
+ mir : & ' b mir:: Body < ' tcx > ,
157
+ bx : & mut Bx ,
158
+ targets : & [ mir:: BasicBlock ] ,
159
+ ) {
160
+ if targets. iter ( ) . any ( |target| {
161
+ * target <= * self . bb
162
+ && target
163
+ . start_location ( )
164
+ . is_predecessor_of ( self . bb . start_location ( ) , mir)
165
+ } ) {
166
+ bx. sideeffect ( ) ;
167
+ }
168
+ }
151
169
}
152
170
153
171
/// Codegen implementations for some terminator variants.
@@ -196,6 +214,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
196
214
let lltrue = helper. llblock ( self , targets[ 0 ] ) ;
197
215
let llfalse = helper. llblock ( self , targets[ 1 ] ) ;
198
216
if switch_ty == bx. tcx ( ) . types . bool {
217
+ helper. maybe_sideeffect ( self . mir , & mut bx, targets. as_slice ( ) ) ;
199
218
// Don't generate trivial icmps when switching on bool
200
219
if let [ 0 ] = values[ ..] {
201
220
bx. cond_br ( discr. immediate ( ) , llfalse, lltrue) ;
@@ -209,9 +228,11 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
209
228
) ;
210
229
let llval = bx. const_uint_big ( switch_llty, values[ 0 ] ) ;
211
230
let cmp = bx. icmp ( IntPredicate :: IntEQ , discr. immediate ( ) , llval) ;
231
+ helper. maybe_sideeffect ( self . mir , & mut bx, targets. as_slice ( ) ) ;
212
232
bx. cond_br ( cmp, lltrue, llfalse) ;
213
233
}
214
234
} else {
235
+ helper. maybe_sideeffect ( self . mir , & mut bx, targets. as_slice ( ) ) ;
215
236
let ( otherwise, targets) = targets. split_last ( ) . unwrap ( ) ;
216
237
bx. switch (
217
238
discr. immediate ( ) ,
@@ -310,6 +331,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
310
331
311
332
if let ty:: InstanceDef :: DropGlue ( _, None ) = drop_fn. def {
312
333
// we don't actually need to drop anything.
334
+ helper. maybe_sideeffect ( self . mir , & mut bx, & [ target] ) ;
313
335
helper. funclet_br ( self , & mut bx, target) ;
314
336
return
315
337
}
@@ -340,6 +362,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
340
362
FnType :: of_instance ( & bx, drop_fn) )
341
363
}
342
364
} ;
365
+ bx. sideeffect ( ) ;
343
366
helper. do_call ( self , & mut bx, fn_ty, drop_fn, args,
344
367
Some ( ( ReturnDest :: Nothing , target) ) ,
345
368
unwind) ;
@@ -375,6 +398,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
375
398
376
399
// Don't codegen the panic block if success if known.
377
400
if const_cond == Some ( expected) {
401
+ helper. maybe_sideeffect ( self . mir , & mut bx, & [ target] ) ;
378
402
helper. funclet_br ( self , & mut bx, target) ;
379
403
return ;
380
404
}
@@ -385,6 +409,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
385
409
// Create the failure block and the conditional branch to it.
386
410
let lltarget = helper. llblock ( self , target) ;
387
411
let panic_block = self . new_block ( "panic" ) ;
412
+ helper. maybe_sideeffect ( self . mir , & mut bx, & [ target] ) ;
388
413
if expected {
389
414
bx. cond_br ( cond, lltarget, panic_block. llbb ( ) ) ;
390
415
} else {
@@ -437,6 +462,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
437
462
let fn_ty = FnType :: of_instance ( & bx, instance) ;
438
463
let llfn = bx. get_fn ( instance) ;
439
464
465
+ bx. sideeffect ( ) ;
440
466
// Codegen the actual panic invoke/call.
441
467
helper. do_call ( self , & mut bx, fn_ty, llfn, & args, None , cleanup) ;
442
468
}
@@ -488,6 +514,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
488
514
if let Some ( destination_ref) = destination. as_ref ( ) {
489
515
let & ( ref dest, target) = destination_ref;
490
516
self . codegen_transmute ( & mut bx, & args[ 0 ] , dest) ;
517
+ helper. maybe_sideeffect ( self . mir , & mut bx, & [ target] ) ;
491
518
helper. funclet_br ( self , & mut bx, target) ;
492
519
} else {
493
520
// If we are trying to transmute to an uninhabited type,
@@ -518,6 +545,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
518
545
Some ( ty:: InstanceDef :: DropGlue ( _, None ) ) => {
519
546
// Empty drop glue; a no-op.
520
547
let & ( _, target) = destination. as_ref ( ) . unwrap ( ) ;
548
+ helper. maybe_sideeffect ( self . mir , & mut bx, & [ target] ) ;
521
549
helper. funclet_br ( self , & mut bx, target) ;
522
550
return ;
523
551
}
@@ -554,6 +582,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
554
582
let fn_ty = FnType :: of_instance ( & bx, instance) ;
555
583
let llfn = bx. get_fn ( instance) ;
556
584
585
+ bx. sideeffect ( ) ;
557
586
// Codegen the actual panic invoke/call.
558
587
helper. do_call (
559
588
self ,
@@ -566,7 +595,9 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
566
595
) ;
567
596
} else {
568
597
// a NOP
569
- helper. funclet_br ( self , & mut bx, destination. as_ref ( ) . unwrap ( ) . 1 )
598
+ let target = destination. as_ref ( ) . unwrap ( ) . 1 ;
599
+ helper. maybe_sideeffect ( self . mir , & mut bx, & [ target] ) ;
600
+ helper. funclet_br ( self , & mut bx, target) ;
570
601
}
571
602
return ;
572
603
}
@@ -675,6 +706,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
675
706
}
676
707
677
708
if let Some ( ( _, target) ) = * destination {
709
+ helper. maybe_sideeffect ( self . mir , & mut bx, & [ target] ) ;
678
710
helper. funclet_br ( self , & mut bx, target) ;
679
711
} else {
680
712
bx. unreachable ( ) ;
@@ -786,6 +818,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
786
818
_ => span_bug ! ( span, "no llfn for call" ) ,
787
819
} ;
788
820
821
+ bx. sideeffect ( ) ;
789
822
helper. do_call ( self , & mut bx, fn_ty, fn_ptr, & llargs,
790
823
destination. as_ref ( ) . map ( |& ( _, target) | ( ret_dest, target) ) ,
791
824
cleanup) ;
@@ -835,6 +868,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
835
868
}
836
869
837
870
mir:: TerminatorKind :: Goto { target } => {
871
+ helper. maybe_sideeffect ( self . mir , & mut bx, & [ target] ) ;
838
872
helper. funclet_br ( self , & mut bx, target) ;
839
873
}
840
874
0 commit comments