1; RUN: opt -passes=dfa-jump-threading -dfa-cost-threshold=25 -pass-remarks-missed='dfa-jump-threading' -pass-remarks-output=%t -disable-output %s 2; RUN: FileCheck --input-file %t --check-prefix=REMARK %s 3; RUN: opt -S -passes=dfa-jump-threading %s | FileCheck %s 4 5; This negative test case checks that the optimization doesn't trigger 6; when the code size cost is too high. 7define i32 @negative1(i32 %num) { 8; REMARK: NotProfitable 9; REMARK-NEXT: negative1 10entry: 11 br label %for.body 12 13for.body: 14 %count = phi i32 [ 0, %entry ], [ %inc, %for.inc ] 15 %state = phi i32 [ 1, %entry ], [ %state.next, %for.inc ] 16 switch i32 %state, label %for.inc [ 17 i32 1, label %case1 18 i32 2, label %case2 19 ] 20 21case1: 22 br label %for.inc 23 24case2: 25 %cmp = icmp eq i32 %count, 50 26 %sel = select i1 %cmp, i32 1, i32 2 27 br label %for.inc 28 29for.inc: 30 %state.next = phi i32 [ %sel, %case2 ], [ 1, %for.body ], [ 2, %case1 ] 31 %add1 = add i32 %num, %num 32 %add2 = add i32 %add1, %add1 33 %add3 = add i32 %add2, %add2 34 %add4 = add i32 %add3, %add3 35 %add5 = add i32 %add4, %add4 36 %add6 = add i32 %add5, %add5 37 %add7 = add i32 %add6, %add6 38 %add8 = add i32 %add7, %add7 39 %add9 = add i32 %add8, %add8 40 %add10 = add i32 %add9, %add9 41 %add11 = add i32 %add10, %add10 42 %add12 = add i32 %add11, %add11 43 %add13 = add i32 %add12, %add12 44 %add14 = add i32 %add13, %add13 45 %add15 = add i32 %add14, %add14 46 %add16 = add i32 %add15, %add15 47 %add17 = add i32 %add16, %add16 48 %add18 = add i32 %add17, %add17 49 %add19 = add i32 %add18, %add18 50 %add20 = add i32 %add19, %add19 51 %add21 = add i32 %add20, %add20 52 %add22 = add i32 %add21, %add21 53 %inc = add nsw i32 %count, 1 54 %cmp.exit = icmp slt i32 %inc, %num 55 br i1 %cmp.exit, label %for.body, label %for.end 56 57for.end: 58 ret i32 %add22 59} 60 61declare void @func() 62 63define i32 @negative2(i32 %num) { 64; REMARK: NonDuplicatableInst 65; REMARK-NEXT: negative2 66entry: 67 br label %for.body 68 69for.body: 70 %count = phi i32 [ 0, %entry ], [ %inc, %for.inc ] 71 %state = phi i32 [ 1, %entry ], [ %state.next, %for.inc ] 72 switch i32 %state, label %for.inc [ 73 i32 1, label %case1 74 i32 2, label %case2 75 ] 76 77case1: 78 br label %for.inc 79 80case2: 81 %cmp = icmp eq i32 %count, 50 82 %sel = select i1 %cmp, i32 1, i32 2 83 br label %for.inc 84 85for.inc: 86 %state.next = phi i32 [ %sel, %case2 ], [ 1, %for.body ], [ 2, %case1 ] 87 call void @func() noduplicate 88 %inc = add nsw i32 %count, 1 89 %cmp.exit = icmp slt i32 %inc, %num 90 br i1 %cmp.exit, label %for.body, label %for.end 91 92for.end: 93 ret i32 0 94} 95 96define i32 @negative3(i32 %num) { 97; REMARK: ConvergentInst 98; REMARK-NEXT: negative3 99entry: 100 br label %for.body 101 102for.body: 103 %count = phi i32 [ 0, %entry ], [ %inc, %for.inc ] 104 %state = phi i32 [ 1, %entry ], [ %state.next, %for.inc ] 105 switch i32 %state, label %for.inc [ 106 i32 1, label %case1 107 i32 2, label %case2 108 ] 109 110case1: 111 br label %for.inc 112 113case2: 114 %cmp = icmp eq i32 %count, 50 115 %sel = select i1 %cmp, i32 1, i32 2 116 br label %for.inc 117 118for.inc: 119 %state.next = phi i32 [ %sel, %case2 ], [ 1, %for.body ], [ 2, %case1 ] 120 call void @func() convergent 121 %inc = add nsw i32 %count, 1 122 %cmp.exit = icmp slt i32 %inc, %num 123 br i1 %cmp.exit, label %for.body, label %for.end 124 125for.end: 126 ret i32 0 127} 128 129define i32 @negative4(i32 %num) { 130; REMARK: SwitchNotPredictable 131; REMARK-NEXT: negative4 132entry: 133 br label %for.body 134 135for.body: 136 %count = phi i32 [ 0, %entry ], [ %inc, %for.inc ] 137 %state = phi i32 [ 1, %entry ], [ %state.next, %for.inc ] 138 switch i32 %state, label %for.inc [ 139 i32 1, label %case1 140 i32 2, label %case2 141 ] 142 143case1: 144 br label %for.inc 145 146case2: 147 %cmp = icmp eq i32 %count, 50 148 %sel = select i1 %cmp, i32 1, i32 2 149 br label %for.inc 150 151for.inc: 152 ; the switch variable is not predictable since the exit value for %case1 153 ; is defined through a non-instruction (function argument). 154 %state.next = phi i32 [ %sel, %case2 ], [ 1, %for.body ], [ %num, %case1 ] 155 %inc = add nsw i32 %count, 1 156 %cmp.exit = icmp slt i32 %inc, %num 157 br i1 %cmp.exit, label %for.body, label %for.end 158 159for.end: 160 ret i32 0 161} 162 163; Do not optimize if marked minsize. 164define i32 @negative5(i32 %num) minsize { 165; CHECK-LABEL: @negative5( 166; CHECK-NEXT: entry: 167; CHECK-NEXT: br label [[FOR_BODY:%.*]] 168; CHECK: for.body: 169; CHECK-NEXT: [[COUNT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_INC:%.*]] ] 170; CHECK-NEXT: [[STATE:%.*]] = phi i32 [ 1, [[ENTRY]] ], [ [[STATE_NEXT:%.*]], [[FOR_INC]] ] 171; CHECK-NEXT: switch i32 [[STATE]], label [[FOR_INC]] [ 172; CHECK-NEXT: i32 1, label [[CASE1:%.*]] 173; CHECK-NEXT: i32 2, label [[CASE2:%.*]] 174; CHECK-NEXT: ] 175; CHECK: case1: 176; CHECK-NEXT: br label [[FOR_INC]] 177; CHECK: case2: 178; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[COUNT]], 50 179; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i32 1, i32 2 180; CHECK-NEXT: br label [[FOR_INC]] 181; CHECK: for.inc: 182; CHECK-NEXT: [[STATE_NEXT]] = phi i32 [ [[SEL]], [[CASE2]] ], [ 1, [[FOR_BODY]] ], [ 2, [[CASE1]] ] 183; CHECK-NEXT: [[INC]] = add nsw i32 [[COUNT]], 1 184; CHECK-NEXT: [[CMP_EXIT:%.*]] = icmp slt i32 [[INC]], [[NUM:%.*]] 185; CHECK-NEXT: br i1 [[CMP_EXIT]], label [[FOR_BODY]], label [[FOR_END:%.*]] 186; CHECK: for.end: 187; CHECK-NEXT: ret i32 0 188; 189entry: 190 br label %for.body 191 192for.body: 193 %count = phi i32 [ 0, %entry ], [ %inc, %for.inc ] 194 %state = phi i32 [ 1, %entry ], [ %state.next, %for.inc ] 195 switch i32 %state, label %for.inc [ 196 i32 1, label %case1 197 i32 2, label %case2 198 ] 199 200case1: 201 br label %for.inc 202 203case2: 204 %cmp = icmp eq i32 %count, 50 205 %sel = select i1 %cmp, i32 1, i32 2 206 br label %for.inc 207 208for.inc: 209 %state.next = phi i32 [ %sel, %case2 ], [ 1, %for.body ], [ 2, %case1 ] 210 %inc = add nsw i32 %count, 1 211 %cmp.exit = icmp slt i32 %inc, %num 212 br i1 %cmp.exit, label %for.body, label %for.end 213 214for.end: 215 ret i32 0 216} 217 218declare i32 @arbitrary_function() 219 220; Don't confuse %state.2 for the initial switch value. 221; [ 3, %case2 ] can still be threaded. 222define i32 @negative6(i32 %init) { 223; CHECK-LABEL: define i32 @negative6( 224; CHECK-SAME: i32 [[INIT:%.*]]) { 225; CHECK-NEXT: [[ENTRY:.*:]] 226; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[INIT]], 0 227; CHECK-NEXT: br label %[[LOOP_2:.*]] 228; CHECK: [[LOOP_2]]: 229; CHECK-NEXT: [[STATE_2:%.*]] = call i32 @arbitrary_function() 230; CHECK-NEXT: br label %[[LOOP_3:.*]] 231; CHECK: [[LOOP_3]]: 232; CHECK-NEXT: [[STATE:%.*]] = phi i32 [ [[STATE_2]], %[[LOOP_2]] ] 233; CHECK-NEXT: switch i32 [[STATE]], label %[[INFLOOP_I:.*]] [ 234; CHECK-NEXT: i32 2, label %[[CASE2:.*]] 235; CHECK-NEXT: i32 3, label %[[CASE3:.*]] 236; CHECK-NEXT: i32 4, label %[[CASE4:.*]] 237; CHECK-NEXT: i32 0, label %[[CASE0:.*]] 238; CHECK-NEXT: i32 1, label %[[CASE1:.*]] 239; CHECK-NEXT: ] 240; CHECK: [[LOOP_3_JT3:.*]]: 241; CHECK-NEXT: [[STATE_JT3:%.*]] = phi i32 [ 3, %[[CASE2]] ] 242; CHECK-NEXT: br label %[[CASE3]] 243; CHECK: [[CASE2]]: 244; CHECK-NEXT: br label %[[LOOP_3_JT3]] 245; CHECK: [[CASE3]]: 246; CHECK-NEXT: br i1 [[CMP]], label %[[LOOP_2_BACKEDGE:.*]], label %[[CASE4]] 247; CHECK: [[CASE4]]: 248; CHECK-NEXT: br label %[[LOOP_2_BACKEDGE]] 249; CHECK: [[LOOP_2_BACKEDGE]]: 250; CHECK-NEXT: br label %[[LOOP_2]] 251; CHECK: [[CASE0]]: 252; CHECK-NEXT: br label %[[EXIT:.*]] 253; CHECK: [[CASE1]]: 254; CHECK-NEXT: br label %[[EXIT]] 255; CHECK: [[INFLOOP_I]]: 256; CHECK-NEXT: br label %[[INFLOOP_I]] 257; CHECK: [[EXIT]]: 258; CHECK-NEXT: ret i32 0 259; 260entry: 261 %cmp = icmp eq i32 %init, 0 262 br label %loop.2 263 264loop.2: 265 %state.2 = call i32 @arbitrary_function() 266 br label %loop.3 267 268loop.3: 269 %state = phi i32 [ %state.2, %loop.2 ], [ 3, %case2 ] 270 switch i32 %state, label %infloop.i [ 271 i32 2, label %case2 272 i32 3, label %case3 273 i32 4, label %case4 274 i32 0, label %case0 275 i32 1, label %case1 276 ] 277 278case2: 279 br label %loop.3 280 281case3: 282 br i1 %cmp, label %loop.2.backedge, label %case4 283 284case4: 285 br label %loop.2.backedge 286 287loop.2.backedge: 288 br label %loop.2 289 290case0: 291 br label %exit 292 293case1: 294 br label %exit 295 296infloop.i: 297 br label %infloop.i 298 299exit: 300 ret i32 0 301} 302