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:%.*]]) {
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
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
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:%.*]]) {
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]]
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
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:%.*]]) {
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
52 %idx = sext i32 %add to i64
53 %gep = getelementptr inbounds i32, ptr %ptr, i64 %idx
54 store i32 %b, ptr %gep
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:%.*]]) {
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
70 %idx = sext i32 %add to i64
71 %gep = getelementptr inbounds i32, ptr %ptr, i64 %idx
72 store i32 %b, ptr %gep
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:%.*]]) {
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
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
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:%.*]]) {
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
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
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
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
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
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
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
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
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
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
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