diff --git a/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp b/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp --- a/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp +++ b/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp @@ -2456,14 +2456,14 @@ Parent->getOpcode() != X86ISD::ENQCMDS && // Fixme Parent->getOpcode() != X86ISD::EH_SJLJ_SETJMP && // setjmp Parent->getOpcode() != X86ISD::EH_SJLJ_LONGJMP) { // longjmp + unsigned AddrSpace = cast(Parent)->getPointerInfo().getAddrSpace(); - // AddrSpace 256 -> GS, 257 -> FS, 258 -> SS. - if (AddrSpace == 256) + if (AddrSpace == X86AS::GS) AM.Segment = CurDAG->getRegister(X86::GS, MVT::i16); - if (AddrSpace == 257) + if (AddrSpace == X86AS::FS) AM.Segment = CurDAG->getRegister(X86::FS, MVT::i16); - if (AddrSpace == 258) + if (AddrSpace == X86AS::SS) AM.Segment = CurDAG->getRegister(X86::SS, MVT::i16); } diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -43044,6 +43044,20 @@ } } + // 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(); } @@ -43471,6 +43485,20 @@ 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.ll b/llvm/test/CodeGen/X86/mixed-ptr-sizes.ll --- a/llvm/test/CodeGen/X86/mixed-ptr-sizes.ll +++ b/llvm/test/CodeGen/X86/mixed-ptr-sizes.ll @@ -1,4 +1,5 @@ -; RUN: llc < %s | FileCheck --check-prefixes=CHECK %s +; RUN: llc -mtriple=x86_64-windows-msvc < %s | FileCheck --check-prefixes=CHECK,X64 %s +; RUN: llc -mtriple=i686-windows-msvc < %s | FileCheck --check-prefixes=X86 %s ; RUN: llc -O0 < %s | FileCheck --check-prefixes=CHECK %s ; Source to regenerate: @@ -126,3 +127,58 @@ tail call void @use_foo(%struct.Foo* %f) ret void } + +; X64-LABEL: test_load_sptr32: +; X64: movslq %ecx, %rax +; X64: movl (%rax), %eax +define i32 @test_load_sptr32(i32 addrspace(270)* %i) { +entry: + %0 = load i32, i32 addrspace(270)* %i, align 4 + ret i32 %0 +} + +; X64-LABEL: test_load_uptr32: +; X64: movl %ecx, %eax +; X64: movl (%rax), %eax +define i32 @test_load_uptr32(i32 addrspace(271)* %i) { +entry: + %0 = load i32, i32 addrspace(271)* %i, align 4 + ret i32 %0 +} + +; X86-LABEL: _test_load_ptr64: +; X86: movl 4(%esp), %eax +; X86: movl (%eax), %eax +define i32 @test_load_ptr64(i32 addrspace(272)* %i) { +entry: + %0 = load i32, i32 addrspace(272)* %i, align 8 + ret i32 %0 +} + +; X64-LABEL: test_store_sptr32: +; X64: movslq %ecx, %rax +; X64: movl %edx, (%rax) +define void @test_store_sptr32(i32 addrspace(270)* %s, i32 %i) { +entry: + store i32 %i, i32 addrspace(270)* %s, align 4 + ret void +} + +; X64-LABEL: test_store_uptr32: +; X64: movl %ecx, %eax +; X64: movl %edx, (%rax) +define void @test_store_uptr32(i32 addrspace(271)* %s, i32 %i) { +entry: + store i32 %i, i32 addrspace(271)* %s, align 4 + ret void +} + +; X86-LABEL: _test_store_ptr64: +; X86: movl 12(%esp), %eax +; X86: movl 4(%esp), %ecx +; X86: movl %eax, (%ecx) +define void @test_store_ptr64(i32 addrspace(272)* %s, i32 %i) { +entry: + store i32 %i, i32 addrspace(272)* %s, align 8 + ret void +}