; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt -S -passes=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
}