xref: /llvm-project/llvm/test/Other/invariant.group.ll (revision 38386b4318e3ba54f450480ad49b237a9c357af4)
1; RUN: opt -S -passes=early-cse -earlycse-debug-hash < %s | FileCheck %s
2; RUN: opt -S -passes=gvn < %s | FileCheck %s
3; RUN: opt -S -passes=newgvn < %s | FileCheck %s
4
5; These tests checks if passes with CSE functionality can do CSE on
6; launder.invariant.group, that is prohibited if there is a memory clobber
7; between barriers call.
8
9; CHECK-LABEL: define i8 @optimizable()
10define i8 @optimizable() {
11entry:
12    %ptr = alloca i8
13    store i8 42, ptr %ptr, !invariant.group !0
14; CHECK: call ptr @llvm.launder.invariant.group.p0
15    %ptr2 = call ptr @llvm.launder.invariant.group.p0(ptr %ptr)
16; FIXME: This one could be CSE
17; CHECK: call ptr @llvm.launder.invariant.group
18    %ptr3 = call ptr @llvm.launder.invariant.group.p0(ptr %ptr)
19; CHECK: call void @clobber(ptr {{.*}}%ptr)
20    call void @clobber(ptr %ptr)
21
22; CHECK: call void @use(ptr {{.*}}%ptr2)
23    call void @use(ptr %ptr2)
24; CHECK: call void @use(ptr {{.*}}%ptr3)
25    call void @use(ptr %ptr3)
26; CHECK: load i8, ptr %ptr3, {{.*}}!invariant.group
27    %v = load i8, ptr %ptr3, !invariant.group !0
28
29    ret i8 %v
30}
31
32; CHECK-LABEL: define i8 @unoptimizable()
33define i8 @unoptimizable() {
34entry:
35    %ptr = alloca i8
36    store i8 42, ptr %ptr, !invariant.group !0
37; CHECK: call ptr @llvm.launder.invariant.group.p0
38    %ptr2 = call ptr @llvm.launder.invariant.group.p0(ptr %ptr)
39    call void @clobber(ptr %ptr)
40; CHECK: call ptr @llvm.launder.invariant.group.p0
41    %ptr3 = call ptr @llvm.launder.invariant.group.p0(ptr %ptr)
42; CHECK: call void @clobber(ptr {{.*}}%ptr)
43    call void @clobber(ptr %ptr)
44; CHECK: call void @use(ptr {{.*}}%ptr2)
45    call void @use(ptr %ptr2)
46; CHECK: call void @use(ptr {{.*}}%ptr3)
47    call void @use(ptr %ptr3)
48; CHECK: load i8, ptr %ptr3, {{.*}}!invariant.group
49    %v = load i8, ptr %ptr3, !invariant.group !0
50
51    ret i8 %v
52}
53
54; CHECK-LABEL: define i8 @unoptimizable2()
55define i8 @unoptimizable2() {
56    %ptr = alloca i8
57    store i8 42, ptr %ptr, !invariant.group !0
58; CHECK: call ptr @llvm.launder.invariant.group
59    %ptr2 = call ptr @llvm.launder.invariant.group.p0(ptr %ptr)
60    store i8 43, ptr %ptr
61; CHECK: call ptr @llvm.launder.invariant.group
62    %ptr3 = call ptr @llvm.launder.invariant.group.p0(ptr %ptr)
63; CHECK: call void @clobber(ptr {{.*}}%ptr)
64    call void @clobber(ptr %ptr)
65; CHECK: call void @use(ptr {{.*}}%ptr2)
66    call void @use(ptr %ptr2)
67; CHECK: call void @use(ptr {{.*}}%ptr3)
68    call void @use(ptr %ptr3)
69; CHECK: load i8, ptr %ptr3, {{.*}}!invariant.group
70    %v = load i8, ptr %ptr3, !invariant.group !0
71    ret i8 %v
72}
73
74; This test check if optimizer is not proving equality based on mustalias
75; CHECK-LABEL: define void @dontProveEquality(ptr %a)
76define void @dontProveEquality(ptr %a) {
77  %b = call ptr @llvm.launder.invariant.group.p0(ptr %a)
78  %r = icmp eq ptr %b, %a
79; CHECK: call void @useBool(i1 %r)
80  call void @useBool(i1 %r)
81
82  %b2 = call ptr @llvm.strip.invariant.group.p0(ptr %a)
83  %r2 = icmp eq ptr %b2, %a
84; CHECK: call void @useBool(i1 %r2)
85  call void @useBool(i1 %r2)
86
87  ret void
88}
89
90declare void @use(ptr readonly)
91declare void @useBool(i1)
92
93declare void @clobber(ptr)
94; CHECK: Function Attrs: nocallback nofree nosync nounwind speculatable willreturn memory(inaccessiblemem: readwrite){{$}}
95; CHECK-NEXT: declare ptr @llvm.launder.invariant.group.p0(ptr)
96declare ptr @llvm.launder.invariant.group.p0(ptr)
97
98; CHECK: Function Attrs: nocallback nofree nosync nounwind speculatable willreturn memory(none){{$}}
99; CHECK-NEXT: declare ptr @llvm.strip.invariant.group.p0(ptr)
100declare ptr @llvm.strip.invariant.group.p0(ptr)
101
102
103!0 = !{}
104