1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -newgvn -S | FileCheck %s 3 4@g_20 = external global i32, align 4 5 6define void @test() { 7; CHECK-LABEL: @test( 8; CHECK-NEXT: entry: 9; CHECK-NEXT: br label [[BB1:%.*]] 10; CHECK: bb1: 11; CHECK-NEXT: [[STOREMERGE:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD1:%.*]], [[CRITEDGE:%.*]] ] 12; CHECK-NEXT: store i32 [[STOREMERGE]], i32* @g_20, align 4 13; CHECK-NEXT: [[CMP0:%.*]] = icmp eq i32 [[STOREMERGE]], 0 14; CHECK-NEXT: br i1 [[CMP0]], label [[LR_PH:%.*]], label [[CRITEDGE]] 15; CHECK: lr.ph: 16; CHECK-NEXT: [[LV:%.*]] = load i64, i64* inttoptr (i64 16 to i64*), align 16 17; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i64 [[LV]], 0 18; CHECK-NEXT: br i1 [[CMP1]], label [[PREHEADER_SPLIT:%.*]], label [[CRITEDGE]] 19; CHECK: preheader.split: 20; CHECK-NEXT: br label [[PREHEADER_SPLIT]] 21; CHECK: critedge: 22; CHECK-NEXT: [[PHIOFOPS1:%.*]] = phi i1 [ false, [[BB1]] ], [ true, [[LR_PH]] ] 23; CHECK-NEXT: [[PHIOFOPS:%.*]] = phi i1 [ [[CMP0]], [[BB1]] ], [ true, [[LR_PH]] ] 24; CHECK-NEXT: [[DOT05_LCSSA:%.*]] = phi i32 [ 0, [[BB1]] ], [ -1, [[LR_PH]] ] 25; CHECK-NEXT: [[ADD1]] = add nsw i32 [[STOREMERGE]], -1 26; CHECK-NEXT: br i1 [[PHIOFOPS]], label [[BB1]], label [[END:%.*]] 27; CHECK: end: 28; CHECK-NEXT: ret void 29; 30entry: 31 br label %bb1 32 33bb1: ; preds = %critedge, %entry 34 %storemerge = phi i32 [ 0, %entry ], [ %add1, %critedge ] 35 store i32 %storemerge, i32* @g_20, align 4 36 %cmp0 = icmp eq i32 %storemerge, 0 37 br i1 %cmp0, label %lr.ph, label %critedge 38 39lr.ph: ; preds = %bb1 40 %lv = load i64, i64* inttoptr (i64 16 to i64*), align 16 41 %cmp1 = icmp eq i64 %lv, 0 42 br i1 %cmp1, label %preheader.split, label %critedge 43 44preheader.split: ; preds = %lr.ph, %preheader.split 45 br label %preheader.split 46 47critedge: ; preds = %lr.ph, %bb1 48 %.05.lcssa = phi i32 [ 0, %bb1 ], [ -1, %lr.ph ] 49 %cmp2 = icmp ne i32 %.05.lcssa, 0 50 %brmerge = or i1 %cmp0, %cmp2 51 %add1 = add nsw i32 %storemerge, -1 52 br i1 %brmerge, label %bb1, label %end 53 54end: 55 ret void 56} 57 58; In this test case a temporary PhiOfOps node gets moved to BB with more 59; predecessors, so a new one needs to be created. 60define void @test2() { 61; CHECK-LABEL: @test2( 62; CHECK-NEXT: br label [[BB1:%.*]] 63; CHECK: bb1: 64; CHECK-NEXT: [[STOREMERGE:%.*]] = phi i32 [ 0, [[TMP0:%.*]] ], [ [[ADD:%.*]], [[CRITEDGE:%.*]] ] 65; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[STOREMERGE]], 0 66; CHECK-NEXT: br i1 [[CMP1]], label [[LR_PH:%.*]], label [[CRITEDGE]] 67; CHECK: lr.ph: 68; CHECK-NEXT: br i1 undef, label [[SPLIT1:%.*]], label [[SPLIT2:%.*]] 69; CHECK: split1: 70; CHECK-NEXT: br label [[CRITEDGE]] 71; CHECK: split2: 72; CHECK-NEXT: br label [[CRITEDGE]] 73; CHECK: critedge: 74; CHECK-NEXT: [[PHIOFOPS1:%.*]] = phi i1 [ false, [[BB1]] ], [ true, [[SPLIT2]] ], [ true, [[SPLIT1]] ] 75; CHECK-NEXT: [[PHIOFOPS:%.*]] = phi i1 [ [[CMP1]], [[BB1]] ], [ true, [[SPLIT2]] ], [ true, [[SPLIT1]] ] 76; CHECK-NEXT: [[LCSSA:%.*]] = phi i32 [ 0, [[BB1]] ], [ -1, [[SPLIT1]] ], [ -1, [[SPLIT2]] ] 77; CHECK-NEXT: [[ADD]] = add nsw i32 [[STOREMERGE]], -1 78; CHECK-NEXT: br i1 [[PHIOFOPS]], label [[BB1]], label [[EXIT:%.*]] 79; CHECK: exit: 80; CHECK-NEXT: ret void 81; 82 br label %bb1 83 84bb1: ; preds = %critedge, %0 85 %storemerge = phi i32 [ 0, %0 ], [ %add, %critedge ] 86 %cmp1 = icmp eq i32 %storemerge, 0 87 br i1 %cmp1, label %lr.ph, label %critedge 88 89lr.ph: ; preds = %bb1 90 br i1 undef, label %split1, label %split2 91 92split1: ; preds = %lr.ph 93 br label %critedge 94 95split2: ; preds = %lr.ph 96 br label %critedge 97 98critedge: ; preds = %split1, %split2, %bb1 99 %lcssa = phi i32 [ 0, %bb1 ], [ -1, %split1 ], [ -1, %split2 ] 100 %cmp2 = icmp ne i32 %lcssa, 0 101 %brmerge = or i1 %cmp1, %cmp2 102 %add = add nsw i32 %storemerge, -1 103 br i1 %brmerge, label %bb1, label %exit 104 105exit: ; preds = %critedge 106 ret void 107} 108