Files
clang-p2996/llvm/test/Transforms/EarlyCSE/phi.ll
Nikita Popov 3c514d31d7 [EarlyCSE] Update tests to use opaque pointers (NFC)
Update the EarlyCSE tests to use opaque pointers.

Worth noting that this leaves some bitcast ptr to ptr instructions
in the input IR behind which are no longer necessary. This is
because these use numbered instructions, so it's hard to drop them
in an automated fashion (as it would require renumbering all other
instructions as well). I'm leaving that as a problem for another day.

The test updates have been performed using
https://gist.github.com/nikic/98357b71fd67756b0f064c9517b62a34.

Differential Revision: https://reviews.llvm.org/D127278
2022-06-10 09:53:35 +02:00

331 lines
9.4 KiB
LLVM

; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt -early-cse -earlycse-debug-hash -S < %s | FileCheck %s
; RUN: opt -basic-aa -early-cse-memssa -S < %s | FileCheck %s
; Most basic case, fully identical PHI nodes
define void @test0(i32 %v0, i32 %v1, i1 %c, ptr %d0, ptr %d1) {
; CHECK-LABEL: @test0(
; CHECK-NEXT: entry:
; CHECK-NEXT: br i1 [[C:%.*]], label [[B0:%.*]], label [[B1:%.*]]
; CHECK: b0:
; CHECK-NEXT: br label [[END:%.*]]
; CHECK: b1:
; CHECK-NEXT: br label [[END]]
; CHECK: end:
; CHECK-NEXT: [[I0:%.*]] = phi i32 [ [[V0:%.*]], [[B0]] ], [ [[V1:%.*]], [[B1]] ]
; CHECK-NEXT: [[I1:%.*]] = phi i32 [ [[V0]], [[B0]] ], [ [[V1]], [[B1]] ]
; CHECK-NEXT: store i32 [[I0]], ptr [[D0:%.*]], align 4
; CHECK-NEXT: store i32 [[I1]], ptr [[D1:%.*]], align 4
; CHECK-NEXT: ret void
;
entry:
br i1 %c, label %b0, label %b1
b0:
br label %end
b1:
br label %end
end:
%i0 = phi i32 [ %v0, %b0 ], [ %v1, %b1 ]
%i1 = phi i32 [ %v0, %b0 ], [ %v1, %b1 ]
store i32 %i0, ptr %d0
store i32 %i1, ptr %d1
ret void
}
; Fully identical PHI nodes, but order of operands differs
define void @test1(i32 %v0, i32 %v1, i1 %c, ptr %d0, ptr %d1) {
; CHECK-LABEL: @test1(
; CHECK-NEXT: entry:
; CHECK-NEXT: br i1 [[C:%.*]], label [[B0:%.*]], label [[B1:%.*]]
; CHECK: b0:
; CHECK-NEXT: br label [[END:%.*]]
; CHECK: b1:
; CHECK-NEXT: br label [[END]]
; CHECK: end:
; CHECK-NEXT: [[I0:%.*]] = phi i32 [ [[V0:%.*]], [[B0]] ], [ [[V1:%.*]], [[B1]] ]
; CHECK-NEXT: [[I1:%.*]] = phi i32 [ [[V1]], [[B1]] ], [ [[V0]], [[B0]] ]
; CHECK-NEXT: store i32 [[I0]], ptr [[D0:%.*]], align 4
; CHECK-NEXT: store i32 [[I1]], ptr [[D1:%.*]], align 4
; CHECK-NEXT: ret void
;
entry:
br i1 %c, label %b0, label %b1
b0:
br label %end
b1:
br label %end
end:
%i0 = phi i32 [ %v0, %b0 ], [ %v1, %b1 ]
%i1 = phi i32 [ %v1, %b1 ], [ %v0, %b0 ]
store i32 %i0, ptr %d0
store i32 %i1, ptr %d1
ret void
}
; Different incoming values in second PHI
define void @negative_test2(i32 %v0, i32 %v1, i32 %v2, i1 %c, ptr %d0, ptr %d1) {
; CHECK-LABEL: @negative_test2(
; CHECK-NEXT: entry:
; CHECK-NEXT: br i1 [[C:%.*]], label [[B0:%.*]], label [[B1:%.*]]
; CHECK: b0:
; CHECK-NEXT: br label [[END:%.*]]
; CHECK: b1:
; CHECK-NEXT: br label [[END]]
; CHECK: end:
; CHECK-NEXT: [[I0:%.*]] = phi i32 [ [[V0:%.*]], [[B0]] ], [ [[V1:%.*]], [[B1]] ]
; CHECK-NEXT: [[I1:%.*]] = phi i32 [ [[V0]], [[B0]] ], [ [[V2:%.*]], [[B1]] ]
; CHECK-NEXT: store i32 [[I0]], ptr [[D0:%.*]], align 4
; CHECK-NEXT: store i32 [[I1]], ptr [[D1:%.*]], align 4
; CHECK-NEXT: ret void
;
entry:
br i1 %c, label %b0, label %b1
b0:
br label %end
b1:
br label %end
end:
%i0 = phi i32 [ %v0, %b0 ], [ %v1, %b1 ]
%i1 = phi i32 [ %v0, %b0 ], [ %v2, %b1 ] ; from %b0 takes %v2 instead of %v1
store i32 %i0, ptr %d0
store i32 %i1, ptr %d1
ret void
}
define void @negative_test3(i32 %v0, i32 %v1, i32 %v2, i1 %c, ptr %d0, ptr %d1) {
; CHECK-LABEL: @negative_test3(
; CHECK-NEXT: entry:
; CHECK-NEXT: br i1 [[C:%.*]], label [[B0:%.*]], label [[B1:%.*]]
; CHECK: b0:
; CHECK-NEXT: br label [[END:%.*]]
; CHECK: b1:
; CHECK-NEXT: br label [[END]]
; CHECK: end:
; CHECK-NEXT: [[I0:%.*]] = phi i32 [ [[V0:%.*]], [[B0]] ], [ [[V1:%.*]], [[B1]] ]
; CHECK-NEXT: [[I1:%.*]] = phi i32 [ [[V2:%.*]], [[B1]] ], [ [[V0]], [[B0]] ]
; CHECK-NEXT: store i32 [[I0]], ptr [[D0:%.*]], align 4
; CHECK-NEXT: store i32 [[I1]], ptr [[D1:%.*]], align 4
; CHECK-NEXT: ret void
;
entry:
br i1 %c, label %b0, label %b1
b0:
br label %end
b1:
br label %end
end:
%i0 = phi i32 [ %v0, %b0 ], [ %v1, %b1 ]
%i1 = phi i32 [ %v2, %b1 ], [ %v0, %b0 ] ; from %b0 takes %v2 instead of %v1
store i32 %i0, ptr %d0
store i32 %i1, ptr %d1
ret void
}
define void @negative_test4(i32 %v0, i32 %v1, i1 %c, ptr %d0, ptr %d1) {
; CHECK-LABEL: @negative_test4(
; CHECK-NEXT: entry:
; CHECK-NEXT: br i1 [[C:%.*]], label [[B0:%.*]], label [[B1:%.*]]
; CHECK: b0:
; CHECK-NEXT: br label [[END:%.*]]
; CHECK: b1:
; CHECK-NEXT: br label [[END]]
; CHECK: end:
; CHECK-NEXT: [[I0:%.*]] = phi i32 [ [[V0:%.*]], [[B0]] ], [ [[V1:%.*]], [[B1]] ]
; CHECK-NEXT: [[I1:%.*]] = phi i32 [ [[V1]], [[B1]] ], [ [[V0]], [[B0]] ]
; CHECK-NEXT: store i32 [[I0]], ptr [[D0:%.*]], align 4
; CHECK-NEXT: store i32 [[I1]], ptr [[D1:%.*]], align 4
; CHECK-NEXT: ret void
;
entry:
br i1 %c, label %b0, label %b1
b0:
br label %end
b1:
br label %end
end:
%i0 = phi i32 [ %v0, %b0 ], [ %v1, %b1 ]
%i1 = phi i32 [ %v1, %b1 ], [ %v0, %b0 ] ; incoming values are swapped
store i32 %i0, ptr %d0
store i32 %i1, ptr %d1
ret void
}
; Both PHI's are identical, but the first one has no uses, so ignore it.
define void @test5(i32 %v0, i32 %v1, i1 %c, ptr %d0, ptr %d1) {
; CHECK-LABEL: @test5(
; CHECK-NEXT: entry:
; CHECK-NEXT: br i1 [[C:%.*]], label [[B0:%.*]], label [[B1:%.*]]
; CHECK: b0:
; CHECK-NEXT: br label [[END:%.*]]
; CHECK: b1:
; CHECK-NEXT: br label [[END]]
; CHECK: end:
; CHECK-NEXT: [[I1:%.*]] = phi i32 [ [[V0:%.*]], [[B0]] ], [ [[V1:%.*]], [[B1]] ]
; CHECK-NEXT: store i32 [[I1]], ptr [[D1:%.*]], align 4
; CHECK-NEXT: ret void
;
entry:
br i1 %c, label %b0, label %b1
b0:
br label %end
b1:
br label %end
end:
%i0 = phi i32 [ %v0, %b0 ], [ %v1, %b1 ] ; unused
%i1 = phi i32 [ %v0, %b0 ], [ %v1, %b1 ]
store i32 %i1, ptr %d1
ret void
}
; Second PHI has no uses
define void @test6(i32 %v0, i32 %v1, i1 %c, ptr %d0, ptr %d1) {
; CHECK-LABEL: @test6(
; CHECK-NEXT: entry:
; CHECK-NEXT: br i1 [[C:%.*]], label [[B0:%.*]], label [[B1:%.*]]
; CHECK: b0:
; CHECK-NEXT: br label [[END:%.*]]
; CHECK: b1:
; CHECK-NEXT: br label [[END]]
; CHECK: end:
; CHECK-NEXT: [[I0:%.*]] = phi i32 [ [[V0:%.*]], [[B0]] ], [ [[V1:%.*]], [[B1]] ]
; CHECK-NEXT: store i32 [[I0]], ptr [[D0:%.*]], align 4
; CHECK-NEXT: ret void
;
entry:
br i1 %c, label %b0, label %b1
b0:
br label %end
b1:
br label %end
end:
%i0 = phi i32 [ %v0, %b0 ], [ %v1, %b1 ]
%i1 = phi i32 [ %v0, %b0 ], [ %v1, %b1 ] ; unused
store i32 %i0, ptr %d0
ret void
}
; Non-matching PHI node should be ignored without terminating CSE.
define void @test7(i32 %v0, i32 %v1, i16 %v2, i16 %v3, i1 %c, ptr %d0, ptr %d1, ptr %d2) {
; CHECK-LABEL: @test7(
; CHECK-NEXT: entry:
; CHECK-NEXT: br i1 [[C:%.*]], label [[B0:%.*]], label [[B1:%.*]]
; CHECK: b0:
; CHECK-NEXT: br label [[END:%.*]]
; CHECK: b1:
; CHECK-NEXT: br label [[END]]
; CHECK: end:
; CHECK-NEXT: [[IBAD:%.*]] = phi i16 [ [[V2:%.*]], [[B0]] ], [ [[V3:%.*]], [[B1]] ]
; CHECK-NEXT: [[I0:%.*]] = phi i32 [ [[V0:%.*]], [[B0]] ], [ [[V1:%.*]], [[B1]] ]
; CHECK-NEXT: [[I1:%.*]] = phi i32 [ [[V0]], [[B0]] ], [ [[V1]], [[B1]] ]
; CHECK-NEXT: store i32 [[I0]], ptr [[D0:%.*]], align 4
; CHECK-NEXT: store i32 [[I1]], ptr [[D1:%.*]], align 4
; CHECK-NEXT: store i16 [[IBAD]], ptr [[D2:%.*]], align 2
; CHECK-NEXT: ret void
;
entry:
br i1 %c, label %b0, label %b1
b0:
br label %end
b1:
br label %end
end:
%iBAD = phi i16 [ %v2, %b0 ], [ %v3, %b1 ]
%i0 = phi i32 [ %v0, %b0 ], [ %v1, %b1 ]
%i1 = phi i32 [ %v0, %b0 ], [ %v1, %b1 ]
store i32 %i0, ptr %d0
store i32 %i1, ptr %d1
store i16 %iBAD, ptr %d2
ret void
}
define void @test8(i32 %v0, i32 %v1, i16 %v2, i16 %v3, i1 %c, ptr %d0, ptr %d1, ptr %d2) {
; CHECK-LABEL: @test8(
; CHECK-NEXT: entry:
; CHECK-NEXT: br i1 [[C:%.*]], label [[B0:%.*]], label [[B1:%.*]]
; CHECK: b0:
; CHECK-NEXT: br label [[END:%.*]]
; CHECK: b1:
; CHECK-NEXT: br label [[END]]
; CHECK: end:
; CHECK-NEXT: [[I0:%.*]] = phi i32 [ [[V0:%.*]], [[B0]] ], [ [[V1:%.*]], [[B1]] ]
; CHECK-NEXT: [[IBAD:%.*]] = phi i16 [ [[V2:%.*]], [[B0]] ], [ [[V3:%.*]], [[B1]] ]
; CHECK-NEXT: [[I1:%.*]] = phi i32 [ [[V0]], [[B0]] ], [ [[V1]], [[B1]] ]
; CHECK-NEXT: store i32 [[I0]], ptr [[D0:%.*]], align 4
; CHECK-NEXT: store i32 [[I1]], ptr [[D1:%.*]], align 4
; CHECK-NEXT: store i16 [[IBAD]], ptr [[D2:%.*]], align 2
; CHECK-NEXT: ret void
;
entry:
br i1 %c, label %b0, label %b1
b0:
br label %end
b1:
br label %end
end:
%i0 = phi i32 [ %v0, %b0 ], [ %v1, %b1 ]
%iBAD = phi i16 [ %v2, %b0 ], [ %v3, %b1 ]
%i1 = phi i32 [ %v0, %b0 ], [ %v1, %b1 ]
store i32 %i0, ptr %d0
store i32 %i1, ptr %d1
store i16 %iBAD, ptr %d2
ret void
}
define void @test9(i32 %v0, i32 %v1, i16 %v2, i16 %v3, i1 %c, ptr %d0, ptr %d1, ptr %d2) {
; CHECK-LABEL: @test9(
; CHECK-NEXT: entry:
; CHECK-NEXT: br i1 [[C:%.*]], label [[B0:%.*]], label [[B1:%.*]]
; CHECK: b0:
; CHECK-NEXT: br label [[END:%.*]]
; CHECK: b1:
; CHECK-NEXT: br label [[END]]
; CHECK: end:
; CHECK-NEXT: [[I0:%.*]] = phi i32 [ [[V0:%.*]], [[B0]] ], [ [[V1:%.*]], [[B1]] ]
; CHECK-NEXT: [[I1:%.*]] = phi i32 [ [[V0]], [[B0]] ], [ [[V1]], [[B1]] ]
; CHECK-NEXT: [[IBAD:%.*]] = phi i16 [ [[V2:%.*]], [[B0]] ], [ [[V3:%.*]], [[B1]] ]
; CHECK-NEXT: store i32 [[I0]], ptr [[D0:%.*]], align 4
; CHECK-NEXT: store i32 [[I1]], ptr [[D1:%.*]], align 4
; CHECK-NEXT: store i16 [[IBAD]], ptr [[D2:%.*]], align 2
; CHECK-NEXT: ret void
;
entry:
br i1 %c, label %b0, label %b1
b0:
br label %end
b1:
br label %end
end:
%i0 = phi i32 [ %v0, %b0 ], [ %v1, %b1 ]
%i1 = phi i32 [ %v0, %b0 ], [ %v1, %b1 ]
%iBAD = phi i16 [ %v2, %b0 ], [ %v3, %b1 ]
store i32 %i0, ptr %d0
store i32 %i1, ptr %d1
store i16 %iBAD, ptr %d2
ret void
}