[ORC] Merge ostream operators for SymbolStringPtrs into SymbolStringPool.h. NFC.
[llvm-project.git] / llvm / test / Transforms / InstCombine / array.ll
blob4f4ae17bebc5035cf272bbceb769694c028c8e41
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 3
2 ; RUN: opt < %s -passes=instcombine -S | FileCheck %s
4 define void @test(ptr %ptr, i32 %a, i32 %b) {
5 ; CHECK-LABEL: define void @test(
6 ; CHECK-SAME: ptr [[PTR:%.*]], i32 [[A:%.*]], i32 [[B:%.*]]) {
7 ; CHECK-NEXT:  entry:
8 ; CHECK-NEXT:    [[TMP0:%.*]] = sext i32 [[A]] to i64
9 ; CHECK-NEXT:    [[TMP1:%.*]] = getelementptr i32, ptr [[PTR]], i64 [[TMP0]]
10 ; CHECK-NEXT:    [[GEP:%.*]] = getelementptr i8, ptr [[TMP1]], i64 40
11 ; CHECK-NEXT:    store i32 [[B]], ptr [[GEP]], align 4
12 ; CHECK-NEXT:    ret void
14 entry:
15   %add = add nsw i32 %a, 10
16   %idx = sext i32 %add to i64
17   %gep = getelementptr inbounds i32, ptr %ptr, i64 %idx
18   store i32 %b, ptr %gep
19   ret void
22 define  i32 @test_add_res_moreoneuse(ptr %ptr, i32 %a, i32 %b) {
23 ; CHECK-LABEL: define i32 @test_add_res_moreoneuse(
24 ; CHECK-SAME: ptr [[PTR:%.*]], i32 [[A:%.*]], i32 [[B:%.*]]) {
25 ; CHECK-NEXT:  entry:
26 ; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[A]], 5
27 ; CHECK-NEXT:    [[IDX:%.*]] = sext i32 [[ADD]] to i64
28 ; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds i32, ptr [[PTR]], i64 [[IDX]]
29 ; CHECK-NEXT:    store i32 [[B]], ptr [[GEP]], align 4
30 ; CHECK-NEXT:    ret i32 [[ADD]]
32 entry:
33   %add = add nsw i32 %a, 5
34   %idx = sext i32 %add to i64
35   %gep = getelementptr inbounds i32, ptr %ptr, i64 %idx
36   store i32 %b, ptr %gep
37   ret i32 %add
40 define void @test_addop_nonsw_flag(ptr %ptr, i32 %a, i32 %b) {
41 ; CHECK-LABEL: define void @test_addop_nonsw_flag(
42 ; CHECK-SAME: ptr [[PTR:%.*]], i32 [[A:%.*]], i32 [[B:%.*]]) {
43 ; CHECK-NEXT:  entry:
44 ; CHECK-NEXT:    [[ADD:%.*]] = add i32 [[A]], 10
45 ; CHECK-NEXT:    [[IDX:%.*]] = sext i32 [[ADD]] to i64
46 ; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds i32, ptr [[PTR]], i64 [[IDX]]
47 ; CHECK-NEXT:    store i32 [[B]], ptr [[GEP]], align 4
48 ; CHECK-NEXT:    ret void
50 entry:
51   %add = add i32 %a, 10
52   %idx = sext i32 %add to i64
53   %gep = getelementptr inbounds i32, ptr %ptr, i64 %idx
54   store i32 %b, ptr %gep
55   ret void
58 define void @test_add_op2_not_constant(ptr %ptr, i32 %a, i32 %b) {
59 ; CHECK-LABEL: define void @test_add_op2_not_constant(
60 ; CHECK-SAME: ptr [[PTR:%.*]], i32 [[A:%.*]], i32 [[B:%.*]]) {
61 ; CHECK-NEXT:  entry:
62 ; CHECK-NEXT:    [[ADD:%.*]] = add i32 [[A]], [[B]]
63 ; CHECK-NEXT:    [[IDX:%.*]] = sext i32 [[ADD]] to i64
64 ; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds i32, ptr [[PTR]], i64 [[IDX]]
65 ; CHECK-NEXT:    store i32 [[B]], ptr [[GEP]], align 4
66 ; CHECK-NEXT:    ret void
68 entry:
69   %add = add i32 %a, %b
70   %idx = sext i32 %add to i64
71   %gep = getelementptr inbounds i32, ptr %ptr, i64 %idx
72   store i32 %b, ptr %gep
73   ret void
76 define void @test_zext_nneg(ptr %ptr, i32 %a, i32 %b) {
77 ; CHECK-LABEL: define void @test_zext_nneg(
78 ; CHECK-SAME: ptr [[PTR:%.*]], i32 [[A:%.*]], i32 [[B:%.*]]) {
79 ; CHECK-NEXT:  entry:
80 ; CHECK-NEXT:    [[TMP0:%.*]] = sext i32 [[A]] to i64
81 ; CHECK-NEXT:    [[TMP1:%.*]] = getelementptr i32, ptr [[PTR]], i64 [[TMP0]]
82 ; CHECK-NEXT:    [[GEP:%.*]] = getelementptr i8, ptr [[TMP1]], i64 40
83 ; CHECK-NEXT:    store i32 [[B]], ptr [[GEP]], align 4
84 ; CHECK-NEXT:    ret void
86 entry:
87   %add = add nsw i32 %a, 10
88   %idx = zext nneg i32 %add to i64
89   %gep = getelementptr inbounds i32, ptr %ptr, i64 %idx
90   store i32 %b, ptr %gep
91   ret void
94 define void @test_zext_missing_nneg(ptr %ptr, i32 %a, i32 %b) {
95 ; CHECK-LABEL: define void @test_zext_missing_nneg(
96 ; CHECK-SAME: ptr [[PTR:%.*]], i32 [[A:%.*]], i32 [[B:%.*]]) {
97 ; CHECK-NEXT:  entry:
98 ; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[A]], 10
99 ; CHECK-NEXT:    [[IDX:%.*]] = zext i32 [[ADD]] to i64
100 ; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds i32, ptr [[PTR]], i64 [[IDX]]
101 ; CHECK-NEXT:    store i32 [[B]], ptr [[GEP]], align 4
102 ; CHECK-NEXT:    ret void
104 entry:
105   %add = add nsw i32 %a, 10
106   %idx = zext i32 %add to i64
107   %gep = getelementptr inbounds i32, ptr %ptr, i64 %idx
108   store i32 %b, ptr %gep
109   ret void
112 define ptr @gep_inbounds_add_nsw_nonneg(ptr %ptr, i64 %a, i64 %b) {
113 ; CHECK-LABEL: define ptr @gep_inbounds_add_nsw_nonneg(
114 ; CHECK-SAME: ptr [[PTR:%.*]], i64 [[A:%.*]], i64 [[B:%.*]]) {
115 ; CHECK-NEXT:    [[A_NNEG:%.*]] = icmp sgt i64 [[A]], -1
116 ; CHECK-NEXT:    call void @llvm.assume(i1 [[A_NNEG]])
117 ; CHECK-NEXT:    [[B_NNEG:%.*]] = icmp sgt i64 [[B]], -1
118 ; CHECK-NEXT:    call void @llvm.assume(i1 [[B_NNEG]])
119 ; CHECK-NEXT:    [[TMP1:%.*]] = getelementptr inbounds i32, ptr [[PTR]], i64 [[A]]
120 ; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds i32, ptr [[TMP1]], i64 [[B]]
121 ; CHECK-NEXT:    ret ptr [[GEP]]
123   %a.nneg = icmp sgt i64 %a, -1
124   call void @llvm.assume(i1 %a.nneg)
125   %b.nneg = icmp sgt i64 %b, -1
126   call void @llvm.assume(i1 %b.nneg)
127   %add = add nsw i64 %a, %b
128   %gep = getelementptr inbounds i32, ptr %ptr, i64 %add
129   ret ptr %gep
132 define ptr @gep_inbounds_add_nsw_not_nonneg1(ptr %ptr, i64 %a, i64 %b) {
133 ; CHECK-LABEL: define ptr @gep_inbounds_add_nsw_not_nonneg1(
134 ; CHECK-SAME: ptr [[PTR:%.*]], i64 [[A:%.*]], i64 [[B:%.*]]) {
135 ; CHECK-NEXT:    [[A_NNEG:%.*]] = icmp sgt i64 [[A]], -1
136 ; CHECK-NEXT:    call void @llvm.assume(i1 [[A_NNEG]])
137 ; CHECK-NEXT:    [[TMP1:%.*]] = getelementptr i32, ptr [[PTR]], i64 [[A]]
138 ; CHECK-NEXT:    [[GEP:%.*]] = getelementptr i32, ptr [[TMP1]], i64 [[B]]
139 ; CHECK-NEXT:    ret ptr [[GEP]]
141   %a.nneg = icmp sgt i64 %a, -1
142   call void @llvm.assume(i1 %a.nneg)
143   %add = add nsw i64 %a, %b
144   %gep = getelementptr inbounds i32, ptr %ptr, i64 %add
145   ret ptr %gep
148 define ptr @gep_inbounds_add_nsw_not_nonneg2(ptr %ptr, i64 %a, i64 %b) {
149 ; CHECK-LABEL: define ptr @gep_inbounds_add_nsw_not_nonneg2(
150 ; CHECK-SAME: ptr [[PTR:%.*]], i64 [[A:%.*]], i64 [[B:%.*]]) {
151 ; CHECK-NEXT:    [[B_NNEG:%.*]] = icmp sgt i64 [[B]], -1
152 ; CHECK-NEXT:    call void @llvm.assume(i1 [[B_NNEG]])
153 ; CHECK-NEXT:    [[TMP1:%.*]] = getelementptr i32, ptr [[PTR]], i64 [[A]]
154 ; CHECK-NEXT:    [[GEP:%.*]] = getelementptr i32, ptr [[TMP1]], i64 [[B]]
155 ; CHECK-NEXT:    ret ptr [[GEP]]
157   %b.nneg = icmp sgt i64 %b, -1
158   call void @llvm.assume(i1 %b.nneg)
159   %add = add nsw i64 %a, %b
160   %gep = getelementptr inbounds i32, ptr %ptr, i64 %add
161   ret ptr %gep
164 define ptr @gep_not_inbounds_add_nsw_nonneg(ptr %ptr, i64 %a, i64 %b) {
165 ; CHECK-LABEL: define ptr @gep_not_inbounds_add_nsw_nonneg(
166 ; CHECK-SAME: ptr [[PTR:%.*]], i64 [[A:%.*]], i64 [[B:%.*]]) {
167 ; CHECK-NEXT:    [[A_NNEG:%.*]] = icmp sgt i64 [[A]], -1
168 ; CHECK-NEXT:    call void @llvm.assume(i1 [[A_NNEG]])
169 ; CHECK-NEXT:    [[B_NNEG:%.*]] = icmp sgt i64 [[B]], -1
170 ; CHECK-NEXT:    call void @llvm.assume(i1 [[B_NNEG]])
171 ; CHECK-NEXT:    [[TMP1:%.*]] = getelementptr i32, ptr [[PTR]], i64 [[A]]
172 ; CHECK-NEXT:    [[GEP:%.*]] = getelementptr i32, ptr [[TMP1]], i64 [[B]]
173 ; CHECK-NEXT:    ret ptr [[GEP]]
175   %a.nneg = icmp sgt i64 %a, -1
176   call void @llvm.assume(i1 %a.nneg)
177   %b.nneg = icmp sgt i64 %b, -1
178   call void @llvm.assume(i1 %b.nneg)
179   %add = add nsw i64 %a, %b
180   %gep = getelementptr i32, ptr %ptr, i64 %add
181   ret ptr %gep
184 define ptr @gep_inbounds_add_not_nsw_nonneg(ptr %ptr, i64 %a, i64 %b) {
185 ; CHECK-LABEL: define ptr @gep_inbounds_add_not_nsw_nonneg(
186 ; CHECK-SAME: ptr [[PTR:%.*]], i64 [[A:%.*]], i64 [[B:%.*]]) {
187 ; CHECK-NEXT:    [[A_NNEG:%.*]] = icmp sgt i64 [[A]], -1
188 ; CHECK-NEXT:    call void @llvm.assume(i1 [[A_NNEG]])
189 ; CHECK-NEXT:    [[B_NNEG:%.*]] = icmp sgt i64 [[B]], -1
190 ; CHECK-NEXT:    call void @llvm.assume(i1 [[B_NNEG]])
191 ; CHECK-NEXT:    [[TMP1:%.*]] = getelementptr i32, ptr [[PTR]], i64 [[A]]
192 ; CHECK-NEXT:    [[GEP:%.*]] = getelementptr i32, ptr [[TMP1]], i64 [[B]]
193 ; CHECK-NEXT:    ret ptr [[GEP]]
195   %a.nneg = icmp sgt i64 %a, -1
196   call void @llvm.assume(i1 %a.nneg)
197   %b.nneg = icmp sgt i64 %b, -1
198   call void @llvm.assume(i1 %b.nneg)
199   %add = add i64 %a, %b
200   %gep = getelementptr inbounds i32, ptr %ptr, i64 %add
201   ret ptr %gep
204 define ptr @gep_inbounds_sext_add_nonneg(ptr %ptr, i32 %a) {
205 ; CHECK-LABEL: define ptr @gep_inbounds_sext_add_nonneg(
206 ; CHECK-SAME: ptr [[PTR:%.*]], i32 [[A:%.*]]) {
207 ; CHECK-NEXT:    [[A_NNEG:%.*]] = icmp sgt i32 [[A]], -1
208 ; CHECK-NEXT:    call void @llvm.assume(i1 [[A_NNEG]])
209 ; CHECK-NEXT:    [[TMP1:%.*]] = zext nneg i32 [[A]] to i64
210 ; CHECK-NEXT:    [[TMP2:%.*]] = getelementptr inbounds i32, ptr [[PTR]], i64 [[TMP1]]
211 ; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds i8, ptr [[TMP2]], i64 40
212 ; CHECK-NEXT:    ret ptr [[GEP]]
214   %a.nneg = icmp sgt i32 %a, -1
215   call void @llvm.assume(i1 %a.nneg)
216   %add = add nsw i32 %a, 10
217   %idx = sext i32 %add to i64
218   %gep = getelementptr inbounds i32, ptr %ptr, i64 %idx
219   ret ptr %gep
222 define ptr @gep_inbounds_sext_add_not_nonneg_1(ptr %ptr, i32 %a) {
223 ; CHECK-LABEL: define ptr @gep_inbounds_sext_add_not_nonneg_1(
224 ; CHECK-SAME: ptr [[PTR:%.*]], i32 [[A:%.*]]) {
225 ; CHECK-NEXT:    [[A_NNEG:%.*]] = icmp sgt i32 [[A]], -1
226 ; CHECK-NEXT:    call void @llvm.assume(i1 [[A_NNEG]])
227 ; CHECK-NEXT:    [[TMP1:%.*]] = zext nneg i32 [[A]] to i64
228 ; CHECK-NEXT:    [[TMP2:%.*]] = getelementptr i32, ptr [[PTR]], i64 [[TMP1]]
229 ; CHECK-NEXT:    [[GEP:%.*]] = getelementptr i8, ptr [[TMP2]], i64 -40
230 ; CHECK-NEXT:    ret ptr [[GEP]]
232   %a.nneg = icmp sgt i32 %a, -1
233   call void @llvm.assume(i1 %a.nneg)
234   %add = add nsw i32 %a, -10
235   %idx = sext i32 %add to i64
236   %gep = getelementptr inbounds i32, ptr %ptr, i64 %idx
237   ret ptr %gep
240 define ptr @gep_inbounds_sext_add_not_nonneg_2(ptr %ptr, i32 %a) {
241 ; CHECK-LABEL: define ptr @gep_inbounds_sext_add_not_nonneg_2(
242 ; CHECK-SAME: ptr [[PTR:%.*]], i32 [[A:%.*]]) {
243 ; CHECK-NEXT:    [[TMP1:%.*]] = sext i32 [[A]] to i64
244 ; CHECK-NEXT:    [[TMP2:%.*]] = getelementptr i32, ptr [[PTR]], i64 [[TMP1]]
245 ; CHECK-NEXT:    [[GEP:%.*]] = getelementptr i8, ptr [[TMP2]], i64 40
246 ; CHECK-NEXT:    ret ptr [[GEP]]
248   %add = add nsw i32 %a, 10
249   %idx = sext i32 %add to i64
250   %gep = getelementptr inbounds i32, ptr %ptr, i64 %idx
251   ret ptr %gep
254 define ptr @gep_not_inbounds_sext_add_nonneg(ptr %ptr, i32 %a) {
255 ; CHECK-LABEL: define ptr @gep_not_inbounds_sext_add_nonneg(
256 ; CHECK-SAME: ptr [[PTR:%.*]], i32 [[A:%.*]]) {
257 ; CHECK-NEXT:    [[A_NNEG:%.*]] = icmp sgt i32 [[A]], -1
258 ; CHECK-NEXT:    call void @llvm.assume(i1 [[A_NNEG]])
259 ; CHECK-NEXT:    [[TMP1:%.*]] = zext nneg i32 [[A]] to i64
260 ; CHECK-NEXT:    [[TMP2:%.*]] = getelementptr i32, ptr [[PTR]], i64 [[TMP1]]
261 ; CHECK-NEXT:    [[GEP:%.*]] = getelementptr i8, ptr [[TMP2]], i64 40
262 ; CHECK-NEXT:    ret ptr [[GEP]]
264   %a.nneg = icmp sgt i32 %a, -1
265   call void @llvm.assume(i1 %a.nneg)
266   %add = add nsw i32 %a, 10
267   %idx = sext i32 %add to i64
268   %gep = getelementptr i32, ptr %ptr, i64 %idx
269   ret ptr %gep