ELF: Have __rela_iplt_{start,end} surround .rela.iplt with --pack-dyn-relocs=android.
[llvm-project.git] / llvm / test / Transforms / GVN / opaque-ptr.ll
blob8a7e4205848598975e5e874cae09732e54a1c36a
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -S -passes=gvn < %s | FileCheck %s
3 ; RUN: opt -S -passes=gvn -use-constant-int-for-fixed-length-splat < %s | FileCheck %s
5 declare void @use(ptr)
6 declare void @use.i32(i32)
8 define void @gep_cse(ptr %p) {
9 ; CHECK-LABEL: @gep_cse(
10 ; CHECK-NEXT:    [[GEP1:%.*]] = getelementptr i32, ptr [[P:%.*]], i64 1
11 ; CHECK-NEXT:    [[GEP3:%.*]] = getelementptr i64, ptr [[P]], i64 1
12 ; CHECK-NEXT:    call void @use(ptr [[GEP1]])
13 ; CHECK-NEXT:    call void @use(ptr [[GEP1]])
14 ; CHECK-NEXT:    call void @use(ptr [[GEP3]])
15 ; CHECK-NEXT:    ret void
17   %gep1 = getelementptr i32, ptr %p, i64 1
18   %gep2 = getelementptr i32, ptr %p, i64 1
19   %gep3 = getelementptr i64, ptr %p, i64 1
20   call void @use(ptr %gep1)
21   call void @use(ptr %gep2)
22   call void @use(ptr %gep3)
23   ret void
26 define void @gep_cse_offset_canonicalization(ptr %p, i64 %idx, i64 %idx2) {
27 ; CHECK-LABEL: @gep_cse_offset_canonicalization(
28 ; CHECK-NEXT:    [[GEP1:%.*]] = getelementptr i64, ptr [[P:%.*]], i64 1
29 ; CHECK-NEXT:    [[GEP1_DIFFERENT:%.*]] = getelementptr i8, ptr [[P]], i64 12
30 ; CHECK-NEXT:    call void @use(ptr [[GEP1]])
31 ; CHECK-NEXT:    call void @use(ptr [[GEP1]])
32 ; CHECK-NEXT:    call void @use(ptr [[GEP1]])
33 ; CHECK-NEXT:    call void @use(ptr [[GEP1_DIFFERENT]])
34 ; CHECK-NEXT:    [[GEP2:%.*]] = getelementptr i64, ptr [[P]], i64 [[IDX:%.*]]
35 ; CHECK-NEXT:    [[GEP2_DIFFERENT:%.*]] = getelementptr { i32, i32, i32 }, ptr [[P]], i64 [[IDX]]
36 ; CHECK-NEXT:    call void @use(ptr [[GEP2]])
37 ; CHECK-NEXT:    call void @use(ptr [[GEP2]])
38 ; CHECK-NEXT:    call void @use(ptr [[GEP2_DIFFERENT]])
39 ; CHECK-NEXT:    [[GEP3:%.*]] = getelementptr { [0 x i32], [0 x i32] }, ptr [[P]], i64 0, i32 0, i64 [[IDX]]
40 ; CHECK-NEXT:    [[GEP3_DIFFERENT:%.*]] = getelementptr { [0 x i32], [0 x i32] }, ptr [[P]], i64 0, i32 0, i64 [[IDX2:%.*]]
41 ; CHECK-NEXT:    call void @use(ptr [[GEP3]])
42 ; CHECK-NEXT:    call void @use(ptr [[GEP3]])
43 ; CHECK-NEXT:    call void @use(ptr [[GEP3]])
44 ; CHECK-NEXT:    call void @use(ptr [[GEP3_DIFFERENT]])
45 ; CHECK-NEXT:    [[GEP4:%.*]] = getelementptr [4 x i32], ptr [[P]], i64 [[IDX]], i64 [[IDX2]]
46 ; CHECK-NEXT:    [[GEP4_DIFFERENT:%.*]] = getelementptr [4 x float], ptr [[P]], i64 [[IDX2]], i64 [[IDX]]
47 ; CHECK-NEXT:    call void @use(ptr [[GEP4]])
48 ; CHECK-NEXT:    call void @use(ptr [[GEP4]])
49 ; CHECK-NEXT:    call void @use(ptr [[GEP4_DIFFERENT]])
50 ; CHECK-NEXT:    [[GEP5:%.*]] = getelementptr <vscale x 2 x i32>, ptr [[P]], i64 1
51 ; CHECK-NEXT:    [[GEP5_SAME:%.*]] = getelementptr <vscale x 2 x float>, ptr [[P]], i64 1
52 ; CHECK-NEXT:    [[GEP5_DIFFERENT:%.*]] = getelementptr <vscale x 2 x i64>, ptr [[P]], i64 1
53 ; CHECK-NEXT:    call void @use(ptr [[GEP5]])
54 ; CHECK-NEXT:    call void @use(ptr [[GEP5_SAME]])
55 ; CHECK-NEXT:    call void @use(ptr [[GEP5_DIFFERENT]])
56 ; CHECK-NEXT:    [[GEP6:%.*]] = getelementptr [4 x <vscale x 4 x i32>], ptr [[P]], i64 [[IDX]], i64 1
57 ; CHECK-NEXT:    [[GEP6_SAME:%.*]] = getelementptr [4 x <vscale x 4 x float>], ptr [[P]], i64 [[IDX]], i64 1
58 ; CHECK-NEXT:    [[GEP6_DIFFERENT:%.*]] = getelementptr [4 x <vscale x 4 x float>], ptr [[P]], i64 [[IDX2]], i64 1
59 ; CHECK-NEXT:    call void @use(ptr [[GEP6]])
60 ; CHECK-NEXT:    call void @use(ptr [[GEP6_SAME]])
61 ; CHECK-NEXT:    call void @use(ptr [[GEP6_DIFFERENT]])
62 ; CHECK-NEXT:    %gep7 = getelementptr <16 x i32>, ptr %p, i64 1
63 ; CHECK-NEXT:    %gep7.different = getelementptr <16 x i32>, ptr %p, <16 x i64> splat (i64 1)
64 ; CHECK-NEXT:    call void @use(ptr %gep7)
65 ; CHECK-NEXT:    call void @use(<16 x ptr> %gep7.different)
66 ; CHECK-NEXT:    ret void
68   %gep1 = getelementptr i64, ptr %p, i64 1
69   %gep1.same1 = getelementptr i32, ptr %p, i64 2
70   %gep1.same2 = getelementptr i8, ptr %p, i64 8
71   %gep1.different = getelementptr i8, ptr %p, i64 12
72   call void @use(ptr %gep1)
73   call void @use(ptr %gep1.same1)
74   call void @use(ptr %gep1.same2)
75   call void @use(ptr %gep1.different)
76   %gep2 = getelementptr i64, ptr %p, i64 %idx
77   %gep2.same = getelementptr { i32, i32 }, ptr %p, i64 %idx
78   %gep2.different = getelementptr { i32, i32, i32 }, ptr %p, i64 %idx
79   call void @use(ptr %gep2)
80   call void @use(ptr %gep2.same)
81   call void @use(ptr %gep2.different)
82   %gep3 = getelementptr { [0 x i32], [0 x i32] }, ptr %p, i64 0, i32 0, i64 %idx
83   %gep3.same1 = getelementptr { [0 x i32], [0 x i32] }, ptr %p, i64 0, i32 1, i64 %idx
84   %gep3.same2 = getelementptr { [0 x i32], [0 x i32] }, ptr %p, i64 1, i32 0, i64 %idx
85   %gep3.different = getelementptr { [0 x i32], [0 x i32] }, ptr %p, i64 0, i32 0, i64 %idx2
86   call void @use(ptr %gep3)
87   call void @use(ptr %gep3.same1)
88   call void @use(ptr %gep3.same2)
89   call void @use(ptr %gep3.different)
90   %gep4 = getelementptr [4 x i32], ptr %p, i64 %idx, i64 %idx2
91   %gep4.same = getelementptr [4 x float], ptr %p, i64 %idx, i64 %idx2
92   %gep4.different = getelementptr [4 x float], ptr %p, i64 %idx2, i64 %idx
93   call void @use(ptr %gep4)
94   call void @use(ptr %gep4.same)
95   call void @use(ptr %gep4.different)
96   ; TODO: %gep5 and %gep5.same are equivalent as well.
97   %gep5 = getelementptr <vscale x 2 x i32>, ptr %p, i64 1
98   %gep5.same = getelementptr <vscale x 2 x float>, ptr %p, i64 1
99   %gep5.different = getelementptr <vscale x 2 x i64>, ptr %p, i64 1
100   call void @use(ptr %gep5)
101   call void @use(ptr %gep5.same)
102   call void @use(ptr %gep5.different)
103   %gep6 = getelementptr [4 x <vscale x 4 x i32>], ptr %p, i64 %idx, i64 1
104   %gep6.same = getelementptr [4 x <vscale x 4 x float>], ptr %p, i64 %idx, i64 1
105   %gep6.different = getelementptr [4 x <vscale x 4 x float>], ptr %p, i64 %idx2, i64 1
106   call void @use(ptr %gep6)
107   call void @use(ptr %gep6.same)
108   call void @use(ptr %gep6.different)
109   %gep7 = getelementptr <16 x i32>, ptr %p, i64 1
110   %gep7.different = getelementptr <16 x i32>, ptr %p, <16 x i64> splat (i64 1)
111   call void @use(ptr %gep7)
112   call void @use(<16 x ptr> %gep7.different)
113   ret void
116 define i32 @phi_trans(i1 %c, ptr %p1, ptr %p2) {
117 ; CHECK-LABEL: @phi_trans(
118 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[IF:%.*]], label [[ELSE:%.*]]
119 ; CHECK:       if:
120 ; CHECK-NEXT:    [[GEP1:%.*]] = getelementptr i32, ptr [[P1:%.*]], i64 1
121 ; CHECK-NEXT:    [[V1:%.*]] = load i32, ptr [[GEP1]], align 4
122 ; CHECK-NEXT:    call void @use(i32 [[V1]]) #[[ATTR0:[0-9]+]]
123 ; CHECK-NEXT:    br label [[JOIN:%.*]]
124 ; CHECK:       else:
125 ; CHECK-NEXT:    [[GEP2:%.*]] = getelementptr i32, ptr [[P2:%.*]], i64 1
126 ; CHECK-NEXT:    [[V2:%.*]] = load i32, ptr [[GEP2]], align 4
127 ; CHECK-NEXT:    call void @use(i32 [[V2]]) #[[ATTR0]]
128 ; CHECK-NEXT:    br label [[JOIN]]
129 ; CHECK:       join:
130 ; CHECK-NEXT:    [[V:%.*]] = phi i32 [ [[V1]], [[IF]] ], [ [[V2]], [[ELSE]] ]
131 ; CHECK-NEXT:    [[PHI:%.*]] = phi ptr [ [[P1]], [[IF]] ], [ [[P2]], [[ELSE]] ]
132 ; CHECK-NEXT:    [[GEP:%.*]] = getelementptr i32, ptr [[PHI]], i64 1
133 ; CHECK-NEXT:    ret i32 [[V]]
135   br i1 %c, label %if, label %else
138   %gep1 = getelementptr i32, ptr %p1, i64 1
139   %v1 = load i32, ptr %gep1
140   call void @use(i32 %v1) readnone
141   br label %join
143 else:
144   %gep2 = getelementptr i32, ptr %p2, i64 1
145   %v2 = load i32, ptr %gep2
146   call void @use(i32 %v2) readnone
147   br label %join
149 join:
150   %phi = phi ptr [ %p1, %if ], [ %p2, %else ]
151   %gep = getelementptr i32, ptr %phi, i64 1
152   %v = load i32, ptr %gep
153   ret i32 %v
156 define i32 @phi_trans_different_types(i1 %c, ptr %p1, ptr %p2) {
157 ; CHECK-LABEL: @phi_trans_different_types(
158 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[IF:%.*]], label [[ELSE:%.*]]
159 ; CHECK:       if:
160 ; CHECK-NEXT:    [[GEP1:%.*]] = getelementptr i32, ptr [[P1:%.*]], i64 1
161 ; CHECK-NEXT:    [[V1:%.*]] = load i32, ptr [[GEP1]], align 4
162 ; CHECK-NEXT:    call void @use.i32(i32 [[V1]]) #[[ATTR0]]
163 ; CHECK-NEXT:    br label [[JOIN:%.*]]
164 ; CHECK:       else:
165 ; CHECK-NEXT:    [[GEP2:%.*]] = getelementptr i64, ptr [[P2:%.*]], i64 1
166 ; CHECK-NEXT:    [[V2:%.*]] = load i32, ptr [[GEP2]], align 4
167 ; CHECK-NEXT:    call void @use.i32(i32 [[V2]]) #[[ATTR0]]
168 ; CHECK-NEXT:    [[GEP_PHI_TRANS_INSERT:%.*]] = getelementptr i32, ptr [[P2]], i64 1
169 ; CHECK-NEXT:    [[V_PRE:%.*]] = load i32, ptr [[GEP_PHI_TRANS_INSERT]], align 4
170 ; CHECK-NEXT:    br label [[JOIN]]
171 ; CHECK:       join:
172 ; CHECK-NEXT:    [[V:%.*]] = phi i32 [ [[V1]], [[IF]] ], [ [[V_PRE]], [[ELSE]] ]
173 ; CHECK-NEXT:    [[PHI:%.*]] = phi ptr [ [[P1]], [[IF]] ], [ [[P2]], [[ELSE]] ]
174 ; CHECK-NEXT:    [[GEP:%.*]] = getelementptr i32, ptr [[PHI]], i64 1
175 ; CHECK-NEXT:    ret i32 [[V]]
177   br i1 %c, label %if, label %else
180   %gep1 = getelementptr i32, ptr %p1, i64 1
181   %v1 = load i32, ptr %gep1
182   call void @use.i32(i32 %v1) readnone
183   br label %join
185 else:
186   %gep2 = getelementptr i64, ptr %p2, i64 1
187   %v2 = load i32, ptr %gep2
188   call void @use.i32(i32 %v2) readnone
189   br label %join
191 join:
192   %phi = phi ptr [ %p1, %if ], [ %p2, %else ]
193   %gep = getelementptr i32, ptr %phi, i64 1
194   %v = load i32, ptr %gep
195   ret i32 %v
198 define i32 @select_pre(ptr %px, ptr %py) {
199 ; CHECK-LABEL: @select_pre(
200 ; CHECK-NEXT:    [[T2:%.*]] = load i32, ptr [[PY:%.*]], align 4
201 ; CHECK-NEXT:    [[T3:%.*]] = load i32, ptr [[PX:%.*]], align 4
202 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[T2]], [[T3]]
203 ; CHECK-NEXT:    [[TMP1:%.*]] = select i1 [[CMP]], i32 [[T3]], i32 [[T2]]
204 ; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[CMP]], ptr [[PX]], ptr [[PY]]
205 ; CHECK-NEXT:    ret i32 [[TMP1]]
207   %t2 = load i32, ptr %py, align 4
208   %t3 = load i32, ptr %px, align 4
209   %cmp = icmp slt i32 %t2, %t3
210   %select = select i1 %cmp, ptr %px, ptr %py
211   %r = load i32, ptr %select, align 4
212   ret i32 %r
215 define i64 @select_pre_different_types(ptr %px, ptr %py) {
216 ; CHECK-LABEL: @select_pre_different_types(
217 ; CHECK-NEXT:    [[T2:%.*]] = load i32, ptr [[PY:%.*]], align 4
218 ; CHECK-NEXT:    [[T3:%.*]] = load i32, ptr [[PX:%.*]], align 4
219 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[T2]], [[T3]]
220 ; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[CMP]], ptr [[PX]], ptr [[PY]]
221 ; CHECK-NEXT:    [[R:%.*]] = load i64, ptr [[SELECT]], align 4
222 ; CHECK-NEXT:    ret i64 [[R]]
224   %t2 = load i32, ptr %py, align 4
225   %t3 = load i32, ptr %px, align 4
226   %cmp = icmp slt i32 %t2, %t3
227   %select = select i1 %cmp, ptr %px, ptr %py
228   %r = load i64, ptr %select, align 4
229   ret i64 %r