[llvm] 8b59c26 - Extend or truncate __ptr32/__ptr64 pointers when dereferenced.

Amy Huang via llvm-commits llvm-commits at lists.llvm.org
Fri Jun 26 13:45:04 PDT 2020


Author: Amy Huang
Date: 2020-06-26T13:33:54-07:00
New Revision: 8b59c26bf347be5d96487c89849c0c1108bb3c42

URL: https://github.com/llvm/llvm-project/commit/8b59c26bf347be5d96487c89849c0c1108bb3c42
DIFF: https://github.com/llvm/llvm-project/commit/8b59c26bf347be5d96487c89849c0c1108bb3c42.diff

LOG: Extend or truncate __ptr32/__ptr64 pointers when dereferenced.

Summary:
A while ago I implemented the functionality to lower Microsoft __ptr32
and __ptr64 pointers, which are stored as 32-bit and 64-bit pointer
and are extended/truncated to the appropriate pointer size when
dereferenced.
This patch adds an addrspacecast to cast from the __ptr32/__ptr64
pointer to a default address space when dereferencing.

Bug: https://bugs.llvm.org/show_bug.cgi?id=42359

Reviewers: hans, arsenm, RKSimon

Subscribers: wdng, hiraditya, llvm-commits

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D81517

Added: 
    

Modified: 
    llvm/lib/Target/X86/X86ISelLowering.cpp
    llvm/test/CodeGen/X86/mixed-ptr-sizes-i686.ll
    llvm/test/CodeGen/X86/mixed-ptr-sizes.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index c3e89854bc48..54cbaccadc9e 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -43443,6 +43443,20 @@ static SDValue combineLoad(SDNode *N, SelectionDAG &DAG,
     }
   }
 
+  // Cast ptr32 and ptr64 pointers to the default address space before a load.
+  unsigned AddrSpace = Ld->getAddressSpace();
+  if (AddrSpace == X86AS::PTR64 || AddrSpace == X86AS::PTR32_SPTR ||
+      AddrSpace == X86AS::PTR32_UPTR) {
+    MVT PtrVT = TLI.getPointerTy(DAG.getDataLayout());
+    if (PtrVT != Ld->getBasePtr().getSimpleValueType()) {
+      SDValue Cast =
+          DAG.getAddrSpaceCast(dl, PtrVT, Ld->getBasePtr(), AddrSpace, 0);
+      return DAG.getLoad(RegVT, dl, Ld->getChain(), Cast, Ld->getPointerInfo(),
+                         Ld->getOriginalAlign(),
+                         Ld->getMemOperand()->getFlags());
+    }
+  }
+
   return SDValue();
 }
 
@@ -43870,6 +43884,20 @@ static SDValue combineStore(SDNode *N, SelectionDAG &DAG,
     return SDValue();
   }
 
+  // Cast ptr32 and ptr64 pointers to the default address space before a store.
+  unsigned AddrSpace = St->getAddressSpace();
+  if (AddrSpace == X86AS::PTR64 || AddrSpace == X86AS::PTR32_SPTR ||
+      AddrSpace == X86AS::PTR32_UPTR) {
+    MVT PtrVT = TLI.getPointerTy(DAG.getDataLayout());
+    if (PtrVT != St->getBasePtr().getSimpleValueType()) {
+      SDValue Cast =
+          DAG.getAddrSpaceCast(dl, PtrVT, St->getBasePtr(), AddrSpace, 0);
+      return DAG.getStore(St->getChain(), dl, StoredVal, Cast,
+                          St->getPointerInfo(), St->getOriginalAlign(),
+                          St->getMemOperand()->getFlags(), St->getAAInfo());
+    }
+  }
+
   // Turn load->store of MMX types into GPR load/stores.  This avoids clobbering
   // the FP state in cases where an emms may be missing.
   // A preferable solution to the general problem is to figure out the right

diff  --git a/llvm/test/CodeGen/X86/mixed-ptr-sizes-i686.ll b/llvm/test/CodeGen/X86/mixed-ptr-sizes-i686.ll
index 8b92376c966e..14a233ed7fd4 100644
--- a/llvm/test/CodeGen/X86/mixed-ptr-sizes-i686.ll
+++ b/llvm/test/CodeGen/X86/mixed-ptr-sizes-i686.ll
@@ -236,3 +236,111 @@ entry:
   tail call void @use_foo(%struct.Foo* %f)
   ret void
 }
