[LLVM][IR] Use splat syntax when printing ConstantExpr based splats. (#116856)
[llvm-project.git] / llvm / test / Analysis / BasicAA / separate_storage.ll
blob35557afecee30bce2627d0f33c824d215fddf782
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -passes='gvn' -basic-aa-separate-storage -S | FileCheck %s
4 declare void @llvm.assume(i1)
6 ; Test basic queries.
8 define i8 @simple_no(ptr %p1, ptr %p2) {
9 ; CHECK-LABEL: @simple_no(
10 ; CHECK-NEXT:  entry:
11 ; CHECK-NEXT:    store i8 0, ptr [[P1:%.*]], align 1
12 ; CHECK-NEXT:    store i8 1, ptr [[P2:%.*]], align 1
13 ; CHECK-NEXT:    [[LOADOFSTORE:%.*]] = load i8, ptr [[P1]], align 1
14 ; CHECK-NEXT:    ret i8 [[LOADOFSTORE]]
16 entry:
17   store i8 0, ptr %p1
18   store i8 1, ptr %p2
19   %loadofstore = load i8, ptr %p1
20   ret i8 %loadofstore
23 define i8 @simple_yes(ptr %p1, ptr %p2) {
24 ; CHECK-LABEL: @simple_yes(
25 ; CHECK-NEXT:  entry:
26 ; CHECK-NEXT:    call void @llvm.assume(i1 true) [ "separate_storage"(ptr [[P1:%.*]], ptr [[P2:%.*]]) ]
27 ; CHECK-NEXT:    store i8 0, ptr [[P1]], align 1
28 ; CHECK-NEXT:    store i8 1, ptr [[P2]], align 1
29 ; CHECK-NEXT:    ret i8 0
31 entry:
32   call void @llvm.assume(i1 1) ["separate_storage"(ptr %p1, ptr %p2)]
33   store i8 0, ptr %p1
34   store i8 1, ptr %p2
35   %loadofstore = load i8, ptr %p1
36   ret i8 %loadofstore
39 define i8 @ptr_to_ptr_no(ptr %pp) {
40 ; CHECK-LABEL: @ptr_to_ptr_no(
41 ; CHECK-NEXT:  entry:
42 ; CHECK-NEXT:    [[P_BASE:%.*]] = load ptr, ptr [[PP:%.*]], align 8
43 ; CHECK-NEXT:    store i8 0, ptr [[P_BASE]], align 1
44 ; CHECK-NEXT:    [[P_BASE2:%.*]] = load ptr, ptr [[PP]], align 8
45 ; CHECK-NEXT:    [[LOADOFSTORE:%.*]] = load i8, ptr [[P_BASE2]], align 1
46 ; CHECK-NEXT:    ret i8 [[LOADOFSTORE]]
48 entry:
49   %p_base = load ptr, ptr %pp
50   store i8 0, ptr %p_base
51   %p_base2 = load ptr, ptr %pp
52   %loadofstore = load i8, ptr %p_base2
53   ret i8 %loadofstore
56 define i8 @ptr_to_ptr_yes(ptr %pp) {
57 ; CHECK-LABEL: @ptr_to_ptr_yes(
58 ; CHECK-NEXT:  entry:
59 ; CHECK-NEXT:    [[P_BASE:%.*]] = load ptr, ptr [[PP:%.*]], align 8
60 ; CHECK-NEXT:    call void @llvm.assume(i1 true) [ "separate_storage"(ptr [[P_BASE]], ptr [[PP]]) ]
61 ; CHECK-NEXT:    store i8 0, ptr [[P_BASE]], align 1
62 ; CHECK-NEXT:    ret i8 0
64 entry:
65   %p_base = load ptr, ptr %pp
66   call void @llvm.assume(i1 1) ["separate_storage"(ptr %p_base, ptr %pp)]
67   store i8 0, ptr %p_base
68   %p_base2 = load ptr, ptr %pp
69   %loadofstore = load i8, ptr %p_base2
70   ret i8 %loadofstore
73 ; The analysis should only kick in if executed (or will be executed) at the
74 ; given program point.
76 define i8 @flow_sensitive(ptr %p1, ptr %p2, i1 %cond) {
77 ; CHECK-LABEL: @flow_sensitive(
78 ; CHECK-NEXT:  entry:
79 ; CHECK-NEXT:    br i1 [[COND:%.*]], label [[TRUE_BRANCH:%.*]], label [[FALSE_BRANCH:%.*]]
80 ; CHECK:       true_branch:
81 ; CHECK-NEXT:    store i8 11, ptr [[P1:%.*]], align 1
82 ; CHECK-NEXT:    store i8 22, ptr [[P2:%.*]], align 1
83 ; CHECK-NEXT:    [[LOADOFSTORE_TRUE:%.*]] = load i8, ptr [[P1]], align 1
84 ; CHECK-NEXT:    br label [[ENDIF:%.*]]
85 ; CHECK:       false_branch:
86 ; CHECK-NEXT:    call void @llvm.assume(i1 true) [ "separate_storage"(ptr [[P1]], ptr [[P2]]) ]
87 ; CHECK-NEXT:    store i8 33, ptr [[P1]], align 1
88 ; CHECK-NEXT:    store i8 44, ptr [[P2]], align 1
89 ; CHECK-NEXT:    br label [[ENDIF]]
90 ; CHECK:       endif:
91 ; CHECK-NEXT:    [[LOADOFSTORE:%.*]] = phi i8 [ [[LOADOFSTORE_TRUE]], [[TRUE_BRANCH]] ], [ 33, [[FALSE_BRANCH]] ]
92 ; CHECK-NEXT:    ret i8 [[LOADOFSTORE]]
94 entry:
95   br i1 %cond, label %true_branch, label %false_branch
97 true_branch:
98   store i8 11, ptr %p1
99   store i8 22, ptr %p2
100   %loadofstore_true = load i8, ptr %p1
101   br label %endif
103 false_branch:
104   call void @llvm.assume(i1 1) ["separate_storage"(ptr %p1, ptr %p2)]
105   store i8 33, ptr %p1
106   store i8 44, ptr %p2
107   %loadofstore_false = load i8, ptr %p1
108   br label %endif
110 endif:
111   %loadofstore = phi i8 [ %loadofstore_true, %true_branch ], [ %loadofstore_false, %false_branch ]
112   ret i8 %loadofstore
115 define i8 @flow_sensitive_with_dominator(ptr %p1, ptr %p2, i1 %cond) {
116 ; CHECK-LABEL: @flow_sensitive_with_dominator(
117 ; CHECK-NEXT:  entry:
118 ; CHECK-NEXT:    call void @llvm.assume(i1 true) [ "separate_storage"(ptr [[P1:%.*]], ptr [[P2:%.*]]) ]
119 ; CHECK-NEXT:    br i1 [[COND:%.*]], label [[TRUE_BRANCH:%.*]], label [[FALSE_BRANCH:%.*]]
120 ; CHECK:       true_branch:
121 ; CHECK-NEXT:    store i8 11, ptr [[P1]], align 1
122 ; CHECK-NEXT:    store i8 22, ptr [[P2]], align 1
123 ; CHECK-NEXT:    br label [[ENDIF:%.*]]
124 ; CHECK:       false_branch:
125 ; CHECK-NEXT:    store i8 33, ptr [[P1]], align 1
126 ; CHECK-NEXT:    store i8 44, ptr [[P2]], align 1
127 ; CHECK-NEXT:    br label [[ENDIF]]
128 ; CHECK:       endif:
129 ; CHECK-NEXT:    [[LOADOFSTORE:%.*]] = phi i8 [ 11, [[TRUE_BRANCH]] ], [ 33, [[FALSE_BRANCH]] ]
130 ; CHECK-NEXT:    ret i8 [[LOADOFSTORE]]
132 entry:
133   call void @llvm.assume(i1 1) ["separate_storage"(ptr %p1, ptr %p2)]
134   br i1 %cond, label %true_branch, label %false_branch
136 true_branch:
137   store i8 11, ptr %p1
138   store i8 22, ptr %p2
139   %loadofstore_true = load i8, ptr %p1
140   br label %endif
142 false_branch:
143   store i8 33, ptr %p1
144   store i8 44, ptr %p2
145   %loadofstore_false = load i8, ptr %p1
146   br label %endif
148 endif:
149   %loadofstore = phi i8 [ %loadofstore_true, %true_branch ], [ %loadofstore_false, %false_branch ]
150   ret i8 %loadofstore
153 ; Hints are relative to entire regions of storage, not particular pointers
154 ; inside them. We should know that the whole ranges are disjoint given hints at
155 ; offsets.
157 define i8 @offset_agnostic(ptr %p1, ptr %p2) {
158 ; CHECK-LABEL: @offset_agnostic(
159 ; CHECK-NEXT:    [[ACCESS1:%.*]] = getelementptr inbounds i8, ptr [[P1:%.*]], i64 12
160 ; CHECK-NEXT:    [[ACCESS2:%.*]] = getelementptr inbounds i8, ptr [[P2:%.*]], i64 34
161 ; CHECK-NEXT:    [[HINT1:%.*]] = getelementptr inbounds i8, ptr [[P1]], i64 56
162 ; CHECK-NEXT:    [[HINT2:%.*]] = getelementptr inbounds i8, ptr [[P2]], i64 78
163 ; CHECK-NEXT:    call void @llvm.assume(i1 true) [ "separate_storage"(ptr [[HINT1]], ptr [[HINT2]]) ]
164 ; CHECK-NEXT:    store i8 0, ptr [[ACCESS1]], align 1
165 ; CHECK-NEXT:    store i8 1, ptr [[ACCESS2]], align 1
166 ; CHECK-NEXT:    ret i8 0
168   %access1 = getelementptr inbounds i8, ptr %p1, i64 12
169   %access2 = getelementptr inbounds i8, ptr %p2, i64 34
171   %hint1 = getelementptr inbounds i8, ptr %p1, i64 56
172   %hint2 = getelementptr inbounds i8, ptr %p2, i64 78
173   call void @llvm.assume(i1 1) ["separate_storage"(ptr %hint1, ptr %hint2)]
175   store i8 0, ptr %access1
176   store i8 1, ptr %access2
177   %loadofstore = load i8, ptr %access1
178   ret i8 %loadofstore