259 lines
		
	
	
		
			7.3 KiB
		
	
	
	
		
			LLVM
		
	
	
	
			
		
		
	
	
			259 lines
		
	
	
		
			7.3 KiB
		
	
	
	
		
			LLVM
		
	
	
	
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
 | 
						|
; RUN: llc < %s | FileCheck %s --check-prefixes=ALL,CHECK
 | 
						|
; RUN: llc -O0 < %s | FileCheck %s --check-prefixes=ALL,CHECK-O0
 | 
						|
 | 
						|
; Source to regenerate:
 | 
						|
; struct Foo {
 | 
						|
;   int * __ptr32 p32;
 | 
						|
;   int * __ptr64 p64;
 | 
						|
;   __attribute__((address_space(9))) int *p_other;
 | 
						|
; };
 | 
						|
; void use_foo(Foo *f);
 | 
						|
; void test_sign_ext(Foo *f, int * __ptr32 __sptr i) {
 | 
						|
;   f->p64 = i;
 | 
						|
;   use_foo(f);
 | 
						|
; }
 | 
						|
; void test_zero_ext(Foo *f, int * __ptr32 __uptr i) {
 | 
						|
;   f->p64 = i;
 | 
						|
;   use_foo(f);
 | 
						|
; }
 | 
						|
; void test_trunc(Foo *f, int * __ptr64 i) {
 | 
						|
;   f->p32 = i;
 | 
						|
;   use_foo(f);
 | 
						|
; }
 | 
						|
; void test_noop1(Foo *f, int * __ptr32 i) {
 | 
						|
;   f->p32 = i;
 | 
						|
;   use_foo(f);
 | 
						|
; }
 | 
						|
; void test_noop2(Foo *f, int * __ptr64 i) {
 | 
						|
;   f->p64 = i;
 | 
						|
;   use_foo(f);
 | 
						|
; }
 | 
						|
; void test_null_arg(Foo *f, int * __ptr32 i) {
 | 
						|
;   test_noop1(f, 0);
 | 
						|
; }
 | 
						|
; void test_unrecognized(Foo *f, __attribute__((address_space(14))) int *i) {
 | 
						|
;   f->p32 = (int * __ptr32)i;
 | 
						|
;   use_foo(f);
 | 
						|
; }
 | 
						|
;
 | 
						|
; $ clang -cc1 -triple x86_64-windows-msvc -fms-extensions -O2 -S t.cpp
 | 
						|
 | 
						|
target datalayout = "e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
 | 
						|
target triple = "x86_64-unknown-windows-msvc"
 | 
						|
 | 
						|
%struct.Foo = type { ptr addrspace(270), ptr, ptr addrspace(9) }
 | 
						|
declare dso_local void @use_foo(ptr)
 | 
						|
 | 
						|
define dso_local void @test_sign_ext(ptr %f, ptr addrspace(270) %i) {
 | 
						|
; ALL-LABEL: test_sign_ext:
 | 
						|
; ALL:       # %bb.0: # %entry
 | 
						|
; ALL-NEXT:    movslq %edx, %rax
 | 
						|
; ALL-NEXT:    movq %rax, 8(%rcx)
 | 
						|
; ALL-NEXT:    jmp use_foo # TAILCALL
 | 
						|
entry:
 | 
						|
  %0 = addrspacecast ptr addrspace(270) %i to ptr
 | 
						|
  %p64 = getelementptr inbounds %struct.Foo, ptr %f, i64 0, i32 1
 | 
						|
  store ptr %0, ptr %p64, align 8
 | 
						|
  tail call void @use_foo(ptr %f)
 | 
						|
  ret void
 | 
						|
}
 | 
						|
 | 
						|
define dso_local void @test_zero_ext(ptr %f, ptr addrspace(271) %i) {
 | 
						|
; CHECK-LABEL: test_zero_ext:
 | 
						|
; CHECK:       # %bb.0: # %entry
 | 
						|
; CHECK-NEXT:    movl %edx, %eax
 | 
						|
; CHECK-NEXT:    movq %rax, 8(%rcx)
 | 
						|
; CHECK-NEXT:    jmp use_foo # TAILCALL
 | 
						|
;
 | 
						|
; CHECK-O0-LABEL: test_zero_ext:
 | 
						|
; CHECK-O0:       # %bb.0: # %entry
 | 
						|
; CHECK-O0-NEXT:    movl %edx, %eax
 | 
						|
; CHECK-O0-NEXT:    # kill: def $rax killed $eax
 | 
						|
; CHECK-O0-NEXT:    movq %rax, 8(%rcx)
 | 
						|
; CHECK-O0-NEXT:    jmp use_foo # TAILCALL
 | 
						|
entry:
 | 
						|
  %0 = addrspacecast ptr addrspace(271) %i to ptr
 | 
						|
  %p64 = getelementptr inbounds %struct.Foo, ptr %f, i64 0, i32 1
 | 
						|
  store ptr %0, ptr %p64, align 8
 | 
						|
  tail call void @use_foo(ptr %f)
 | 
						|
  ret void
 | 
						|
}
 | 
						|
 | 
						|
