[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