1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -S -simplifycfg -simplifycfg-require-and-preserve-domtree=1 < %s | FileCheck %s 3target datalayout="p:40:64:64:32" 4 5declare void @foo1() 6 7declare void @foo2() 8 9define void @test1(i32 %V) { 10; CHECK-LABEL: @test1( 11; CHECK-NEXT: switch i32 [[V:%.*]], label [[F:%.*]] [ 12; CHECK-NEXT: i32 17, label [[T:%.*]] 13; CHECK-NEXT: i32 4, label [[T]] 14; CHECK-NEXT: ] 15; CHECK: T: 16; CHECK-NEXT: call void @foo1() 17; CHECK-NEXT: ret void 18; CHECK: F: 19; CHECK-NEXT: call void @foo2() 20; CHECK-NEXT: ret void 21; 22 %C1 = icmp eq i32 %V, 4 ; <i1> [#uses=1] 23 %C2 = icmp eq i32 %V, 17 ; <i1> [#uses=1] 24 %CN = or i1 %C1, %C2 ; <i1> [#uses=1] 25 br i1 %CN, label %T, label %F 26T: ; preds = %0 27 call void @foo1( ) 28 ret void 29F: ; preds = %0 30 call void @foo2( ) 31 ret void 32} 33 34define void @test1_ptr(i32* %V) { 35; CHECK-LABEL: @test1_ptr( 36; CHECK-NEXT: [[MAGICPTR:%.*]] = ptrtoint i32* [[V:%.*]] to i40 37; CHECK-NEXT: switch i40 [[MAGICPTR]], label [[F:%.*]] [ 38; CHECK-NEXT: i40 17, label [[T:%.*]] 39; CHECK-NEXT: i40 4, label [[T]] 40; CHECK-NEXT: ] 41; CHECK: T: 42; CHECK-NEXT: call void @foo1() 43; CHECK-NEXT: ret void 44; CHECK: F: 45; CHECK-NEXT: call void @foo2() 46; CHECK-NEXT: ret void 47; 48 %C1 = icmp eq i32* %V, inttoptr (i32 4 to i32*) 49 %C2 = icmp eq i32* %V, inttoptr (i32 17 to i32*) 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} 59 60define void @test1_ptr_as1(i32 addrspace(1)* %V) { 61; CHECK-LABEL: @test1_ptr_as1( 62; CHECK-NEXT: [[MAGICPTR:%.*]] = ptrtoint i32 addrspace(1)* [[V:%.*]] to i40 63; CHECK-NEXT: switch i40 [[MAGICPTR]], label [[F:%.*]] [ 64; CHECK-NEXT: i40 17, label [[T:%.*]] 65; CHECK-NEXT: i40 4, label [[T]] 66; CHECK-NEXT: ] 67; CHECK: T: 68; CHECK-NEXT: call void @foo1() 69; CHECK-NEXT: ret void 70; CHECK: F: 71; CHECK-NEXT: call void @foo2() 72; CHECK-NEXT: ret void 73; 74 %C1 = icmp eq i32 addrspace(1)* %V, inttoptr (i32 4 to i32 addrspace(1)*) 75 %C2 = icmp eq i32 addrspace(1)* %V, inttoptr (i32 17 to i32 addrspace(1)*) 76 %CN = or i1 %C1, %C2 ; <i1> [#uses=1] 77 br i1 %CN, label %T, label %F 78T: ; preds = %0 79 call void @foo1( ) 80 ret void 81F: ; preds = %0 82 call void @foo2( ) 83 ret void 84} 85 86define void @test2(i32 %V) { 87; CHECK-LABEL: @test2( 88; CHECK-NEXT: switch i32 [[V:%.*]], label [[T:%.*]] [ 89; CHECK-NEXT: i32 17, label [[F:%.*]] 90; CHECK-NEXT: i32 4, label [[F]] 91; CHECK-NEXT: ] 92; CHECK: T: 93; CHECK-NEXT: call void @foo1() 94; CHECK-NEXT: ret void 95; CHECK: F: 96; CHECK-NEXT: call void @foo2() 97; CHECK-NEXT: ret void 98; 99 %C1 = icmp ne i32 %V, 4 ; <i1> [#uses=1] 100 %C2 = icmp ne i32 %V, 17 ; <i1> [#uses=1] 101 %CN = and i1 %C1, %C2 ; <i1> [#uses=1] 102 br i1 %CN, label %T, label %F 103T: ; preds = %0 104 call void @foo1( ) 105 ret void 106F: ; preds = %0 107 call void @foo2( ) 108 ret void 109} 110 111define void @test3(i32 %V) { 112; CHECK-LABEL: @test3( 113; CHECK-NEXT: switch i32 [[V:%.*]], label [[F:%.*]] [ 114; CHECK-NEXT: i32 4, label [[T:%.*]] 115; CHECK-NEXT: i32 17, label [[T]] 116; CHECK-NEXT: ] 117; CHECK: T: 118; CHECK-NEXT: call void @foo1() 119; CHECK-NEXT: ret void 120; CHECK: F: 121; CHECK-NEXT: call void @foo2() 122; CHECK-NEXT: ret void 123; 124 %C1 = icmp eq i32 %V, 4 ; <i1> [#uses=1] 125 br i1 %C1, label %T, label %N 126N: ; preds = %0 127 %C2 = icmp eq i32 %V, 17 ; <i1> [#uses=1] 128 br i1 %C2, label %T, label %F 129T: ; preds = %N, %0 130 call void @foo1( ) 131 ret void 132F: ; preds = %N 133 call void @foo2( ) 134 ret void 135 136} 137 138 139 140define i32 @test4(i8 zeroext %c) nounwind ssp noredzone { 141; CHECK-LABEL: @test4( 142; CHECK-NEXT: entry: 143; CHECK-NEXT: switch i8 [[C:%.*]], label [[LOR_RHS:%.*]] [ 144; CHECK-NEXT: i8 62, label [[LOR_END:%.*]] 145; CHECK-NEXT: i8 34, label [[LOR_END]] 146; CHECK-NEXT: i8 92, label [[LOR_END]] 147; CHECK-NEXT: ] 148; CHECK: lor.rhs: 149; CHECK-NEXT: br label [[LOR_END]] 150; CHECK: lor.end: 151; CHECK-NEXT: [[TMP0:%.*]] = phi i1 [ true, [[ENTRY:%.*]] ], [ false, [[LOR_RHS]] ], [ true, [[ENTRY]] ], [ true, [[ENTRY]] ] 152; CHECK-NEXT: [[LOR_EXT:%.*]] = zext i1 [[TMP0]] to i32 153; CHECK-NEXT: ret i32 [[LOR_EXT]] 154; 155entry: 156 %cmp = icmp eq i8 %c, 62 157 br i1 %cmp, label %lor.end, label %lor.lhs.false 158 159lor.lhs.false: ; preds = %entry 160 %cmp4 = icmp eq i8 %c, 34 161 br i1 %cmp4, label %lor.end, label %lor.rhs 162 163lor.rhs: ; preds = %lor.lhs.false 164 %cmp8 = icmp eq i8 %c, 92 165 br label %lor.end 166 167lor.end: ; preds = %lor.rhs, %lor.lhs.false, %entry 168 %0 = phi i1 [ true, %lor.lhs.false ], [ true, %entry ], [ %cmp8, %lor.rhs ] 169 %lor.ext = zext i1 %0 to i32 170 ret i32 %lor.ext 171 172} 173 174define i32 @test5(i8 zeroext %c) nounwind ssp noredzone { 175; CHECK-LABEL: @test5( 176; CHECK-NEXT: entry: 177; CHECK-NEXT: switch i8 [[C:%.*]], label [[LOR_RHS:%.*]] [ 178; CHECK-NEXT: i8 62, label [[LOR_END:%.*]] 179; CHECK-NEXT: i8 34, label [[LOR_END]] 180; CHECK-NEXT: i8 92, label [[LOR_END]] 181; CHECK-NEXT: ] 182; CHECK: lor.rhs: 183; CHECK-NEXT: br label [[LOR_END]] 184; CHECK: lor.end: 185; CHECK-NEXT: [[TMP0:%.*]] = phi i1 [ true, [[ENTRY:%.*]] ], [ false, [[LOR_RHS]] ], [ true, [[ENTRY]] ], [ true, [[ENTRY]] ] 186; CHECK-NEXT: [[LOR_EXT:%.*]] = zext i1 [[TMP0]] to i32 187; CHECK-NEXT: ret i32 [[LOR_EXT]] 188; 189entry: 190 switch i8 %c, label %lor.rhs [ 191 i8 62, label %lor.end 192 i8 34, label %lor.end 193 i8 92, label %lor.end 194 ] 195 196lor.rhs: ; preds = %entry 197 %V = icmp eq i8 %c, 92 198 br label %lor.end 199 200lor.end: ; preds = %entry, %entry, %entry, %lor.rhs 201 %0 = phi i1 [ true, %entry ], [ %V, %lor.rhs ], [ true, %entry ], [ true, %entry ] 202 %lor.ext = zext i1 %0 to i32 203 ret i32 %lor.ext 204} 205 206 207define i1 @test6({ i32, i32 }* %I) { 208; CHECK-LABEL: @test6( 209; CHECK-NEXT: entry: 210; CHECK-NEXT: [[TMP_1_I:%.*]] = getelementptr { i32, i32 }, { i32, i32 }* [[I:%.*]], i64 0, i32 1 211; CHECK-NEXT: [[TMP_2_I:%.*]] = load i32, i32* [[TMP_1_I]], align 4 212; CHECK-NEXT: [[TMP_2_I_OFF:%.*]] = add i32 [[TMP_2_I]], -14 213; CHECK-NEXT: [[SWITCH:%.*]] = icmp ult i32 [[TMP_2_I_OFF]], 6 214; CHECK-NEXT: [[SPEC_SELECT:%.*]] = select i1 [[SWITCH]], i1 true, i1 false 215; CHECK-NEXT: ret i1 [[SPEC_SELECT]] 216; 217entry: 218 %tmp.1.i = getelementptr { i32, i32 }, { i32, i32 }* %I, i64 0, i32 1 ; <i32*> [#uses=1] 219 %tmp.2.i = load i32, i32* %tmp.1.i ; <i32> [#uses=6] 220 %tmp.2 = icmp eq i32 %tmp.2.i, 14 ; <i1> [#uses=1] 221 br i1 %tmp.2, label %shortcirc_done.4, label %shortcirc_next.0 222shortcirc_next.0: ; preds = %entry 223 %tmp.6 = icmp eq i32 %tmp.2.i, 15 ; <i1> [#uses=1] 224 br i1 %tmp.6, label %shortcirc_done.4, label %shortcirc_next.1 225shortcirc_next.1: ; preds = %shortcirc_next.0 226 %tmp.11 = icmp eq i32 %tmp.2.i, 16 ; <i1> [#uses=1] 227 br i1 %tmp.11, label %shortcirc_done.4, label %shortcirc_next.2 228shortcirc_next.2: ; preds = %shortcirc_next.1 229 %tmp.16 = icmp eq i32 %tmp.2.i, 17 ; <i1> [#uses=1] 230 br i1 %tmp.16, label %shortcirc_done.4, label %shortcirc_next.3 231shortcirc_next.3: ; preds = %shortcirc_next.2 232 %tmp.21 = icmp eq i32 %tmp.2.i, 18 ; <i1> [#uses=1] 233 br i1 %tmp.21, label %shortcirc_done.4, label %shortcirc_next.4 234shortcirc_next.4: ; preds = %shortcirc_next.3 235 %tmp.26 = icmp eq i32 %tmp.2.i, 19 ; <i1> [#uses=1] 236 br label %UnifiedReturnBlock 237shortcirc_done.4: ; preds = %shortcirc_next.3, %shortcirc_next.2, %shortcirc_next.1, %shortcirc_next.0, %entry 238 br label %UnifiedReturnBlock 239UnifiedReturnBlock: ; preds = %shortcirc_done.4, %shortcirc_next.4 240 %UnifiedRetVal = phi i1 [ %tmp.26, %shortcirc_next.4 ], [ true, %shortcirc_done.4 ] ; <i1> [#uses=1] 241 ret i1 %UnifiedRetVal 242 243} 244 245define void @test7(i8 zeroext %c, i32 %x) nounwind ssp noredzone { 246; CHECK-LABEL: @test7( 247; CHECK-NEXT: entry: 248; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[X:%.*]], 32 249; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[SWITCH_EARLY_TEST:%.*]] 250; CHECK: switch.early.test: 251; CHECK-NEXT: switch i8 [[C:%.*]], label [[IF_END:%.*]] [ 252; CHECK-NEXT: i8 99, label [[IF_THEN]] 253; CHECK-NEXT: i8 97, label [[IF_THEN]] 254; CHECK-NEXT: ] 255; CHECK: if.then: 256; CHECK-NEXT: tail call void @foo1() #[[ATTR2:[0-9]+]] 257; CHECK-NEXT: ret void 258; CHECK: if.end: 259; CHECK-NEXT: ret void 260; 261entry: 262 %cmp = icmp ult i32 %x, 32 263 %cmp4 = icmp eq i8 %c, 97 264 %or.cond = or i1 %cmp, %cmp4 265 %cmp9 = icmp eq i8 %c, 99 266 %or.cond11 = or i1 %or.cond, %cmp9 267 br i1 %or.cond11, label %if.then, label %if.end 268 269if.then: ; preds = %entry 270 tail call void @foo1() nounwind noredzone 271 ret void 272 273if.end: ; preds = %entry 274 ret void 275 276} 277 278define i32 @test8(i8 zeroext %c, i32 %x, i1 %C) nounwind ssp noredzone { 279; CHECK-LABEL: @test8( 280; CHECK-NEXT: entry: 281; CHECK-NEXT: br i1 [[C:%.*]], label [[N:%.*]], label [[IF_THEN:%.*]] 282; CHECK: N: 283; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[X:%.*]], 32 284; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN]], label [[SWITCH_EARLY_TEST:%.*]] 285; CHECK: switch.early.test: 286; CHECK-NEXT: switch i8 [[C:%.*]], label [[IF_END:%.*]] [ 287; CHECK-NEXT: i8 99, label [[IF_THEN]] 288; CHECK-NEXT: i8 97, label [[IF_THEN]] 289; CHECK-NEXT: ] 290; CHECK: if.then: 291; CHECK-NEXT: [[A:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ 42, [[SWITCH_EARLY_TEST]] ], [ 42, [[N]] ], [ 42, [[SWITCH_EARLY_TEST]] ] 292; CHECK-NEXT: tail call void @foo1() #[[ATTR2]] 293; CHECK-NEXT: ret i32 [[A]] 294; CHECK: if.end: 295; CHECK-NEXT: ret i32 0 296; 297entry: 298 br i1 %C, label %N, label %if.then 299N: 300 %cmp = icmp ult i32 %x, 32 301 %cmp4 = icmp eq i8 %c, 97 302 %or.cond = or i1 %cmp, %cmp4 303 %cmp9 = icmp eq i8 %c, 99 304 %or.cond11 = or i1 %or.cond, %cmp9 305 br i1 %or.cond11, label %if.then, label %if.end 306 307if.then: ; preds = %entry 308 %A = phi i32 [0, %entry], [42, %N] 309 tail call void @foo1() nounwind noredzone 310 ret i32 %A 311 312if.end: ; preds = %entry 313 ret i32 0 314 315} 316 317;; This is "Example 7" from http://blog.regehr.org/archives/320 318define i32 @test9(i8 zeroext %c) nounwind ssp noredzone { 319; CHECK-LABEL: @test9( 320; CHECK-NEXT: entry: 321; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[C:%.*]], 33 322; CHECK-NEXT: br i1 [[CMP]], label [[LOR_END:%.*]], label [[SWITCH_EARLY_TEST:%.*]] 323; CHECK: switch.early.test: 324; CHECK-NEXT: switch i8 [[C]], label [[LOR_RHS:%.*]] [ 325; CHECK-NEXT: i8 92, label [[LOR_END]] 326; CHECK-NEXT: i8 62, label [[LOR_END]] 327; CHECK-NEXT: i8 60, label [[LOR_END]] 328; CHECK-NEXT: i8 59, label [[LOR_END]] 329; CHECK-NEXT: i8 58, label [[LOR_END]] 330; CHECK-NEXT: i8 46, label [[LOR_END]] 331; CHECK-NEXT: i8 44, label [[LOR_END]] 332; CHECK-NEXT: i8 34, label [[LOR_END]] 333; CHECK-NEXT: i8 39, label [[LOR_END]] 334; CHECK-NEXT: ] 335; CHECK: lor.rhs: 336; CHECK-NEXT: br label [[LOR_END]] 337; CHECK: lor.end: 338; CHECK-NEXT: [[TMP0:%.*]] = phi i1 [ true, [[SWITCH_EARLY_TEST]] ], [ false, [[LOR_RHS]] ], [ true, [[ENTRY:%.*]] ], [ true, [[SWITCH_EARLY_TEST]] ], [ true, [[SWITCH_EARLY_TEST]] ], [ true, [[SWITCH_EARLY_TEST]] ], [ true, [[SWITCH_EARLY_TEST]] ], [ true, [[SWITCH_EARLY_TEST]] ], [ true, [[SWITCH_EARLY_TEST]] ], [ true, [[SWITCH_EARLY_TEST]] ], [ true, [[SWITCH_EARLY_TEST]] ] 339; CHECK-NEXT: [[CONV46:%.*]] = zext i1 [[TMP0]] to i32 340; CHECK-NEXT: ret i32 [[CONV46]] 341; 342entry: 343 %cmp = icmp ult i8 %c, 33 344 br i1 %cmp, label %lor.end, label %lor.lhs.false 345 346lor.lhs.false: ; preds = %entry 347 %cmp4 = icmp eq i8 %c, 46 348 br i1 %cmp4, label %lor.end, label %lor.lhs.false6 349 350lor.lhs.false6: ; preds = %lor.lhs.false 351 %cmp9 = icmp eq i8 %c, 44 352 br i1 %cmp9, label %lor.end, label %lor.lhs.false11 353 354lor.lhs.false11: ; preds = %lor.lhs.false6 355 %cmp14 = icmp eq i8 %c, 58 356 br i1 %cmp14, label %lor.end, label %lor.lhs.false16 357 358lor.lhs.false16: ; preds = %lor.lhs.false11 359 %cmp19 = icmp eq i8 %c, 59 360 br i1 %cmp19, label %lor.end, label %lor.lhs.false21 361 362lor.lhs.false21: ; preds = %lor.lhs.false16 363 %cmp24 = icmp eq i8 %c, 60 364 br i1 %cmp24, label %lor.end, label %lor.lhs.false26 365 366lor.lhs.false26: ; preds = %lor.lhs.false21 367 %cmp29 = icmp eq i8 %c, 62 368 br i1 %cmp29, label %lor.end, label %lor.lhs.false31 369 370lor.lhs.false31: ; preds = %lor.lhs.false26 371 %cmp34 = icmp eq i8 %c, 34 372 br i1 %cmp34, label %lor.end, label %lor.lhs.false36 373 374lor.lhs.false36: ; preds = %lor.lhs.false31 375 %cmp39 = icmp eq i8 %c, 92 376 br i1 %cmp39, label %lor.end, label %lor.rhs 377 378lor.rhs: ; preds = %lor.lhs.false36 379 %cmp43 = icmp eq i8 %c, 39 380 br label %lor.end 381 382lor.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 383 %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 ] 384 %conv46 = zext i1 %0 to i32 385 ret i32 %conv46 386 387 388} 389 390define i32 @test10(i32 %mode, i1 %Cond) { 391; CHECK-LABEL: @test10( 392; CHECK-NEXT: br i1 [[COND:%.*]], label [[SWITCH_EARLY_TEST:%.*]], label [[F:%.*]] 393; CHECK: switch.early.test: 394; CHECK-NEXT: switch i32 [[MODE:%.*]], label [[T:%.*]] [ 395; CHECK-NEXT: i32 51, label [[F]] 396; CHECK-NEXT: i32 0, label [[F]] 397; CHECK-NEXT: ] 398; CHECK: T: 399; CHECK-NEXT: call void @foo1() 400; CHECK-NEXT: ret i32 123 401; CHECK: F: 402; CHECK-NEXT: call void @foo2() 403; CHECK-NEXT: ret i32 324 404; 405 %A = icmp ne i32 %mode, 0 406 %B = icmp ne i32 %mode, 51 407 %C = and i1 %A, %B 408 %D = and i1 %C, %Cond 409 br i1 %D, label %T, label %F 410T: 411 call void @foo1() 412 ret i32 123 413F: 414 call void @foo2() 415 ret i32 324 416 417} 418 419; PR8780 420define i32 @test11(i32 %bar) nounwind { 421; CHECK-LABEL: @test11( 422; CHECK-NEXT: entry: 423; CHECK-NEXT: switch i32 [[BAR:%.*]], label [[IF_END:%.*]] [ 424; CHECK-NEXT: i32 55, label [[RETURN:%.*]] 425; CHECK-NEXT: i32 53, label [[RETURN]] 426; CHECK-NEXT: i32 35, label [[RETURN]] 427; CHECK-NEXT: i32 24, label [[RETURN]] 428; CHECK-NEXT: i32 23, label [[RETURN]] 429; CHECK-NEXT: i32 12, label [[RETURN]] 430; CHECK-NEXT: i32 4, label [[RETURN]] 431; CHECK-NEXT: ] 432; CHECK: if.end: 433; CHECK-NEXT: br label [[RETURN]] 434; CHECK: return: 435; CHECK-NEXT: [[RETVAL_0:%.*]] = phi i32 [ 0, [[IF_END]] ], [ 1, [[ENTRY:%.*]] ], [ 1, [[ENTRY]] ], [ 1, [[ENTRY]] ], [ 1, [[ENTRY]] ], [ 1, [[ENTRY]] ], [ 1, [[ENTRY]] ], [ 1, [[ENTRY]] ] 436; CHECK-NEXT: ret i32 [[RETVAL_0]] 437; 438entry: 439 %cmp = icmp eq i32 %bar, 4 440 %cmp2 = icmp eq i32 %bar, 35 441 %or.cond = or i1 %cmp, %cmp2 442 %cmp5 = icmp eq i32 %bar, 53 443 %or.cond1 = or i1 %or.cond, %cmp5 444 %cmp8 = icmp eq i32 %bar, 24 445 %or.cond2 = or i1 %or.cond1, %cmp8 446 %cmp11 = icmp eq i32 %bar, 23 447 %or.cond3 = or i1 %or.cond2, %cmp11 448 %cmp14 = icmp eq i32 %bar, 55 449 %or.cond4 = or i1 %or.cond3, %cmp14 450 %cmp17 = icmp eq i32 %bar, 12 451 %or.cond5 = or i1 %or.cond4, %cmp17 452 %cmp20 = icmp eq i32 %bar, 35 453 %or.cond6 = or i1 %or.cond5, %cmp20 454 br i1 %or.cond6, label %if.then, label %if.end 455 456if.then: ; preds = %entry 457 br label %return 458 459if.end: ; preds = %entry 460 br label %return 461 462return: ; preds = %if.end, %if.then 463 %retval.0 = phi i32 [ 1, %if.then ], [ 0, %if.end ] 464 ret i32 %retval.0 465 466} 467 468define void @test12() nounwind { 469; CHECK-LABEL: @test12( 470; CHECK-NEXT: entry: 471; CHECK-NEXT: [[A_OLD:%.*]] = icmp eq i32 undef, undef 472; CHECK-NEXT: br i1 [[A_OLD]], label [[BB55_US_US:%.*]], label [[MALFORMED:%.*]] 473; CHECK: bb55.us.us: 474; CHECK-NEXT: [[B:%.*]] = icmp ugt i32 undef, undef 475; CHECK-NEXT: [[A:%.*]] = icmp eq i32 undef, undef 476; CHECK-NEXT: [[OR_COND:%.*]] = or i1 [[B]], [[A]] 477; CHECK-NEXT: br i1 [[OR_COND]], label [[BB55_US_US]], label [[MALFORMED]] 478; CHECK: malformed: 479; CHECK-NEXT: ret void 480; 481entry: 482 br label %bb49.us.us 483 484bb49.us.us: 485 %A = icmp eq i32 undef, undef 486 br i1 %A, label %bb55.us.us, label %malformed 487 488bb48.us.us: 489 %B = icmp ugt i32 undef, undef 490 br i1 %B, label %bb55.us.us, label %bb49.us.us 491 492bb55.us.us: 493 br label %bb48.us.us 494 495malformed: 496 ret void 497 498} 499 500; test13 - handle switch formation with ult. 501define void @test13(i32 %x) nounwind ssp noredzone { 502; CHECK-LABEL: @test13( 503; CHECK-NEXT: entry: 504; CHECK-NEXT: switch i32 [[X:%.*]], label [[IF_END:%.*]] [ 505; CHECK-NEXT: i32 6, label [[IF_THEN:%.*]] 506; CHECK-NEXT: i32 4, label [[IF_THEN]] 507; CHECK-NEXT: i32 3, label [[IF_THEN]] 508; CHECK-NEXT: i32 1, label [[IF_THEN]] 509; CHECK-NEXT: i32 0, label [[IF_THEN]] 510; CHECK-NEXT: ] 511; CHECK: if.then: 512; CHECK-NEXT: call void @foo1() #[[ATTR3:[0-9]+]] 513; CHECK-NEXT: br label [[IF_END]] 514; CHECK: if.end: 515; CHECK-NEXT: ret void 516; 517entry: 518 %cmp = icmp ult i32 %x, 2 519 br i1 %cmp, label %if.then, label %lor.lhs.false3 520 521lor.lhs.false3: ; preds = %lor.lhs.false 522 %cmp5 = icmp eq i32 %x, 3 523 br i1 %cmp5, label %if.then, label %lor.lhs.false6 524 525lor.lhs.false6: ; preds = %lor.lhs.false3 526 %cmp8 = icmp eq i32 %x, 4 527 br i1 %cmp8, label %if.then, label %lor.lhs.false9 528 529lor.lhs.false9: ; preds = %lor.lhs.false6 530 %cmp11 = icmp eq i32 %x, 6 531 br i1 %cmp11, label %if.then, label %if.end 532 533if.then: ; preds = %lor.lhs.false9, %lor.lhs.false6, %lor.lhs.false3, %lor.lhs.false, %entry 534 call void @foo1() noredzone 535 br label %if.end 536 537if.end: ; preds = %if.then, %lor.lhs.false9 538 ret void 539} 540 541; test14 - handle switch formation with ult. 542define void @test14(i32 %x) nounwind ssp noredzone { 543; CHECK-LABEL: @test14( 544; CHECK-NEXT: entry: 545; CHECK-NEXT: switch i32 [[X:%.*]], label [[IF_END:%.*]] [ 546; CHECK-NEXT: i32 6, label [[IF_THEN:%.*]] 547; CHECK-NEXT: i32 4, label [[IF_THEN]] 548; CHECK-NEXT: i32 3, label [[IF_THEN]] 549; CHECK-NEXT: i32 2, label [[IF_THEN]] 550; CHECK-NEXT: i32 1, label [[IF_THEN]] 551; CHECK-NEXT: i32 0, label [[IF_THEN]] 552; CHECK-NEXT: ] 553; CHECK: if.then: 554; CHECK-NEXT: call void @foo1() #[[ATTR3]] 555; CHECK-NEXT: br label [[IF_END]] 556; CHECK: if.end: 557; CHECK-NEXT: ret void 558; 559entry: 560 %cmp = icmp ugt i32 %x, 2 561 br i1 %cmp, label %lor.lhs.false3, label %if.then 562 563lor.lhs.false3: ; preds = %lor.lhs.false 564 %cmp5 = icmp ne i32 %x, 3 565 br i1 %cmp5, label %lor.lhs.false6, label %if.then 566 567lor.lhs.false6: ; preds = %lor.lhs.false3 568 %cmp8 = icmp ne i32 %x, 4 569 br i1 %cmp8, label %lor.lhs.false9, label %if.then 570 571lor.lhs.false9: ; preds = %lor.lhs.false6 572 %cmp11 = icmp ne i32 %x, 6 573 br i1 %cmp11, label %if.end, label %if.then 574 575if.then: ; preds = %lor.lhs.false9, %lor.lhs.false6, %lor.lhs.false3, %lor.lhs.false, %entry 576 call void @foo1() noredzone 577 br label %if.end 578 579if.end: ; preds = %if.then, %lor.lhs.false9 580 ret void 581} 582 583; Don't crash on ginormous ranges. 584define void @test15(i128 %x) nounwind { 585; CHECK-LABEL: @test15( 586; CHECK-NEXT: if.end: 587; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i128 [[X:%.*]], 2 588; CHECK-NEXT: ret void 589; 590 %cmp = icmp ugt i128 %x, 2 591 br i1 %cmp, label %if.end, label %lor.false 592 593lor.false: 594 %cmp2 = icmp ne i128 %x, 100000000000000000000 595 br i1 %cmp2, label %if.end, label %if.then 596 597if.then: 598 call void @foo1() noredzone 599 br label %if.end 600 601if.end: 602 ret void 603 604} 605 606; PR8675 607; rdar://5134905 608define zeroext i1 @test16(i32 %x) nounwind { 609; CHECK-LABEL: @test16( 610; CHECK-NEXT: entry: 611; CHECK-NEXT: [[X_OFF:%.*]] = add i32 [[X:%.*]], -1 612; CHECK-NEXT: [[SWITCH:%.*]] = icmp ult i32 [[X_OFF]], 3 613; CHECK-NEXT: [[SPEC_SELECT:%.*]] = select i1 [[SWITCH]], i1 true, i1 false 614; CHECK-NEXT: ret i1 [[SPEC_SELECT]] 615; 616entry: 617 %cmp.i = icmp eq i32 %x, 1 618 br i1 %cmp.i, label %lor.end, label %lor.lhs.false 619 620lor.lhs.false: 621 %cmp.i2 = icmp eq i32 %x, 2 622 br i1 %cmp.i2, label %lor.end, label %lor.rhs 623 624lor.rhs: 625 %cmp.i1 = icmp eq i32 %x, 3 626 br label %lor.end 627 628lor.end: 629 %0 = phi i1 [ true, %lor.lhs.false ], [ true, %entry ], [ %cmp.i1, %lor.rhs ] 630 ret i1 %0 631} 632 633; Check that we don't turn an icmp into a switch where it's not useful. 634define void @test17(i32 %x, i32 %y) { 635; CHECK-LABEL: @test17( 636; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[X:%.*]], 3 637; CHECK-NEXT: [[SWITCH:%.*]] = icmp ult i32 [[Y:%.*]], 2 638; CHECK-NEXT: [[OR_COND775:%.*]] = or i1 [[CMP]], [[SWITCH]] 639; CHECK-NEXT: br i1 [[OR_COND775]], label [[LOR_LHS_FALSE8:%.*]], label [[RETURN:%.*]] 640; CHECK: lor.lhs.false8: 641; CHECK-NEXT: tail call void @foo1() 642; CHECK-NEXT: ret void 643; CHECK: return: 644; CHECK-NEXT: ret void 645; 646 %cmp = icmp ult i32 %x, 3 647 %switch = icmp ult i32 %y, 2 648 %or.cond775 = or i1 %cmp, %switch 649 br i1 %or.cond775, label %lor.lhs.false8, label %return 650 651lor.lhs.false8: 652 tail call void @foo1() 653 ret void 654 655return: 656 ret void 657 658} 659 660define void @test18(i32 %arg) { 661; CHECK-LABEL: @test18( 662; CHECK-NEXT: bb: 663; CHECK-NEXT: [[ARG_OFF:%.*]] = add i32 [[ARG:%.*]], -8 664; CHECK-NEXT: [[SWITCH:%.*]] = icmp ult i32 [[ARG_OFF]], 11 665; CHECK-NEXT: br i1 [[SWITCH]], label [[BB19:%.*]], label [[BB20:%.*]] 666; CHECK: bb19: 667; CHECK-NEXT: tail call void @foo1() 668; CHECK-NEXT: br label [[BB20]] 669; CHECK: bb20: 670; CHECK-NEXT: ret void 671; 672bb: 673 %tmp = and i32 %arg, -2 674 %tmp1 = icmp eq i32 %tmp, 8 675 %tmp2 = icmp eq i32 %arg, 10 676 %tmp3 = or i1 %tmp1, %tmp2 677 %tmp4 = icmp eq i32 %arg, 11 678 %tmp5 = or i1 %tmp3, %tmp4 679 %tmp6 = icmp eq i32 %arg, 12 680 %tmp7 = or i1 %tmp5, %tmp6 681 br i1 %tmp7, label %bb19, label %bb8 682 683bb8: ; preds = %bb 684 %tmp9 = add i32 %arg, -13 685 %tmp10 = icmp ult i32 %tmp9, 2 686 %tmp11 = icmp eq i32 %arg, 16 687 %tmp12 = or i1 %tmp10, %tmp11 688 %tmp13 = icmp eq i32 %arg, 17 689 %tmp14 = or i1 %tmp12, %tmp13 690 %tmp15 = icmp eq i32 %arg, 18 691 %tmp16 = or i1 %tmp14, %tmp15 692 %tmp17 = icmp eq i32 %arg, 15 693 %tmp18 = or i1 %tmp16, %tmp17 694 br i1 %tmp18, label %bb19, label %bb20 695 696bb19: ; preds = %bb8, %bb 697 tail call void @foo1() 698 br label %bb20 699 700bb20: ; preds = %bb19, %bb8 701 ret void 702 703} 704 705define void @PR26323(i1 %tobool23, i32 %tmp3) { 706; CHECK-LABEL: @PR26323( 707; CHECK-NEXT: entry: 708; CHECK-NEXT: [[TOBOOL5:%.*]] = icmp ne i32 [[TMP3:%.*]], 0 709; CHECK-NEXT: [[NEG14:%.*]] = and i32 [[TMP3]], -2 710; CHECK-NEXT: [[CMP17:%.*]] = icmp ne i32 [[NEG14]], -1 711; CHECK-NEXT: [[OR_COND:%.*]] = and i1 [[TOBOOL5]], [[TOBOOL23:%.*]] 712; CHECK-NEXT: [[OR_COND1:%.*]] = and i1 [[CMP17]], [[OR_COND]] 713; CHECK-NEXT: br i1 [[OR_COND1]], label [[IF_END29:%.*]], label [[IF_THEN27:%.*]] 714; CHECK: if.then27: 715; CHECK-NEXT: call void @foo1() 716; CHECK-NEXT: unreachable 717; CHECK: if.end29: 718; CHECK-NEXT: ret void 719; 720entry: 721 %tobool5 = icmp ne i32 %tmp3, 0 722 %neg14 = and i32 %tmp3, -2 723 %cmp17 = icmp ne i32 %neg14, -1 724 %or.cond = and i1 %tobool5, %tobool23 725 %or.cond1 = and i1 %cmp17, %or.cond 726 br i1 %or.cond1, label %if.end29, label %if.then27 727 728if.then27: ; preds = %entry 729 call void @foo1() 730 unreachable 731 732if.end29: ; preds = %entry 733 ret void 734} 735 736define void @test19(i32 %arg) { 737; CHECK-LABEL: @test19( 738; CHECK-NEXT: switch i32 [[ARG:%.*]], label [[ELSE:%.*]] [ 739; CHECK-NEXT: i32 32, label [[IF:%.*]] 740; CHECK-NEXT: i32 13, label [[IF]] 741; CHECK-NEXT: i32 12, label [[IF]] 742; CHECK-NEXT: ] 743; CHECK: if: 744; CHECK-NEXT: call void @foo1() 745; CHECK-NEXT: ret void 746; CHECK: else: 747; CHECK-NEXT: ret void 748; 749 %and = and i32 %arg, -2 750 %cmp1 = icmp eq i32 %and, 12 751 %cmp2 = icmp eq i32 %arg, 32 752 %pred = or i1 %cmp1, %cmp2 753 br i1 %pred, label %if, label %else 754 755if: 756 call void @foo1() 757 ret void 758 759else: 760 ret void 761} 762 763; Since %cmp1 is always false, a switch is never formed 764define void @test20(i32 %arg) { 765; CHECK-LABEL: @test20( 766; CHECK-NEXT: [[AND:%.*]] = and i32 [[ARG:%.*]], -2 767; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[AND]], 13 768; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i32 [[ARG]], 32 769; CHECK-NEXT: [[PRED:%.*]] = or i1 [[CMP1]], [[CMP2]] 770; CHECK-NEXT: br i1 [[PRED]], label [[IF:%.*]], label [[ELSE:%.*]] 771; CHECK: if: 772; CHECK-NEXT: call void @foo1() 773; CHECK-NEXT: ret void 774; CHECK: else: 775; CHECK-NEXT: ret void 776; 777 %and = and i32 %arg, -2 778 %cmp1 = icmp eq i32 %and, 13 779 %cmp2 = icmp eq i32 %arg, 32 780 %pred = or i1 %cmp1, %cmp2 781 br i1 %pred, label %if, label %else 782 783if: 784 call void @foo1() 785 ret void 786 787else: 788 ret void 789} 790 791; Form a switch when or'ing a power of two 792define void @test21(i32 %arg) { 793; CHECK-LABEL: @test21( 794; CHECK-NEXT: switch i32 [[ARG:%.*]], label [[IF:%.*]] [ 795; CHECK-NEXT: i32 32, label [[ELSE:%.*]] 796; CHECK-NEXT: i32 13, label [[ELSE]] 797; CHECK-NEXT: i32 12, label [[ELSE]] 798; CHECK-NEXT: ] 799; CHECK: if: 800; CHECK-NEXT: call void @foo1() 801; CHECK-NEXT: ret void 802; CHECK: else: 803; CHECK-NEXT: ret void 804; 805 %and = or i32 %arg, 1 806 %cmp1 = icmp ne i32 %and, 13 807 %cmp2 = icmp ne i32 %arg, 32 808 %pred = and i1 %cmp1, %cmp2 809 br i1 %pred, label %if, label %else 810 811if: 812 call void @foo1() 813 ret void 814 815else: 816 ret void 817} 818 819; Since %cmp1 is always false, a switch is never formed 820define void @test22(i32 %arg) { 821; CHECK-LABEL: @test22( 822; CHECK-NEXT: [[AND:%.*]] = or i32 [[ARG:%.*]], 1 823; CHECK-NEXT: [[CMP1:%.*]] = icmp ne i32 [[AND]], 12 824; CHECK-NEXT: [[CMP2:%.*]] = icmp ne i32 [[ARG]], 32 825; CHECK-NEXT: [[PRED:%.*]] = and i1 [[CMP1]], [[CMP2]] 826; CHECK-NEXT: br i1 [[PRED]], label [[IF:%.*]], label [[ELSE:%.*]] 827; CHECK: if: 828; CHECK-NEXT: call void @foo1() 829; CHECK-NEXT: ret void 830; CHECK: else: 831; CHECK-NEXT: ret void 832; 833 %and = or i32 %arg, 1 834 %cmp1 = icmp ne i32 %and, 12 835 %cmp2 = icmp ne i32 %arg, 32 836 %pred = and i1 %cmp1, %cmp2 837 br i1 %pred, label %if, label %else 838 839if: 840 call void @foo1() 841 ret void 842 843else: 844 ret void 845} 846