+
+define i32 @test_load_sptr32(i32 addrspace(270)* %i) {
+; CHECK-LABEL: test_load_sptr32:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; CHECK-NEXT:    movl (%eax), %eax
+; CHECK-NEXT:    retl
+; CHECK-O0-LABEL: test_load_sptr32:
+; CHECK-O0:       # %bb.0: # %entry
+; CHECK-O0-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; CHECK-O0-NEXT:    movl (%eax), %eax
+; CHECK-O0-NEXT:    retl
+entry:
+  %0 = load i32, i32 addrspace(270)* %i, align 4
+  ret i32 %0
+}
+
+define i32 @test_load_uptr32(i32 addrspace(271)* %i) {
+; CHECK-LABEL: test_load_uptr32:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; CHECK-NEXT:    movl (%eax), %eax
+; CHECK-NEXT:    retl
+; CHECK-O0-LABEL: test_load_uptr32:
+; CHECK-O0:       # %bb.0: # %entry
+; CHECK-O0-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; CHECK-O0-NEXT:    movl (%eax), %eax
+; CHECK-O0-NEXT:    retl
+entry:
+  %0 = load i32, i32 addrspace(271)* %i, align 4
+  ret i32 %0
+}
+
+define i32 @test_load_ptr64(i32 addrspace(272)* %i) {
+; CHECK-LABEL: test_load_ptr64:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; CHECK-NEXT:    movl (%eax), %eax
+; CHECK-NEXT:    retl
+; CHECK-O0-LABEL: test_load_ptr64:
+; CHECK-O0:       # %bb.0: # %entry
+; CHECK-O0-NEXT:    pushl %eax
+; CHECK-O0-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; CHECK-O0-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; CHECK-O0-NEXT:    movl (%ecx), %ecx
+; CHECK-O0-NEXT:    movl %eax, (%esp)
+; CHECK-O0-NEXT:    movl %ecx, %eax
+; CHECK-O0-NEXT:    popl %ecx
+; CHECK-O0-NEXT:    retl
+entry:
+  %0 = load i32, i32 addrspace(272)* %i, align 8
+  ret i32 %0
+}
+
+define void @test_store_sptr32(i32 addrspace(270)* %s, i32 %i) {
+; CHECK-LABEL: test_store_sptr32:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; CHECK-NEXT:    movl %eax, (%ecx)
+; CHECK-NEXT:    retl
+; CHECK-O0-LABEL: test_store_sptr32:
+; CHECK-O0:       # %bb.0: # %entry
+; CHECK-O0-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; CHECK-O0-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; CHECK-O0-NEXT:    movl %eax, (%ecx)
+; CHECK-O0-NEXT:    retl
+entry:
+  store i32 %i, i32 addrspace(270)* %s, align 4
+  ret void
+}
+
+define void @test_store_uptr32(i32 addrspace(271)* %s, i32 %i) {
+; CHECK-LABEL: test_store_uptr32:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; CHECK-NEXT:    movl %eax, (%ecx)
+; CHECK-NEXT:    retl
+; CHECK-O0-LABEL: test_store_uptr32:
+; CHECK-O0:       # %bb.0: # %entry
+; CHECK-O0-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; CHECK-O0-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; CHECK-O0-NEXT:    movl %eax, (%ecx)
+; CHECK-O0-NEXT:    retl
+entry:
+  store i32 %i, i32 addrspace(271)* %s, align 4
+  ret void
+}
+
+define void @test_store_ptr64(i32 addrspace(272)* %s, i32 %i) {
+; CHECK-LABEL: test_store_ptr64:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; CHECK-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; CHECK-NEXT:    movl %eax, (%ecx)
+; CHECK-NEXT:    retl
+; CHECK-O0-LABEL: test_store_ptr64:
+; CHECK-O0:       # %bb.0: # %entry
+; CHECK-O0-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; CHECK-O0-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; CHECK-O0-NEXT:    movl {{[0-9]+}}(%esp), %edx
+; CHECK-O0-NEXT:    movl %edx, (%ecx)
+; CHECK-O0-NEXT:    retl
+entry:
+  store i32 %i, i32 addrspace(272)* %s, align 8
+  ret void
+}

diff  --git a/llvm/test/CodeGen/X86/mixed-ptr-sizes.ll b/llvm/test/CodeGen/X86/mixed-ptr-sizes.ll
index 7a470fb21317..ac55e1a1fc65 100644
--- a/llvm/test/CodeGen/X86/mixed-ptr-sizes.ll
+++ b/llvm/test/CodeGen/X86/mixed-ptr-sizes.ll
@@ -125,6 +125,23 @@ entry:
 
 ; Test that null can be passed as a 32-bit pointer.
 define dso_local void @test_null_arg(%struct.Foo* %f) {
+; CHECK-LABEL: test_null_arg:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    subq $40, %rsp
+; CHECK:         xorl %edx, %edx
+; CHECK-NEXT:    callq test_noop1
+; CHECK-NEXT:    nop
+; CHECK-NEXT:    addq $40, %rsp
+; CHECK-NEXT:    retq
+;
+; CHECK-O0-LABEL: test_null_arg:
+; CHECK-O0:       # %bb.0: # %entry
+; CHECK-O0-NEXT:    subq $40, %rsp
+; CHECK-O0:         xorl %edx, %edx
+; CHECK-O0-NEXT:    callq test_noop1
+; CHECK-O0-NEXT:    nop
+; CHECK-O0-NEXT:    addq $40, %rsp
+; CHECK-O0-NEXT:    retq
 entry:
   call void @test_noop1(%struct.Foo* %f, i32 addrspace(270)* null)
   ret void
@@ -170,3 +187,97 @@ entry:
   tail call void @use_foo(%struct.Foo* %f)
   ret void
 }
