}
}
+ // 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();
}
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
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
+}
; 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
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
+}