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:
parent
a0bb794c89
commit
85900aef27
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user