1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2025-01-31 12:41:49 +01:00

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
This commit is contained in:
Amy Huang 2020-05-11 14:13:37 -07:00
parent a0bb794c89
commit 85900aef27
3 changed files with 247 additions and 0 deletions

View File

@ -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

View File

@ -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
}

View File

@ -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
}