define dso_local void @test_trunc(ptr %f, ptr %i) {
 | 
						|
; CHECK-LABEL: test_trunc:
 | 
						|
; CHECK:       # %bb.0: # %entry
 | 
						|
; CHECK-NEXT:    movl %edx, (%rcx)
 | 
						|
; CHECK-NEXT:    jmp use_foo # TAILCALL
 | 
						|
;
 | 
						|
; CHECK-O0-LABEL: test_trunc:
 | 
						|
; CHECK-O0:       # %bb.0: # %entry
 | 
						|
; CHECK-O0-NEXT:    movl %edx, %eax
 | 
						|
; CHECK-O0-NEXT:    movl %eax, (%rcx)
 | 
						|
; CHECK-O0-NEXT:    jmp use_foo # TAILCALL
 | 
						|
entry:
 | 
						|
  %0 = addrspacecast ptr %i to ptr addrspace(270)
 | 
						|
  store ptr addrspace(270) %0, ptr %f, align 8
 | 
						|
  tail call void @use_foo(ptr %f)
 | 
						|
  ret void
 | 
						|
}
 | 
						|
 | 
						|
define dso_local void @test_noop1(ptr %f, ptr addrspace(270) %i) {
 | 
						|
; ALL-LABEL: test_noop1:
 | 
						|
; ALL:       # %bb.0: # %entry
 | 
						|
; ALL-NEXT:    movl %edx, (%rcx)
 | 
						|
; ALL-NEXT:    jmp use_foo # TAILCALL
 | 
						|
entry:
 | 
						|
  store ptr addrspace(270) %i, ptr %f, align 8
 | 
						|
  tail call void @use_foo(ptr %f)
 | 
						|
  ret void
 | 
						|
}
 | 
						|
 | 
						|
define dso_local void @test_noop2(ptr %f, ptr %i) {
 | 
						|
; ALL-LABEL: test_noop2:
 | 
						|
; ALL:       # %bb.0: # %entry
 | 
						|
; ALL-NEXT:    movq %rdx, 8(%rcx)
 | 
						|
; ALL-NEXT:    jmp use_foo # TAILCALL
 | 
						|
entry:
 | 
						|
  %p64 = getelementptr inbounds %struct.Foo, ptr %f, i64 0, i32 1
 | 
						|
  store ptr %i, ptr %p64, align 8
 | 
						|
  tail call void @use_foo(ptr %f)
 | 
						|
  ret void
 | 
						|
}
 | 
						|
 | 
						|
; Test that null can be passed as a 32-bit pointer.
 | 
						|
define dso_local void @test_null_arg(ptr %f) {
 | 
						|
; ALL-LABEL: test_null_arg:
 | 
						|
; ALL:       # %bb.0: # %entry
 | 
						|
; ALL-NEXT:    subq $40, %rsp
 | 
						|
; ALL-NEXT:    .seh_stackalloc 40
 | 
						|
; ALL-NEXT:    .seh_endprologue
 | 
						|
; ALL-NEXT:    xorl %edx, %edx
 | 
						|
; ALL-NEXT:    callq test_noop1
 | 
						|
; ALL-NEXT:    nop
 | 
						|
; ALL-NEXT:    addq $40, %rsp
 | 
						|
; ALL-NEXT:    retq
 | 
						|
; ALL-NEXT:    .seh_endproc
 | 
						|
entry:
 | 
						|
  call void @test_noop1(ptr %f, ptr addrspace(270) null)
 | 
						|
  ret void
 | 
						|
}
 | 
						|
 | 
						|
; Test casts between unrecognized address spaces.
 | 
						|
define void @test_unrecognized(ptr %f, ptr addrspace(14) %i) {
 | 
						|
; CHECK-LABEL: test_unrecognized:
 | 
						|
; CHECK:       # %bb.0: # %entry
 | 
						|
; CHECK-NEXT:    movl %edx, (%rcx)
 | 
						|
; CHECK-NEXT:    jmp use_foo # TAILCALL
 | 
						|
;
 | 
						|
; CHECK-O0-LABEL: test_unrecognized:
 | 
						|
; CHECK-O0:       # %bb.0: # %entry
 | 
						|
; CHECK-O0-NEXT:    movl %edx, %eax
 | 
						|
; CHECK-O0-NEXT:    movl %eax, (%rcx)
 | 
						|
; CHECK-O0-NEXT:    jmp use_foo # TAILCALL
 | 
						|
entry:
 | 
						|
  %0 = addrspacecast ptr addrspace(14) %i to ptr addrspace(270)
 | 
						|
  store ptr addrspace(270) %0, ptr %f, align 8
 | 
						|
  tail call void @use_foo(ptr %f)
 | 
						|
  ret void
 | 
						|
}
 | 
						|
 | 
						|
