| ; 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 |
| } |