+
+define i32 @test_load_sptr32(i32 addrspace(270)* %i) {
+; CHECK-LABEL: test_load_sptr32:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    movslq  %ecx, %rax
+; CHECK-NEXT:    movl (%rax), %eax
+; CHECK-NEXT:    retq
+; CHECK-O0-LABEL: test_load_sptr32:
+; CHECK-O0:       # %bb.0: # %entry
+; CHECK-O0-NEXT:    movslq  %ecx, %rax
+; CHECK-O0-NEXT:    movl (%rax), %eax
+; CHECK-O0-NEXT:    retq
+entry:
+  %0 = load i32, i32 addrspace(270)* %i, align 4
+  ret i32 %0
+}
+
+define i32 @test_load_uptr32(i32 addrspace(271)* %i) {
+; CHECK-LABEL: test_load_uptr32:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    movl %ecx, %eax
+; CHECK-NEXT:    movl (%rax), %eax
+; CHECK-NEXT:    retq
+; CHECK-O0-LABEL: test_load_uptr32:
+; CHECK-O0:       # %bb.0: # %entry
+; CHECK-O0-NEXT:    movl %ecx, %eax
+; CHECK-O0-NEXT:    # kill: def $rax killed $eax
+; CHECK-O0-NEXT:    movl (%rax), %eax
+; CHECK-O0-NEXT:    retq
+entry:
+  %0 = load i32, i32 addrspace(271)* %i, align 4
+  ret i32 %0
+}
+
+define i32 @test_load_ptr64(i32 addrspace(272)* %i) {
+; CHECK-LABEL: test_load_ptr64:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    movl (%rcx), %eax
+; CHECK-NEXT:    retq
+; CHECK-O0-LABEL: test_load_ptr64:
+; CHECK-O0:       # %bb.0: # %entry
+; CHECK-O0-NEXT:    movl (%rcx), %eax
+; CHECK-O0-NEXT:    retq
+entry:
+  %0 = load i32, i32 addrspace(272)* %i, align 8
+  ret i32 %0
+}
+
+define void @test_store_sptr32(i32 addrspace(270)* %s, i32 %i) {
+; CHECK-LABEL: test_store_sptr32:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    movslq %ecx, %rax
+; CHECK-NEXT:    movl %edx, (%rax)
+; CHECK-NEXT:    retq
+; CHECK-O0-LABEL: test_store_sptr32:
+; CHECK-O0:       # %bb.0: # %entry
+; CHECK-O0-NEXT:    movslq %ecx, %rax
+; CHECK-O0-NEXT:    movl %edx, (%rax)
+; CHECK-O0-NEXT:    retq
+entry:
+  store i32 %i, i32 addrspace(270)* %s, align 4
+  ret void
+}
+
+define void @test_store_uptr32(i32 addrspace(271)* %s, i32 %i) {
+; CHECK-LABEL: test_store_uptr32:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    movl %ecx, %eax
+; CHECK-NEXT:    movl %edx, (%rax)
+; CHECK-NEXT:    retq
+; CHECK-O0-LABEL: test_store_uptr32:
+; CHECK-O0:       # %bb.0: # %entry
+; CHECK-O0-NEXT:    movl %ecx, %eax
+; CHECK-O0-NEXT:    # kill: def $rax killed $eax
+; CHECK-O0-NEXT:    movl %edx, (%rax)
+; CHECK-O0-NEXT:    retq
+entry:
+  store i32 %i, i32 addrspace(271)* %s, align 4
+  ret void
+}
+
+define void @test_store_ptr64(i32 addrspace(272)* %s, i32 %i) {
+; CHECK-LABEL: test_store_ptr64:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    movl %edx, (%rcx)
+; CHECK-NEXT:    retq
+; CHECK-O0-LABEL: test_store_ptr64:
+; CHECK-O0:       # %bb.0: # %entry
+; CHECK-O0-NEXT:    movl %edx, (%rcx)
+; CHECK-O0-NEXT:    retq
+entry:
+  store i32 %i, i32 addrspace(272)* %s, align 8
+  ret void
+}


        


More information about the llvm-commits mailing list