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