| ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py | |
| ; RUN: opt -S -passes=gvn < %s | FileCheck --check-prefixes=CHECK,MDEP %s | |
| ; RUN: opt -S -passes='gvn<memoryssa>' < %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 | |
| } | |
| ;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line: | |
| ; MDEP: {{.*}} |