1; RUN: llc < %s | FileCheck --check-prefixes=CHECK %s 2; RUN: llc -O0 < %s | FileCheck --check-prefixes=CHECK %s 3 4; Source to regenerate: 5; struct Foo { 6; int * __ptr32 p32; 7; int * __ptr64 p64; 8; __attribute__((address_space(9))) int *p_other; 9; }; 10; void use_foo(Foo *f); 11; void test_sign_ext(Foo *f, int * __ptr32 __sptr i) { 12; f->p64 = i; 13; use_foo(f); 14; } 15; void test_zero_ext(Foo *f, int * __ptr32 __uptr i) { 16; f->p64 = i; 17; use_foo(f); 18; } 19; void test_trunc(Foo *f, int * __ptr64 i) { 20; f->p32 = i; 21; use_foo(f); 22; } 23; void test_noop1(Foo *f, int * __ptr32 i) { 24; f->p32 = i; 25; use_foo(f); 26; } 27; void test_noop2(Foo *f, int * __ptr64 i) { 28; f->p64 = i; 29; use_foo(f); 30; } 31; void test_null_arg(Foo *f, int * __ptr32 i) { 32; test_noop1(f, 0); 33; } 34; void test_unrecognized(Foo *f, __attribute__((address_space(14))) int *i) { 35; f->p32 = (int * __ptr32)i; 36; use_foo(f); 37; } 38; 39; $ clang -cc1 -triple x86_64-windows-msvc -fms-extensions -O2 -S t.cpp 40 41target datalayout = "e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" 42target triple = "x86_64-unknown-windows-msvc" 43 44%struct.Foo = type { i32 addrspace(270)*, i32*, i32 addrspace(9)* } 45declare dso_local void @use_foo(%struct.Foo*) 46 47define dso_local void @test_sign_ext(%struct.Foo* %f, i32 addrspace(270)* %i) { 48; CHECK-LABEL: test_sign_ext 49; CHECK: movslq %edx, %rax 50entry: 51 %0 = addrspacecast i32 addrspace(270)* %i to i32* 52 %p64 = getelementptr inbounds %struct.Foo, %struct.Foo* %f, i64 0, i32 1 53 store i32* %0, i32** %p64, align 8 54 tail call void @use_foo(%struct.Foo* %f) 55 ret void 56} 57 58define dso_local void @test_zero_ext(%struct.Foo* %f, i32 addrspace(271)* %i) { 59; CHECK-LABEL: test_zero_ext 60; CHECK: movl %edx, %eax 61entry: 62 %0 = addrspacecast i32 addrspace(271)* %i to i32* 63 %p64 = getelementptr inbounds %struct.Foo, %struct.Foo* %f, i64 0, i32 1 64 store i32* %0, i32** %p64, align 8 65 tail call void @use_foo(%struct.Foo* %f) 66 ret void 67} 68 69define dso_local void @test_trunc(%struct.Foo* %f, i32* %i) { 70; CHECK-LABEL: test_trunc 71; CHECK: movl %edx, (%rcx) 72entry: 73 %0 = addrspacecast i32* %i to i32 addrspace(270)* 74 %p32 = getelementptr inbounds %struct.Foo, %struct.Foo* %f, i64 0, i32 0 75 store i32 addrspace(270)* %0, i32 addrspace(270)** %p32, align 8 76 tail call void @use_foo(%struct.Foo* %f) 77 ret void 78} 79 80define dso_local void @test_noop1(%struct.Foo* %f, i32 addrspace(270)* %i) { 81; CHECK-LABEL: test_noop1 82; CHECK: movl %edx, (%rcx) 83entry: 84 %p32 = getelementptr inbounds %struct.Foo, %struct.Foo* %f, i64 0, i32 0 85 store i32 addrspace(270)* %i, i32 addrspace(270)** %p32, align 8 86 tail call void @use_foo(%struct.Foo* %f) 87 ret void 88} 89 90define dso_local void @test_noop2(%struct.Foo* %f, i32* %i) { 91; CHECK-LABEL: test_noop2 92; CHECK: movq %rdx, 8(%rcx) 93entry: 94 %p64 = getelementptr inbounds %struct.Foo, %struct.Foo* %f, i64 0, i32 1 95 store i32* %i, i32** %p64, align 8 96 tail call void @use_foo(%struct.Foo* %f) 97 ret void 98} 99 100; Test that null can be passed as a 32-bit pointer. 101define dso_local void @test_null_arg(%struct.Foo* %f) { 102entry: 103 call void @test_noop1(%struct.Foo* %f, i32 addrspace(270)* null) 104 ret void 105} 106 107; Test casts between unrecognized address spaces. 108define void @test_unrecognized(%struct.Foo* %f, i32 addrspace(14)* %i) { 109; CHECK-LABEL: test_unrecognized 110; CHECK: movl %edx, (%rcx) 111entry: 112 %0 = addrspacecast i32 addrspace(14)* %i to i32 addrspace(270)* 113 %p32 = getelementptr inbounds %struct.Foo, %struct.Foo* %f, i64 0, i32 0 114 store i32 addrspace(270)* %0, i32 addrspace(270)** %p32, align 8 115 tail call void @use_foo(%struct.Foo* %f) 116 ret void 117} 118 119define void @test_unrecognized2(%struct.Foo* %f, i32 addrspace(271)* %i) { 120; CHECK-LABEL: test_unrecognized2 121; CHECK: movl %edx, %eax 122entry: 123 %0 = addrspacecast i32 addrspace(271)* %i to i32 addrspace(9)* 124 %p32 = getelementptr inbounds %struct.Foo, %struct.Foo* %f, i64 0, i32 2 125 store i32 addrspace(9)* %0, i32 addrspace(9)** %p32, align 8 126 tail call void @use_foo(%struct.Foo* %f) 127 ret void 128} 129