define void @test_unrecognized2(ptr %f, ptr addrspace(271) %i) {
 | 
						|
; CHECK-LABEL: test_unrecognized2:
 | 
						|
; CHECK:       # %bb.0: # %entry
 | 
						|
; CHECK-NEXT:    movl %edx, %eax
 | 
						|
; CHECK-NEXT:    movq %rax, 16(%rcx)
 | 
						|
; CHECK-NEXT:    jmp use_foo # TAILCALL
 | 
						|
;
 | 
						|
; CHECK-O0-LABEL: test_unrecognized2:
 | 
						|
; CHECK-O0:       # %bb.0: # %entry
 | 
						|
; CHECK-O0-NEXT:    movl %edx, %eax
 | 
						|
; CHECK-O0-NEXT:    # kill: def $rax killed $eax
 | 
						|
; CHECK-O0-NEXT:    movq %rax, 16(%rcx)
 | 
						|
; CHECK-O0-NEXT:    jmp use_foo # TAILCALL
 | 
						|
entry:
 | 
						|
  %0 = addrspacecast ptr addrspace(271) %i to ptr addrspace(9)
 | 
						|
  %p32 = getelementptr inbounds %struct.Foo, ptr %f, i64 0, i32 2
 | 
						|
  store ptr addrspace(9) %0, ptr %p32, align 8
 | 
						|
  tail call void @use_foo(ptr %f)
 | 
						|
  ret void
 | 
						|
}
 | 
						|
 | 
						|
define i32 @test_load_sptr32(ptr addrspace(270) %i) {
 | 
						|
; ALL-LABEL: test_load_sptr32:
 | 
						|
; ALL:       # %bb.0: # %entry
 | 
						|
; ALL-NEXT:    movslq %ecx, %rax
 | 
						|
; ALL-NEXT:    movl (%rax), %eax
 | 
						|
; ALL-NEXT:    retq
 | 
						|
entry:
 | 
						|
  %0 = load i32, ptr addrspace(270) %i, align 4
 | 
						|
  ret i32 %0
 | 
						|
}
 | 
						|
 | 
						|
define i32 @test_load_uptr32(ptr 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, ptr addrspace(271) %i, align 4
 | 
						|
  ret i32 %0
 | 
						|
}
 | 
						|
 | 
						|
define i32 @test_load_ptr64(ptr addrspace(272) %i) {
 | 
						|
; ALL-LABEL: test_load_ptr64:
 | 
						|
; ALL:       # %bb.0: # %entry
 | 
						|
; ALL-NEXT:    movl (%rcx), %eax
 | 
						|
; ALL-NEXT:    retq
 | 
						|
entry:
 | 
						|
  %0 = load i32, ptr addrspace(272) %i, align 8
 | 
						|
  ret i32 %0
 | 
						|
}
 | 
						|
 | 
						|
define void @test_store_sptr32(ptr addrspace(270) %s, i32 %i) {
 | 
						|
; ALL-LABEL: test_store_sptr32:
 | 
						|
; ALL:       # %bb.0: # %entry
 | 
						|
; ALL-NEXT:    movslq %ecx, %rax
 | 
						|
; ALL-NEXT:    movl %edx, (%rax)
 | 
						|
; ALL-NEXT:    retq
 | 
						|
entry:
 | 
						|
  store i32 %i, ptr addrspace(270) %s, align 4
 | 
						|
  ret void
 | 
						|
}
 | 
						|
 | 
						|
define void @test_store_uptr32(ptr 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, ptr addrspace(271) %s, align 4
 | 
						|
  ret void
 | 
						|
}
 | 
						|
 | 
						|
define void @test_store_ptr64(ptr addrspace(272) %s, i32 %i) {
 | 
						|
; ALL-LABEL: test_store_ptr64:
 | 
						|
; ALL:       # %bb.0: # %entry
 | 
						|
; ALL-NEXT:    movl %edx, (%rcx)
 | 
						|
; ALL-NEXT:    retq
 | 
						|
entry:
 | 
						|
  store i32 %i, ptr addrspace(272) %s, align 8
 | 
						|
  ret void
 | 
						|
}
 |