1; RUN: opt -S -simplifycfg < %s | FileCheck -check-prefix=CHECK %s 2; RUN: opt -S -default-data-layout="p:32:32-p1:16:16" -simplifycfg < %s | FileCheck -check-prefix=DL %s 3 4; TODO: Other tests should also have check lines with datalayout 5 6declare void @foo1() 7 8declare void @foo2() 9 10define void @test1(i32 %V) { 11 %C1 = icmp eq i32 %V, 4 ; <i1> [#uses=1] 12 %C2 = icmp eq i32 %V, 17 ; <i1> [#uses=1] 13 %CN = or i1 %C1, %C2 ; <i1> [#uses=1] 14 br i1 %CN, label %T, label %F 15T: ; preds = %0 16 call void @foo1( ) 17 ret void 18F: ; preds = %0 19 call void @foo2( ) 20 ret void 21; CHECK-LABEL: @test1( 22; CHECK: switch i32 %V, label %F [ 23; CHECK: i32 17, label %T 24; CHECK: i32 4, label %T 25; CHECK: ] 26} 27 28define void @test1_ptr(i32* %V) { 29 %C1 = icmp eq i32* %V, inttoptr (i32 4 to i32*) 30 %C2 = icmp eq i32* %V, inttoptr (i32 17 to i32*) 31 %CN = or i1 %C1, %C2 ; <i1> [#uses=1] 32 br i1 %CN, label %T, label %F 33T: ; preds = %0 34 call void @foo1( ) 35 ret void 36F: ; preds = %0 37 call void @foo2( ) 38 ret void 39; DL-LABEL: @test1_ptr( 40; DL: %magicptr = ptrtoint i32* %V to i32 41; DL: switch i32 %magicptr, label %F [ 42; DL: i32 17, label %T 43; DL: i32 4, label %T 44; DL: ] 45} 46 47define void @test1_ptr_as1(i32 addrspace(1)* %V) { 48 %C1 = icmp eq i32 addrspace(1)* %V, inttoptr (i32 4 to i32 addrspace(1)*) 49 %C2 = icmp eq i32 addrspace(1)* %V, inttoptr (i32 17 to i32 addrspace(1)*) 50 %CN = or i1 %C1, %C2 ; <i1> [#uses=1] 51 br i1 %CN, label %T, label %F 52T: ; preds = %0 53 call void @foo1( ) 54 ret void 55F: ; preds = %0 56 call void @foo2( ) 57 ret void 58; DL-LABEL: @test1_ptr_as1( 59; DL: %magicptr = ptrtoint i32 addrspace(1)* %V to i16 60; DL: switch i16 %magicptr, label %F [ 61; DL: i16 17, label %T 62; DL: i16 4, label %T 63; DL: ] 64} 65 66define void @test2(i32 %V) { 67 %C1 = icmp ne i32 %V, 4 ; <i1> [#uses=1] 68 %C2 = icmp ne i32 %V, 17 ; <i1> [#uses=1] 69 %CN = and i1 %C1, %C2 ; <i1> [#uses=1] 70 br i1 %CN, label %T, label %F 71T: ; preds = %0 72 call void @foo1( ) 73 ret void 74F: ; preds = %0 75 call void @foo2( ) 76 ret void 77; CHECK-LABEL: @test2( 78; CHECK: switch i32 %V, label %T [ 79; CHECK: i32 17, label %F 80; CHECK: i32 4, label %F 81; CHECK: ] 82} 83 84define void @test3(i32 %V) { 85 %C1 = icmp eq i32 %V, 4 ; <i1> [#uses=1] 86 br i1 %C1, label %T, label %N 87N: ; preds = %0 88 %C2 = icmp eq i32 %V, 17 ; <i1> [#uses=1] 89 br i1 %C2, label %T, label %F 90T: ; preds = %N, %0 91 call void @foo1( ) 92 ret void 93F: ; preds = %N 94 call void @foo2( ) 95 ret void 96 97; CHECK-LABEL: @test3( 98; CHECK: switch i32 %V, label %F [ 99; CHECK: i32 4, label %T 100; CHECK: i32 17, label %T 101; CHECK: ] 102} 103 104 105 106define i32 @test4(i8 zeroext %c) nounwind ssp noredzone { 107entry: 108 %cmp = icmp eq i8 %c, 62 109 br i1 %cmp, label %lor.end, label %lor.lhs.false 110 111lor.lhs.false: ; preds = %entry 112 %cmp4 = icmp eq i8 %c, 34 113 br i1 %cmp4, label %lor.end, label %lor.rhs 114 115lor.rhs: ; preds = %lor.lhs.false 116 %cmp8 = icmp eq i8 %c, 92 117 br label %lor.end 118 119lor.end: ; preds = %lor.rhs, %lor.lhs.false, %entry 120 %0 = phi i1 [ true, %lor.lhs.false ], [ true, %entry ], [ %cmp8, %lor.rhs ] 121 %lor.ext = zext i1 %0 to i32 122 ret i32 %lor.ext 123 124; CHECK-LABEL: @test4( 125; CHECK: switch i8 %c, label %lor.rhs [ 126; CHECK: i8 62, label %lor.end 127; CHECK: i8 34, label %lor.end 128; CHECK: i8 92, label %lor.end 129; CHECK: ] 130} 131 132define i32 @test5(i8 zeroext %c) nounwind ssp noredzone { 133entry: 134 switch i8 %c, label %lor.rhs [ 135 i8 62, label %lor.end 136 i8 34, label %lor.end 137 i8 92, label %lor.end 138 ] 139 140lor.rhs: ; preds = %entry 141 %V = icmp eq i8 %c, 92 142 br label %lor.end 143 144lor.end: ; preds = %entry, %entry, %entry, %lor.rhs 145 %0 = phi i1 [ true, %entry ], [ %V, %lor.rhs ], [ true, %entry ], [ true, %entry ] 146 %lor.ext = zext i1 %0 to i32 147 ret i32 %lor.ext 148; CHECK-LABEL: @test5( 149; CHECK: switch i8 %c, label %lor.rhs [ 150; CHECK: i8 62, label %lor.end 151; CHECK: i8 34, label %lor.end 152; CHECK: i8 92, label %lor.end 153; CHECK: ] 154} 155 156 157define i1 @test6({ i32, i32 }* %I) { 158entry: 159 %tmp.1.i = getelementptr { i32, i32 }* %I, i64 0, i32 1 ; <i32*> [#uses=1] 160 %tmp.2.i = load i32* %tmp.1.i ; <i32> [#uses=6] 161 %tmp.2 = icmp eq i32 %tmp.2.i, 14 ; <i1> [#uses=1] 162 br i1 %tmp.2, label %shortcirc_done.4, label %shortcirc_next.0 163shortcirc_next.0: ; preds = %entry 164 %tmp.6 = icmp eq i32 %tmp.2.i, 15 ; <i1> [#uses=1] 165 br i1 %tmp.6, label %shortcirc_done.4, label %shortcirc_next.1 166shortcirc_next.1: ; preds = %shortcirc_next.0 167 %tmp.11 = icmp eq i32 %tmp.2.i, 16 ; <i1> [#uses=1] 168 br i1 %tmp.11, label %shortcirc_done.4, label %shortcirc_next.2 169shortcirc_next.2: ; preds = %shortcirc_next.1 170 %tmp.16 = icmp eq i32 %tmp.2.i, 17 ; <i1> [#uses=1] 171 br i1 %tmp.16, label %shortcirc_done.4, label %shortcirc_next.3 172shortcirc_next.3: ; preds = %shortcirc_next.2 173 %tmp.21 = icmp eq i32 %tmp.2.i, 18 ; <i1> [#uses=1] 174 br i1 %tmp.21, label %shortcirc_done.4, label %shortcirc_next.4 175shortcirc_next.4: ; preds = %shortcirc_next.3 176 %tmp.26 = icmp eq i32 %tmp.2.i, 19 ; <i1> [#uses=1] 177 br label %UnifiedReturnBlock 178shortcirc_done.4: ; preds = %shortcirc_next.3, %shortcirc_next.2, %shortcirc_next.1, %shortcirc_next.0, %entry 179 br label %UnifiedReturnBlock 180UnifiedReturnBlock: ; preds = %shortcirc_done.4, %shortcirc_next.4 181 %UnifiedRetVal = phi i1 [ %tmp.26, %shortcirc_next.4 ], [ true, %shortcirc_done.4 ] ; <i1> [#uses=1] 182 ret i1 %UnifiedRetVal 183 184; CHECK-LABEL: @test6( 185; CHECK: %tmp.2.i.off = add i32 %tmp.2.i, -14 186; CHECK: %switch = icmp ult i32 %tmp.2.i.off, 6 187} 188 189define void @test7(i8 zeroext %c, i32 %x) nounwind ssp noredzone { 190entry: 191 %cmp = icmp ult i32 %x, 32 192 %cmp4 = icmp eq i8 %c, 97 193 %or.cond = or i1 %cmp, %cmp4 194 %cmp9 = icmp eq i8 %c, 99 195 %or.cond11 = or i1 %or.cond, %cmp9 196 br i1 %or.cond11, label %if.then, label %if.end 197 198if.then: ; preds = %entry 199 tail call void @foo1() nounwind noredzone 200 ret void 201 202if.end: ; preds = %entry 203 ret void 204 205; CHECK-LABEL: @test7( 206; CHECK: %cmp = icmp ult i32 %x, 32 207; CHECK: br i1 %cmp, label %if.then, label %switch.early.test 208; CHECK: switch.early.test: 209; CHECK: switch i8 %c, label %if.end [ 210; CHECK: i8 99, label %if.then 211; CHECK: i8 97, label %if.then 212; CHECK: ] 213} 214 215define i32 @test8(i8 zeroext %c, i32 %x, i1 %C) nounwind ssp noredzone { 216entry: 217 br i1 %C, label %N, label %if.then 218N: 219 %cmp = icmp ult i32 %x, 32 220 %cmp4 = icmp eq i8 %c, 97 221 %or.cond = or i1 %cmp, %cmp4 222 %cmp9 = icmp eq i8 %c, 99 223 %or.cond11 = or i1 %or.cond, %cmp9 224 br i1 %or.cond11, label %if.then, label %if.end 225 226if.then: ; preds = %entry 227 %A = phi i32 [0, %entry], [42, %N] 228 tail call void @foo1() nounwind noredzone 229 ret i32 %A 230 231if.end: ; preds = %entry 232 ret i32 0 233 234; CHECK-LABEL: @test8( 235; CHECK: switch.early.test: 236; CHECK: switch i8 %c, label %if.end [ 237; CHECK: i8 99, label %if.then 238; CHECK: i8 97, label %if.then 239; CHECK: ] 240; CHECK: %A = phi i32 [ 0, %entry ], [ 42, %switch.early.test ], [ 42, %N ], [ 42, %switch.early.test ] 241} 242 243;; This is "Example 7" from http://blog.regehr.org/archives/320 244define i32 @test9(i8 zeroext %c) nounwind ssp noredzone { 245entry: 246 %cmp = icmp ult i8 %c, 33 247 br i1 %cmp, label %lor.end, label %lor.lhs.false 248 249lor.lhs.false: ; preds = %entry 250 %cmp4 = icmp eq i8 %c, 46 251 br i1 %cmp4, label %lor.end, label %lor.lhs.false6 252 253lor.lhs.false6: ; preds = %lor.lhs.false 254 %cmp9 = icmp eq i8 %c, 44 255 br i1 %cmp9, label %lor.end, label %lor.lhs.false11 256 257lor.lhs.false11: ; preds = %lor.lhs.false6 258 %cmp14 = icmp eq i8 %c, 58 259 br i1 %cmp14, label %lor.end, label %lor.lhs.false16 260 261lor.lhs.false16: ; preds = %lor.lhs.false11 262 %cmp19 = icmp eq i8 %c, 59 263 br i1 %cmp19, label %lor.end, label %lor.lhs.false21 264 265lor.lhs.false21: ; preds = %lor.lhs.false16 266 %cmp24 = icmp eq i8 %c, 60 267 br i1 %cmp24, label %lor.end, label %lor.lhs.false26 268 269lor.lhs.false26: ; preds = %lor.lhs.false21 270 %cmp29 = icmp eq i8 %c, 62 271 br i1 %cmp29, label %lor.end, label %lor.lhs.false31 272 273lor.lhs.false31: ; preds = %lor.lhs.false26 274 %cmp34 = icmp eq i8 %c, 34 275 br i1 %cmp34, label %lor.end, label %lor.lhs.false36 276 277lor.lhs.false36: ; preds = %lor.lhs.false31 278 %cmp39 = icmp eq i8 %c, 92 279 br i1 %cmp39, label %lor.end, label %lor.rhs 280 281lor.rhs: ; preds = %lor.lhs.false36 282 %cmp43 = icmp eq i8 %c, 39 283 br label %lor.end 284 285lor.end: ; preds = %lor.rhs, %lor.lhs.false36, %lor.lhs.false31, %lor.lhs.false26, %lor.lhs.false21, %lor.lhs.false16, %lor.lhs.false11, %lor.lhs.false6, %lor.lhs.false, %entry 286 %0 = phi i1 [ true, %lor.lhs.false36 ], [ true, %lor.lhs.false31 ], [ true, %lor.lhs.false26 ], [ true, %lor.lhs.false21 ], [ true, %lor.lhs.false16 ], [ true, %lor.lhs.false11 ], [ true, %lor.lhs.false6 ], [ true, %lor.lhs.false ], [ true, %entry ], [ %cmp43, %lor.rhs ] 287 %conv46 = zext i1 %0 to i32 288 ret i32 %conv46 289 290; CHECK-LABEL: @test9( 291; CHECK: %cmp = icmp ult i8 %c, 33 292; CHECK: br i1 %cmp, label %lor.end, label %switch.early.test 293 294; CHECK: switch.early.test: 295; CHECK: switch i8 %c, label %lor.rhs [ 296; CHECK: i8 92, label %lor.end 297; CHECK: i8 62, label %lor.end 298; CHECK: i8 60, label %lor.end 299; CHECK: i8 59, label %lor.end 300; CHECK: i8 58, label %lor.end 301; CHECK: i8 46, label %lor.end 302; CHECK: i8 44, label %lor.end 303; CHECK: i8 34, label %lor.end 304; CHECK: i8 39, label %lor.end 305; CHECK: ] 306} 307 308define i32 @test10(i32 %mode, i1 %Cond) { 309 %A = icmp ne i32 %mode, 0 310 %B = icmp ne i32 %mode, 51 311 %C = and i1 %A, %B 312 %D = and i1 %C, %Cond 313 br i1 %D, label %T, label %F 314T: 315 ret i32 123 316F: 317 ret i32 324 318 319; CHECK-LABEL: @test10( 320; CHECK: br i1 %Cond, label %switch.early.test, label %F 321; CHECK:switch.early.test: 322; CHECK: switch i32 %mode, label %T [ 323; CHECK: i32 51, label %F 324; CHECK: i32 0, label %F 325; CHECK: ] 326} 327 328; PR8780 329define i32 @test11(i32 %bar) nounwind { 330entry: 331 %cmp = icmp eq i32 %bar, 4 332 %cmp2 = icmp eq i32 %bar, 35 333 %or.cond = or i1 %cmp, %cmp2 334 %cmp5 = icmp eq i32 %bar, 53 335 %or.cond1 = or i1 %or.cond, %cmp5 336 %cmp8 = icmp eq i32 %bar, 24 337 %or.cond2 = or i1 %or.cond1, %cmp8 338 %cmp11 = icmp eq i32 %bar, 23 339 %or.cond3 = or i1 %or.cond2, %cmp11 340 %cmp14 = icmp eq i32 %bar, 55 341 %or.cond4 = or i1 %or.cond3, %cmp14 342 %cmp17 = icmp eq i32 %bar, 12 343 %or.cond5 = or i1 %or.cond4, %cmp17 344 %cmp20 = icmp eq i32 %bar, 35 345 %or.cond6 = or i1 %or.cond5, %cmp20 346 br i1 %or.cond6, label %if.then, label %if.end 347 348if.then: ; preds = %entry 349 br label %return 350 351if.end: ; preds = %entry 352 br label %return 353 354return: ; preds = %if.end, %if.then 355 %retval.0 = phi i32 [ 1, %if.then ], [ 0, %if.end ] 356 ret i32 %retval.0 357 358; CHECK-LABEL: @test11( 359; CHECK: switch i32 %bar, label %if.end [ 360; CHECK: i32 55, label %return 361; CHECK: i32 53, label %return 362; CHECK: i32 35, label %return 363; CHECK: i32 24, label %return 364; CHECK: i32 23, label %return 365; CHECK: i32 12, label %return 366; CHECK: i32 4, label %return 367; CHECK: ] 368} 369 370define void @test12() nounwind { 371entry: 372 br label %bb49.us.us 373 374bb49.us.us: 375 %A = icmp eq i32 undef, undef 376 br i1 %A, label %bb55.us.us, label %malformed 377 378bb48.us.us: 379 %B = icmp ugt i32 undef, undef 380 br i1 %B, label %bb55.us.us, label %bb49.us.us 381 382bb55.us.us: 383 br label %bb48.us.us 384 385malformed: 386 ret void 387; CHECK-LABEL: @test12( 388 389} 390 391; test13 - handle switch formation with ult. 392define void @test13(i32 %x) nounwind ssp noredzone { 393entry: 394 %cmp = icmp ult i32 %x, 2 395 br i1 %cmp, label %if.then, label %lor.lhs.false3 396 397lor.lhs.false3: ; preds = %lor.lhs.false 398 %cmp5 = icmp eq i32 %x, 3 399 br i1 %cmp5, label %if.then, label %lor.lhs.false6 400 401lor.lhs.false6: ; preds = %lor.lhs.false3 402 %cmp8 = icmp eq i32 %x, 4 403 br i1 %cmp8, label %if.then, label %lor.lhs.false9 404 405lor.lhs.false9: ; preds = %lor.lhs.false6 406 %cmp11 = icmp eq i32 %x, 6 407 br i1 %cmp11, label %if.then, label %if.end 408 409if.then: ; preds = %lor.lhs.false9, %lor.lhs.false6, %lor.lhs.false3, %lor.lhs.false, %entry 410 call void @foo1() noredzone 411 br label %if.end 412 413if.end: ; preds = %if.then, %lor.lhs.false9 414 ret void 415; CHECK-LABEL: @test13( 416; CHECK: switch i32 %x, label %if.end [ 417; CHECK: i32 6, label %if.then 418; CHECK: i32 4, label %if.then 419; CHECK: i32 3, label %if.then 420; CHECK: i32 1, label %if.then 421; CHECK: i32 0, label %if.then 422; CHECK: ] 423} 424 425; test14 - handle switch formation with ult. 426define void @test14(i32 %x) nounwind ssp noredzone { 427entry: 428 %cmp = icmp ugt i32 %x, 2 429 br i1 %cmp, label %lor.lhs.false3, label %if.then 430 431lor.lhs.false3: ; preds = %lor.lhs.false 432 %cmp5 = icmp ne i32 %x, 3 433 br i1 %cmp5, label %lor.lhs.false6, label %if.then 434 435lor.lhs.false6: ; preds = %lor.lhs.false3 436 %cmp8 = icmp ne i32 %x, 4 437 br i1 %cmp8, label %lor.lhs.false9, label %if.then 438 439lor.lhs.false9: ; preds = %lor.lhs.false6 440 %cmp11 = icmp ne i32 %x, 6 441 br i1 %cmp11, label %if.end, label %if.then 442 443if.then: ; preds = %lor.lhs.false9, %lor.lhs.false6, %lor.lhs.false3, %lor.lhs.false, %entry 444 call void @foo1() noredzone 445 br label %if.end 446 447if.end: ; preds = %if.then, %lor.lhs.false9 448 ret void 449; CHECK-LABEL: @test14( 450; CHECK: switch i32 %x, label %if.end [ 451; CHECK: i32 6, label %if.then 452; CHECK: i32 4, label %if.then 453; CHECK: i32 3, label %if.then 454; CHECK: i32 1, label %if.then 455; CHECK: i32 0, label %if.then 456; CHECK: ] 457} 458 459; Don't crash on ginormous ranges. 460define void @test15(i128 %x) nounwind { 461 %cmp = icmp ugt i128 %x, 2 462 br i1 %cmp, label %if.end, label %lor.false 463 464lor.false: 465 %cmp2 = icmp ne i128 %x, 100000000000000000000 466 br i1 %cmp2, label %if.end, label %if.then 467 468if.then: 469 call void @foo1() noredzone 470 br label %if.end 471 472if.end: 473 ret void 474 475; CHECK-LABEL: @test15( 476; CHECK-NOT: switch 477; CHECK: ret void 478} 479 480; PR8675 481; rdar://5134905 482define zeroext i1 @test16(i32 %x) nounwind { 483entry: 484; CHECK-LABEL: @test16( 485; CHECK: %x.off = add i32 %x, -1 486; CHECK: %switch = icmp ult i32 %x.off, 3 487 %cmp.i = icmp eq i32 %x, 1 488 br i1 %cmp.i, label %lor.end, label %lor.lhs.false 489 490lor.lhs.false: 491 %cmp.i2 = icmp eq i32 %x, 2 492 br i1 %cmp.i2, label %lor.end, label %lor.rhs 493 494lor.rhs: 495 %cmp.i1 = icmp eq i32 %x, 3 496 br label %lor.end 497 498lor.end: 499 %0 = phi i1 [ true, %lor.lhs.false ], [ true, %entry ], [ %cmp.i1, %lor.rhs ] 500 ret i1 %0 501} 502 503; Check that we don't turn an icmp into a switch where it's not useful. 504define void @test17(i32 %x, i32 %y) { 505 %cmp = icmp ult i32 %x, 3 506 %switch = icmp ult i32 %y, 2 507 %or.cond775 = or i1 %cmp, %switch 508 br i1 %or.cond775, label %lor.lhs.false8, label %return 509 510lor.lhs.false8: 511 tail call void @foo1() 512 ret void 513 514return: 515 ret void 516 517; CHECK-LABEL: @test17( 518; CHECK-NOT: switch.early.test 519; CHECK-NOT: switch i32 520; CHECK: ret void 521} 522 523define void @test18(i32 %arg) { 524bb: 525 %tmp = and i32 %arg, -2 526 %tmp1 = icmp eq i32 %tmp, 8 527 %tmp2 = icmp eq i32 %arg, 10 528 %tmp3 = or i1 %tmp1, %tmp2 529 %tmp4 = icmp eq i32 %arg, 11 530 %tmp5 = or i1 %tmp3, %tmp4 531 %tmp6 = icmp eq i32 %arg, 12 532 %tmp7 = or i1 %tmp5, %tmp6 533 br i1 %tmp7, label %bb19, label %bb8 534 535bb8: ; preds = %bb 536 %tmp9 = add i32 %arg, -13 537 %tmp10 = icmp ult i32 %tmp9, 2 538 %tmp11 = icmp eq i32 %arg, 16 539 %tmp12 = or i1 %tmp10, %tmp11 540 %tmp13 = icmp eq i32 %arg, 17 541 %tmp14 = or i1 %tmp12, %tmp13 542 %tmp15 = icmp eq i32 %arg, 18 543 %tmp16 = or i1 %tmp14, %tmp15 544 %tmp17 = icmp eq i32 %arg, 15 545 %tmp18 = or i1 %tmp16, %tmp17 546 br i1 %tmp18, label %bb19, label %bb20 547 548bb19: ; preds = %bb8, %bb 549 tail call void @foo1() 550 br label %bb20 551 552bb20: ; preds = %bb19, %bb8 553 ret void 554 555; CHECK-LABEL: @test18( 556; CHECK: %arg.off = add i32 %arg, -8 557; CHECK: icmp ult i32 %arg.off, 11 558} 559