@@ -149,6 +149,18 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'a, 'tcx> {
149
149
}
150
150
}
151
151
}
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
+ }
152
164
}
153
165
154
166
/// Codegen implementations for some terminator variants.
@@ -197,6 +209,7 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
197
209
let lltrue = helper. llblock ( self , targets[ 0 ] ) ;
198
210
let llfalse = helper. llblock ( self , targets[ 1 ] ) ;
199
211
if switch_ty == bx. tcx ( ) . types . bool {
212
+ helper. maybe_sideeffect ( & mut bx, targets. as_slice ( ) ) ;
200
213
// Don't generate trivial icmps when switching on bool
201
214
if let [ 0 ] = values[ ..] {
202
215
bx. cond_br ( discr. immediate ( ) , llfalse, lltrue) ;
@@ -210,9 +223,11 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
210
223
) ;
211
224
let llval = bx. const_uint_big ( switch_llty, values[ 0 ] ) ;
212
225
let cmp = bx. icmp ( IntPredicate :: IntEQ , discr. immediate ( ) , llval) ;
226
+ helper. maybe_sideeffect ( & mut bx, targets. as_slice ( ) ) ;
213
227
bx. cond_br ( cmp, lltrue, llfalse) ;
214
228
}
215
229
} else {
230
+ helper. maybe_sideeffect ( & mut bx, targets. as_slice ( ) ) ;
216
231
let ( otherwise, targets) = targets. split_last ( ) . unwrap ( ) ;
217
232
bx. switch (
218
233
discr. immediate ( ) ,
@@ -307,6 +322,7 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
307
322
308
323
if let ty:: InstanceDef :: DropGlue ( _, None ) = drop_fn. def {
309
324
// we don't actually need to drop anything.
325
+ helper. maybe_sideeffect ( & mut bx, & [ target] ) ;
310
326
helper. funclet_br ( self , & mut bx, target) ;
311
327
return
312
328
}
@@ -337,6 +353,7 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
337
353
bx. fn_type_of_instance ( & drop_fn) )
338
354
}
339
355
} ;
356
+ bx. sideeffect ( ) ;
340
357
helper. do_call ( self , & mut bx, fn_ty, drop_fn, args,
341
358
Some ( ( ReturnDest :: Nothing , target) ) ,
342
359
unwind) ;
@@ -372,6 +389,7 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
372
389
373
390
// Don't codegen the panic block if success if known.
374
391
if const_cond == Some ( expected) {
392
+ helper. maybe_sideeffect ( & mut bx, & [ target] ) ;
375
393
helper. funclet_br ( self , & mut bx, target) ;
376
394
return ;
377
395
}
@@ -382,6 +400,7 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
382
400
// Create the failure block and the conditional branch to it.
383
401
let lltarget = helper. llblock ( self , target) ;
384
402
let panic_block = self . new_block ( "panic" ) ;
403
+ helper. maybe_sideeffect ( & mut bx, & [ target] ) ;
385
404
if expected {
386
405
bx. cond_br ( cond, lltarget, panic_block. llbb ( ) ) ;
387
406
} else {
@@ -435,6 +454,7 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
435
454
let fn_ty = bx. fn_type_of_instance ( & instance) ;
436
455
let llfn = bx. get_fn ( instance) ;
437
456
457
+ bx. sideeffect ( ) ;
438
458
// Codegen the actual panic invoke/call.
439
459
helper. do_call ( self , & mut bx, fn_ty, llfn, & args, None , cleanup) ;
440
460
}
@@ -486,6 +506,7 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
486
506
if let Some ( destination_ref) = destination. as_ref ( ) {
487
507
let & ( ref dest, target) = destination_ref;
488
508
self . codegen_transmute ( & mut bx, & args[ 0 ] , dest) ;
509
+ helper. maybe_sideeffect ( & mut bx, & [ target] ) ;
489
510
helper. funclet_br ( self , & mut bx, target) ;
490
511
} else {
491
512
// 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> {
516
537
Some ( ty:: InstanceDef :: DropGlue ( _, None ) ) => {
517
538
// Empty drop glue; a no-op.
518
539
let & ( _, target) = destination. as_ref ( ) . unwrap ( ) ;
540
+ helper. maybe_sideeffect ( & mut bx, & [ target] ) ;
519
541
helper. funclet_br ( self , & mut bx, target) ;
520
542
return ;
521
543
}
@@ -552,6 +574,7 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
552
574
let fn_ty = bx. fn_type_of_instance ( & instance) ;
553
575
let llfn = bx. get_fn ( instance) ;
554
576
577
+ bx. sideeffect ( ) ;
555
578
// Codegen the actual panic invoke/call.
556
579
helper. do_call (
557
580
self ,
@@ -564,7 +587,9 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
564
587
) ;
565
588
} else {
566
589
// 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) ;
568
593
}
569
594
return ;
570
595
}
@@ -668,6 +693,7 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
668
693
}
669
694
670
695
if let Some ( ( _, target) ) = * destination {
696
+ helper. maybe_sideeffect ( & mut bx, & [ target] ) ;
671
697
helper. funclet_br ( self , & mut bx, target) ;
672
698
} else {
673
699
bx. unreachable ( ) ;
@@ -779,6 +805,7 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
779
805
_ => span_bug ! ( span, "no llfn for call" ) ,
780
806
} ;
781
807
808
+ bx. sideeffect ( ) ;
782
809
helper. do_call ( self , & mut bx, fn_ty, fn_ptr, & llargs,
783
810
destination. as_ref ( ) . map ( |& ( _, target) | ( ret_dest, target) ) ,
784
811
cleanup) ;
@@ -828,6 +855,7 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
828
855
}
829
856
830
857
mir:: TerminatorKind :: Goto { target } => {
858
+ helper. maybe_sideeffect ( & mut bx, & [ target] ) ;
831
859
helper. funclet_br ( self , & mut bx, target) ;
832
860
}
833
861
0 commit comments