@@ -316,3 +316,85 @@ define ptr @gep_gep_inv_ptrtoaddr(ptr %p) {
316316 %gep2 = getelementptr i8 , ptr %gep1 , i64 %p.addr.inv
317317 ret ptr %gep2
318318}
319+
320+ define i1 @icmp_ptrtoaddr_0 () {
321+ ; CHECK-LABEL: define i1 @icmp_ptrtoaddr_0() {
322+ ; CHECK-NEXT: ret i1 true
323+ ;
324+ %cmp = icmp ne i64 ptr toaddr (ptr @g to i64 ), 0
325+ ret i1 %cmp
326+ }
327+
328+ ; This fails to fold because we currently don't assume that globals are located
329+ ; at a non-null address for non-default address spaces.
330+ define i1 @icmp_ptrtoaddr_0_addrsize () {
331+ ; CHECK-LABEL: define i1 @icmp_ptrtoaddr_0_addrsize() {
332+ ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 ptrtoaddr (ptr addrspace(1) @g.as1 to i32), 0
333+ ; CHECK-NEXT: ret i1 [[CMP]]
334+ ;
335+ %cmp = icmp ne i32 ptr toaddr (ptr addrspace (1 ) @g.as1 to i32 ), 0
336+ ret i1 %cmp
337+ }
338+
339+ define i1 @icmp_ptrtoint_0_addrsize () {
340+ ; CHECK-LABEL: define i1 @icmp_ptrtoint_0_addrsize() {
341+ ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i64 ptrtoint (ptr addrspace(1) @g.as1 to i64), 0
342+ ; CHECK-NEXT: ret i1 [[CMP]]
343+ ;
344+ %cmp = icmp ne i64 ptrtoint (ptr addrspace (1 ) @g.as1 to i64 ), 0
345+ ret i1 %cmp
346+ }
347+
348+ define i1 @icmp_ptrtoaddr_ptrtoaddr () {
349+ ; CHECK-LABEL: define i1 @icmp_ptrtoaddr_ptrtoaddr() {
350+ ; CHECK-NEXT: ret i1 true
351+ ;
352+ %cmp = icmp ne i64 ptr toaddr (ptr @g to i64 ), ptr toaddr (ptr @g2 to i64 )
353+ ret i1 %cmp
354+ }
355+
356+ define i1 @icmp_ptrtoaddr_ptrtoaddr_addrsize () {
357+ ; CHECK-LABEL: define i1 @icmp_ptrtoaddr_ptrtoaddr_addrsize() {
358+ ; CHECK-NEXT: ret i1 true
359+ ;
360+ %cmp = icmp ne i32 ptr toaddr (ptr addrspace (1 ) @g.as1 to i32 ), ptr toaddr (ptr addrspace (1 ) @g2.as1 to i32 )
361+ ret i1 %cmp
362+ }
363+
364+ ; This could still be folded because the address being non-equal also implies
365+ ; that all pointer bits together are non-equal.
366+ define i1 @icmp_ptrtoint_ptrtoint_addrsize () {
367+ ; CHECK-LABEL: define i1 @icmp_ptrtoint_ptrtoint_addrsize() {
368+ ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i64 ptrtoint (ptr addrspace(1) @g.as1 to i64), ptrtoint (ptr addrspace(1) @g2.as1 to i64)
369+ ; CHECK-NEXT: ret i1 [[CMP]]
370+ ;
371+ %cmp = icmp ne i64 ptrtoint (ptr addrspace (1 ) @g.as1 to i64 ), ptrtoint (ptr addrspace (1 ) @g2.as1 to i64 )
372+ ret i1 %cmp
373+ }
374+
375+ define i1 @icmp_relational_ptrtoaddr_ptrtoaddr () {
376+ ; CHECK-LABEL: define i1 @icmp_relational_ptrtoaddr_ptrtoaddr() {
377+ ; CHECK-NEXT: ret i1 true
378+ ;
379+ %cmp = icmp ult i64 ptr toaddr (ptr @g to i64 ), ptr toaddr (ptr getelementptr inbounds (i8 , ptr @g , i64 1 ) to i64 )
380+ ret i1 %cmp
381+ }
382+
383+ define i1 @icmp_relational_ptrtoaddr_ptrtoaddr_addrsize () {
384+ ; CHECK-LABEL: define i1 @icmp_relational_ptrtoaddr_ptrtoaddr_addrsize() {
385+ ; CHECK-NEXT: ret i1 true
386+ ;
387+ %cmp = icmp ult i32 ptr toaddr (ptr addrspace (1 ) @g.as1 to i32 ), ptr toaddr (ptr addrspace (1 ) getelementptr inbounds (i8 , ptr addrspace (1 ) @g.as1 , i32 1 ) to i32 )
388+ ret i1 %cmp
389+ }
390+
391+ ; This could still be folded because we know that the non-address bits must be
392+ ; the same, as GEP does not modify them.
393+ define i1 @icmp_relational_ptrtoint_ptrtoint_addrsize () {
394+ ; CHECK-LABEL: define i1 @icmp_relational_ptrtoint_ptrtoint_addrsize() {
395+ ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i64 ptrtoint (ptr addrspace(1) @g.as1 to i64), ptrtoint (ptr addrspace(1) getelementptr inbounds (i8, ptr addrspace(1) @g.as1, i64 1) to i64)
396+ ; CHECK-NEXT: ret i1 [[CMP]]
397+ ;
398+ %cmp = icmp ult i64 ptrtoint (ptr addrspace (1 ) @g.as1 to i64 ), ptrtoint (ptr addrspace (1 ) getelementptr inbounds (i8 , ptr addrspace (1 ) @g.as1 , i64 1 ) to i64 )
399+ ret i1 %cmp
400+ }
0 commit comments