1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc < %s | FileCheck %s --check-prefixes=ALL,CHECK 3; RUN: llc -O0 < %s | FileCheck %s --check-prefixes=ALL,CHECK-O0 4 5; Source to regenerate: 6; struct Foo { 7; int * __ptr32 p32; 8; int * __ptr64 p64; 9; __attribute__((address_space(9))) int *p_other; 10; }; 11; void use_foo(Foo *f); 12; void test_sign_ext(Foo *f, int * __ptr32 __sptr i) { 13; f->p64 = i; 14; use_foo(f); 15; } 16; void test_zero_ext(Foo *f, int * __ptr32 __uptr i) { 17; f->p64 = i; 18; use_foo(f); 19; } 20; void test_trunc(Foo *f, int * __ptr64 i) { 21; f->p32 = i; 22; use_foo(f); 23; } 24; void test_noop1(Foo *f, int * __ptr32 i) { 25; f->p32 = i; 26; use_foo(f); 27; } 28; void test_noop2(Foo *f, int * __ptr64 i) { 29; f->p64 = i; 30; use_foo(f); 31; } 32; void test_null_arg(Foo *f) { 33; test_noop2(f, 0); 34; } 35; void test_unrecognized(Foo *f, __attribute__((address_space(14))) int *i) { 36; f->p64 = (int * __ptr64)i; 37; use_foo(f); 38; } 39; void test_unrecognized2(Foo *f, int * __ptr64 i) { 40; f->p_other = i; 41; use_foo(f); 42; } 43; 44; $ clang -cc1 -triple x86_64-windows-msvc -fms-extensions -O2 -S t.cpp 45 46target datalayout = "e-m:x-p:32:32-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:32-n8:16:32-a:0:32-S32" 47target triple = "i686-unknown-windows-msvc" 48 49%struct.Foo = type { ptr, ptr addrspace(272), ptr addrspace(9) } 50declare dso_local void @use_foo(ptr) 51 52define dso_local void @test_sign_ext(ptr %f, ptr %i) { 53; CHECK-LABEL: test_sign_ext: 54; CHECK: # %bb.0: # %entry 55; CHECK-NEXT: movl {{[0-9]+}}(%esp), %eax 56; CHECK-NEXT: movl {{[0-9]+}}(%esp), %ecx 57; CHECK-NEXT: movl %ecx, 8(%eax) 58; CHECK-NEXT: sarl $31, %ecx 59; CHECK-NEXT: movl %ecx, 12(%eax) 60; CHECK-NEXT: jmp _use_foo # TAILCALL 61; 62; CHECK-O0-LABEL: test_sign_ext: 63; CHECK-O0: # %bb.0: # %entry 64; CHECK-O0-NEXT: movl {{[0-9]+}}(%esp), %edx 65; CHECK-O0-NEXT: movl {{[0-9]+}}(%esp), %eax 66; CHECK-O0-NEXT: movl %edx, %ecx 67; CHECK-O0-NEXT: sarl $31, %ecx 68; CHECK-O0-NEXT: movl %edx, 8(%eax) 69; CHECK-O0-NEXT: movl %ecx, 12(%eax) 70; CHECK-O0-NEXT: jmp _use_foo # TAILCALL 71entry: 72 %0 = addrspacecast ptr %i to ptr addrspace(272) 73 %p64 = getelementptr inbounds %struct.Foo, ptr %f, i32 0, i32 1 74 store ptr addrspace(272) %0, ptr %p64, align 8 75 tail call void @use_foo(ptr %f) 76 ret void 77} 78 79define dso_local void @test_zero_ext(ptr %f, ptr addrspace(271) %i) { 80; CHECK-LABEL: test_zero_ext: 81; CHECK: # %bb.0: # %entry 82; CHECK-NEXT: movl {{[0-9]+}}(%esp), %eax 83; CHECK-NEXT: movl {{[0-9]+}}(%esp), %ecx 84; CHECK-NEXT: movl %eax, 8(%ecx) 85; CHECK-NEXT: movl $0, 12(%ecx) 86; CHECK-NEXT: jmp _use_foo # TAILCALL 87; 88; CHECK-O0-LABEL: test_zero_ext: 89; CHECK-O0: # %bb.0: # %entry 90; CHECK-O0-NEXT: movl {{[0-9]+}}(%esp), %ecx 91; CHECK-O0-NEXT: movl {{[0-9]+}}(%esp), %eax 92; CHECK-O0-NEXT: movl %ecx, 8(%eax) 93; CHECK-O0-NEXT: movl $0, 12(%eax) 94; CHECK-O0-NEXT: jmp _use_foo # TAILCALL 95entry: 96 %0 = addrspacecast ptr addrspace(271) %i to ptr addrspace(272) 97 %p64 = getelementptr inbounds %struct.Foo, ptr %f, i32 0, i32 1 98 store ptr addrspace(272) %0, ptr %p64, align 8 99 tail call void @use_foo(ptr %f) 100 ret void 101} 102 103define dso_local void @test_trunc(ptr %f, ptr addrspace(272) %i) { 104; CHECK-LABEL: test_trunc: 105; CHECK: # %bb.0: # %entry 106; CHECK-NEXT: movl {{[0-9]+}}(%esp), %eax 107; CHECK-NEXT: movl {{[0-9]+}}(%esp), %ecx 108; CHECK-NEXT: movl %eax, (%ecx) 109; CHECK-NEXT: jmp _use_foo # TAILCALL 110; 111; CHECK-O0-LABEL: test_trunc: 112; CHECK-O0: # %bb.0: # %entry 113; CHECK-O0-NEXT: movl {{[0-9]+}}(%esp), %eax 114; CHECK-O0-NEXT: movl {{[0-9]+}}(%esp), %ecx 115; CHECK-O0-NEXT: movl {{[0-9]+}}(%esp), %eax 116; CHECK-O0-NEXT: movl %ecx, (%eax) 117; CHECK-O0-NEXT: jmp _use_foo # TAILCALL 118entry: 119 %0 = addrspacecast ptr addrspace(272) %i to ptr 120 store ptr %0, ptr %f, align 8 121 tail call void @use_foo(ptr %f) 122 ret void 123} 124 125define dso_local void @test_noop1(ptr %f, ptr %i) { 126; CHECK-LABEL: test_noop1: 127; CHECK: # %bb.0: # %entry 128; CHECK-NEXT: movl {{[0-9]+}}(%esp), %eax 129; CHECK-NEXT: movl {{[0-9]+}}(%esp), %ecx 130; CHECK-NEXT: movl %eax, (%ecx) 131; CHECK-NEXT: jmp _use_foo # TAILCALL 132; 133; CHECK-O0-LABEL: test_noop1: 134; CHECK-O0: # %bb.0: # %entry 135; CHECK-O0-NEXT: movl {{[0-9]+}}(%esp), %ecx 136; CHECK-O0-NEXT: movl {{[0-9]+}}(%esp), %eax 137; CHECK-O0-NEXT: movl %ecx, (%eax) 138; CHECK-O0-NEXT: jmp _use_foo # TAILCALL 139entry: 140 store ptr %i, ptr %f, align 8 141 tail call void @use_foo(ptr %f) 142 ret void 143} 144 145define dso_local void @test_noop2(ptr %f, ptr addrspace(272) %i) { 146; CHECK-LABEL: test_noop2: 147; CHECK: # %bb.0: # %entry 148; CHECK-NEXT: movl {{[0-9]+}}(%esp), %eax 149; CHECK-NEXT: movl {{[0-9]+}}(%esp), %ecx 150; CHECK-NEXT: movl {{[0-9]+}}(%esp), %edx 151; CHECK-NEXT: movl %ecx, 12(%edx) 152; CHECK-NEXT: movl %eax, 8(%edx) 153; CHECK-NEXT: jmp _use_foo # TAILCALL 154; 155; CHECK-O0-LABEL: test_noop2: 156; CHECK-O0: # %bb.0: # %entry 157; CHECK-O0-NEXT: movl {{[0-9]+}}(%esp), %ecx 158; CHECK-O0-NEXT: movl {{[0-9]+}}(%esp), %edx 159; CHECK-O0-NEXT: movl {{[0-9]+}}(%esp), %eax 160; CHECK-O0-NEXT: movl %edx, 8(%eax) 161; CHECK-O0-NEXT: movl %ecx, 12(%eax) 162; CHECK-O0-NEXT: jmp _use_foo # TAILCALL 163entry: 164 %p64 = getelementptr inbounds %struct.Foo, ptr %f, i32 0, i32 1 165 store ptr addrspace(272) %i, ptr %p64, align 8 166 tail call void @use_foo(ptr %f) 167 ret void 168} 169 170; Test that null can be passed as a 64-bit pointer. 171define dso_local void @test_null_arg(ptr %f) { 172; CHECK-LABEL: test_null_arg: 173; CHECK: # %bb.0: # %entry 174; CHECK-NEXT: pushl $0 175; CHECK-NEXT: pushl $0 176; CHECK-NEXT: pushl {{[0-9]+}}(%esp) 177; CHECK-NEXT: calll _test_noop2 178; CHECK-NEXT: addl $12, %esp 179; CHECK-NEXT: retl 180; 181; CHECK-O0-LABEL: test_null_arg: 182; CHECK-O0: # %bb.0: # %entry 183; CHECK-O0-NEXT: subl $12, %esp 184; CHECK-O0-NEXT: movl {{[0-9]+}}(%esp), %ecx 185; CHECK-O0-NEXT: movl %esp, %eax 186; CHECK-O0-NEXT: movl %ecx, (%eax) 187; CHECK-O0-NEXT: movl $0, 8(%eax) 188; CHECK-O0-NEXT: movl $0, 4(%eax) 189; CHECK-O0-NEXT: calll _test_noop2 190; CHECK-O0-NEXT: addl $12, %esp 191; CHECK-O0-NEXT: retl 192entry: 193 call void @test_noop2(ptr %f, ptr addrspace(272) null) 194 ret void 195} 196 197define dso_local void @test_unrecognized(ptr %f, ptr addrspace(14) %i) { 198; CHECK-LABEL: test_unrecognized: 199; CHECK: # %bb.0: # %entry 200; CHECK-NEXT: movl {{[0-9]+}}(%esp), %eax 201; CHECK-NEXT: movl {{[0-9]+}}(%esp), %ecx 202; CHECK-NEXT: movl %ecx, 8(%eax) 203; CHECK-NEXT: sarl $31, %ecx 204; CHECK-NEXT: movl %ecx, 12(%eax) 205; CHECK-NEXT: jmp _use_foo # TAILCALL 206; 207; CHECK-O0-LABEL: test_unrecognized: 208; CHECK-O0: # %bb.0: # %entry 209; CHECK-O0-NEXT: movl {{[0-9]+}}(%esp), %edx 210; CHECK-O0-NEXT: movl {{[0-9]+}}(%esp), %eax 211; CHECK-O0-NEXT: movl %edx, %ecx 212; CHECK-O0-NEXT: sarl $31, %ecx 213; CHECK-O0-NEXT: movl %edx, 8(%eax) 214; CHECK-O0-NEXT: movl %ecx, 12(%eax) 215; CHECK-O0-NEXT: jmp _use_foo # TAILCALL 216entry: 217 %0 = addrspacecast ptr addrspace(14) %i to ptr addrspace(272) 218 %p64 = getelementptr inbounds %struct.Foo, ptr %f, i32 0, i32 1 219 store ptr addrspace(272) %0, ptr %p64, align 8 220 tail call void @use_foo(ptr %f) 221 ret void 222} 223 224define dso_local void @test_unrecognized2(ptr %f, ptr addrspace(272) %i) { 225; CHECK-LABEL: test_unrecognized2: 226; CHECK: # %bb.0: # %entry 227; CHECK-NEXT: movl {{[0-9]+}}(%esp), %eax 228; CHECK-NEXT: movl {{[0-9]+}}(%esp), %ecx 229; CHECK-NEXT: movl %eax, 16(%ecx) 230; CHECK-NEXT: jmp _use_foo # TAILCALL 231; 232; CHECK-O0-LABEL: test_unrecognized2: 233; CHECK-O0: # %bb.0: # %entry 234; CHECK-O0-NEXT: movl {{[0-9]+}}(%esp), %eax 235; CHECK-O0-NEXT: movl {{[0-9]+}}(%esp), %ecx 236; CHECK-O0-NEXT: movl {{[0-9]+}}(%esp), %eax 237; CHECK-O0-NEXT: movl %ecx, 16(%eax) 238; CHECK-O0-NEXT: jmp _use_foo # TAILCALL 239entry: 240 %0 = addrspacecast ptr addrspace(272) %i to ptr addrspace(9) 241 %p_other = getelementptr inbounds %struct.Foo, ptr %f, i32 0, i32 2 242 store ptr addrspace(9) %0, ptr %p_other, align 8 243 tail call void @use_foo(ptr %f) 244 ret void 245} 246 247define i32 @test_load_sptr32(ptr addrspace(270) %i) { 248; ALL-LABEL: test_load_sptr32: 249; ALL: # %bb.0: # %entry 250; ALL-NEXT: movl {{[0-9]+}}(%esp), %eax 251; ALL-NEXT: movl (%eax), %eax 252; ALL-NEXT: retl 253entry: 254 %0 = load i32, ptr addrspace(270) %i, align 4 255 ret i32 %0 256} 257 258define i32 @test_load_uptr32(ptr addrspace(271) %i) { 259; ALL-LABEL: test_load_uptr32: 260; ALL: # %bb.0: # %entry 261; ALL-NEXT: movl {{[0-9]+}}(%esp), %eax 262; ALL-NEXT: movl (%eax), %eax 263; ALL-NEXT: retl 264entry: 265 %0 = load i32, ptr addrspace(271) %i, align 4 266 ret i32 %0 267} 268 269define i32 @test_load_ptr64(ptr addrspace(272) %i) { 270; CHECK-LABEL: test_load_ptr64: 271; CHECK: # %bb.0: # %entry 272; CHECK-NEXT: movl {{[0-9]+}}(%esp), %eax 273; CHECK-NEXT: movl (%eax), %eax 274; CHECK-NEXT: retl 275; 276; CHECK-O0-LABEL: test_load_ptr64: 277; CHECK-O0: # %bb.0: # %entry 278; CHECK-O0-NEXT: movl {{[0-9]+}}(%esp), %eax 279; CHECK-O0-NEXT: movl {{[0-9]+}}(%esp), %eax 280; CHECK-O0-NEXT: movl (%eax), %eax 281; CHECK-O0-NEXT: retl 282entry: 283 %0 = load i32, ptr addrspace(272) %i, align 8 284 ret i32 %0 285} 286 287define void @test_store_sptr32(ptr addrspace(270) %s, i32 %i) { 288; CHECK-LABEL: test_store_sptr32: 289; CHECK: # %bb.0: # %entry 290; CHECK-NEXT: movl {{[0-9]+}}(%esp), %eax 291; CHECK-NEXT: movl {{[0-9]+}}(%esp), %ecx 292; CHECK-NEXT: movl %eax, (%ecx) 293; CHECK-NEXT: retl 294; 295; CHECK-O0-LABEL: test_store_sptr32: 296; CHECK-O0: # %bb.0: # %entry 297; CHECK-O0-NEXT: movl {{[0-9]+}}(%esp), %ecx 298; CHECK-O0-NEXT: movl {{[0-9]+}}(%esp), %eax 299; CHECK-O0-NEXT: movl %ecx, (%eax) 300; CHECK-O0-NEXT: retl 301entry: 302 store i32 %i, ptr addrspace(270) %s, align 4 303 ret void 304} 305 306define void @test_store_uptr32(ptr addrspace(271) %s, i32 %i) { 307; CHECK-LABEL: test_store_uptr32: 308; CHECK: # %bb.0: # %entry 309; CHECK-NEXT: movl {{[0-9]+}}(%esp), %eax 310; CHECK-NEXT: movl {{[0-9]+}}(%esp), %ecx 311; CHECK-NEXT: movl %eax, (%ecx) 312; CHECK-NEXT: retl 313; 314; CHECK-O0-LABEL: test_store_uptr32: 315; CHECK-O0: # %bb.0: # %entry 316; CHECK-O0-NEXT: movl {{[0-9]+}}(%esp), %ecx 317; CHECK-O0-NEXT: movl {{[0-9]+}}(%esp), %eax 318; CHECK-O0-NEXT: movl %ecx, (%eax) 319; CHECK-O0-NEXT: retl 320entry: 321 store i32 %i, ptr addrspace(271) %s, align 4 322 ret void 323} 324 325define void @test_store_ptr64(ptr addrspace(272) %s, i32 %i) { 326; CHECK-LABEL: test_store_ptr64: 327; CHECK: # %bb.0: # %entry 328; CHECK-NEXT: movl {{[0-9]+}}(%esp), %eax 329; CHECK-NEXT: movl {{[0-9]+}}(%esp), %ecx 330; CHECK-NEXT: movl %eax, (%ecx) 331; CHECK-NEXT: retl 332; 333; CHECK-O0-LABEL: test_store_ptr64: 334; CHECK-O0: # %bb.0: # %entry 335; CHECK-O0-NEXT: movl {{[0-9]+}}(%esp), %eax 336; CHECK-O0-NEXT: movl {{[0-9]+}}(%esp), %eax 337; CHECK-O0-NEXT: movl {{[0-9]+}}(%esp), %ecx 338; CHECK-O0-NEXT: movl %ecx, (%eax) 339; CHECK-O0-NEXT: retl 340entry: 341 store i32 %i, ptr addrspace(272) %s, align 8 342 ret void 343} 344 345define i64 @test_load_sptr32_zext_i64(ptr addrspace(270) %i) { 346; ALL-LABEL: test_load_sptr32_zext_i64: 347; ALL: # %bb.0: # %entry 348; ALL-NEXT: movl {{[0-9]+}}(%esp), %eax 349; ALL-NEXT: movl (%eax), %eax 350; ALL-NEXT: xorl %edx, %edx 351; ALL-NEXT: retl 352entry: 353 %0 = load i32, ptr addrspace(270) %i, align 4 354 %1 = zext i32 %0 to i64 355 ret i64 %1 356} 357 358define void @test_store_sptr32_trunc_i1(ptr addrspace(270) %s, i32 %i) { 359; CHECK-LABEL: test_store_sptr32_trunc_i1: 360; CHECK: # %bb.0: # %entry 361; CHECK-NEXT: movl {{[0-9]+}}(%esp), %eax 362; CHECK-NEXT: movl {{[0-9]+}}(%esp), %ecx 363; CHECK-NEXT: andl $1, %ecx 364; CHECK-NEXT: movb %cl, (%eax) 365; CHECK-NEXT: retl 366; 367; CHECK-O0-LABEL: test_store_sptr32_trunc_i1: 368; CHECK-O0: # %bb.0: # %entry 369; CHECK-O0-NEXT: movl {{[0-9]+}}(%esp), %ecx 370; CHECK-O0-NEXT: movl {{[0-9]+}}(%esp), %eax 371; CHECK-O0-NEXT: andl $1, %ecx 372; CHECK-O0-NEXT: # kill: def $cl killed $cl killed $ecx 373; CHECK-O0-NEXT: movb %cl, (%eax) 374; CHECK-O0-NEXT: retl 375entry: 376 %0 = trunc i32 %i to i1 377 store i1 %0, ptr addrspace(270) %s 378 ret void 379} 380