@@ -109,6 +109,45 @@ entry:
109
109
ret void
110
110
}
111
111
112
+ ; FIXME: Should be transformed as OR+GEP -> GEP+GEP (similar to gep_inbounds_add_nuw below).
113
+ define ptr @gep_inbounds_nuwaddlike (ptr %ptr , i64 %a , i64 %b ) {
114
+ ; CHECK-LABEL: define ptr @gep_inbounds_nuwaddlike(
115
+ ; CHECK-SAME: ptr [[PTR:%.*]], i64 [[A:%.*]], i64 [[B:%.*]]) {
116
+ ; CHECK-NEXT: [[ADD:%.*]] = or disjoint i64 [[A]], [[B]]
117
+ ; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds nuw i32, ptr [[PTR]], i64 [[ADD]]
118
+ ; CHECK-NEXT: ret ptr [[GEP]]
119
+ ;
120
+ %add = or disjoint i64 %a , %b
121
+ %gep = getelementptr inbounds nuw i32 , ptr %ptr , i64 %add
122
+ ret ptr %gep
123
+ }
124
+
125
+ ; FIXME: Preserve "inbounds nuw".
126
+ define ptr @gep_inbounds_add_nuw (ptr %ptr , i64 %a , i64 %b ) {
127
+ ; CHECK-LABEL: define ptr @gep_inbounds_add_nuw(
128
+ ; CHECK-SAME: ptr [[PTR:%.*]], i64 [[A:%.*]], i64 [[B:%.*]]) {
129
+ ; CHECK-NEXT: [[TMP1:%.*]] = getelementptr i32, ptr [[PTR]], i64 [[A]]
130
+ ; CHECK-NEXT: [[GEP:%.*]] = getelementptr i32, ptr [[TMP1]], i64 [[B]]
131
+ ; CHECK-NEXT: ret ptr [[GEP]]
132
+ ;
133
+ %add = add nuw i64 %a , %b
134
+ %gep = getelementptr inbounds nuw i32 , ptr %ptr , i64 %add
135
+ ret ptr %gep
136
+ }
137
+
138
+ ; FIXME: Preserve "nuw".
139
+ define ptr @gep_add_nuw (ptr %ptr , i64 %a , i64 %b ) {
140
+ ; CHECK-LABEL: define ptr @gep_add_nuw(
141
+ ; CHECK-SAME: ptr [[PTR:%.*]], i64 [[A:%.*]], i64 [[B:%.*]]) {
142
+ ; CHECK-NEXT: [[TMP1:%.*]] = getelementptr i32, ptr [[PTR]], i64 [[A]]
143
+ ; CHECK-NEXT: [[GEP:%.*]] = getelementptr i32, ptr [[TMP1]], i64 [[B]]
144
+ ; CHECK-NEXT: ret ptr [[GEP]]
145
+ ;
146
+ %add = add nuw i64 %a , %b
147
+ %gep = getelementptr nuw i32 , ptr %ptr , i64 %add
148
+ ret ptr %gep
149
+ }
150
+
112
151
define ptr @gep_inbounds_add_nsw_nonneg (ptr %ptr , i64 %a , i64 %b ) {
113
152
; CHECK-LABEL: define ptr @gep_inbounds_add_nsw_nonneg(
114
153
; CHECK-SAME: ptr [[PTR:%.*]], i64 [[A:%.*]], i64 [[B:%.*]]) {
@@ -219,6 +258,27 @@ define ptr @gep_inbounds_sext_add_nonneg(ptr %ptr, i32 %a) {
219
258
ret ptr %gep
220
259
}
221
260
261
+ ; FIXME: Could be optimized similar to gep_inbounds_sext_add_nonneg above
262
+ ; (difference is that we are using disjoint OR which is canonical form
263
+ ; of ADD with disjoint operands).
264
+ define ptr @gep_inbounds_sext_addlike_nonneg (ptr %ptr , i32 %a ) {
265
+ ; CHECK-LABEL: define ptr @gep_inbounds_sext_addlike_nonneg(
266
+ ; CHECK-SAME: ptr [[PTR:%.*]], i32 [[A:%.*]]) {
267
+ ; CHECK-NEXT: [[A_NNEG:%.*]] = icmp sgt i32 [[A]], -1
268
+ ; CHECK-NEXT: call void @llvm.assume(i1 [[A_NNEG]])
269
+ ; CHECK-NEXT: [[ADD:%.*]] = or disjoint i32 [[A]], 10
270
+ ; CHECK-NEXT: [[IDX:%.*]] = zext nneg i32 [[ADD]] to i64
271
+ ; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds nuw i32, ptr [[PTR]], i64 [[IDX]]
272
+ ; CHECK-NEXT: ret ptr [[GEP]]
273
+ ;
274
+ %a.nneg = icmp sgt i32 %a , -1
275
+ call void @llvm.assume (i1 %a.nneg )
276
+ %add = or disjoint i32 %a , 10
277
+ %idx = sext i32 %add to i64
278
+ %gep = getelementptr inbounds i32 , ptr %ptr , i64 %idx
279
+ ret ptr %gep
280
+ }
281
+
222
282
define ptr @gep_inbounds_sext_add_not_nonneg_1 (ptr %ptr , i32 %a ) {
223
283
; CHECK-LABEL: define ptr @gep_inbounds_sext_add_not_nonneg_1(
224
284
; CHECK-SAME: ptr [[PTR:%.*]], i32 [[A:%.*]]) {
0 commit comments