@@ -117,3 +117,133 @@ if.end:
117117 %size = call i64 @llvm.objectsize.i64.p0 (ptr %p , i1 true , i1 true , i1 false )
118118 ret i64 %size
119119}
120+
121+ define i64 @pick_negative_offset (i32 %n ) {
122+ ; CHECK-LABEL: @pick_negative_offset(
123+ ; CHECK-NEXT: entry:
124+ ; CHECK-NEXT: [[BUFFER0:%.*]] = alloca i8, i64 20, align 1
125+ ; CHECK-NEXT: [[OFFSETED0:%.*]] = getelementptr i8, ptr [[BUFFER0]], i64 20
126+ ; CHECK-NEXT: [[COND:%.*]] = icmp eq i32 [[N:%.*]], 0
127+ ; CHECK-NEXT: br i1 [[COND]], label [[IF_ELSE:%.*]], label [[IF_END:%.*]]
128+ ; CHECK: if.else:
129+ ; CHECK-NEXT: [[BUFFER1:%.*]] = alloca i8, i64 20, align 1
130+ ; CHECK-NEXT: [[OFFSETED1:%.*]] = getelementptr i8, ptr [[BUFFER1]], i64 20
131+ ; CHECK-NEXT: br label [[IF_END]]
132+ ; CHECK: if.end:
133+ ; CHECK-NEXT: [[P:%.*]] = phi ptr [ [[OFFSETED1]], [[IF_ELSE]] ], [ [[OFFSETED0]], [[ENTRY:%.*]] ]
134+ ; CHECK-NEXT: [[POFFSETED:%.*]] = getelementptr i8, ptr [[P]], i64 -4
135+ ; CHECK-NEXT: ret i64 4
136+ ;
137+ entry:
138+ %buffer0 = alloca i8 , i64 20
139+ %offseted0 = getelementptr i8 , ptr %buffer0 , i64 20
140+ %cond = icmp eq i32 %n , 0
141+ br i1 %cond , label %if.else , label %if.end
142+
143+ if.else:
144+ %buffer1 = alloca i8 , i64 20
145+ %offseted1 = getelementptr i8 , ptr %buffer1 , i64 20
146+ br label %if.end
147+
148+ if.end:
149+ %p = phi ptr [ %offseted1 , %if.else ], [ %offseted0 , %entry ]
150+ %poffseted = getelementptr i8 , ptr %p , i64 -4
151+ %size = call i64 @llvm.objectsize.i64.p0 (ptr %poffseted , i1 false , i1 false , i1 false )
152+ ret i64 %size
153+ }
154+
155+ define i64 @pick_negative_offset_with_nullptr (i32 %n ) {
156+ ; CHECK-LABEL: @pick_negative_offset_with_nullptr(
157+ ; CHECK-NEXT: entry:
158+ ; CHECK-NEXT: [[BUFFER0:%.*]] = alloca i8, i64 20, align 1
159+ ; CHECK-NEXT: [[OFFSETED0:%.*]] = getelementptr i8, ptr [[BUFFER0]], i64 20
160+ ; CHECK-NEXT: [[COND:%.*]] = icmp eq i32 [[N:%.*]], 0
161+ ; CHECK-NEXT: br i1 [[COND]], label [[IF_ELSE:%.*]], label [[IF_END:%.*]]
162+ ; CHECK: if.else:
163+ ; CHECK-NEXT: br label [[IF_END]]
164+ ; CHECK: if.end:
165+ ; CHECK-NEXT: [[P0:%.*]] = phi ptr [ [[OFFSETED0]], [[ENTRY:%.*]] ], [ null, [[IF_ELSE]] ]
166+ ; CHECK-NEXT: [[P1:%.*]] = phi ptr [ null, [[IF_ELSE]] ], [ [[OFFSETED0]], [[ENTRY]] ]
167+ ; CHECK-NEXT: [[P0OFFSETED:%.*]] = getelementptr i8, ptr [[P0]], i64 -4
168+ ; CHECK-NEXT: [[P1OFFSETED:%.*]] = getelementptr i8, ptr [[P1]], i64 -4
169+ ; CHECK-NEXT: ret i64 4
170+ ;
171+ entry:
172+ %buffer0 = alloca i8 , i64 20
173+ %offseted0 = getelementptr i8 , ptr %buffer0 , i64 20
174+ %cond = icmp eq i32 %n , 0
175+ br i1 %cond , label %if.else , label %if.end
176+
177+ if.else:
178+ br label %if.end
179+
180+ if.end:
181+ %p0 = phi ptr [ %offseted0 , %entry ], [ null , %if.else ]
182+ %p1 = phi ptr [ null , %if.else ], [ %offseted0 , %entry ]
183+ %p0offseted = getelementptr i8 , ptr %p0 , i64 -4
184+ %p1offseted = getelementptr i8 , ptr %p1 , i64 -4
185+ %size0 = call i64 @llvm.objectsize.i64.p0 (ptr %p0offseted , i1 false , i1 false , i1 false )
186+ %size1 = call i64 @llvm.objectsize.i64.p0 (ptr %p1offseted , i1 false , i1 false , i1 false )
187+ %size = select i1 %cond , i64 %size0 , i64 %size1
188+ ret i64 %size
189+ }
190+
191+ define i64 @pick_negative_offset_with_unsized_nullptr (i32 %n ) {
192+ ; CHECK-LABEL: @pick_negative_offset_with_unsized_nullptr(
193+ ; CHECK-NEXT: entry:
194+ ; CHECK-NEXT: [[BUFFER0:%.*]] = alloca i8, i64 20, align 1
195+ ; CHECK-NEXT: [[OFFSETED0:%.*]] = getelementptr i8, ptr [[BUFFER0]], i64 20
196+ ; CHECK-NEXT: [[COND:%.*]] = icmp eq i32 [[N:%.*]], 0
197+ ; CHECK-NEXT: br i1 [[COND]], label [[IF_ELSE:%.*]], label [[IF_END:%.*]]
198+ ; CHECK: if.else:
199+ ; CHECK-NEXT: br label [[IF_END]]
200+ ; CHECK: if.end:
201+ ; CHECK-NEXT: [[P0:%.*]] = phi ptr [ [[OFFSETED0]], [[ENTRY:%.*]] ], [ null, [[IF_ELSE]] ]
202+ ; CHECK-NEXT: [[P1:%.*]] = phi ptr [ null, [[IF_ELSE]] ], [ [[OFFSETED0]], [[ENTRY]] ]
203+ ; CHECK-NEXT: [[P0OFFSETED:%.*]] = getelementptr i8, ptr [[P0]], i64 -4
204+ ; CHECK-NEXT: [[P1OFFSETED:%.*]] = getelementptr i8, ptr [[P1]], i64 -4
205+ ; CHECK-NEXT: ret i64 -1
206+ ;
207+ entry:
208+ %buffer0 = alloca i8 , i64 20
209+ %offseted0 = getelementptr i8 , ptr %buffer0 , i64 20
210+ %cond = icmp eq i32 %n , 0
211+ br i1 %cond , label %if.else , label %if.end
212+
213+ if.else:
214+ br label %if.end
215+
216+ if.end:
217+ %p0 = phi ptr [ %offseted0 , %entry ], [ null , %if.else ]
218+ %p1 = phi ptr [ null , %if.else ], [ %offseted0 , %entry ]
219+ %p0offseted = getelementptr i8 , ptr %p0 , i64 -4
220+ %p1offseted = getelementptr i8 , ptr %p1 , i64 -4
221+ %size0 = call i64 @llvm.objectsize.i64.p0 (ptr %p0offseted , i1 false , i1 true , i1 false )
222+ %size1 = call i64 @llvm.objectsize.i64.p0 (ptr %p1offseted , i1 false , i1 true , i1 false )
223+ %size = select i1 %cond , i64 %size0 , i64 %size1
224+ ret i64 %size
225+ }
226+
227+ define i64 @chain_pick_negative_offset_with_nullptr (i32 %x ) {
228+ ; CHECK-LABEL: @chain_pick_negative_offset_with_nullptr(
229+ ; CHECK-NEXT: entry:
230+ ; CHECK-NEXT: [[ARRAY:%.*]] = alloca [4 x i32], align 4
231+ ; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[X:%.*]], 0
232+ ; CHECK-NEXT: [[P:%.*]] = getelementptr i8, ptr [[ARRAY]], i64 8
233+ ; CHECK-NEXT: [[COND:%.*]] = select i1 [[C]], ptr [[P]], ptr null
234+ ; CHECK-NEXT: [[P4:%.*]] = getelementptr i8, ptr [[COND]], i64 8
235+ ; CHECK-NEXT: [[COND6:%.*]] = select i1 [[C]], ptr [[P4]], ptr null
236+ ; CHECK-NEXT: [[P7:%.*]] = getelementptr i8, ptr [[COND6]], i64 -4
237+ ; CHECK-NEXT: ret i64 4
238+ ;
239+ entry:
240+ %array = alloca [4 x i32 ]
241+ %c = icmp eq i32 %x , 0
242+ %p = getelementptr i8 , ptr %array , i64 8
243+ %cond = select i1 %c , ptr %p , ptr null
244+ %p4 = getelementptr i8 , ptr %cond , i64 8
245+ %cond6 = select i1 %c , ptr %p4 , ptr null
246+ %p7 = getelementptr i8 , ptr %cond6 , i64 -4
247+ %size = call i64 @llvm.objectsize.i64.p0 (ptr %p7 , i1 false , i1 false , i1 false )
248+ ret i64 %size
249+ }
0 commit comments