1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -passes=instcombine -S | FileCheck %s 3 4target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128:n8:16:32:64" 5 6define i32 @test1(i32 %A, i1 %b) { 7; CHECK-LABEL: @test1( 8; CHECK-NEXT: BB0: 9; CHECK-NEXT: br i1 [[B:%.*]], label [[BB1:%.*]], label [[BB2:%.*]] 10; CHECK: BB1: 11; CHECK-NEXT: ret i32 [[A:%.*]] 12; CHECK: BB2: 13; CHECK-NEXT: ret i32 [[A]] 14; 15BB0: 16 br i1 %b, label %BB1, label %BB2 17 18BB1: 19 ; Combine away one argument PHI nodes 20 %B = phi i32 [ %A, %BB0 ] 21 ret i32 %B 22 23BB2: 24 ret i32 %A 25} 26 27define i32 @test2(i32 %A, i1 %b) { 28; CHECK-LABEL: @test2( 29; CHECK-NEXT: BB0: 30; CHECK-NEXT: br i1 [[B:%.*]], label [[BB1:%.*]], label [[BB2:%.*]] 31; CHECK: BB1: 32; CHECK-NEXT: br label [[BB2]] 33; CHECK: BB2: 34; CHECK-NEXT: ret i32 [[A:%.*]] 35; 36BB0: 37 br i1 %b, label %BB1, label %BB2 38 39BB1: 40 br label %BB2 41 42BB2: 43 ; Combine away PHI nodes with same values 44 %B = phi i32 [ %A, %BB0 ], [ %A, %BB1 ] 45 ret i32 %B 46} 47 48define i32 @test3(i32 %A, i1 %b) { 49; CHECK-LABEL: @test3( 50; CHECK-NEXT: BB0: 51; CHECK-NEXT: br label [[LOOP:%.*]] 52; CHECK: Loop: 53; CHECK-NEXT: br i1 [[B:%.*]], label [[LOOP]], label [[EXIT:%.*]] 54; CHECK: Exit: 55; CHECK-NEXT: ret i32 [[A:%.*]] 56; 57BB0: 58 br label %Loop 59 60Loop: 61 ; PHI has same value always. 62 %B = phi i32 [ %A, %BB0 ], [ %B, %Loop ] 63 br i1 %b, label %Loop, label %Exit 64 65Exit: 66 ret i32 %B 67} 68 69define i32 @test4(i1 %b) { 70; CHECK-LABEL: @test4( 71; CHECK-NEXT: BB0: 72; CHECK-NEXT: ret i32 7 73; CHECK: Loop: 74; CHECK-NEXT: br i1 [[B:%.*]], label [[L2:%.*]], label [[LOOP:%.*]] 75; CHECK: L2: 76; CHECK-NEXT: br label [[LOOP]] 77; 78BB0: 79 ; Loop is unreachable 80 ret i32 7 81 82Loop: ; preds = %L2, %Loop 83 ; PHI has same value always. 84 %B = phi i32 [ %B, %L2 ], [ %B, %Loop ] 85 br i1 %b, label %L2, label %Loop 86 87L2: ; preds = %Loop 88 br label %Loop 89} 90 91define i32 @test5(i32 %A, i1 %b) { 92; CHECK-LABEL: @test5( 93; CHECK-NEXT: BB0: 94; CHECK-NEXT: br label [[LOOP:%.*]] 95; CHECK: Loop: 96; CHECK-NEXT: br i1 [[B:%.*]], label [[LOOP]], label [[EXIT:%.*]] 97; CHECK: Exit: 98; CHECK-NEXT: ret i32 [[A:%.*]] 99; 100BB0: 101 br label %Loop 102 103Loop: ; preds = %Loop, %BB0 104 ; PHI has same value always. 105 %B = phi i32 [ %A, %BB0 ], [ undef, %Loop ] 106 br i1 %b, label %Loop, label %Exit 107 108Exit: ; preds = %Loop 109 ret i32 %B 110} 111 112define i32 @test6(i16 %A, i1 %b) { 113; CHECK-LABEL: @test6( 114; CHECK-NEXT: BB0: 115; CHECK-NEXT: br i1 [[B:%.*]], label [[BB1:%.*]], label [[BB2:%.*]] 116; CHECK: BB1: 117; CHECK-NEXT: br label [[BB2]] 118; CHECK: BB2: 119; CHECK-NEXT: [[B:%.*]] = zext i16 [[A:%.*]] to i32 120; CHECK-NEXT: ret i32 [[B]] 121; 122BB0: 123 %X = zext i16 %A to i32 124 br i1 %b, label %BB1, label %BB2 125 126BB1: 127 %Y = zext i16 %A to i32 128 br label %BB2 129 130BB2: 131 ;; Suck casts into phi 132 %B = phi i32 [ %X, %BB0 ], [ %Y, %BB1 ] 133 ret i32 %B 134} 135 136define i32 @test7(i32 %A, i1 %b) { 137; CHECK-LABEL: @test7( 138; CHECK-NEXT: BB0: 139; CHECK-NEXT: br label [[LOOP:%.*]] 140; CHECK: Loop: 141; CHECK-NEXT: br i1 [[B:%.*]], label [[LOOP]], label [[EXIT:%.*]] 142; CHECK: Exit: 143; CHECK-NEXT: ret i32 0 144; 145BB0: 146 br label %Loop 147 148Loop: ; preds = %Loop, %BB0 149 ; PHI is dead. 150 %B = phi i32 [ %A, %BB0 ], [ %C, %Loop ] 151 %C = add i32 %B, 123 152 br i1 %b, label %Loop, label %Exit 153 154Exit: ; preds = %Loop 155 ret i32 0 156} 157 158define i32* @test8({ i32, i32 } *%A, i1 %b) { 159; CHECK-LABEL: @test8( 160; CHECK-NEXT: BB0: 161; CHECK-NEXT: br i1 [[B:%.*]], label [[BB1:%.*]], label [[BB2:%.*]] 162; CHECK: BB1: 163; CHECK-NEXT: br label [[BB2]] 164; CHECK: BB2: 165; CHECK-NEXT: [[B:%.*]] = getelementptr { i32, i32 }, { i32, i32 }* [[A:%.*]], i64 0, i32 1 166; CHECK-NEXT: ret i32* [[B]] 167; 168BB0: 169 %X = getelementptr inbounds { i32, i32 }, { i32, i32 } *%A, i32 0, i32 1 170 br i1 %b, label %BB1, label %BB2 171 172BB1: 173 %Y = getelementptr { i32, i32 }, { i32, i32 } *%A, i32 0, i32 1 174 br label %BB2 175 176BB2: 177 ;; Suck GEPs into phi 178 %B = phi i32* [ %X, %BB0 ], [ %Y, %BB1 ] 179 ret i32* %B 180} 181 182define i32 @test9(i32* %A, i32* %B) { 183; CHECK-LABEL: @test9( 184; CHECK-NEXT: entry: 185; CHECK-NEXT: [[C:%.*]] = icmp eq i32* [[A:%.*]], null 186; CHECK-NEXT: br i1 [[C]], label [[BB1:%.*]], label [[BB:%.*]] 187; CHECK: bb: 188; CHECK-NEXT: br label [[BB2:%.*]] 189; CHECK: bb1: 190; CHECK-NEXT: br label [[BB2]] 191; CHECK: bb2: 192; CHECK-NEXT: [[E_IN:%.*]] = phi i32* [ [[B:%.*]], [[BB]] ], [ [[A]], [[BB1]] ] 193; CHECK-NEXT: [[E:%.*]] = load i32, i32* [[E_IN]], align 1 194; CHECK-NEXT: ret i32 [[E]] 195; 196entry: 197 %c = icmp eq i32* %A, null 198 br i1 %c, label %bb1, label %bb 199 200bb: 201 %C = load i32, i32* %B, align 1 202 br label %bb2 203 204bb1: 205 %D = load i32, i32* %A, align 1 206 br label %bb2 207 208bb2: 209 %E = phi i32 [ %C, %bb ], [ %D, %bb1 ] 210 ret i32 %E 211 212} 213 214define i32 @test10(i32* %A, i32* %B) { 215; CHECK-LABEL: @test10( 216; CHECK-NEXT: entry: 217; CHECK-NEXT: [[C:%.*]] = icmp eq i32* [[A:%.*]], null 218; CHECK-NEXT: br i1 [[C]], label [[BB1:%.*]], label [[BB:%.*]] 219; CHECK: bb: 220; CHECK-NEXT: br label [[BB2:%.*]] 221; CHECK: bb1: 222; CHECK-NEXT: br label [[BB2]] 223; CHECK: bb2: 224; CHECK-NEXT: [[E_IN:%.*]] = phi i32* [ [[B:%.*]], [[BB]] ], [ [[A]], [[BB1]] ] 225; CHECK-NEXT: [[E:%.*]] = load i32, i32* [[E_IN]], align 16 226; CHECK-NEXT: ret i32 [[E]] 227; 228entry: 229 %c = icmp eq i32* %A, null 230 br i1 %c, label %bb1, label %bb 231 232bb: 233 %C = load i32, i32* %B, align 16 234 br label %bb2 235 236bb1: 237 %D = load i32, i32* %A, align 32 238 br label %bb2 239 240bb2: 241 %E = phi i32 [ %C, %bb ], [ %D, %bb1 ] 242 ret i32 %E 243} 244 245 246; PR1777 247declare i1 @test11a() 248 249define i1 @test11() { 250; CHECK-LABEL: @test11( 251; CHECK-NEXT: entry: 252; CHECK-NEXT: [[B:%.*]] = call i1 @test11a() 253; CHECK-NEXT: br i1 [[B]], label [[ONE:%.*]], label [[TWO:%.*]] 254; CHECK: one: 255; CHECK-NEXT: [[C:%.*]] = call i1 @test11a() 256; CHECK-NEXT: br i1 [[C]], label [[TWO]], label [[END:%.*]] 257; CHECK: two: 258; CHECK-NEXT: [[D:%.*]] = call i1 @test11a() 259; CHECK-NEXT: br i1 [[D]], label [[ONE]], label [[END]] 260; CHECK: end: 261; CHECK-NEXT: [[Z:%.*]] = call i1 @test11a() 262; CHECK-NEXT: ret i1 [[Z]] 263; 264entry: 265 %a = alloca i32 266 %i = ptrtoint i32* %a to i64 267 %b = call i1 @test11a() 268 br i1 %b, label %one, label %two 269 270one: 271 %x = phi i64 [%i, %entry], [%y, %two] 272 %c = call i1 @test11a() 273 br i1 %c, label %two, label %end 274 275two: 276 %y = phi i64 [%i, %entry], [%x, %one] 277 %d = call i1 @test11a() 278 br i1 %d, label %one, label %end 279 280end: 281 %f = phi i64 [ %x, %one], [%y, %two] 282 ; Change the %f to %i, and the optimizer suddenly becomes a lot smarter 283 ; even though %f must equal %i at this point 284 %g = inttoptr i64 %f to i32* 285 store i32 10, i32* %g 286 %z = call i1 @test11a() 287 ret i1 %z 288} 289 290 291define i64 @test12(i1 %cond, i8* %Ptr, i64 %Val) { 292; CHECK-LABEL: @test12( 293; CHECK-NEXT: entry: 294; CHECK-NEXT: br i1 [[COND:%.*]], label [[END:%.*]], label [[TWO:%.*]] 295; CHECK: two: 296; CHECK-NEXT: br label [[END]] 297; CHECK: end: 298; CHECK-NEXT: [[T869_0_OFF64:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[VAL:%.*]], [[TWO]] ] 299; CHECK-NEXT: [[T41:%.*]] = ptrtoint i8* [[PTR:%.*]] to i64 300; CHECK-NEXT: [[T2:%.*]] = add i64 [[T869_0_OFF64]], [[T41]] 301; CHECK-NEXT: ret i64 [[T2]] 302; 303entry: 304 %t41 = ptrtoint i8* %Ptr to i64 305 %t42 = zext i64 %t41 to i128 306 br i1 %cond, label %end, label %two 307 308two: 309 %t36 = zext i64 %Val to i128 ; <i128> [#uses=1] 310 %t37 = shl i128 %t36, 64 ; <i128> [#uses=1] 311 %ins39 = or i128 %t42, %t37 ; <i128> [#uses=1] 312 br label %end 313 314end: 315 %t869.0 = phi i128 [ %t42, %entry ], [ %ins39, %two ] 316 %t32 = trunc i128 %t869.0 to i64 ; <i64> [#uses=1] 317 %t29 = lshr i128 %t869.0, 64 ; <i128> [#uses=1] 318 %t30 = trunc i128 %t29 to i64 ; <i64> [#uses=1] 319 320 %t2 = add i64 %t32, %t30 321 ret i64 %t2 322} 323 324declare void @test13f(double, i32) 325 326define void @test13(i1 %cond, i32 %V1, double %Vald) { 327; CHECK-LABEL: @test13( 328; CHECK-NEXT: entry: 329; CHECK-NEXT: br i1 [[COND:%.*]], label [[END:%.*]], label [[TWO:%.*]] 330; CHECK: two: 331; CHECK-NEXT: br label [[END]] 332; CHECK: end: 333; CHECK-NEXT: [[TMP0:%.*]] = phi double [ 0.000000e+00, [[ENTRY:%.*]] ], [ [[VALD:%.*]], [[TWO]] ] 334; CHECK-NEXT: call void @test13f(double [[TMP0]], i32 [[V1:%.*]]) 335; CHECK-NEXT: ret void 336; 337entry: 338 %t42 = zext i32 %V1 to i128 339 br i1 %cond, label %end, label %two 340 341two: 342 %Val = bitcast double %Vald to i64 343 %t36 = zext i64 %Val to i128 ; <i128> [#uses=1] 344 %t37 = shl i128 %t36, 64 ; <i128> [#uses=1] 345 %ins39 = or i128 %t42, %t37 ; <i128> [#uses=1] 346 br label %end 347 348end: 349 %t869.0 = phi i128 [ %t42, %entry ], [ %ins39, %two ] 350 %t32 = trunc i128 %t869.0 to i32 351 %t29 = lshr i128 %t869.0, 64 ; <i128> [#uses=1] 352 %t30 = trunc i128 %t29 to i64 ; <i64> [#uses=1] 353 %t31 = bitcast i64 %t30 to double 354 355 call void @test13f(double %t31, i32 %t32) 356 ret void 357} 358 359define i640 @test14a(i320 %A, i320 %B, i1 %b1) { 360; CHECK-LABEL: @test14a( 361; CHECK-NEXT: BB0: 362; CHECK-NEXT: br label [[LOOP:%.*]] 363; CHECK: Loop: 364; CHECK-NEXT: [[C_IN:%.*]] = phi i320 [ [[A:%.*]], [[BB0:%.*]] ], [ [[B:%.*]], [[LOOP]] ] 365; CHECK-NEXT: br i1 [[B1:%.*]], label [[LOOP]], label [[EXIT:%.*]] 366; CHECK: Exit: 367; CHECK-NEXT: [[C:%.*]] = zext i320 [[C_IN]] to i640 368; CHECK-NEXT: ret i640 [[C]] 369; 370BB0: 371 %a = zext i320 %A to i640 372 %b = zext i320 %B to i640 373 br label %Loop 374 375Loop: 376 %C = phi i640 [ %a, %BB0 ], [ %b, %Loop ] 377 br i1 %b1, label %Loop, label %Exit 378 379Exit: ; preds = %Loop 380 ret i640 %C 381} 382 383define i160 @test14b(i320 %pA, i320 %pB, i1 %b1) { 384; CHECK-LABEL: @test14b( 385; CHECK-NEXT: BB0: 386; CHECK-NEXT: [[A:%.*]] = trunc i320 [[PA:%.*]] to i160 387; CHECK-NEXT: [[B:%.*]] = trunc i320 [[PB:%.*]] to i160 388; CHECK-NEXT: br label [[LOOP:%.*]] 389; CHECK: Loop: 390; CHECK-NEXT: [[C:%.*]] = phi i160 [ [[A]], [[BB0:%.*]] ], [ [[B]], [[LOOP]] ] 391; CHECK-NEXT: br i1 [[B1:%.*]], label [[LOOP]], label [[EXIT:%.*]] 392; CHECK: Exit: 393; CHECK-NEXT: ret i160 [[C]] 394; 395BB0: 396 %a = trunc i320 %pA to i160 397 %b = trunc i320 %pB to i160 398 br label %Loop 399 400Loop: 401 %C = phi i160 [ %a, %BB0 ], [ %b, %Loop ] 402 br i1 %b1, label %Loop, label %Exit 403 404Exit: ; preds = %Loop 405 ret i160 %C 406} 407 408declare i64 @test15a(i64) 409 410define i64 @test15b(i64 %A, i1 %b) { 411; CHECK-LABEL: @test15b( 412; CHECK-NEXT: entry: 413; CHECK-NEXT: br i1 [[B:%.*]], label [[ONE:%.*]], label [[TWO:%.*]] 414; CHECK: one: 415; CHECK-NEXT: [[X_OFF64:%.*]] = phi i64 [ [[A:%.*]], [[ENTRY:%.*]] ], [ [[Y_OFF64:%.*]], [[TWO]] ] 416; CHECK-NEXT: [[C:%.*]] = call i64 @test15a(i64 [[X_OFF64]]) 417; CHECK-NEXT: br label [[TWO]] 418; CHECK: two: 419; CHECK-NEXT: [[Y_OFF0:%.*]] = phi i64 [ [[A]], [[ENTRY]] ], [ [[C]], [[ONE]] ] 420; CHECK-NEXT: [[Y_OFF64]] = phi i64 [ [[A]], [[ENTRY]] ], [ 0, [[ONE]] ] 421; CHECK-NEXT: [[D:%.*]] = call i64 @test15a(i64 [[Y_OFF64]]) 422; CHECK-NEXT: [[TMP0:%.*]] = and i64 [[D]], 1 423; CHECK-NEXT: [[D1_NOT:%.*]] = icmp eq i64 [[TMP0]], 0 424; CHECK-NEXT: br i1 [[D1_NOT]], label [[END:%.*]], label [[ONE]] 425; CHECK: end: 426; CHECK-NEXT: ret i64 [[Y_OFF0]] 427; 428entry: 429 %i0 = zext i64 %A to i128 430 %i1 = shl i128 %i0, 64 431 %i = or i128 %i1, %i0 432 br i1 %b, label %one, label %two 433 434one: 435 %x = phi i128 [%i, %entry], [%y, %two] 436 %x1 = lshr i128 %x, 64 437 %x2 = trunc i128 %x1 to i64 438 %c = call i64 @test15a(i64 %x2) 439 %c1 = zext i64 %c to i128 440 br label %two 441 442 443two: 444 %y = phi i128 [%i, %entry], [%c1, %one] 445 %y1 = lshr i128 %y, 64 446 %y2 = trunc i128 %y1 to i64 447 %d = call i64 @test15a(i64 %y2) 448 %d1 = trunc i64 %d to i1 449 br i1 %d1, label %one, label %end 450 451 452end: 453 %g = trunc i128 %y to i64 454 ret i64 %g 455} 456 457; PR6512 - Shouldn't merge loads from different addr spaces. 458define i32 @test16(i32 addrspace(1)* %pointer1, i32 %flag, i32* %pointer2) 459; CHECK-LABEL: @test16( 460; CHECK-NEXT: entry: 461; CHECK-NEXT: [[RETVAL:%.*]] = alloca i32, align 4 462; CHECK-NEXT: [[POINTER1_ADDR:%.*]] = alloca i32 addrspace(1)*, align 8 463; CHECK-NEXT: [[POINTER2_ADDR:%.*]] = alloca i32*, align 8 464; CHECK-NEXT: store i32 addrspace(1)* [[POINTER1:%.*]], i32 addrspace(1)** [[POINTER1_ADDR]], align 8 465; CHECK-NEXT: store i32* [[POINTER2:%.*]], i32** [[POINTER2_ADDR]], align 8 466; CHECK-NEXT: [[TOBOOL_NOT:%.*]] = icmp eq i32 [[FLAG:%.*]], 0 467; CHECK-NEXT: br i1 [[TOBOOL_NOT]], label [[IF_ELSE:%.*]], label [[IF_THEN:%.*]] 468; CHECK: return: 469; CHECK-NEXT: [[T7:%.*]] = load i32, i32* [[RETVAL]], align 4 470; CHECK-NEXT: ret i32 [[T7]] 471; CHECK: if.end: 472; CHECK-NEXT: [[STOREMERGE:%.*]] = phi i32 [ [[T5:%.*]], [[IF_ELSE]] ], [ [[T2:%.*]], [[IF_THEN]] ] 473; CHECK-NEXT: store i32 [[STOREMERGE]], i32* [[RETVAL]], align 4 474; CHECK-NEXT: br label [[RETURN:%.*]] 475; CHECK: if.then: 476; CHECK-NEXT: [[T1:%.*]] = load i32 addrspace(1)*, i32 addrspace(1)** [[POINTER1_ADDR]], align 8 477; CHECK-NEXT: [[T2]] = load i32, i32 addrspace(1)* [[T1]], align 4 478; CHECK-NEXT: br label [[IF_END:%.*]] 479; CHECK: if.else: 480; CHECK-NEXT: [[T3:%.*]] = load i32*, i32** [[POINTER2_ADDR]], align 8 481; CHECK-NEXT: [[T5]] = load i32, i32* [[T3]], align 4 482; CHECK-NEXT: br label [[IF_END]] 483; 484nounwind { 485entry: 486 %retval = alloca i32, align 4 ; <i32*> [#uses=2] 487 %pointer1.addr = alloca i32 addrspace(1)*, align 4 ; <i32 addrspace(1)**> 488 %flag.addr = alloca i32, align 4 ; <i32*> [#uses=2] 489 %pointer2.addr = alloca i32*, align 4 ; <i32**> [#uses=2] 490 %res = alloca i32, align 4 ; <i32*> [#uses=4] 491 store i32 addrspace(1)* %pointer1, i32 addrspace(1)** %pointer1.addr 492 store i32 %flag, i32* %flag.addr 493 store i32* %pointer2, i32** %pointer2.addr 494 store i32 10, i32* %res 495 %t = load i32, i32* %flag.addr ; <i32> [#uses=1] 496 %tobool = icmp ne i32 %t, 0 ; <i1> [#uses=1] 497 br i1 %tobool, label %if.then, label %if.else 498 499return: ; preds = %if.end 500 %t7 = load i32, i32* %retval ; <i32> [#uses=1] 501 ret i32 %t7 502 503if.end: ; preds = %if.else, %if.then 504 %t6 = load i32, i32* %res ; <i32> [#uses=1] 505 store i32 %t6, i32* %retval 506 br label %return 507 508if.then: ; preds = %entry 509 %t1 = load i32 addrspace(1)*, i32 addrspace(1)** %pointer1.addr ; <i32 addrspace(1)*> 510 %arrayidx = getelementptr i32, i32 addrspace(1)* %t1, i32 0 ; <i32 addrspace(1)*> [#uses=1] 511 %t2 = load i32, i32 addrspace(1)* %arrayidx ; <i32> [#uses=1] 512 store i32 %t2, i32* %res 513 br label %if.end 514 515if.else: ; preds = %entry 516 %t3 = load i32*, i32** %pointer2.addr ; <i32*> [#uses=1] 517 %arrayidx4 = getelementptr i32, i32* %t3, i32 0 ; <i32*> [#uses=1] 518 %t5 = load i32, i32* %arrayidx4 ; <i32> [#uses=1] 519 store i32 %t5, i32* %res 520 br label %if.end 521} 522 523; PR4413 524declare i32 @ext() 525define i32 @test17(i1 %a) { 526; CHECK-LABEL: @test17( 527; CHECK-NEXT: entry: 528; CHECK-NEXT: br i1 [[A:%.*]], label [[BB1:%.*]], label [[BB2:%.*]] 529; CHECK: bb1: 530; CHECK-NEXT: [[TMP0:%.*]] = tail call i32 @ext() 531; CHECK-NEXT: br label [[BB2]] 532; CHECK: bb2: 533; CHECK-NEXT: [[RES:%.*]] = phi i32 [ [[TMP0]], [[BB1]] ], [ 0, [[ENTRY:%.*]] ] 534; CHECK-NEXT: ret i32 [[RES]] 535; 536entry: 537 br i1 %a, label %bb1, label %bb2 538 539bb1: ; preds = %entry 540 %0 = tail call i32 @ext() ; <i32> [#uses=1] 541 br label %bb2 542 543bb2: ; preds = %bb1, %entry 544 %cond = phi i1 [ true, %bb1 ], [ false, %entry ] ; <i1> [#uses=1] 545 %val = phi i32 [ %0, %bb1 ], [ 0, %entry ] ; <i32> [#uses=1] 546 %res = select i1 %cond, i32 %val, i32 0 ; <i32> [#uses=1] 547 ret i32 %res 548} 549 550; Atomic and non-atomic loads should not be combined. 551define i32 @PR51435(i32* %ptr, i32* %atomic_ptr, i1 %c) { 552; CHECK-LABEL: @PR51435( 553; CHECK: entry: 554; CHECK-NEXT: [[NON_ATOMIC:%.*]] = load i32, i32* %ptr, align 4 555; CHECK: if: 556; CHECK-NEXT: [[ATOMIC:%.*]] = load atomic i32, i32* %atomic_ptr acquire, align 4 557; CHECK: end: 558; CHECK-NEXT: [[COND:%.*]] = phi i32 [ [[NON_ATOMIC]], %entry ], [ [[ATOMIC]], %if ] 559; CHECK-NEXT: ret i32 [[COND]] 560entry: 561 %x = load i32, i32* %ptr, align 4 562 br i1 %c, label %if, label %end 563 564if: 565 %y = load atomic i32, i32* %atomic_ptr acquire, align 4 566 br label %end 567 568end: 569 %cond = phi i32 [ %x, %entry ], [ %y, %if ] 570 ret i32 %cond 571} 572 573define i1 @test18(i1 %cond) { 574; CHECK-LABEL: @test18( 575; CHECK-NEXT: br i1 [[COND:%.*]], label [[TRUE:%.*]], label [[FALSE:%.*]] 576; CHECK: true: 577; CHECK-NEXT: br label [[RET:%.*]] 578; CHECK: false: 579; CHECK-NEXT: br label [[RET]] 580; CHECK: ret: 581; CHECK-NEXT: ret i1 false 582; 583 %zero = alloca i32 584 %one = alloca i32 585 br i1 %cond, label %true, label %false 586true: 587 br label %ret 588false: 589 br label %ret 590ret: 591 %ptr = phi i32* [ %zero, %true ] , [ %one, %false ] 592 %isnull = icmp eq i32* %ptr, null 593 ret i1 %isnull 594} 595 596define i1 @test19(i1 %cond, double %x) { 597; CHECK-LABEL: @test19( 598; CHECK-NEXT: br i1 [[COND:%.*]], label [[TRUE:%.*]], label [[FALSE:%.*]] 599; CHECK: true: 600; CHECK-NEXT: br label [[RET:%.*]] 601; CHECK: false: 602; CHECK-NEXT: br label [[RET]] 603; CHECK: ret: 604; CHECK-NEXT: ret i1 true 605; 606 br i1 %cond, label %true, label %false 607true: 608 br label %ret 609false: 610 br label %ret 611ret: 612 %p = phi double [ %x, %true ], [ 0x7FF0000000000000, %false ]; RHS = +infty 613 %cmp = fcmp ule double %x, %p 614 ret i1 %cmp 615} 616 617define i1 @test20(i1 %cond) { 618; CHECK-LABEL: @test20( 619; CHECK-NEXT: br i1 [[COND:%.*]], label [[TRUE:%.*]], label [[FALSE:%.*]] 620; CHECK: true: 621; CHECK-NEXT: br label [[RET:%.*]] 622; CHECK: false: 623; CHECK-NEXT: br label [[RET]] 624; CHECK: ret: 625; CHECK-NEXT: ret i1 false 626; 627 %a = alloca i32 628 %b = alloca i32 629 %c = alloca i32 630 br i1 %cond, label %true, label %false 631true: 632 br label %ret 633false: 634 br label %ret 635ret: 636 %p = phi i32* [ %a, %true ], [ %b, %false ] 637 %r = icmp eq i32* %p, %c 638 ret i1 %r 639} 640 641define i1 @test21(i1 %c1, i1 %c2) { 642; CHECK-LABEL: @test21( 643; CHECK-NEXT: br i1 [[C1:%.*]], label [[TRUE:%.*]], label [[FALSE:%.*]] 644; CHECK: true: 645; CHECK-NEXT: br label [[LOOP:%.*]] 646; CHECK: false: 647; CHECK-NEXT: br label [[LOOP]] 648; CHECK: loop: 649; CHECK-NEXT: br i1 [[C2:%.*]], label [[RET:%.*]], label [[LOOP]] 650; CHECK: ret: 651; CHECK-NEXT: ret i1 false 652; 653 %a = alloca i32 654 %b = alloca i32 655 %c = alloca i32 656 br i1 %c1, label %true, label %false 657true: 658 br label %loop 659false: 660 br label %loop 661loop: 662 %p = phi i32* [ %a, %true ], [ %b, %false ], [ %p, %loop ] 663 %r = icmp eq i32* %p, %c 664 br i1 %c2, label %ret, label %loop 665ret: 666 ret i1 %r 667} 668 669define void @test22() { 670; CHECK-LABEL: @test22( 671; CHECK-NEXT: entry: 672; CHECK-NEXT: br label [[LOOP:%.*]] 673; CHECK: loop: 674; CHECK-NEXT: [[PHI:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[Y:%.*]], [[LOOP]] ] 675; CHECK-NEXT: [[Y]] = add i32 [[PHI]], 1 676; CHECK-NEXT: [[O:%.*]] = or i32 [[Y]], [[PHI]] 677; CHECK-NEXT: [[E:%.*]] = icmp eq i32 [[O]], [[Y]] 678; CHECK-NEXT: br i1 [[E]], label [[LOOP]], label [[RET:%.*]] 679; CHECK: ret: 680; CHECK-NEXT: ret void 681; 682entry: 683 br label %loop 684loop: 685 %phi = phi i32 [ 0, %entry ], [ %y, %loop ] 686 %y = add i32 %phi, 1 687 %o = or i32 %y, %phi 688 %e = icmp eq i32 %o, %y 689 br i1 %e, label %loop, label %ret 690ret: 691 ret void 692} 693 694define i32 @test23(i32 %A, i1 %pb, i32 * %P) { 695; CHECK-LABEL: @test23( 696; CHECK-NEXT: BB0: 697; CHECK-NEXT: [[PHI_BO:%.*]] = add i32 [[A:%.*]], 19 698; CHECK-NEXT: br label [[LOOP:%.*]] 699; CHECK: Loop: 700; CHECK-NEXT: [[B:%.*]] = phi i32 [ [[PHI_BO]], [[BB0:%.*]] ], [ 61, [[LOOP]] ] 701; CHECK-NEXT: store i32 [[B]], i32* [[P:%.*]], align 4 702; CHECK-NEXT: br i1 [[PB:%.*]], label [[LOOP]], label [[EXIT:%.*]] 703; CHECK: Exit: 704; CHECK-NEXT: ret i32 [[B]] 705; 706BB0: 707 br label %Loop 708 709Loop: ; preds = %Loop, %BB0 710 ; PHI has same value always. 711 %B = phi i32 [ %A, %BB0 ], [ 42, %Loop ] 712 %D = add i32 %B, 19 713 store i32 %D, i32* %P 714 br i1 %pb, label %Loop, label %Exit 715 716Exit: ; preds = %Loop 717 %E = add i32 %B, 19 718 ret i32 %E 719} 720 721define i32 @test24(i32 %A, i1 %cond) { 722; CHECK-LABEL: @test24( 723; CHECK-NEXT: BB0: 724; CHECK-NEXT: br i1 [[COND:%.*]], label [[BB1:%.*]], label [[BB2:%.*]] 725; CHECK: BB1: 726; CHECK-NEXT: br label [[BB2]] 727; CHECK: BB2: 728; CHECK-NEXT: [[C:%.*]] = add nuw i32 [[A:%.*]], 1 729; CHECK-NEXT: ret i32 [[C]] 730; 731BB0: 732 %X = add nuw nsw i32 %A, 1 733 br i1 %cond, label %BB1, label %BB2 734 735BB1: 736 %Y = add nuw i32 %A, 1 737 br label %BB2 738 739BB2: 740 %C = phi i32 [ %X, %BB0 ], [ %Y, %BB1 ] 741 ret i32 %C 742} 743 744; Same as test11, but used to be missed due to a bug. 745declare i1 @test25a() 746 747define i1 @test25() { 748; CHECK-LABEL: @test25( 749; CHECK-NEXT: entry: 750; CHECK-NEXT: [[B:%.*]] = call i1 @test25a() 751; CHECK-NEXT: br i1 [[B]], label [[ONE:%.*]], label [[TWO:%.*]] 752; CHECK: one: 753; CHECK-NEXT: [[C:%.*]] = call i1 @test25a() 754; CHECK-NEXT: br i1 [[C]], label [[TWO]], label [[END:%.*]] 755; CHECK: two: 756; CHECK-NEXT: [[D:%.*]] = call i1 @test25a() 757; CHECK-NEXT: br i1 [[D]], label [[ONE]], label [[END]] 758; CHECK: end: 759; CHECK-NEXT: [[Z:%.*]] = call i1 @test25a() 760; CHECK-NEXT: ret i1 [[Z]] 761; 762entry: 763 %a = alloca i32 764 %i = ptrtoint i32* %a to i64 765 %b = call i1 @test25a() 766 br i1 %b, label %one, label %two 767 768one: 769 %x = phi i64 [%y, %two], [%i, %entry] 770 %c = call i1 @test25a() 771 br i1 %c, label %two, label %end 772 773two: 774 %y = phi i64 [%x, %one], [%i, %entry] 775 %d = call i1 @test25a() 776 br i1 %d, label %one, label %end 777 778end: 779 %f = phi i64 [ %x, %one], [%y, %two] 780 ; Change the %f to %i, and the optimizer suddenly becomes a lot smarter 781 ; even though %f must equal %i at this point 782 %g = inttoptr i64 %f to i32* 783 store i32 10, i32* %g 784 %z = call i1 @test25a() 785 ret i1 %z 786} 787 788declare i1 @test26a() 789 790define i1 @test26(i32 %n) { 791; CHECK-LABEL: @test26( 792; CHECK-NEXT: entry: 793; CHECK-NEXT: [[B:%.*]] = call i1 @test26a() 794; CHECK-NEXT: br label [[ONE:%.*]] 795; CHECK: one: 796; CHECK-NEXT: [[C:%.*]] = call i1 @test26a() 797; CHECK-NEXT: switch i32 [[N:%.*]], label [[END:%.*]] [ 798; CHECK-NEXT: i32 2, label [[TWO:%.*]] 799; CHECK-NEXT: i32 3, label [[THREE:%.*]] 800; CHECK-NEXT: ] 801; CHECK: two: 802; CHECK-NEXT: [[D:%.*]] = call i1 @test26a() 803; CHECK-NEXT: switch i32 [[N]], label [[END]] [ 804; CHECK-NEXT: i32 10, label [[ONE]] 805; CHECK-NEXT: i32 30, label [[THREE]] 806; CHECK-NEXT: ] 807; CHECK: three: 808; CHECK-NEXT: [[E:%.*]] = call i1 @test26a() 809; CHECK-NEXT: br i1 [[E]], label [[ONE]], label [[TWO]] 810; CHECK: end: 811; CHECK-NEXT: [[Z:%.*]] = call i1 @test26a() 812; CHECK-NEXT: ret i1 [[Z]] 813; 814entry: 815 %a = alloca i32 816 %i = ptrtoint i32* %a to i64 817 %b = call i1 @test26a() 818 br label %one 819 820one: 821 %x = phi i64 [%y, %two], [%w, %three], [%i, %entry] 822 %c = call i1 @test26a() 823 switch i32 %n, label %end [ 824 i32 2, label %two 825 i32 3, label %three 826 ] 827 828two: 829 %y = phi i64 [%x, %one], [%w, %three] 830 %d = call i1 @test26a() 831 switch i32 %n, label %end [ 832 i32 10, label %one 833 i32 30, label %three 834 ] 835 836three: 837 %w = phi i64 [%y, %two], [%x, %one] 838 %e = call i1 @test26a() 839 br i1 %e, label %one, label %two 840 841end: 842 %f = phi i64 [ %x, %one], [%y, %two] 843 ; Change the %f to %i, and the optimizer suddenly becomes a lot smarter 844 ; even though %f must equal %i at this point 845 %g = inttoptr i64 %f to i32* 846 store i32 10, i32* %g 847 %z = call i1 @test26a() 848 ret i1 %z 849} 850 851define i32 @test27(i1 %b) { 852; CHECK-LABEL: @test27( 853; CHECK-NEXT: entry: 854; CHECK-NEXT: br label [[DONE:%.*]] 855; CHECK: done: 856; CHECK-NEXT: ret i32 undef 857; 858entry: 859 br label %done 860done: 861 %y = phi i32 [ undef, %entry ] 862 ret i32 %y 863} 864 865; We should be able to fold the zexts to the other side of the phi 866; even though there's a constant value input to the phi. This is 867; because we can shrink that constant to the smaller phi type. 868 869define i1 @PR24766(i8 %x1, i8 %x2, i8 %condition) { 870; CHECK-LABEL: @PR24766( 871; CHECK-NEXT: entry: 872; CHECK-NEXT: [[CONV:%.*]] = sext i8 [[CONDITION:%.*]] to i32 873; CHECK-NEXT: switch i32 [[CONV]], label [[EPILOG:%.*]] [ 874; CHECK-NEXT: i32 0, label [[SW1:%.*]] 875; CHECK-NEXT: i32 1, label [[SW2:%.*]] 876; CHECK-NEXT: ] 877; CHECK: sw1: 878; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i8 [[X1:%.*]], [[X2:%.*]] 879; CHECK-NEXT: br label [[EPILOG]] 880; CHECK: sw2: 881; CHECK-NEXT: [[CMP2:%.*]] = icmp sle i8 [[X1]], [[X2]] 882; CHECK-NEXT: br label [[EPILOG]] 883; CHECK: epilog: 884; CHECK-NEXT: [[CONDITIONMET_SHRUNK:%.*]] = phi i1 [ false, [[ENTRY:%.*]] ], [ [[CMP2]], [[SW2]] ], [ [[CMP1]], [[SW1]] ] 885; CHECK-NEXT: ret i1 [[CONDITIONMET_SHRUNK]] 886; 887entry: 888 %conv = sext i8 %condition to i32 889 switch i32 %conv, label %epilog [ 890 i32 0, label %sw1 891 i32 1, label %sw2 892 ] 893 894sw1: 895 %cmp1 = icmp eq i8 %x1, %x2 896 %frombool1 = zext i1 %cmp1 to i8 897 br label %epilog 898 899sw2: 900 %cmp2 = icmp sle i8 %x1, %x2 901 %frombool2 = zext i1 %cmp2 to i8 902 br label %epilog 903 904epilog: 905 %conditionMet = phi i8 [ 0, %entry ], [ %frombool2, %sw2 ], [ %frombool1, %sw1 ] 906 %tobool = icmp ne i8 %conditionMet, 0 907 ret i1 %tobool 908 909} 910 911; Same as above (a phi with more than 2 operands), but no constants 912 913define i1 @PR24766_no_constants(i8 %x1, i8 %x2, i8 %condition, i1 %another_condition) { 914; CHECK-LABEL: @PR24766_no_constants( 915; CHECK-NEXT: entry: 916; CHECK-NEXT: [[CONV:%.*]] = sext i8 [[CONDITION:%.*]] to i32 917; CHECK-NEXT: switch i32 [[CONV]], label [[EPILOG:%.*]] [ 918; CHECK-NEXT: i32 0, label [[SW1:%.*]] 919; CHECK-NEXT: i32 1, label [[SW2:%.*]] 920; CHECK-NEXT: ] 921; CHECK: sw1: 922; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i8 [[X1:%.*]], [[X2:%.*]] 923; CHECK-NEXT: br label [[EPILOG]] 924; CHECK: sw2: 925; CHECK-NEXT: [[CMP2:%.*]] = icmp sle i8 [[X1]], [[X2]] 926; CHECK-NEXT: br label [[EPILOG]] 927; CHECK: epilog: 928; CHECK-NEXT: [[CONDITIONMET_IN:%.*]] = phi i1 [ [[ANOTHER_CONDITION:%.*]], [[ENTRY:%.*]] ], [ [[CMP2]], [[SW2]] ], [ [[CMP1]], [[SW1]] ] 929; CHECK-NEXT: ret i1 [[CONDITIONMET_IN]] 930; 931entry: 932 %frombool0 = zext i1 %another_condition to i8 933 %conv = sext i8 %condition to i32 934 switch i32 %conv, label %epilog [ 935 i32 0, label %sw1 936 i32 1, label %sw2 937 ] 938 939sw1: 940 %cmp1 = icmp eq i8 %x1, %x2 941 %frombool1 = zext i1 %cmp1 to i8 942 br label %epilog 943 944sw2: 945 %cmp2 = icmp sle i8 %x1, %x2 946 %frombool2 = zext i1 %cmp2 to i8 947 br label %epilog 948 949epilog: 950 %conditionMet = phi i8 [ %frombool0, %entry ], [ %frombool2, %sw2 ], [ %frombool1, %sw1 ] 951 %tobool = icmp ne i8 %conditionMet, 0 952 ret i1 %tobool 953 954} 955 956; Same as above (a phi with more than 2 operands), but two constants 957 958define i1 @PR24766_two_constants(i8 %x1, i8 %x2, i8 %condition) { 959; CHECK-LABEL: @PR24766_two_constants( 960; CHECK-NEXT: entry: 961; CHECK-NEXT: [[CONV:%.*]] = sext i8 [[CONDITION:%.*]] to i32 962; CHECK-NEXT: switch i32 [[CONV]], label [[EPILOG:%.*]] [ 963; CHECK-NEXT: i32 0, label [[SW1:%.*]] 964; CHECK-NEXT: i32 1, label [[SW2:%.*]] 965; CHECK-NEXT: ] 966; CHECK: sw1: 967; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i8 [[X1:%.*]], [[X2:%.*]] 968; CHECK-NEXT: br label [[EPILOG]] 969; CHECK: sw2: 970; CHECK-NEXT: br label [[EPILOG]] 971; CHECK: epilog: 972; CHECK-NEXT: [[CONDITIONMET:%.*]] = phi i1 [ false, [[ENTRY:%.*]] ], [ true, [[SW2]] ], [ [[CMP1]], [[SW1]] ] 973; CHECK-NEXT: ret i1 [[CONDITIONMET]] 974; 975entry: 976 %conv = sext i8 %condition to i32 977 switch i32 %conv, label %epilog [ 978 i32 0, label %sw1 979 i32 1, label %sw2 980 ] 981 982sw1: 983 %cmp1 = icmp eq i8 %x1, %x2 984 %frombool1 = zext i1 %cmp1 to i8 985 br label %epilog 986 987sw2: 988 %cmp2 = icmp sle i8 %x1, %x2 989 %frombool2 = zext i1 %cmp2 to i8 990 br label %epilog 991 992epilog: 993 %conditionMet = phi i8 [ 0, %entry ], [ 1, %sw2 ], [ %frombool1, %sw1 ] 994 %tobool = icmp ne i8 %conditionMet, 0 995 ret i1 %tobool 996 997} 998 999; Same as above (a phi with more than 2 operands), but two constants and two variables 1000 1001define i1 @PR24766_two_constants_two_var(i8 %x1, i8 %x2, i8 %condition) { 1002; CHECK-LABEL: @PR24766_two_constants_two_var( 1003; CHECK-NEXT: entry: 1004; CHECK-NEXT: [[CONV:%.*]] = sext i8 [[CONDITION:%.*]] to i32 1005; CHECK-NEXT: switch i32 [[CONV]], label [[EPILOG:%.*]] [ 1006; CHECK-NEXT: i32 0, label [[SW1:%.*]] 1007; CHECK-NEXT: i32 1, label [[SW2:%.*]] 1008; CHECK-NEXT: i32 2, label [[SW3:%.*]] 1009; CHECK-NEXT: ] 1010; CHECK: sw1: 1011; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i8 [[X1:%.*]], [[X2:%.*]] 1012; CHECK-NEXT: br label [[EPILOG]] 1013; CHECK: sw2: 1014; CHECK-NEXT: [[CMP2:%.*]] = icmp sle i8 [[X1]], [[X2]] 1015; CHECK-NEXT: br label [[EPILOG]] 1016; CHECK: sw3: 1017; CHECK-NEXT: br label [[EPILOG]] 1018; CHECK: epilog: 1019; CHECK-NEXT: [[CONDITIONMET_SHRUNK:%.*]] = phi i1 [ false, [[ENTRY:%.*]] ], [ [[CMP2]], [[SW2]] ], [ [[CMP1]], [[SW1]] ], [ true, [[SW3]] ] 1020; CHECK-NEXT: ret i1 [[CONDITIONMET_SHRUNK]] 1021; 1022entry: 1023 %conv = sext i8 %condition to i32 1024 switch i32 %conv, label %epilog [ 1025 i32 0, label %sw1 1026 i32 1, label %sw2 1027 i32 2, label %sw3 1028 ] 1029 1030sw1: 1031 %cmp1 = icmp eq i8 %x1, %x2 1032 %frombool1 = zext i1 %cmp1 to i8 1033 br label %epilog 1034 1035sw2: 1036 %cmp2 = icmp sle i8 %x1, %x2 1037 %frombool2 = zext i1 %cmp2 to i8 1038 br label %epilog 1039 1040sw3: 1041 %cmp3 = icmp sge i8 %x1, %x2 1042 %frombool3 = zext i1 %cmp3 to i8 1043 br label %epilog 1044 1045epilog: 1046 %conditionMet = phi i8 [ 0, %entry ], [ %frombool2, %sw2 ], [ %frombool1, %sw1 ], [ 1, %sw3 ] 1047 %tobool = icmp ne i8 %conditionMet, 0 1048 ret i1 %tobool 1049 1050} 1051 1052define i1 @phi_allnonzeroconstant(i1 %c, i32 %a, i32 %b) { 1053; CHECK-LABEL: @phi_allnonzeroconstant( 1054; CHECK-NEXT: entry: 1055; CHECK-NEXT: br i1 [[C:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] 1056; CHECK: if.then: 1057; CHECK-NEXT: br label [[IF_END:%.*]] 1058; CHECK: if.else: 1059; CHECK-NEXT: call void @dummy() 1060; CHECK-NEXT: br label [[IF_END]] 1061; CHECK: if.end: 1062; CHECK-NEXT: ret i1 false 1063; 1064entry: 1065 br i1 %c, label %if.then, label %if.else 1066 1067if.then: ; preds = %entry 1068 br label %if.end 1069 1070if.else: ; preds = %entry 1071 call void @dummy() 1072 1073 br label %if.end 1074 1075if.end: ; preds = %if.else, %if.then 1076 %x.0 = phi i32 [ 1, %if.then ], [ 2, %if.else ] 1077 %or = or i32 %x.0, %a 1078 %cmp1 = icmp eq i32 %or, 0 1079 ret i1 %cmp1 1080} 1081 1082define i1 @phi_allnonzerononconstant(i1 %c, i32 %a, i32* nonnull %b1, i32* nonnull %b2) { 1083; CHECK-LABEL: @phi_allnonzerononconstant( 1084; CHECK-NEXT: entry: 1085; CHECK-NEXT: br i1 [[C:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] 1086; CHECK: if.then: 1087; CHECK-NEXT: br label [[IF_END:%.*]] 1088; CHECK: if.else: 1089; CHECK-NEXT: call void @dummy() 1090; CHECK-NEXT: br label [[IF_END]] 1091; CHECK: if.end: 1092; CHECK-NEXT: ret i1 false 1093; 1094entry: 1095 br i1 %c, label %if.then, label %if.else 1096 1097if.then: ; preds = %entry 1098 br label %if.end 1099 1100if.else: ; preds = %entry 1101 call void @dummy() 1102 1103 br label %if.end 1104 1105if.end: ; preds = %if.else, %if.then 1106 %x.0 = phi i32* [ %b1, %if.then ], [ %b2, %if.else ] 1107 %cmp1 = icmp eq i32* %x.0, null 1108 ret i1 %cmp1 1109} 1110 1111declare void @dummy() 1112 1113define i1 @phi_knownnonzero_eq(i32 %n, i32 %s, i32* nocapture readonly %P) { 1114; CHECK-LABEL: @phi_knownnonzero_eq( 1115; CHECK-NEXT: entry: 1116; CHECK-NEXT: [[TOBOOL:%.*]] = icmp slt i32 [[N:%.*]], [[S:%.*]] 1117; CHECK-NEXT: br i1 [[TOBOOL]], label [[IF_END:%.*]], label [[IF_THEN:%.*]] 1118; CHECK: if.then: 1119; CHECK-NEXT: br label [[IF_END]] 1120; CHECK: if.end: 1121; CHECK-NEXT: [[A_0:%.*]] = phi i32 [ 1, [[IF_THEN]] ], [ [[N]], [[ENTRY:%.*]] ] 1122; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[A_0]], 0 1123; CHECK-NEXT: ret i1 [[CMP1]] 1124; 1125entry: 1126 %tobool = icmp slt i32 %n, %s 1127 br i1 %tobool, label %if.end, label %if.then 1128 1129if.then: ; preds = %entry 1130 %0 = load i32, i32* %P 1131 %cmp = icmp eq i32 %n, %0 1132 %1 = select i1 %cmp, i32 1, i32 2 1133 br label %if.end 1134 1135if.end: ; preds = %entry, %if.then 1136 %a.0 = phi i32 [ %1, %if.then ], [ %n, %entry ] 1137 %cmp1 = icmp eq i32 %a.0, 0 1138 ret i1 %cmp1 1139} 1140 1141define i1 @phi_knownnonzero_ne(i32 %n, i32 %s, i32* nocapture readonly %P) { 1142; CHECK-LABEL: @phi_knownnonzero_ne( 1143; CHECK-NEXT: entry: 1144; CHECK-NEXT: [[TOBOOL:%.*]] = icmp slt i32 [[N:%.*]], [[S:%.*]] 1145; CHECK-NEXT: br i1 [[TOBOOL]], label [[IF_END:%.*]], label [[IF_THEN:%.*]] 1146; CHECK: if.then: 1147; CHECK-NEXT: br label [[IF_END]] 1148; CHECK: if.end: 1149; CHECK-NEXT: [[A_0:%.*]] = phi i32 [ 1, [[IF_THEN]] ], [ [[N]], [[ENTRY:%.*]] ] 1150; CHECK-NEXT: [[CMP1:%.*]] = icmp ne i32 [[A_0]], 0 1151; CHECK-NEXT: ret i1 [[CMP1]] 1152; 1153entry: 1154 %tobool = icmp slt i32 %n, %s 1155 br i1 %tobool, label %if.end, label %if.then 1156 1157if.then: ; preds = %entry 1158 %0 = load i32, i32* %P 1159 %cmp = icmp eq i32 %n, %0 1160 %1 = select i1 %cmp, i32 1, i32 2 1161 br label %if.end 1162 1163if.end: ; preds = %entry, %if.then 1164 %a.0 = phi i32 [ %1, %if.then ], [ %n, %entry ] 1165 %cmp1 = icmp ne i32 %a.0, 0 1166 ret i1 %cmp1 1167} 1168 1169define i1 @phi_knownnonzero_eq_2(i32 %n, i32 %s, i32* nocapture readonly %P) { 1170; CHECK-LABEL: @phi_knownnonzero_eq_2( 1171; CHECK-NEXT: entry: 1172; CHECK-NEXT: [[TOBOOL:%.*]] = icmp slt i32 [[N:%.*]], [[S:%.*]] 1173; CHECK-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] 1174; CHECK: if.then: 1175; CHECK-NEXT: br i1 true, label [[IF_ELSE:%.*]], label [[IF_END]] 1176; CHECK: if.else: 1177; CHECK-NEXT: br label [[IF_END]] 1178; CHECK: if.end: 1179; CHECK-NEXT: [[A_0:%.*]] = phi i32 [ 2, [[IF_ELSE]] ], [ [[N]], [[ENTRY:%.*]] ], [ 2, [[IF_THEN]] ] 1180; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[A_0]], 0 1181; CHECK-NEXT: ret i1 [[CMP1]] 1182; 1183entry: 1184 %tobool = icmp slt i32 %n, %s 1185 br i1 %tobool, label %if.then, label %if.end 1186 1187if.then: 1188 %tobool2 = icmp slt i32 %n, %s 1189 br i1 %tobool2, label %if.else, label %if.end 1190 1191if.else: ; preds = %entry 1192 %0 = load i32, i32* %P 1193 %cmp = icmp eq i32 %n, %0 1194 %1 = select i1 %cmp, i32 1, i32 2 1195 br label %if.end 1196 1197if.end: ; preds = %entry, %if.then 1198 %a.0 = phi i32 [ %1, %if.else], [ %n, %entry ], [2, %if.then] 1199 %cmp1 = icmp eq i32 %a.0, 0 1200 ret i1 %cmp1 1201} 1202 1203define i1 @phi_knownnonzero_ne_2(i32 %n, i32 %s, i32* nocapture readonly %P) { 1204; CHECK-LABEL: @phi_knownnonzero_ne_2( 1205; CHECK-NEXT: entry: 1206; CHECK-NEXT: [[TOBOOL:%.*]] = icmp slt i32 [[N:%.*]], [[S:%.*]] 1207; CHECK-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] 1208; CHECK: if.then: 1209; CHECK-NEXT: br i1 true, label [[IF_ELSE:%.*]], label [[IF_END]] 1210; CHECK: if.else: 1211; CHECK-NEXT: br label [[IF_END]] 1212; CHECK: if.end: 1213; CHECK-NEXT: [[A_0:%.*]] = phi i32 [ 2, [[IF_ELSE]] ], [ [[N]], [[ENTRY:%.*]] ], [ 2, [[IF_THEN]] ] 1214; CHECK-NEXT: [[CMP1:%.*]] = icmp ne i32 [[A_0]], 0 1215; CHECK-NEXT: ret i1 [[CMP1]] 1216; 1217entry: 1218 %tobool = icmp slt i32 %n, %s 1219 br i1 %tobool, label %if.then, label %if.end 1220 1221if.then: 1222 %tobool2 = icmp slt i32 %n, %s 1223 br i1 %tobool2, label %if.else, label %if.end 1224 1225if.else: ; preds = %entry 1226 %0 = load i32, i32* %P 1227 %cmp = icmp eq i32 %n, %0 1228 %1 = select i1 %cmp, i32 1, i32 2 1229 br label %if.end 1230 1231if.end: ; preds = %entry, %if.then 1232 %a.0 = phi i32 [ %1, %if.else], [ %n, %entry ], [2, %if.then] 1233 %cmp1 = icmp ne i32 %a.0, 0 1234 ret i1 %cmp1 1235} 1236 1237; This would crash trying to delete an instruction (conv) 1238; that still had uses because the user (the phi) was not 1239; updated to remove a use from an unreachable block (g.exit). 1240 1241define void @main(i1 %cond, i16 %x) { 1242; CHECK-LABEL: @main( 1243; CHECK-NEXT: entry: 1244; CHECK-NEXT: br label [[FOR_COND:%.*]] 1245; CHECK: for.cond: 1246; CHECK-NEXT: br i1 [[COND:%.*]], label [[FOR_END:%.*]], label [[FOR_BODY:%.*]] 1247; CHECK: for.body: 1248; CHECK-NEXT: unreachable 1249; CHECK: g.exit: 1250; CHECK-NEXT: br label [[FOR_COND]] 1251; CHECK: for.end: 1252; CHECK-NEXT: ret void 1253; 1254entry: 1255 br label %for.cond 1256 1257for.cond: 1258 %p = phi double [ %conv, %g.exit ], [ undef, %entry ] 1259 br i1 %cond, label %for.end, label %for.body 1260 1261for.body: 1262 %conv = sitofp i16 %x to double 1263 unreachable 1264 1265g.exit: 1266 br label %for.cond 1267 1268for.end: 1269 store double %p, double* undef 1270 ret void 1271} 1272