1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -passes=simplifycfg -simplifycfg-require-and-preserve-domtree=1 -sink-common-insts -S | FileCheck %s 3; RUN: opt < %s -passes='simplifycfg<sink-common-insts>' -S | FileCheck %s 4 5target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" 6target triple = "x86_64-pc-linux-gnu" 7 8; `unreachable` block has conditional predecessors, 9; but everything we'd sink from unconditional predecessors are speculatable. 10; Also, too many phi's would normally be needed. 11define void @t0(i4 %cond, i32 %a, i32 %b, i32 %c, i32 %d, i32 %e, i32 %f, i32 %g, i32 %h) { 12; CHECK-LABEL: @t0( 13; CHECK-NEXT: switch i4 [[COND:%.*]], label [[END:%.*]] [ 14; CHECK-NEXT: i4 0, label [[END_SINK_SPLIT:%.*]] 15; CHECK-NEXT: i4 -1, label [[END_SINK_SPLIT]] 16; CHECK-NEXT: i4 1, label [[BB1:%.*]] 17; CHECK-NEXT: i4 -2, label [[BB1]] 18; CHECK-NEXT: ] 19; CHECK: bb1: 20; CHECK-NEXT: br label [[END_SINK_SPLIT]] 21; CHECK: end.sink.split: 22; CHECK-NEXT: [[H_SINK:%.*]] = phi i32 [ [[H:%.*]], [[BB1]] ], [ [[E:%.*]], [[TMP0:%.*]] ], [ [[E]], [[TMP0]] ] 23; CHECK-NEXT: [[G_SINK:%.*]] = phi i32 [ [[G:%.*]], [[BB1]] ], [ [[D:%.*]], [[TMP0]] ], [ [[D]], [[TMP0]] ] 24; CHECK-NEXT: [[V4:%.*]] = add i32 [[A:%.*]], [[B:%.*]] 25; CHECK-NEXT: [[V5:%.*]] = add i32 [[V4]], [[C:%.*]] 26; CHECK-NEXT: [[V6:%.*]] = add i32 [[G_SINK]], [[H_SINK]] 27; CHECK-NEXT: [[R7:%.*]] = add i32 [[V5]], [[V6]] 28; CHECK-NEXT: call void @use32(i32 [[R7]]) 29; CHECK-NEXT: unreachable 30; CHECK: end: 31; CHECK-NEXT: unreachable 32; 33 switch i4 %cond, label %end [ 34 i4 0, label %bb0 35 i4 -1, label %bb0 36 i4 1, label %bb1 37 i4 -2, label %bb1 38 ] 39 40bb0: 41 %v0 = add i32 %a, %b 42 %v1 = add i32 %v0, %c 43 %v2 = add i32 %d, %e 44 %r3 = add i32 %v1, %v2 45 call void @use32(i32 %r3) 46 br label %end 47 48bb1: 49 %v4 = add i32 %a, %b 50 %v5 = add i32 %v4, %c 51 %v6 = add i32 %g, %h 52 %r7 = add i32 %v5, %v6 53 call void @use32(i32 %r7) 54 br label %end 55 56end: 57 unreachable 58} 59 60; Same, as @t0, but there's also a loop. 61define void @t1(i4 %cond, i1 %cond.loop, i32 %a, i32 %b, i32 %c, i32 %d, i32 %e, i32 %f, i32 %g, i32 %h) { 62; CHECK-LABEL: @t1( 63; CHECK-NEXT: switch i4 [[COND:%.*]], label [[END_EARLY:%.*]] [ 64; CHECK-NEXT: i4 0, label [[BB0:%.*]] 65; CHECK-NEXT: i4 -1, label [[BB0]] 66; CHECK-NEXT: i4 1, label [[BB1:%.*]] 67; CHECK-NEXT: i4 -2, label [[BB1]] 68; CHECK-NEXT: ] 69; CHECK: bb0: 70; CHECK-NEXT: [[V0:%.*]] = add i32 [[A:%.*]], [[B:%.*]] 71; CHECK-NEXT: [[V1:%.*]] = add i32 [[V0]], [[C:%.*]] 72; CHECK-NEXT: [[V2:%.*]] = add i32 [[D:%.*]], [[E:%.*]] 73; CHECK-NEXT: [[R3:%.*]] = add i32 [[V1]], [[V2]] 74; CHECK-NEXT: call void @use32(i32 [[R3]]) 75; CHECK-NEXT: br label [[END_EARLY]] 76; CHECK: bb1: 77; CHECK-NEXT: [[V4:%.*]] = add i32 [[A]], [[B]] 78; CHECK-NEXT: [[V5:%.*]] = add i32 [[V4]], [[C]] 79; CHECK-NEXT: [[V6:%.*]] = add i32 [[G:%.*]], [[H:%.*]] 80; CHECK-NEXT: [[R7:%.*]] = add i32 [[V5]], [[V6]] 81; CHECK-NEXT: call void @use32(i32 [[R7]]) 82; CHECK-NEXT: br label [[END_EARLY]] 83; CHECK: end.early: 84; CHECK-NEXT: call void @sideeffect() 85; CHECK-NEXT: br i1 [[COND_LOOP:%.*]], label [[END_EARLY]], label [[END:%.*]] 86; CHECK: end: 87; CHECK-NEXT: call void @sideeffect() 88; CHECK-NEXT: unreachable 89; 90 switch i4 %cond, label %end.early [ 91 i4 0, label %bb0 92 i4 -1, label %bb0 93 i4 1, label %bb1 94 i4 -2, label %bb1 95 ] 96 97bb0: 98 %v0 = add i32 %a, %b 99 %v1 = add i32 %v0, %c 100 %v2 = add i32 %d, %e 101 %r3 = add i32 %v1, %v2 102 call void @use32(i32 %r3) 103 br label %end.early 104 105bb1: 106 %v4 = add i32 %a, %b 107 %v5 = add i32 %v4, %c 108 %v6 = add i32 %g, %h 109 %r7 = add i32 %v5, %v6 110 call void @use32(i32 %r7) 111 br label %end.early 112 113end.early: 114 call void @sideeffect() 115 br i1 %cond.loop, label %end.early, label %end 116 117end: 118 call void @sideeffect() 119 unreachable 120} 121 122declare void @use32(i32) speculatable 123 124declare void @sideeffect() 125