1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -S -passes=gvn < %s | FileCheck %s 3 4 5define i64 @test1(i1 %c, i64 %a, i64 %b) { 6; CHECK-LABEL: @test1( 7; CHECK-NEXT: br i1 [[C:%.*]], label [[TAKEN:%.*]], label [[UNTAKEN:%.*]] 8; CHECK: taken: 9; CHECK-NEXT: br label [[MERGE:%.*]] 10; CHECK: untaken: 11; CHECK-NEXT: br label [[MERGE]] 12; CHECK: merge: 13; CHECK-NEXT: [[PHI1:%.*]] = phi i64 [ [[A:%.*]], [[TAKEN]] ], [ [[B:%.*]], [[UNTAKEN]] ] 14; CHECK-NEXT: ret i64 0 15; 16 br i1 %c, label %taken, label %untaken 17taken: 18 br label %merge 19untaken: 20 br label %merge 21merge: 22 %phi1 = phi i64 [%a, %taken], [%b, %untaken] 23 %phi2 = phi i64 [%a, %taken], [%b, %untaken] 24 %ret = sub i64 %phi1, %phi2 25 ret i64 %ret 26} 27 28declare void @llvm.assume(i1) 29 30define i64 @test2(i1 %c, i64 %a, i64 %b) { 31; CHECK-LABEL: @test2( 32; CHECK-NEXT: br i1 [[C:%.*]], label [[TAKEN:%.*]], label [[UNTAKEN:%.*]] 33; CHECK: taken: 34; CHECK-NEXT: [[ASSUMPTION:%.*]] = icmp eq i64 [[A:%.*]], 0 35; CHECK-NEXT: call void @llvm.assume(i1 [[ASSUMPTION]]) 36; CHECK-NEXT: br label [[MERGE:%.*]] 37; CHECK: untaken: 38; CHECK-NEXT: br label [[MERGE]] 39; CHECK: merge: 40; CHECK-NEXT: [[PHI1:%.*]] = phi i64 [ 0, [[TAKEN]] ], [ [[B:%.*]], [[UNTAKEN]] ] 41; CHECK-NEXT: ret i64 0 42; 43 br i1 %c, label %taken, label %untaken 44taken: 45 %assumption = icmp eq i64 %a, 0 46 call void @llvm.assume(i1 %assumption) 47 br label %merge 48untaken: 49 br label %merge 50merge: 51 %phi1 = phi i64 [%a, %taken], [%b, %untaken] 52 %phi2 = phi i64 [0, %taken], [%b, %untaken] 53 %ret = sub i64 %phi1, %phi2 54 ret i64 %ret 55} 56 57 58define i64 @test3(i1 %c, i64 %a, i64 %b) { 59; CHECK-LABEL: @test3( 60; CHECK-NEXT: br i1 [[C:%.*]], label [[TAKEN:%.*]], label [[UNTAKEN:%.*]] 61; CHECK: taken: 62; CHECK-NEXT: [[ADD1:%.*]] = add i64 [[A:%.*]], 5 63; CHECK-NEXT: br label [[MERGE:%.*]] 64; CHECK: untaken: 65; CHECK-NEXT: br label [[MERGE]] 66; CHECK: merge: 67; CHECK-NEXT: [[PHI1:%.*]] = phi i64 [ [[ADD1]], [[TAKEN]] ], [ [[B:%.*]], [[UNTAKEN]] ] 68; CHECK-NEXT: ret i64 0 69; 70 br i1 %c, label %taken, label %untaken 71taken: 72 %add1 = add i64 %a, 5 73 %add2 = add i64 %a, 5 74 br label %merge 75untaken: 76 br label %merge 77merge: 78 %phi1 = phi i64 [%add1, %taken], [%b, %untaken] 79 %phi2 = phi i64 [%add2, %taken], [%b, %untaken] 80 %ret = sub i64 %phi1, %phi2 81 ret i64 %ret 82} 83 84define i64 @test4(i1 %c, i64 %a, i64 %b) { 85; CHECK-LABEL: @test4( 86; CHECK-NEXT: br i1 [[C:%.*]], label [[TAKEN:%.*]], label [[UNTAKEN:%.*]] 87; CHECK: taken: 88; CHECK-NEXT: br label [[MERGE:%.*]] 89; CHECK: untaken: 90; CHECK-NEXT: br label [[MERGE]] 91; CHECK: merge: 92; CHECK-NEXT: [[PHI1:%.*]] = phi i64 [ [[A:%.*]], [[TAKEN]] ], [ [[B:%.*]], [[UNTAKEN]] ] 93; CHECK-NEXT: br i1 [[C]], label [[TAKEN2:%.*]], label [[UNTAKEN2:%.*]] 94; CHECK: taken2: 95; CHECK-NEXT: [[ADD1:%.*]] = add i64 [[PHI1]], 5 96; CHECK-NEXT: br label [[MERGE2:%.*]] 97; CHECK: untaken2: 98; CHECK-NEXT: br label [[MERGE2]] 99; CHECK: merge2: 100; CHECK-NEXT: [[PHI3:%.*]] = phi i64 [ [[ADD1]], [[TAKEN2]] ], [ [[PHI1]], [[UNTAKEN2]] ] 101; CHECK-NEXT: ret i64 0 102; 103 br i1 %c, label %taken, label %untaken 104taken: 105 br label %merge 106untaken: 107 br label %merge 108merge: 109 %phi1 = phi i64 [%a, %taken], [%b, %untaken] 110 %phi2 = phi i64 [%a, %taken], [%b, %untaken] 111 br i1 %c, label %taken2, label %untaken2 112taken2: 113 %add1 = add i64 %phi1, 5 114 %add2 = add i64 %phi2, 5 115 br label %merge2 116untaken2: 117 br label %merge2 118merge2: 119 %phi3 = phi i64 [%add1, %taken2], [%phi2, %untaken2] 120 %phi4 = phi i64 [%add2, %taken2], [%phi2, %untaken2] 121 %ret = sub i64 %phi4, %phi3 122 ret i64 %ret 123} 124 125define i64 @test5(i1 %c, i64 %a) { 126; CHECK-LABEL: @test5( 127; CHECK-NEXT: br i1 [[C:%.*]], label [[TAKEN:%.*]], label [[UNTAKEN:%.*]] 128; CHECK: taken: 129; CHECK-NEXT: [[ASSUMPTION:%.*]] = icmp eq i64 [[A:%.*]], 0 130; CHECK-NEXT: call void @llvm.assume(i1 [[ASSUMPTION]]) 131; CHECK-NEXT: br label [[MERGE:%.*]] 132; CHECK: untaken: 133; CHECK-NEXT: br label [[MERGE]] 134; CHECK: merge: 135; CHECK-NEXT: ret i64 0 136; 137 br i1 %c, label %taken, label %untaken 138taken: 139 %assumption = icmp eq i64 %a, 0 140 call void @llvm.assume(i1 %assumption) 141 br label %merge 142untaken: 143 br label %merge 144merge: 145 %phi = phi i64 [%a, %taken], [0, %untaken] 146 ret i64 %phi 147} 148 149define i64 @test6(i1 %c, i64 %a) { 150; CHECK-LABEL: @test6( 151; CHECK-NEXT: br i1 [[C:%.*]], label [[TAKEN:%.*]], label [[UNTAKEN:%.*]] 152; CHECK: taken: 153; CHECK-NEXT: [[ASSUMPTION:%.*]] = icmp eq i64 [[A:%.*]], 0 154; CHECK-NEXT: call void @llvm.assume(i1 [[ASSUMPTION]]) 155; CHECK-NEXT: br label [[MERGE:%.*]] 156; CHECK: untaken: 157; CHECK-NEXT: br label [[MERGE]] 158; CHECK: merge: 159; CHECK-NEXT: ret i64 0 160; 161 br i1 %c, label %taken, label %untaken 162taken: 163 %assumption = icmp eq i64 %a, 0 164 call void @llvm.assume(i1 %assumption) 165 br label %next 166next: 167 br label %merge 168untaken: 169 br label %merge 170merge: 171 %phi = phi i64 [%a, %next], [0, %untaken] 172 ret i64 %phi 173} 174 175; negative test, phi use is NOT dominated by assume 176define i64 @test7(i1 %c, i64 %a) { 177; CHECK-LABEL: @test7( 178; CHECK-NEXT: br i1 [[C:%.*]], label [[TAKEN:%.*]], label [[UNTAKEN:%.*]] 179; CHECK: taken: 180; CHECK-NEXT: [[ASSUMPTION:%.*]] = icmp eq i64 [[A:%.*]], 0 181; CHECK-NEXT: call void @llvm.assume(i1 [[ASSUMPTION]]) 182; CHECK-NEXT: br label [[MERGE:%.*]] 183; CHECK: untaken: 184; CHECK-NEXT: br label [[MERGE]] 185; CHECK: merge: 186; CHECK-NEXT: ret i64 [[A]] 187; 188 br i1 %c, label %taken, label %untaken 189taken: 190 %assumption = icmp eq i64 %a, 0 191 call void @llvm.assume(i1 %assumption) 192 br label %merge 193untaken: 194 br label %merge 195merge: 196 br label %next 197next: 198 %phi = phi i64 [%a, %merge] 199 ret i64 %phi 200} 201