|
4 | 4 | ; The ptrtoaddr folds are also valid for pointers that have external state. |
5 | 5 | target datalayout = "pe1:64:64:64:32" |
6 | 6 |
|
| 7 | +declare void @use.i1(i1) |
| 8 | +declare void @use.i32(i32) |
| 9 | +declare void @use.i64(i64) |
| 10 | + |
7 | 11 | ; ptrtoaddr result type is fixed, and can't be combined with integer cast. |
8 | 12 | define i32 @ptrtoaddr_trunc(ptr %p) { |
9 | 13 | ; CHECK-LABEL: define i32 @ptrtoaddr_trunc( |
@@ -171,3 +175,65 @@ define i128 @sub_zext_ptrtoint_ptrtoaddr_addrsize(ptr addrspace(1) %p, i32 %offs |
171 | 175 | %sub = sub i128 %p2.addr.ext, %p.int.ext |
172 | 176 | ret i128 %sub |
173 | 177 | } |
| 178 | + |
| 179 | +; The uses in icmp, ptrtoint, ptrtoaddr should be replaced. The one in the |
| 180 | +; return value should not, as the provenance differs. |
| 181 | +define ptr @gep_sub_ptrtoaddr_different_obj(ptr %p, ptr %p2, ptr %p3) { |
| 182 | +; CHECK-LABEL: define ptr @gep_sub_ptrtoaddr_different_obj( |
| 183 | +; CHECK-SAME: ptr [[P:%.*]], ptr [[P2:%.*]], ptr [[P3:%.*]]) { |
| 184 | +; CHECK-NEXT: [[P_ADDR:%.*]] = ptrtoaddr ptr [[P]] to i64 |
| 185 | +; CHECK-NEXT: [[P2_ADDR:%.*]] = ptrtoaddr ptr [[P2]] to i64 |
| 186 | +; CHECK-NEXT: [[SUB:%.*]] = sub i64 [[P2_ADDR]], [[P_ADDR]] |
| 187 | +; CHECK-NEXT: [[GEP:%.*]] = getelementptr i8, ptr [[P]], i64 [[SUB]] |
| 188 | +; CHECK-NEXT: [[CMP:%.*]] = icmp eq ptr [[P2]], [[P3]] |
| 189 | +; CHECK-NEXT: call void @use.i1(i1 [[CMP]]) |
| 190 | +; CHECK-NEXT: [[INT:%.*]] = ptrtoint ptr [[P2]] to i64 |
| 191 | +; CHECK-NEXT: call void @use.i64(i64 [[INT]]) |
| 192 | +; CHECK-NEXT: [[ADDR:%.*]] = ptrtoaddr ptr [[P2]] to i64 |
| 193 | +; CHECK-NEXT: call void @use.i64(i64 [[ADDR]]) |
| 194 | +; CHECK-NEXT: ret ptr [[GEP]] |
| 195 | +; |
| 196 | + %p.addr = ptrtoaddr ptr %p to i64 |
| 197 | + %p2.addr = ptrtoaddr ptr %p2 to i64 |
| 198 | + %sub = sub i64 %p2.addr, %p.addr |
| 199 | + %gep = getelementptr i8, ptr %p, i64 %sub |
| 200 | + %cmp = icmp eq ptr %gep, %p3 |
| 201 | + call void @use.i1(i1 %cmp) |
| 202 | + %int = ptrtoint ptr %gep to i64 |
| 203 | + call void @use.i64(i64 %int) |
| 204 | + %addr = ptrtoaddr ptr %gep to i64 |
| 205 | + call void @use.i64(i64 %addr) |
| 206 | + ret ptr %gep |
| 207 | +} |
| 208 | + |
| 209 | +; The use in ptrtoaddr should be replaced. The uses in ptrtoint and icmp should |
| 210 | +; not be replaced, as the non-address bits differ. The use in the return value |
| 211 | +; should not be replaced as the provenace differs. |
| 212 | +define ptr addrspace(1) @gep_sub_ptrtoaddr_different_obj_addrsize(ptr addrspace(1) %p, ptr addrspace(1) %p2, ptr addrspace(1) %p3) { |
| 213 | +; CHECK-LABEL: define ptr addrspace(1) @gep_sub_ptrtoaddr_different_obj_addrsize( |
| 214 | +; CHECK-SAME: ptr addrspace(1) [[P:%.*]], ptr addrspace(1) [[P2:%.*]], ptr addrspace(1) [[P3:%.*]]) { |
| 215 | +; CHECK-NEXT: [[P_ADDR:%.*]] = ptrtoaddr ptr addrspace(1) [[P]] to i32 |
| 216 | +; CHECK-NEXT: [[P2_ADDR:%.*]] = ptrtoaddr ptr addrspace(1) [[P2]] to i32 |
| 217 | +; CHECK-NEXT: [[SUB:%.*]] = sub i32 [[P2_ADDR]], [[P_ADDR]] |
| 218 | +; CHECK-NEXT: [[GEP:%.*]] = getelementptr i8, ptr addrspace(1) [[P]], i32 [[SUB]] |
| 219 | +; CHECK-NEXT: [[CMP:%.*]] = icmp eq ptr addrspace(1) [[GEP]], [[P3]] |
| 220 | +; CHECK-NEXT: call void @use.i1(i1 [[CMP]]) |
| 221 | +; CHECK-NEXT: [[TMP1:%.*]] = ptrtoint ptr addrspace(1) [[GEP]] to i64 |
| 222 | +; CHECK-NEXT: [[INT:%.*]] = trunc i64 [[TMP1]] to i32 |
| 223 | +; CHECK-NEXT: call void @use.i32(i32 [[INT]]) |
| 224 | +; CHECK-NEXT: [[ADDR:%.*]] = ptrtoaddr ptr addrspace(1) [[P2]] to i32 |
| 225 | +; CHECK-NEXT: call void @use.i32(i32 [[ADDR]]) |
| 226 | +; CHECK-NEXT: ret ptr addrspace(1) [[GEP]] |
| 227 | +; |
| 228 | + %p.addr = ptrtoaddr ptr addrspace(1) %p to i32 |
| 229 | + %p2.addr = ptrtoaddr ptr addrspace(1) %p2 to i32 |
| 230 | + %sub = sub i32 %p2.addr, %p.addr |
| 231 | + %gep = getelementptr i8, ptr addrspace(1) %p, i32 %sub |
| 232 | + %cmp = icmp eq ptr addrspace(1) %gep, %p3 |
| 233 | + call void @use.i1(i1 %cmp) |
| 234 | + %int = ptrtoint ptr addrspace(1) %gep to i32 |
| 235 | + call void @use.i32(i32 %int) |
| 236 | + %addr = ptrtoaddr ptr addrspace(1) %gep to i32 |
| 237 | + call void @use.i32(i32 %addr) |
| 238 | + ret ptr addrspace(1) %gep |
| 239 | +} |
0 commit comments