; NOTE: Assertions have been autogenerated by utils/update_test_checks.py ; RUN: opt -S -gvn < %s | FileCheck %s define i64 @test1(i1 %c, i64 %a, i64 %b) { ; CHECK-LABEL: @test1( ; CHECK-NEXT: br i1 [[C:%.*]], label [[TAKEN:%.*]], label [[UNTAKEN:%.*]] ; CHECK: taken: ; CHECK-NEXT: br label [[MERGE:%.*]] ; CHECK: untaken: ; CHECK-NEXT: br label [[MERGE]] ; CHECK: merge: ; CHECK-NEXT: [[PHI1:%.*]] = phi i64 [ [[A:%.*]], [[TAKEN]] ], [ [[B:%.*]], [[UNTAKEN]] ] ; CHECK-NEXT: ret i64 0 ; br i1 %c, label %taken, label %untaken taken: br label %merge untaken: br label %merge merge: %phi1 = phi i64 [%a, %taken], [%b, %untaken] %phi2 = phi i64 [%a, %taken], [%b, %untaken] %ret = sub i64 %phi1, %phi2 ret i64 %ret } declare void @llvm.assume(i1) define i64 @test2(i1 %c, i64 %a, i64 %b) { ; CHECK-LABEL: @test2( ; CHECK-NEXT: br i1 [[C:%.*]], label [[TAKEN:%.*]], label [[UNTAKEN:%.*]] ; CHECK: taken: ; CHECK-NEXT: [[ASSUMPTION:%.*]] = icmp eq i64 [[A:%.*]], 0 ; CHECK-NEXT: call void @llvm.assume(i1 [[ASSUMPTION]]) ; CHECK-NEXT: br label [[MERGE:%.*]] ; CHECK: untaken: ; CHECK-NEXT: br label [[MERGE]] ; CHECK: merge: ; CHECK-NEXT: [[PHI1:%.*]] = phi i64 [ 0, [[TAKEN]] ], [ [[B:%.*]], [[UNTAKEN]] ] ; CHECK-NEXT: ret i64 0 ; br i1 %c, label %taken, label %untaken taken: %assumption = icmp eq i64 %a, 0 call void @llvm.assume(i1 %assumption) br label %merge untaken: br label %merge merge: %phi1 = phi i64 [%a, %taken], [%b, %untaken] %phi2 = phi i64 [0, %taken], [%b, %untaken] %ret = sub i64 %phi1, %phi2 ret i64 %ret } define i64 @test3(i1 %c, i64 %a, i64 %b) { ; CHECK-LABEL: @test3( ; CHECK-NEXT: br i1 [[C:%.*]], label [[TAKEN:%.*]], label [[UNTAKEN:%.*]] ; CHECK: taken: ; CHECK-NEXT: [[ADD1:%.*]] = add i64 [[A:%.*]], 5 ; CHECK-NEXT: br label [[MERGE:%.*]] ; CHECK: untaken: ; CHECK-NEXT: br label [[MERGE]] ; CHECK: merge: ; CHECK-NEXT: [[PHI1:%.*]] = phi i64 [ [[ADD1]], [[TAKEN]] ], [ [[B:%.*]], [[UNTAKEN]] ] ; CHECK-NEXT: ret i64 0 ; br i1 %c, label %taken, label %untaken taken: %add1 = add i64 %a, 5 %add2 = add i64 %a, 5 br label %merge untaken: br label %merge merge: %phi1 = phi i64 [%add1, %taken], [%b, %untaken] %phi2 = phi i64 [%add2, %taken], [%b, %untaken] %ret = sub i64 %phi1, %phi2 ret i64 %ret } define i64 @test4(i1 %c, i64 %a, i64 %b) { ; CHECK-LABEL: @test4( ; CHECK-NEXT: br i1 [[C:%.*]], label [[TAKEN:%.*]], label [[UNTAKEN:%.*]] ; CHECK: taken: ; CHECK-NEXT: br label [[MERGE:%.*]] ; CHECK: untaken: ; CHECK-NEXT: br label [[MERGE]] ; CHECK: merge: ; CHECK-NEXT: [[PHI1:%.*]] = phi i64 [ [[A:%.*]], [[TAKEN]] ], [ [[B:%.*]], [[UNTAKEN]] ] ; CHECK-NEXT: br i1 [[C]], label [[TAKEN2:%.*]], label [[UNTAKEN2:%.*]] ; CHECK: taken2: ; CHECK-NEXT: [[ADD1:%.*]] = add i64 [[PHI1]], 5 ; CHECK-NEXT: br label [[MERGE2:%.*]] ; CHECK: untaken2: ; CHECK-NEXT: br label [[MERGE2]] ; CHECK: merge2: ; CHECK-NEXT: [[PHI3:%.*]] = phi i64 [ [[ADD1]], [[TAKEN2]] ], [ [[PHI1]], [[UNTAKEN2]] ] ; CHECK-NEXT: ret i64 0 ; br i1 %c, label %taken, label %untaken taken: br label %merge untaken: br label %merge merge: %phi1 = phi i64 [%a, %taken], [%b, %untaken] %phi2 = phi i64 [%a, %taken], [%b, %untaken] br i1 %c, label %taken2, label %untaken2 taken2: %add1 = add i64 %phi1, 5 %add2 = add i64 %phi2, 5 br label %merge2 untaken2: br label %merge2 merge2: %phi3 = phi i64 [%add1, %taken2], [%phi2, %untaken2] %phi4 = phi i64 [%add2, %taken2], [%phi2, %untaken2] %ret = sub i64 %phi4, %phi3 ret i64 %ret } define i64 @test5(i1 %c, i64 %a) { ; CHECK-LABEL: @test5( ; CHECK-NEXT: br i1 [[C:%.*]], label [[TAKEN:%.*]], label [[UNTAKEN:%.*]] ; CHECK: taken: ; CHECK-NEXT: [[ASSUMPTION:%.*]] = icmp eq i64 [[A:%.*]], 0 ; CHECK-NEXT: call void @llvm.assume(i1 [[ASSUMPTION]]) ; CHECK-NEXT: br label [[MERGE:%.*]] ; CHECK: untaken: ; CHECK-NEXT: br label [[MERGE]] ; CHECK: merge: ; CHECK-NEXT: ret i64 0 ; br i1 %c, label %taken, label %untaken taken: %assumption = icmp eq i64 %a, 0 call void @llvm.assume(i1 %assumption) br label %merge untaken: br label %merge merge: %phi = phi i64 [%a, %taken], [0, %untaken] ret i64 %phi } define i64 @test6(i1 %c, i64 %a) { ; CHECK-LABEL: @test6( ; CHECK-NEXT: br i1 [[C:%.*]], label [[TAKEN:%.*]], label [[UNTAKEN:%.*]] ; CHECK: taken: ; CHECK-NEXT: [[ASSUMPTION:%.*]] = icmp eq i64 [[A:%.*]], 0 ; CHECK-NEXT: call void @llvm.assume(i1 [[ASSUMPTION]]) ; CHECK-NEXT: br label [[MERGE:%.*]] ; CHECK: untaken: ; CHECK-NEXT: br label [[MERGE]] ; CHECK: merge: ; CHECK-NEXT: ret i64 0 ; br i1 %c, label %taken, label %untaken taken: %assumption = icmp eq i64 %a, 0 call void @llvm.assume(i1 %assumption) br label %next next: br label %merge untaken: br label %merge merge: %phi = phi i64 [%a, %next], [0, %untaken] ret i64 %phi } ; negative test, phi use is NOT dominated by assume define i64 @test7(i1 %c, i64 %a) { ; CHECK-LABEL: @test7( ; CHECK-NEXT: br i1 [[C:%.*]], label [[TAKEN:%.*]], label [[UNTAKEN:%.*]] ; CHECK: taken: ; CHECK-NEXT: [[ASSUMPTION:%.*]] = icmp eq i64 [[A:%.*]], 0 ; CHECK-NEXT: call void @llvm.assume(i1 [[ASSUMPTION]]) ; CHECK-NEXT: br label [[MERGE:%.*]] ; CHECK: untaken: ; CHECK-NEXT: br label [[MERGE]] ; CHECK: merge: ; CHECK-NEXT: ret i64 [[A]] ; br i1 %c, label %taken, label %untaken taken: %assumption = icmp eq i64 %a, 0 call void @llvm.assume(i1 %assumption) br label %merge untaken: br label %merge merge: br label %next next: %phi = phi i64 [%a, %merge] ret i64 %phi }