Files
clang-p2996/llvm/test/Transforms/GVN/phi.ll
Philip Reames 97a7bc5831 [gvn] Precisely propagate equalities to phi operands
The code used for propagating equalities (e.g. assume facts) was conservative in two ways - one of which this patch fixes. Specifically, it shifts the code reasoning about whether a use is dominated by the end of the assume block to consider phi uses to exist on the predecessor edge. This matches the dominator tree handling for dominates(Edge, Use), and simply extends it to dominates(BB, Use).

Note that the decision to use the end of the block is itself a conservative choice. The more precise option would be to use the later of the assume and the value, and replace all uses after that. GVN handles that case separately (with the replace operand mechanism) because it used to be expensive to ask dominator questions within blocks. With the new instruction ordering support, we should probably rewrite this code at some point to simplify.

Differential Revision: https://reviews.llvm.org/D98082
2021-03-08 08:59:00 -08:00

201 lines
5.6 KiB
LLVM

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