1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -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 550define i1 @test18(i1 %cond) { 551; CHECK-LABEL: @test18( 552; CHECK-NEXT: br i1 [[COND:%.*]], label [[TRUE:%.*]], label [[FALSE:%.*]] 553; CHECK: true: 554; CHECK-NEXT: br label [[RET:%.*]] 555; CHECK: false: 556; CHECK-NEXT: br label [[RET]] 557; CHECK: ret: 558; CHECK-NEXT: ret i1 false 559; 560 %zero = alloca i32 561 %one = alloca i32 562 br i1 %cond, label %true, label %false 563true: 564 br label %ret 565false: 566 br label %ret 567ret: 568 %ptr = phi i32* [ %zero, %true ] , [ %one, %false ] 569 %isnull = icmp eq i32* %ptr, null 570 ret i1 %isnull 571} 572 573define i1 @test19(i1 %cond, double %x) { 574; CHECK-LABEL: @test19( 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 true 582; 583 br i1 %cond, label %true, label %false 584true: 585 br label %ret 586false: 587 br label %ret 588ret: 589 %p = phi double [ %x, %true ], [ 0x7FF0000000000000, %false ]; RHS = +infty 590 %cmp = fcmp ule double %x, %p 591 ret i1 %cmp 592} 593 594define i1 @test20(i1 %cond) { 595; CHECK-LABEL: @test20( 596; CHECK-NEXT: br i1 [[COND:%.*]], label [[TRUE:%.*]], label [[FALSE:%.*]] 597; CHECK: true: 598; CHECK-NEXT: br label [[RET:%.*]] 599; CHECK: false: 600; CHECK-NEXT: br label [[RET]] 601; CHECK: ret: 602; CHECK-NEXT: ret i1 false 603; 604 %a = alloca i32 605 %b = alloca i32 606 %c = alloca i32 607 br i1 %cond, label %true, label %false 608true: 609 br label %ret 610false: 611 br label %ret 612ret: 613 %p = phi i32* [ %a, %true ], [ %b, %false ] 614 %r = icmp eq i32* %p, %c 615 ret i1 %r 616} 617 618define i1 @test21(i1 %c1, i1 %c2) { 619; CHECK-LABEL: @test21( 620; CHECK-NEXT: br i1 [[C1:%.*]], label [[TRUE:%.*]], label [[FALSE:%.*]] 621; CHECK: true: 622; CHECK-NEXT: br label [[LOOP:%.*]] 623; CHECK: false: 624; CHECK-NEXT: br label [[LOOP]] 625; CHECK: loop: 626; CHECK-NEXT: br i1 [[C2:%.*]], label [[RET:%.*]], label [[LOOP]] 627; CHECK: ret: 628; CHECK-NEXT: ret i1 false 629; 630 %a = alloca i32 631 %b = alloca i32 632 %c = alloca i32 633 br i1 %c1, label %true, label %false 634true: 635 br label %loop 636false: 637 br label %loop 638loop: 639 %p = phi i32* [ %a, %true ], [ %b, %false ], [ %p, %loop ] 640 %r = icmp eq i32* %p, %c 641 br i1 %c2, label %ret, label %loop 642ret: 643 ret i1 %r 644} 645 646define void @test22() { 647; CHECK-LABEL: @test22( 648; CHECK-NEXT: entry: 649; CHECK-NEXT: br label [[LOOP:%.*]] 650; CHECK: loop: 651; CHECK-NEXT: [[PHI:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[Y:%.*]], [[LOOP]] ] 652; CHECK-NEXT: [[Y]] = add i32 [[PHI]], 1 653; CHECK-NEXT: [[O:%.*]] = or i32 [[Y]], [[PHI]] 654; CHECK-NEXT: [[E:%.*]] = icmp eq i32 [[O]], [[Y]] 655; CHECK-NEXT: br i1 [[E]], label [[LOOP]], label [[RET:%.*]] 656; CHECK: ret: 657; CHECK-NEXT: ret void 658; 659entry: 660 br label %loop 661loop: 662 %phi = phi i32 [ 0, %entry ], [ %y, %loop ] 663 %y = add i32 %phi, 1 664 %o = or i32 %y, %phi 665 %e = icmp eq i32 %o, %y 666 br i1 %e, label %loop, label %ret 667ret: 668 ret void 669} 670 671define i32 @test23(i32 %A, i1 %pb, i32 * %P) { 672; CHECK-LABEL: @test23( 673; CHECK-NEXT: BB0: 674; CHECK-NEXT: [[PHI_BO:%.*]] = add i32 [[A:%.*]], 19 675; CHECK-NEXT: br label [[LOOP:%.*]] 676; CHECK: Loop: 677; CHECK-NEXT: [[B:%.*]] = phi i32 [ [[PHI_BO]], [[BB0:%.*]] ], [ 61, [[LOOP]] ] 678; CHECK-NEXT: store i32 [[B]], i32* [[P:%.*]], align 4 679; CHECK-NEXT: br i1 [[PB:%.*]], label [[LOOP]], label [[EXIT:%.*]] 680; CHECK: Exit: 681; CHECK-NEXT: ret i32 [[B]] 682; 683BB0: 684 br label %Loop 685 686Loop: ; preds = %Loop, %BB0 687 ; PHI has same value always. 688 %B = phi i32 [ %A, %BB0 ], [ 42, %Loop ] 689 %D = add i32 %B, 19 690 store i32 %D, i32* %P 691 br i1 %pb, label %Loop, label %Exit 692 693Exit: ; preds = %Loop 694 %E = add i32 %B, 19 695 ret i32 %E 696} 697 698define i32 @test24(i32 %A, i1 %cond) { 699; CHECK-LABEL: @test24( 700; CHECK-NEXT: BB0: 701; CHECK-NEXT: br i1 [[COND:%.*]], label [[BB1:%.*]], label [[BB2:%.*]] 702; CHECK: BB1: 703; CHECK-NEXT: br label [[BB2]] 704; CHECK: BB2: 705; CHECK-NEXT: [[C:%.*]] = add nuw i32 [[A:%.*]], 1 706; CHECK-NEXT: ret i32 [[C]] 707; 708BB0: 709 %X = add nuw nsw i32 %A, 1 710 br i1 %cond, label %BB1, label %BB2 711 712BB1: 713 %Y = add nuw i32 %A, 1 714 br label %BB2 715 716BB2: 717 %C = phi i32 [ %X, %BB0 ], [ %Y, %BB1 ] 718 ret i32 %C 719} 720 721; Same as test11, but used to be missed due to a bug. 722declare i1 @test25a() 723 724define i1 @test25() { 725; CHECK-LABEL: @test25( 726; CHECK-NEXT: entry: 727; CHECK-NEXT: [[B:%.*]] = call i1 @test25a() 728; CHECK-NEXT: br i1 [[B]], label [[ONE:%.*]], label [[TWO:%.*]] 729; CHECK: one: 730; CHECK-NEXT: [[C:%.*]] = call i1 @test25a() 731; CHECK-NEXT: br i1 [[C]], label [[TWO]], label [[END:%.*]] 732; CHECK: two: 733; CHECK-NEXT: [[D:%.*]] = call i1 @test25a() 734; CHECK-NEXT: br i1 [[D]], label [[ONE]], label [[END]] 735; CHECK: end: 736; CHECK-NEXT: [[Z:%.*]] = call i1 @test25a() 737; CHECK-NEXT: ret i1 [[Z]] 738; 739entry: 740 %a = alloca i32 741 %i = ptrtoint i32* %a to i64 742 %b = call i1 @test25a() 743 br i1 %b, label %one, label %two 744 745one: 746 %x = phi i64 [%y, %two], [%i, %entry] 747 %c = call i1 @test25a() 748 br i1 %c, label %two, label %end 749 750two: 751 %y = phi i64 [%x, %one], [%i, %entry] 752 %d = call i1 @test25a() 753 br i1 %d, label %one, label %end 754 755end: 756 %f = phi i64 [ %x, %one], [%y, %two] 757 ; Change the %f to %i, and the optimizer suddenly becomes a lot smarter 758 ; even though %f must equal %i at this point 759 %g = inttoptr i64 %f to i32* 760 store i32 10, i32* %g 761 %z = call i1 @test25a() 762 ret i1 %z 763} 764 765declare i1 @test26a() 766 767define i1 @test26(i32 %n) { 768; CHECK-LABEL: @test26( 769; CHECK-NEXT: entry: 770; CHECK-NEXT: [[B:%.*]] = call i1 @test26a() 771; CHECK-NEXT: br label [[ONE:%.*]] 772; CHECK: one: 773; CHECK-NEXT: [[C:%.*]] = call i1 @test26a() 774; CHECK-NEXT: switch i32 [[N:%.*]], label [[END:%.*]] [ 775; CHECK-NEXT: i32 2, label [[TWO:%.*]] 776; CHECK-NEXT: i32 3, label [[THREE:%.*]] 777; CHECK-NEXT: ] 778; CHECK: two: 779; CHECK-NEXT: [[D:%.*]] = call i1 @test26a() 780; CHECK-NEXT: switch i32 [[N]], label [[END]] [ 781; CHECK-NEXT: i32 10, label [[ONE]] 782; CHECK-NEXT: i32 30, label [[THREE]] 783; CHECK-NEXT: ] 784; CHECK: three: 785; CHECK-NEXT: [[E:%.*]] = call i1 @test26a() 786; CHECK-NEXT: br i1 [[E]], label [[ONE]], label [[TWO]] 787; CHECK: end: 788; CHECK-NEXT: [[Z:%.*]] = call i1 @test26a() 789; CHECK-NEXT: ret i1 [[Z]] 790; 791entry: 792 %a = alloca i32 793 %i = ptrtoint i32* %a to i64 794 %b = call i1 @test26a() 795 br label %one 796 797one: 798 %x = phi i64 [%y, %two], [%w, %three], [%i, %entry] 799 %c = call i1 @test26a() 800 switch i32 %n, label %end [ 801 i32 2, label %two 802 i32 3, label %three 803 ] 804 805two: 806 %y = phi i64 [%x, %one], [%w, %three] 807 %d = call i1 @test26a() 808 switch i32 %n, label %end [ 809 i32 10, label %one 810 i32 30, label %three 811 ] 812 813three: 814 %w = phi i64 [%y, %two], [%x, %one] 815 %e = call i1 @test26a() 816 br i1 %e, label %one, label %two 817 818end: 819 %f = phi i64 [ %x, %one], [%y, %two] 820 ; Change the %f to %i, and the optimizer suddenly becomes a lot smarter 821 ; even though %f must equal %i at this point 822 %g = inttoptr i64 %f to i32* 823 store i32 10, i32* %g 824 %z = call i1 @test26a() 825 ret i1 %z 826} 827 828define i32 @test27(i1 %b) { 829; CHECK-LABEL: @test27( 830; CHECK-NEXT: entry: 831; CHECK-NEXT: br label [[DONE:%.*]] 832; CHECK: done: 833; CHECK-NEXT: ret i32 undef 834; 835entry: 836 br label %done 837done: 838 %y = phi i32 [ undef, %entry ] 839 ret i32 %y 840} 841 842; We should be able to fold the zexts to the other side of the phi 843; even though there's a constant value input to the phi. This is 844; because we can shrink that constant to the smaller phi type. 845 846define i1 @PR24766(i8 %x1, i8 %x2, i8 %condition) { 847; CHECK-LABEL: @PR24766( 848; CHECK-NEXT: entry: 849; CHECK-NEXT: [[CONV:%.*]] = sext i8 [[CONDITION:%.*]] to i32 850; CHECK-NEXT: switch i32 [[CONV]], label [[EPILOG:%.*]] [ 851; CHECK-NEXT: i32 0, label [[SW1:%.*]] 852; CHECK-NEXT: i32 1, label [[SW2:%.*]] 853; CHECK-NEXT: ] 854; CHECK: sw1: 855; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i8 [[X1:%.*]], [[X2:%.*]] 856; CHECK-NEXT: br label [[EPILOG]] 857; CHECK: sw2: 858; CHECK-NEXT: [[CMP2:%.*]] = icmp sle i8 [[X1]], [[X2]] 859; CHECK-NEXT: br label [[EPILOG]] 860; CHECK: epilog: 861; CHECK-NEXT: [[CONDITIONMET_SHRUNK:%.*]] = phi i1 [ false, [[ENTRY:%.*]] ], [ [[CMP2]], [[SW2]] ], [ [[CMP1]], [[SW1]] ] 862; CHECK-NEXT: ret i1 [[CONDITIONMET_SHRUNK]] 863; 864entry: 865 %conv = sext i8 %condition to i32 866 switch i32 %conv, label %epilog [ 867 i32 0, label %sw1 868 i32 1, label %sw2 869 ] 870 871sw1: 872 %cmp1 = icmp eq i8 %x1, %x2 873 %frombool1 = zext i1 %cmp1 to i8 874 br label %epilog 875 876sw2: 877 %cmp2 = icmp sle i8 %x1, %x2 878 %frombool2 = zext i1 %cmp2 to i8 879 br label %epilog 880 881epilog: 882 %conditionMet = phi i8 [ 0, %entry ], [ %frombool2, %sw2 ], [ %frombool1, %sw1 ] 883 %tobool = icmp ne i8 %conditionMet, 0 884 ret i1 %tobool 885 886} 887 888; Same as above (a phi with more than 2 operands), but no constants 889 890define i1 @PR24766_no_constants(i8 %x1, i8 %x2, i8 %condition, i1 %another_condition) { 891; CHECK-LABEL: @PR24766_no_constants( 892; CHECK-NEXT: entry: 893; CHECK-NEXT: [[CONV:%.*]] = sext i8 [[CONDITION:%.*]] to i32 894; CHECK-NEXT: switch i32 [[CONV]], label [[EPILOG:%.*]] [ 895; CHECK-NEXT: i32 0, label [[SW1:%.*]] 896; CHECK-NEXT: i32 1, label [[SW2:%.*]] 897; CHECK-NEXT: ] 898; CHECK: sw1: 899; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i8 [[X1:%.*]], [[X2:%.*]] 900; CHECK-NEXT: br label [[EPILOG]] 901; CHECK: sw2: 902; CHECK-NEXT: [[CMP2:%.*]] = icmp sle i8 [[X1]], [[X2]] 903; CHECK-NEXT: br label [[EPILOG]] 904; CHECK: epilog: 905; CHECK-NEXT: [[CONDITIONMET_IN:%.*]] = phi i1 [ [[ANOTHER_CONDITION:%.*]], [[ENTRY:%.*]] ], [ [[CMP2]], [[SW2]] ], [ [[CMP1]], [[SW1]] ] 906; CHECK-NEXT: ret i1 [[CONDITIONMET_IN]] 907; 908entry: 909 %frombool0 = zext i1 %another_condition to i8 910 %conv = sext i8 %condition to i32 911 switch i32 %conv, label %epilog [ 912 i32 0, label %sw1 913 i32 1, label %sw2 914 ] 915 916sw1: 917 %cmp1 = icmp eq i8 %x1, %x2 918 %frombool1 = zext i1 %cmp1 to i8 919 br label %epilog 920 921sw2: 922 %cmp2 = icmp sle i8 %x1, %x2 923 %frombool2 = zext i1 %cmp2 to i8 924 br label %epilog 925 926epilog: 927 %conditionMet = phi i8 [ %frombool0, %entry ], [ %frombool2, %sw2 ], [ %frombool1, %sw1 ] 928 %tobool = icmp ne i8 %conditionMet, 0 929 ret i1 %tobool 930 931} 932 933; Same as above (a phi with more than 2 operands), but two constants 934 935define i1 @PR24766_two_constants(i8 %x1, i8 %x2, i8 %condition) { 936; CHECK-LABEL: @PR24766_two_constants( 937; CHECK-NEXT: entry: 938; CHECK-NEXT: [[CONV:%.*]] = sext i8 [[CONDITION:%.*]] to i32 939; CHECK-NEXT: switch i32 [[CONV]], label [[EPILOG:%.*]] [ 940; CHECK-NEXT: i32 0, label [[SW1:%.*]] 941; CHECK-NEXT: i32 1, label [[SW2:%.*]] 942; CHECK-NEXT: ] 943; CHECK: sw1: 944; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i8 [[X1:%.*]], [[X2:%.*]] 945; CHECK-NEXT: br label [[EPILOG]] 946; CHECK: sw2: 947; CHECK-NEXT: br label [[EPILOG]] 948; CHECK: epilog: 949; CHECK-NEXT: [[CONDITIONMET:%.*]] = phi i1 [ false, [[ENTRY:%.*]] ], [ true, [[SW2]] ], [ [[CMP1]], [[SW1]] ] 950; CHECK-NEXT: ret i1 [[CONDITIONMET]] 951; 952entry: 953 %conv = sext i8 %condition to i32 954 switch i32 %conv, label %epilog [ 955 i32 0, label %sw1 956 i32 1, label %sw2 957 ] 958 959sw1: 960 %cmp1 = icmp eq i8 %x1, %x2 961 %frombool1 = zext i1 %cmp1 to i8 962 br label %epilog 963 964sw2: 965 %cmp2 = icmp sle i8 %x1, %x2 966 %frombool2 = zext i1 %cmp2 to i8 967 br label %epilog 968 969epilog: 970 %conditionMet = phi i8 [ 0, %entry ], [ 1, %sw2 ], [ %frombool1, %sw1 ] 971 %tobool = icmp ne i8 %conditionMet, 0 972 ret i1 %tobool 973 974} 975 976; Same as above (a phi with more than 2 operands), but two constants and two variables 977 978define i1 @PR24766_two_constants_two_var(i8 %x1, i8 %x2, i8 %condition) { 979; CHECK-LABEL: @PR24766_two_constants_two_var( 980; CHECK-NEXT: entry: 981; CHECK-NEXT: [[CONV:%.*]] = sext i8 [[CONDITION:%.*]] to i32 982; CHECK-NEXT: switch i32 [[CONV]], label [[EPILOG:%.*]] [ 983; CHECK-NEXT: i32 0, label [[SW1:%.*]] 984; CHECK-NEXT: i32 1, label [[SW2:%.*]] 985; CHECK-NEXT: i32 2, label [[SW3:%.*]] 986; CHECK-NEXT: ] 987; CHECK: sw1: 988; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i8 [[X1:%.*]], [[X2:%.*]] 989; CHECK-NEXT: br label [[EPILOG]] 990; CHECK: sw2: 991; CHECK-NEXT: [[CMP2:%.*]] = icmp sle i8 [[X1]], [[X2]] 992; CHECK-NEXT: br label [[EPILOG]] 993; CHECK: sw3: 994; CHECK-NEXT: br label [[EPILOG]] 995; CHECK: epilog: 996; CHECK-NEXT: [[CONDITIONMET_SHRUNK:%.*]] = phi i1 [ false, [[ENTRY:%.*]] ], [ [[CMP2]], [[SW2]] ], [ [[CMP1]], [[SW1]] ], [ true, [[SW3]] ] 997; CHECK-NEXT: ret i1 [[CONDITIONMET_SHRUNK]] 998; 999entry: 1000 %conv = sext i8 %condition to i32 1001 switch i32 %conv, label %epilog [ 1002 i32 0, label %sw1 1003 i32 1, label %sw2 1004 i32 2, label %sw3 1005 ] 1006 1007sw1: 1008 %cmp1 = icmp eq i8 %x1, %x2 1009 %frombool1 = zext i1 %cmp1 to i8 1010 br label %epilog 1011 1012sw2: 1013 %cmp2 = icmp sle i8 %x1, %x2 1014 %frombool2 = zext i1 %cmp2 to i8 1015 br label %epilog 1016 1017sw3: 1018 %cmp3 = icmp sge i8 %x1, %x2 1019 %frombool3 = zext i1 %cmp3 to i8 1020 br label %epilog 1021 1022epilog: 1023 %conditionMet = phi i8 [ 0, %entry ], [ %frombool2, %sw2 ], [ %frombool1, %sw1 ], [ 1, %sw3 ] 1024 %tobool = icmp ne i8 %conditionMet, 0 1025 ret i1 %tobool 1026 1027} 1028 1029define i1 @phi_allnonzeroconstant(i1 %c, i32 %a, i32 %b) { 1030; CHECK-LABEL: @phi_allnonzeroconstant( 1031; CHECK-NEXT: entry: 1032; CHECK-NEXT: br i1 [[C:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] 1033; CHECK: if.then: 1034; CHECK-NEXT: br label [[IF_END:%.*]] 1035; CHECK: if.else: 1036; CHECK-NEXT: call void @dummy() 1037; CHECK-NEXT: br label [[IF_END]] 1038; CHECK: if.end: 1039; CHECK-NEXT: ret i1 false 1040; 1041entry: 1042 br i1 %c, label %if.then, label %if.else 1043 1044if.then: ; preds = %entry 1045 br label %if.end 1046 1047if.else: ; preds = %entry 1048 call void @dummy() 1049 1050 br label %if.end 1051 1052if.end: ; preds = %if.else, %if.then 1053 %x.0 = phi i32 [ 1, %if.then ], [ 2, %if.else ] 1054 %or = or i32 %x.0, %a 1055 %cmp1 = icmp eq i32 %or, 0 1056 ret i1 %cmp1 1057} 1058 1059define i1 @phi_allnonzerononconstant(i1 %c, i32 %a, i32* nonnull %b1, i32* nonnull %b2) { 1060; CHECK-LABEL: @phi_allnonzerononconstant( 1061; CHECK-NEXT: entry: 1062; CHECK-NEXT: br i1 [[C:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] 1063; CHECK: if.then: 1064; CHECK-NEXT: br label [[IF_END:%.*]] 1065; CHECK: if.else: 1066; CHECK-NEXT: call void @dummy() 1067; CHECK-NEXT: br label [[IF_END]] 1068; CHECK: if.end: 1069; CHECK-NEXT: ret i1 false 1070; 1071entry: 1072 br i1 %c, label %if.then, label %if.else 1073 1074if.then: ; preds = %entry 1075 br label %if.end 1076 1077if.else: ; preds = %entry 1078 call void @dummy() 1079 1080 br label %if.end 1081 1082if.end: ; preds = %if.else, %if.then 1083 %x.0 = phi i32* [ %b1, %if.then ], [ %b2, %if.else ] 1084 %cmp1 = icmp eq i32* %x.0, null 1085 ret i1 %cmp1 1086} 1087 1088declare void @dummy() 1089 1090define i1 @phi_knownnonzero_eq(i32 %n, i32 %s, i32* nocapture readonly %P) { 1091; CHECK-LABEL: @phi_knownnonzero_eq( 1092; CHECK-NEXT: entry: 1093; CHECK-NEXT: [[TOBOOL:%.*]] = icmp slt i32 [[N:%.*]], [[S:%.*]] 1094; CHECK-NEXT: br i1 [[TOBOOL]], label [[IF_END:%.*]], label [[IF_THEN:%.*]] 1095; CHECK: if.then: 1096; CHECK-NEXT: br label [[IF_END]] 1097; CHECK: if.end: 1098; CHECK-NEXT: [[A_0:%.*]] = phi i32 [ 1, [[IF_THEN]] ], [ [[N]], [[ENTRY:%.*]] ] 1099; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[A_0]], 0 1100; CHECK-NEXT: ret i1 [[CMP1]] 1101; 1102entry: 1103 %tobool = icmp slt i32 %n, %s 1104 br i1 %tobool, label %if.end, label %if.then 1105 1106if.then: ; preds = %entry 1107 %0 = load i32, i32* %P 1108 %cmp = icmp eq i32 %n, %0 1109 %1 = select i1 %cmp, i32 1, i32 2 1110 br label %if.end 1111 1112if.end: ; preds = %entry, %if.then 1113 %a.0 = phi i32 [ %1, %if.then ], [ %n, %entry ] 1114 %cmp1 = icmp eq i32 %a.0, 0 1115 ret i1 %cmp1 1116} 1117 1118define i1 @phi_knownnonzero_ne(i32 %n, i32 %s, i32* nocapture readonly %P) { 1119; CHECK-LABEL: @phi_knownnonzero_ne( 1120; CHECK-NEXT: entry: 1121; CHECK-NEXT: [[TOBOOL:%.*]] = icmp slt i32 [[N:%.*]], [[S:%.*]] 1122; CHECK-NEXT: br i1 [[TOBOOL]], label [[IF_END:%.*]], label [[IF_THEN:%.*]] 1123; CHECK: if.then: 1124; CHECK-NEXT: br label [[IF_END]] 1125; CHECK: if.end: 1126; CHECK-NEXT: [[A_0:%.*]] = phi i32 [ 1, [[IF_THEN]] ], [ [[N]], [[ENTRY:%.*]] ] 1127; CHECK-NEXT: [[CMP1:%.*]] = icmp ne i32 [[A_0]], 0 1128; CHECK-NEXT: ret i1 [[CMP1]] 1129; 1130entry: 1131 %tobool = icmp slt i32 %n, %s 1132 br i1 %tobool, label %if.end, label %if.then 1133 1134if.then: ; preds = %entry 1135 %0 = load i32, i32* %P 1136 %cmp = icmp eq i32 %n, %0 1137 %1 = select i1 %cmp, i32 1, i32 2 1138 br label %if.end 1139 1140if.end: ; preds = %entry, %if.then 1141 %a.0 = phi i32 [ %1, %if.then ], [ %n, %entry ] 1142 %cmp1 = icmp ne i32 %a.0, 0 1143 ret i1 %cmp1 1144} 1145 1146define i1 @phi_knownnonzero_eq_2(i32 %n, i32 %s, i32* nocapture readonly %P) { 1147; CHECK-LABEL: @phi_knownnonzero_eq_2( 1148; CHECK-NEXT: entry: 1149; CHECK-NEXT: [[TOBOOL:%.*]] = icmp slt i32 [[N:%.*]], [[S:%.*]] 1150; CHECK-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] 1151; CHECK: if.then: 1152; CHECK-NEXT: br i1 true, label [[IF_ELSE:%.*]], label [[IF_END]] 1153; CHECK: if.else: 1154; CHECK-NEXT: br label [[IF_END]] 1155; CHECK: if.end: 1156; CHECK-NEXT: [[A_0:%.*]] = phi i32 [ 2, [[IF_ELSE]] ], [ [[N]], [[ENTRY:%.*]] ], [ 2, [[IF_THEN]] ] 1157; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[A_0]], 0 1158; CHECK-NEXT: ret i1 [[CMP1]] 1159; 1160entry: 1161 %tobool = icmp slt i32 %n, %s 1162 br i1 %tobool, label %if.then, label %if.end 1163 1164if.then: 1165 %tobool2 = icmp slt i32 %n, %s 1166 br i1 %tobool2, label %if.else, label %if.end 1167 1168if.else: ; preds = %entry 1169 %0 = load i32, i32* %P 1170 %cmp = icmp eq i32 %n, %0 1171 %1 = select i1 %cmp, i32 1, i32 2 1172 br label %if.end 1173 1174if.end: ; preds = %entry, %if.then 1175 %a.0 = phi i32 [ %1, %if.else], [ %n, %entry ], [2, %if.then] 1176 %cmp1 = icmp eq i32 %a.0, 0 1177 ret i1 %cmp1 1178} 1179 1180define i1 @phi_knownnonzero_ne_2(i32 %n, i32 %s, i32* nocapture readonly %P) { 1181; CHECK-LABEL: @phi_knownnonzero_ne_2( 1182; CHECK-NEXT: entry: 1183; CHECK-NEXT: [[TOBOOL:%.*]] = icmp slt i32 [[N:%.*]], [[S:%.*]] 1184; CHECK-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] 1185; CHECK: if.then: 1186; CHECK-NEXT: br i1 true, label [[IF_ELSE:%.*]], label [[IF_END]] 1187; CHECK: if.else: 1188; CHECK-NEXT: br label [[IF_END]] 1189; CHECK: if.end: 1190; CHECK-NEXT: [[A_0:%.*]] = phi i32 [ 2, [[IF_ELSE]] ], [ [[N]], [[ENTRY:%.*]] ], [ 2, [[IF_THEN]] ] 1191; CHECK-NEXT: [[CMP1:%.*]] = icmp ne i32 [[A_0]], 0 1192; CHECK-NEXT: ret i1 [[CMP1]] 1193; 1194entry: 1195 %tobool = icmp slt i32 %n, %s 1196 br i1 %tobool, label %if.then, label %if.end 1197 1198if.then: 1199 %tobool2 = icmp slt i32 %n, %s 1200 br i1 %tobool2, label %if.else, label %if.end 1201 1202if.else: ; preds = %entry 1203 %0 = load i32, i32* %P 1204 %cmp = icmp eq i32 %n, %0 1205 %1 = select i1 %cmp, i32 1, i32 2 1206 br label %if.end 1207 1208if.end: ; preds = %entry, %if.then 1209 %a.0 = phi i32 [ %1, %if.else], [ %n, %entry ], [2, %if.then] 1210 %cmp1 = icmp ne i32 %a.0, 0 1211 ret i1 %cmp1 1212} 1213 1214; This would crash trying to delete an instruction (conv) 1215; that still had uses because the user (the phi) was not 1216; updated to remove a use from an unreachable block (g.exit). 1217 1218define void @main(i1 %cond, i16 %x) { 1219; CHECK-LABEL: @main( 1220; CHECK-NEXT: entry: 1221; CHECK-NEXT: br label [[FOR_COND:%.*]] 1222; CHECK: for.cond: 1223; CHECK-NEXT: br i1 [[COND:%.*]], label [[FOR_END:%.*]], label [[FOR_BODY:%.*]] 1224; CHECK: for.body: 1225; CHECK-NEXT: unreachable 1226; CHECK: g.exit: 1227; CHECK-NEXT: br label [[FOR_COND]] 1228; CHECK: for.end: 1229; CHECK-NEXT: ret void 1230; 1231entry: 1232 br label %for.cond 1233 1234for.cond: 1235 %p = phi double [ %conv, %g.exit ], [ undef, %entry ] 1236 br i1 %cond, label %for.end, label %for.body 1237 1238for.body: 1239 %conv = sitofp i16 %x to double 1240 unreachable 1241 1242g.exit: 1243 br label %for.cond 1244 1245for.end: 1246 store double %p, double* undef 1247 ret void 1248} 1249