1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -S -simplifycfg < %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]] 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() #2 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() #2 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: [[MERGE:%.*]] = phi i32 [ 123, [[SWITCH_EARLY_TEST]] ], [ 324, [[F]] ] 400; CHECK-NEXT: ret i32 [[MERGE]] 401; CHECK: F: 402; CHECK-NEXT: br label [[T]] 403; 404 %A = icmp ne i32 %mode, 0 405 %B = icmp ne i32 %mode, 51 406 %C = and i1 %A, %B 407 %D = and i1 %C, %Cond 408 br i1 %D, label %T, label %F 409T: 410 ret i32 123 411F: 412 ret i32 324 413 414} 415 416; PR8780 417define i32 @test11(i32 %bar) nounwind { 418; CHECK-LABEL: @test11( 419; CHECK-NEXT: entry: 420; CHECK-NEXT: switch i32 [[BAR:%.*]], label [[IF_END:%.*]] [ 421; CHECK-NEXT: i32 55, label [[RETURN:%.*]] 422; CHECK-NEXT: i32 53, label [[RETURN]] 423; CHECK-NEXT: i32 35, label [[RETURN]] 424; CHECK-NEXT: i32 24, label [[RETURN]] 425; CHECK-NEXT: i32 23, label [[RETURN]] 426; CHECK-NEXT: i32 12, label [[RETURN]] 427; CHECK-NEXT: i32 4, label [[RETURN]] 428; CHECK-NEXT: ] 429; CHECK: if.end: 430; CHECK-NEXT: br label [[RETURN]] 431; CHECK: return: 432; CHECK-NEXT: [[RETVAL_0:%.*]] = phi i32 [ 0, [[IF_END]] ], [ 1, [[ENTRY:%.*]] ], [ 1, [[ENTRY]] ], [ 1, [[ENTRY]] ], [ 1, [[ENTRY]] ], [ 1, [[ENTRY]] ], [ 1, [[ENTRY]] ], [ 1, [[ENTRY]] ] 433; CHECK-NEXT: ret i32 [[RETVAL_0]] 434; 435entry: 436 %cmp = icmp eq i32 %bar, 4 437 %cmp2 = icmp eq i32 %bar, 35 438 %or.cond = or i1 %cmp, %cmp2 439 %cmp5 = icmp eq i32 %bar, 53 440 %or.cond1 = or i1 %or.cond, %cmp5 441 %cmp8 = icmp eq i32 %bar, 24 442 %or.cond2 = or i1 %or.cond1, %cmp8 443 %cmp11 = icmp eq i32 %bar, 23 444 %or.cond3 = or i1 %or.cond2, %cmp11 445 %cmp14 = icmp eq i32 %bar, 55 446 %or.cond4 = or i1 %or.cond3, %cmp14 447 %cmp17 = icmp eq i32 %bar, 12 448 %or.cond5 = or i1 %or.cond4, %cmp17 449 %cmp20 = icmp eq i32 %bar, 35 450 %or.cond6 = or i1 %or.cond5, %cmp20 451 br i1 %or.cond6, label %if.then, label %if.end 452 453if.then: ; preds = %entry 454 br label %return 455 456if.end: ; preds = %entry 457 br label %return 458 459return: ; preds = %if.end, %if.then 460 %retval.0 = phi i32 [ 1, %if.then ], [ 0, %if.end ] 461 ret i32 %retval.0 462 463} 464 465define void @test12() nounwind { 466; CHECK-LABEL: @test12( 467; CHECK-NEXT: entry: 468; CHECK-NEXT: [[A_OLD:%.*]] = icmp eq i32 undef, undef 469; CHECK-NEXT: br i1 [[A_OLD]], label [[BB55_US_US:%.*]], label [[MALFORMED:%.*]] 470; CHECK: bb55.us.us: 471; CHECK-NEXT: [[B:%.*]] = icmp ugt i32 undef, undef 472; CHECK-NEXT: [[A:%.*]] = icmp eq i32 undef, undef 473; CHECK-NEXT: [[OR_COND:%.*]] = or i1 [[B]], [[A]] 474; CHECK-NEXT: br i1 [[OR_COND]], label [[BB55_US_US]], label [[MALFORMED]] 475; CHECK: malformed: 476; CHECK-NEXT: ret void 477; 478entry: 479 br label %bb49.us.us 480 481bb49.us.us: 482 %A = icmp eq i32 undef, undef 483 br i1 %A, label %bb55.us.us, label %malformed 484 485bb48.us.us: 486 %B = icmp ugt i32 undef, undef 487 br i1 %B, label %bb55.us.us, label %bb49.us.us 488 489bb55.us.us: 490 br label %bb48.us.us 491 492malformed: 493 ret void 494 495} 496 497; test13 - handle switch formation with ult. 498define void @test13(i32 %x) nounwind ssp noredzone { 499; CHECK-LABEL: @test13( 500; CHECK-NEXT: entry: 501; CHECK-NEXT: switch i32 [[X:%.*]], label [[IF_END:%.*]] [ 502; CHECK-NEXT: i32 6, label [[IF_THEN:%.*]] 503; CHECK-NEXT: i32 4, label [[IF_THEN]] 504; CHECK-NEXT: i32 3, label [[IF_THEN]] 505; CHECK-NEXT: i32 1, label [[IF_THEN]] 506; CHECK-NEXT: i32 0, label [[IF_THEN]] 507; CHECK-NEXT: ] 508; CHECK: if.then: 509; CHECK-NEXT: call void @foo1() #3 510; CHECK-NEXT: br label [[IF_END]] 511; CHECK: if.end: 512; CHECK-NEXT: ret void 513; 514entry: 515 %cmp = icmp ult i32 %x, 2 516 br i1 %cmp, label %if.then, label %lor.lhs.false3 517 518lor.lhs.false3: ; preds = %lor.lhs.false 519 %cmp5 = icmp eq i32 %x, 3 520 br i1 %cmp5, label %if.then, label %lor.lhs.false6 521 522lor.lhs.false6: ; preds = %lor.lhs.false3 523 %cmp8 = icmp eq i32 %x, 4 524 br i1 %cmp8, label %if.then, label %lor.lhs.false9 525 526lor.lhs.false9: ; preds = %lor.lhs.false6 527 %cmp11 = icmp eq i32 %x, 6 528 br i1 %cmp11, label %if.then, label %if.end 529 530if.then: ; preds = %lor.lhs.false9, %lor.lhs.false6, %lor.lhs.false3, %lor.lhs.false, %entry 531 call void @foo1() noredzone 532 br label %if.end 533 534if.end: ; preds = %if.then, %lor.lhs.false9 535 ret void 536} 537 538; test14 - handle switch formation with ult. 539define void @test14(i32 %x) nounwind ssp noredzone { 540; CHECK-LABEL: @test14( 541; CHECK-NEXT: entry: 542; CHECK-NEXT: switch i32 [[X:%.*]], label [[IF_END:%.*]] [ 543; CHECK-NEXT: i32 6, label [[IF_THEN:%.*]] 544; CHECK-NEXT: i32 4, label [[IF_THEN]] 545; CHECK-NEXT: i32 3, label [[IF_THEN]] 546; CHECK-NEXT: i32 2, label [[IF_THEN]] 547; CHECK-NEXT: i32 1, label [[IF_THEN]] 548; CHECK-NEXT: i32 0, label [[IF_THEN]] 549; CHECK-NEXT: ] 550; CHECK: if.then: 551; CHECK-NEXT: call void @foo1() #3 552; CHECK-NEXT: br label [[IF_END]] 553; CHECK: if.end: 554; CHECK-NEXT: ret void 555; 556entry: 557 %cmp = icmp ugt i32 %x, 2 558 br i1 %cmp, label %lor.lhs.false3, label %if.then 559 560lor.lhs.false3: ; preds = %lor.lhs.false 561 %cmp5 = icmp ne i32 %x, 3 562 br i1 %cmp5, label %lor.lhs.false6, label %if.then 563 564lor.lhs.false6: ; preds = %lor.lhs.false3 565 %cmp8 = icmp ne i32 %x, 4 566 br i1 %cmp8, label %lor.lhs.false9, label %if.then 567 568lor.lhs.false9: ; preds = %lor.lhs.false6 569 %cmp11 = icmp ne i32 %x, 6 570 br i1 %cmp11, label %if.end, label %if.then 571 572if.then: ; preds = %lor.lhs.false9, %lor.lhs.false6, %lor.lhs.false3, %lor.lhs.false, %entry 573 call void @foo1() noredzone 574 br label %if.end 575 576if.end: ; preds = %if.then, %lor.lhs.false9 577 ret void 578} 579 580; Don't crash on ginormous ranges. 581define void @test15(i128 %x) nounwind { 582; CHECK-LABEL: @test15( 583; CHECK-NEXT: if.end: 584; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i128 [[X:%.*]], 2 585; CHECK-NEXT: ret void 586; 587 %cmp = icmp ugt i128 %x, 2 588 br i1 %cmp, label %if.end, label %lor.false 589 590lor.false: 591 %cmp2 = icmp ne i128 %x, 100000000000000000000 592 br i1 %cmp2, label %if.end, label %if.then 593 594if.then: 595 call void @foo1() noredzone 596 br label %if.end 597 598if.end: 599 ret void 600 601} 602 603; PR8675 604; rdar://5134905 605define zeroext i1 @test16(i32 %x) nounwind { 606; CHECK-LABEL: @test16( 607; CHECK-NEXT: entry: 608; CHECK-NEXT: [[X_OFF:%.*]] = add i32 [[X:%.*]], -1 609; CHECK-NEXT: [[SWITCH:%.*]] = icmp ult i32 [[X_OFF]], 3 610; CHECK-NEXT: [[SPEC_SELECT:%.*]] = select i1 [[SWITCH]], i1 true, i1 false 611; CHECK-NEXT: ret i1 [[SPEC_SELECT]] 612; 613entry: 614 %cmp.i = icmp eq i32 %x, 1 615 br i1 %cmp.i, label %lor.end, label %lor.lhs.false 616 617lor.lhs.false: 618 %cmp.i2 = icmp eq i32 %x, 2 619 br i1 %cmp.i2, label %lor.end, label %lor.rhs 620 621lor.rhs: 622 %cmp.i1 = icmp eq i32 %x, 3 623 br label %lor.end 624 625lor.end: 626 %0 = phi i1 [ true, %lor.lhs.false ], [ true, %entry ], [ %cmp.i1, %lor.rhs ] 627 ret i1 %0 628} 629 630; Check that we don't turn an icmp into a switch where it's not useful. 631define void @test17(i32 %x, i32 %y) { 632; CHECK-LABEL: @test17( 633; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[X:%.*]], 3 634; CHECK-NEXT: [[SWITCH:%.*]] = icmp ult i32 [[Y:%.*]], 2 635; CHECK-NEXT: [[OR_COND775:%.*]] = or i1 [[CMP]], [[SWITCH]] 636; CHECK-NEXT: br i1 [[OR_COND775]], label [[LOR_LHS_FALSE8:%.*]], label [[RETURN:%.*]] 637; CHECK: lor.lhs.false8: 638; CHECK-NEXT: tail call void @foo1() 639; CHECK-NEXT: ret void 640; CHECK: return: 641; CHECK-NEXT: ret void 642; 643 %cmp = icmp ult i32 %x, 3 644 %switch = icmp ult i32 %y, 2 645 %or.cond775 = or i1 %cmp, %switch 646 br i1 %or.cond775, label %lor.lhs.false8, label %return 647 648lor.lhs.false8: 649 tail call void @foo1() 650 ret void 651 652return: 653 ret void 654 655} 656 657define void @test18(i32 %arg) { 658; CHECK-LABEL: @test18( 659; CHECK-NEXT: bb: 660; CHECK-NEXT: [[ARG_OFF:%.*]] = add i32 [[ARG:%.*]], -8 661; CHECK-NEXT: [[SWITCH:%.*]] = icmp ult i32 [[ARG_OFF]], 11 662; CHECK-NEXT: br i1 [[SWITCH]], label [[BB19:%.*]], label [[BB20:%.*]] 663; CHECK: bb19: 664; CHECK-NEXT: tail call void @foo1() 665; CHECK-NEXT: br label [[BB20]] 666; CHECK: bb20: 667; CHECK-NEXT: ret void 668; 669bb: 670 %tmp = and i32 %arg, -2 671 %tmp1 = icmp eq i32 %tmp, 8 672 %tmp2 = icmp eq i32 %arg, 10 673 %tmp3 = or i1 %tmp1, %tmp2 674 %tmp4 = icmp eq i32 %arg, 11 675 %tmp5 = or i1 %tmp3, %tmp4 676 %tmp6 = icmp eq i32 %arg, 12 677 %tmp7 = or i1 %tmp5, %tmp6 678 br i1 %tmp7, label %bb19, label %bb8 679 680bb8: ; preds = %bb 681 %tmp9 = add i32 %arg, -13 682 %tmp10 = icmp ult i32 %tmp9, 2 683 %tmp11 = icmp eq i32 %arg, 16 684 %tmp12 = or i1 %tmp10, %tmp11 685 %tmp13 = icmp eq i32 %arg, 17 686 %tmp14 = or i1 %tmp12, %tmp13 687 %tmp15 = icmp eq i32 %arg, 18 688 %tmp16 = or i1 %tmp14, %tmp15 689 %tmp17 = icmp eq i32 %arg, 15 690 %tmp18 = or i1 %tmp16, %tmp17 691 br i1 %tmp18, label %bb19, label %bb20 692 693bb19: ; preds = %bb8, %bb 694 tail call void @foo1() 695 br label %bb20 696 697bb20: ; preds = %bb19, %bb8 698 ret void 699 700} 701 702define void @PR26323(i1 %tobool23, i32 %tmp3) { 703; CHECK-LABEL: @PR26323( 704; CHECK-NEXT: entry: 705; CHECK-NEXT: [[TOBOOL5:%.*]] = icmp ne i32 [[TMP3:%.*]], 0 706; CHECK-NEXT: [[NEG14:%.*]] = and i32 [[TMP3]], -2 707; CHECK-NEXT: [[CMP17:%.*]] = icmp ne i32 [[NEG14]], -1 708; CHECK-NEXT: [[OR_COND:%.*]] = and i1 [[TOBOOL5]], [[TOBOOL23:%.*]] 709; CHECK-NEXT: [[OR_COND1:%.*]] = and i1 [[CMP17]], [[OR_COND]] 710; CHECK-NEXT: br i1 [[OR_COND1]], label [[IF_END29:%.*]], label [[IF_THEN27:%.*]] 711; CHECK: if.then27: 712; CHECK-NEXT: call void @foo1() 713; CHECK-NEXT: unreachable 714; CHECK: if.end29: 715; CHECK-NEXT: ret void 716; 717entry: 718 %tobool5 = icmp ne i32 %tmp3, 0 719 %neg14 = and i32 %tmp3, -2 720 %cmp17 = icmp ne i32 %neg14, -1 721 %or.cond = and i1 %tobool5, %tobool23 722 %or.cond1 = and i1 %cmp17, %or.cond 723 br i1 %or.cond1, label %if.end29, label %if.then27 724 725if.then27: ; preds = %entry 726 call void @foo1() 727 unreachable 728 729if.end29: ; preds = %entry 730 ret void 731} 732 733define void @test19(i32 %arg) { 734; CHECK-LABEL: @test19( 735; CHECK-NEXT: switch i32 [[ARG:%.*]], label [[ELSE:%.*]] [ 736; CHECK-NEXT: i32 32, label [[IF:%.*]] 737; CHECK-NEXT: i32 13, label [[IF]] 738; CHECK-NEXT: i32 12, label [[IF]] 739; CHECK-NEXT: ] 740; CHECK: if: 741; CHECK-NEXT: call void @foo1() 742; CHECK-NEXT: ret void 743; CHECK: else: 744; CHECK-NEXT: ret void 745; 746 %and = and i32 %arg, -2 747 %cmp1 = icmp eq i32 %and, 12 748 %cmp2 = icmp eq i32 %arg, 32 749 %pred = or i1 %cmp1, %cmp2 750 br i1 %pred, label %if, label %else 751 752if: 753 call void @foo1() 754 ret void 755 756else: 757 ret void 758} 759 760; Since %cmp1 is always false, a switch is never formed 761define void @test20(i32 %arg) { 762; CHECK-LABEL: @test20( 763; CHECK-NEXT: [[AND:%.*]] = and i32 [[ARG:%.*]], -2 764; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[AND]], 13 765; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i32 [[ARG]], 32 766; CHECK-NEXT: [[PRED:%.*]] = or i1 [[CMP1]], [[CMP2]] 767; CHECK-NEXT: br i1 [[PRED]], label [[IF:%.*]], label [[ELSE:%.*]] 768; CHECK: if: 769; CHECK-NEXT: call void @foo1() 770; CHECK-NEXT: ret void 771; CHECK: else: 772; CHECK-NEXT: ret void 773; 774 %and = and i32 %arg, -2 775 %cmp1 = icmp eq i32 %and, 13 776 %cmp2 = icmp eq i32 %arg, 32 777 %pred = or i1 %cmp1, %cmp2 778 br i1 %pred, label %if, label %else 779 780if: 781 call void @foo1() 782 ret void 783 784else: 785 ret void 786} 787 788; Form a switch when or'ing a power of two 789define void @test21(i32 %arg) { 790; CHECK-LABEL: @test21( 791; CHECK-NEXT: switch i32 [[ARG:%.*]], label [[IF:%.*]] [ 792; CHECK-NEXT: i32 32, label [[ELSE:%.*]] 793; CHECK-NEXT: i32 13, label [[ELSE]] 794; CHECK-NEXT: i32 12, label [[ELSE]] 795; CHECK-NEXT: ] 796; CHECK: if: 797; CHECK-NEXT: call void @foo1() 798; CHECK-NEXT: ret void 799; CHECK: else: 800; CHECK-NEXT: ret void 801; 802 %and = or i32 %arg, 1 803 %cmp1 = icmp ne i32 %and, 13 804 %cmp2 = icmp ne i32 %arg, 32 805 %pred = and i1 %cmp1, %cmp2 806 br i1 %pred, label %if, label %else 807 808if: 809 call void @foo1() 810 ret void 811 812else: 813 ret void 814} 815 816; Since %cmp1 is always false, a switch is never formed 817define void @test22(i32 %arg) { 818; CHECK-LABEL: @test22( 819; CHECK-NEXT: [[AND:%.*]] = or i32 [[ARG:%.*]], 1 820; CHECK-NEXT: [[CMP1:%.*]] = icmp ne i32 [[AND]], 12 821; CHECK-NEXT: [[CMP2:%.*]] = icmp ne i32 [[ARG]], 32 822; CHECK-NEXT: [[PRED:%.*]] = and i1 [[CMP1]], [[CMP2]] 823; CHECK-NEXT: br i1 [[PRED]], label [[IF:%.*]], label [[ELSE:%.*]] 824; CHECK: if: 825; CHECK-NEXT: call void @foo1() 826; CHECK-NEXT: ret void 827; CHECK: else: 828; CHECK-NEXT: ret void 829; 830 %and = or i32 %arg, 1 831 %cmp1 = icmp ne i32 %and, 12 832 %cmp2 = icmp ne i32 %arg, 32 833 %pred = and i1 %cmp1, %cmp2 834 br i1 %pred, label %if, label %else 835 836if: 837 call void @foo1() 838 ret void 839 840else: 841 ret void 842} 843