1; Verifies correctness of load/store of parameters and return values. 2; RUN: llc < %s -march=nvptx64 -mcpu=sm_35 -O0 -verify-machineinstrs | FileCheck -allow-deprecated-dag-overlap %s 3; RUN: %if ptxas %{ llc < %s -march=nvptx64 -mcpu=sm_35 -O0 -verify-machineinstrs | %ptxas-verify -arch=sm_35 %} 4 5%s_i1 = type { i1 } 6%s_i8 = type { i8 } 7%s_i16 = type { i16 } 8%s_f16 = type { half } 9%s_i32 = type { i32 } 10%s_f32 = type { float } 11%s_i64 = type { i64 } 12%s_f64 = type { double } 13 14; More complicated types. i64 is used to increase natural alignment 15; requirement for the type. 16%s_i32x4 = type { i32, i32, i32, i32, i64} 17%s_i32f32 = type { i32, float, i32, float, i64} 18%s_i8i32x4 = type { i32, i32, i8, i32, i32, i64} 19%s_i8i32x4p = type <{ i32, i32, i8, i32, i32, i64}> 20%s_crossfield = type { i32, [2 x i32], <4 x i32>, [3 x {i32, i32, i32}]} 21; All scalar parameters must be at least 32 bits in size. 22; i1 is loaded/stored as i8. 23 24; CHECK: .func (.param .b32 func_retval0) 25; CHECK-LABEL: test_i1( 26; CHECK-NEXT: .param .b32 test_i1_param_0 27; CHECK: ld.param.u8 [[A8:%rs[0-9]+]], [test_i1_param_0]; 28; CHECK: and.b16 [[A:%rs[0-9]+]], [[A8]], 1; 29; CHECK: setp.eq.b16 %p1, [[A]], 1 30; CHECK: cvt.u32.u16 [[B:%r[0-9]+]], [[A8]] 31; CHECK: and.b32 [[C:%r[0-9]+]], [[B]], 1; 32; CHECK: .param .b32 param0; 33; CHECK: st.param.b32 [param0+0], [[C]] 34; CHECK: .param .b32 retval0; 35; CHECK: call.uni 36; CHECK-NEXT: test_i1, 37; CHECK: ld.param.b32 [[R8:%r[0-9]+]], [retval0+0]; 38; CHECK: and.b32 [[R:%r[0-9]+]], [[R8]], 1; 39; CHECK: st.param.b32 [func_retval0+0], [[R]]; 40; CHECK: ret; 41define i1 @test_i1(i1 %a) { 42 %r = tail call i1 @test_i1(i1 %a); 43 ret i1 %r; 44} 45 46; Signed i1 is a somewhat special case. We only care about one bit and 47; then us neg.s32 to convert it to 32-bit -1 if it's set. 48; CHECK: .func (.param .b32 func_retval0) 49; CHECK-LABEL: test_i1s( 50; CHECK-NEXT: .param .b32 test_i1s_param_0 51; CHECK: ld.param.u8 [[A8:%rs[0-9]+]], [test_i1s_param_0]; 52; CHECK: cvt.u32.u16 [[A32:%r[0-9]+]], [[A8]]; 53; CHECK: and.b32 [[A1:%r[0-9]+]], [[A32]], 1; 54; CHECK: neg.s32 [[A:%r[0-9]+]], [[A1]]; 55; CHECK: .param .b32 param0; 56; CHECK: st.param.b32 [param0+0], [[A]]; 57; CHECK: .param .b32 retval0; 58; CHECK: call.uni 59; CHECK: ld.param.b32 [[R8:%r[0-9]+]], [retval0+0]; 60; CHECK: and.b32 [[R1:%r[0-9]+]], [[R8]], 1; 61; CHECK: neg.s32 [[R:%r[0-9]+]], [[R1]]; 62; CHECK: st.param.b32 [func_retval0+0], [[R]]; 63; CHECK-NEXT: ret; 64define signext i1 @test_i1s(i1 signext %a) { 65 %r = tail call signext i1 @test_i1s(i1 signext %a); 66 ret i1 %r; 67} 68 69; Make sure that i1 loads are vectorized as i8 loads, respecting each element alignment. 70; CHECK: .func (.param .align 1 .b8 func_retval0[1]) 71; CHECK-LABEL: test_v3i1( 72; CHECK-NEXT: .param .align 1 .b8 test_v3i1_param_0[1] 73; CHECK-DAG: ld.param.u8 [[E2:%rs[0-9]+]], [test_v3i1_param_0+2]; 74; CHECK-DAG: ld.param.u8 [[E0:%rs[0-9]+]], [test_v3i1_param_0] 75; CHECK: .param .align 1 .b8 param0[1]; 76; CHECK-DAG: st.param.b8 [param0+0], [[E0]]; 77; CHECK-DAG: st.param.b8 [param0+2], [[E2]]; 78; CHECK: .param .align 1 .b8 retval0[1]; 79; CHECK: call.uni (retval0), 80; CHECK-NEXT: test_v3i1, 81; CHECK-DAG: ld.param.b8 [[RE0:%rs[0-9]+]], [retval0+0]; 82; CHECK-DAG: ld.param.b8 [[RE2:%rs[0-9]+]], [retval0+2]; 83; CHECK-DAG: st.param.b8 [func_retval0+0], [[RE0]] 84; CHECK-DAG: st.param.b8 [func_retval0+2], [[RE2]]; 85; CHECK-NEXT: ret; 86define <3 x i1> @test_v3i1(<3 x i1> %a) { 87 %r = tail call <3 x i1> @test_v3i1(<3 x i1> %a); 88 ret <3 x i1> %r; 89} 90 91; CHECK: .func (.param .align 1 .b8 func_retval0[1]) 92; CHECK-LABEL: test_v4i1( 93; CHECK-NEXT: .param .align 1 .b8 test_v4i1_param_0[1] 94; CHECK: ld.param.u8 [[E0:%rs[0-9]+]], [test_v4i1_param_0] 95; CHECK: .param .align 1 .b8 param0[1]; 96; CHECK: st.param.b8 [param0+0], [[E0]]; 97; CHECK: .param .align 1 .b8 retval0[1]; 98; CHECK: call.uni (retval0), 99; CHECK: test_v4i1, 100; CHECK: ld.param.b8 [[RE0:%rs[0-9]+]], [retval0+0]; 101; CHECK: ld.param.b8 [[RE1:%rs[0-9]+]], [retval0+1]; 102; CHECK: ld.param.b8 [[RE2:%rs[0-9]+]], [retval0+2]; 103; CHECK: ld.param.b8 [[RE3:%rs[0-9]+]], [retval0+3]; 104; CHECK: st.param.b8 [func_retval0+0], [[RE0]]; 105; CHECK: st.param.b8 [func_retval0+1], [[RE1]]; 106; CHECK: st.param.b8 [func_retval0+2], [[RE2]]; 107; CHECK: st.param.b8 [func_retval0+3], [[RE3]]; 108; CHECK-NEXT: ret; 109define <4 x i1> @test_v4i1(<4 x i1> %a) { 110 %r = tail call <4 x i1> @test_v4i1(<4 x i1> %a); 111 ret <4 x i1> %r; 112} 113 114; CHECK: .func (.param .align 1 .b8 func_retval0[1]) 115; CHECK-LABEL: test_v5i1( 116; CHECK-NEXT: .param .align 1 .b8 test_v5i1_param_0[1] 117; CHECK-DAG: ld.param.u8 [[E4:%rs[0-9]+]], [test_v5i1_param_0+4]; 118; CHECK-DAG: ld.param.u8 [[E0:%rs[0-9]+]], [test_v5i1_param_0] 119; CHECK: .param .align 1 .b8 param0[1]; 120; CHECK-DAG: st.param.b8 [param0+0], [[E0]]; 121; CHECK-DAG: st.param.b8 [param0+4], [[E4]]; 122; CHECK: .param .align 1 .b8 retval0[1]; 123; CHECK: call.uni (retval0), 124; CHECK-NEXT: test_v5i1, 125; CHECK-DAG: ld.param.b8 [[RE0:%rs[0-9]+]], [retval0+0]; 126; CHECK-DAG: ld.param.b8 [[RE4:%rs[0-9]+]], [retval0+4]; 127; CHECK-DAG: st.param.b8 [func_retval0+0], [[RE0]] 128; CHECK-DAG: st.param.b8 [func_retval0+4], [[RE4]]; 129; CHECK-NEXT: ret; 130define <5 x i1> @test_v5i1(<5 x i1> %a) { 131 %r = tail call <5 x i1> @test_v5i1(<5 x i1> %a); 132 ret <5 x i1> %r; 133} 134 135; Unsigned i8 is loaded directly into 32-bit register. 136; CHECK: .func (.param .b32 func_retval0) 137; CHECK-LABEL: test_i8( 138; CHECK-NEXT: .param .b32 test_i8_param_0 139; CHECK: ld.param.u8 [[A8:%rs[0-9]+]], [test_i8_param_0]; 140; CHECK: cvt.u32.u16 [[A32:%r[0-9]+]], [[A8]]; 141; CHECK: and.b32 [[A:%r[0-9]+]], [[A32]], 255; 142; CHECK: .param .b32 param0; 143; CHECK: st.param.b32 [param0+0], [[A]]; 144; CHECK: .param .b32 retval0; 145; CHECK: call.uni (retval0), 146; CHECK: test_i8, 147; CHECK: ld.param.b32 [[R32:%r[0-9]+]], [retval0+0]; 148; CHECK: and.b32 [[R:%r[0-9]+]], [[R32]], 255; 149; CHECK: st.param.b32 [func_retval0+0], [[R]]; 150; CHECK-NEXT: ret; 151define i8 @test_i8(i8 %a) { 152 %r = tail call i8 @test_i8(i8 %a); 153 ret i8 %r; 154} 155 156; signed i8 is loaded into 16-bit register which is then sign-extended to i32. 157; CHECK: .func (.param .b32 func_retval0) 158; CHECK-LABEL: test_i8s( 159; CHECK-NEXT: .param .b32 test_i8s_param_0 160; CHECK: ld.param.s8 [[A8:%rs[0-9]+]], [test_i8s_param_0]; 161; CHECK: cvt.s32.s16 [[A:%r[0-9]+]], [[A8]]; 162; CHECK: .param .b32 param0; 163; CHECK: st.param.b32 [param0+0], [[A]]; 164; CHECK: .param .b32 retval0; 165; CHECK: call.uni (retval0), 166; CHECK: test_i8s, 167; CHECK: ld.param.b32 [[R32:%r[0-9]+]], [retval0+0]; 168; -- This is suspicious (though correct) -- why not cvt.u8.u32, cvt.s8.s32 ? 169; CHECK: cvt.u16.u32 [[R16:%rs[0-9]+]], [[R32]]; 170; CHECK: cvt.s32.s16 [[R:%r[0-9]+]], [[R16]]; 171; CHECK: st.param.b32 [func_retval0+0], [[R]]; 172; CHECK-NEXT: ret; 173define signext i8 @test_i8s(i8 signext %a) { 174 %r = tail call signext i8 @test_i8s(i8 signext %a); 175 ret i8 %r; 176} 177 178; CHECK: .func (.param .align 4 .b8 func_retval0[4]) 179; CHECK-LABEL: test_v3i8( 180; CHECK-NEXT: .param .align 4 .b8 test_v3i8_param_0[4] 181; CHECK-DAG: ld.param.u8 [[E2:%rs[0-9]+]], [test_v3i8_param_0+2]; 182; CHECK-DAG: ld.param.v2.u8 {[[E0:%rs[0-9]+]], [[E1:%rs[0-9]+]]}, [test_v3i8_param_0]; 183; CHECK: .param .align 4 .b8 param0[4]; 184; CHECK: st.param.v2.b8 [param0+0], {[[E0]], [[E1]]}; 185; CHECK: st.param.b8 [param0+2], [[E2]]; 186; CHECK: .param .align 4 .b8 retval0[4]; 187; CHECK: call.uni (retval0), 188; CHECK-NEXT: test_v3i8, 189; CHECK-DAG: ld.param.v2.b8 {[[RE0:%rs[0-9]+]], [[RE1:%rs[0-9]+]]}, [retval0+0]; 190; CHECK-DAG: ld.param.b8 [[RE2:%rs[0-9]+]], [retval0+2]; 191; CHECK-DAG: st.param.v2.b8 [func_retval0+0], {[[RE0]], [[RE1]]}; 192; CHECK-DAG: st.param.b8 [func_retval0+2], [[RE2]]; 193; CHECK-NEXT: ret; 194define <3 x i8> @test_v3i8(<3 x i8> %a) { 195 %r = tail call <3 x i8> @test_v3i8(<3 x i8> %a); 196 ret <3 x i8> %r; 197} 198 199; CHECK: .func (.param .align 4 .b8 func_retval0[4]) 200; CHECK-LABEL: test_v4i8( 201; CHECK-NEXT: .param .align 4 .b8 test_v4i8_param_0[4] 202; CHECK: ld.param.v4.u8 {[[E0:%rs[0-9]+]], [[E1:%rs[0-9]+]], [[E2:%rs[0-9]+]], [[E3:%rs[0-9]+]]}, [test_v4i8_param_0] 203; CHECK: .param .align 4 .b8 param0[4]; 204; CHECK: st.param.v4.b8 [param0+0], {[[E0]], [[E1]], [[E2]], [[E3]]}; 205; CHECK: .param .align 4 .b8 retval0[4]; 206; CHECK: call.uni (retval0), 207; CHECK-NEXT: test_v4i8, 208; CHECK: ld.param.v4.b8 {[[RE0:%rs[0-9]+]], [[RE1:%rs[0-9]+]], [[RE2:%rs[0-9]+]], [[RE3:%rs[0-9]+]]}, [retval0+0]; 209; CHECK: st.param.v4.b8 [func_retval0+0], {[[RE0]], [[RE1]], [[RE2]], [[RE3]]} 210; CHECK-NEXT: ret; 211define <4 x i8> @test_v4i8(<4 x i8> %a) { 212 %r = tail call <4 x i8> @test_v4i8(<4 x i8> %a); 213 ret <4 x i8> %r; 214} 215 216; CHECK: .func (.param .align 8 .b8 func_retval0[8]) 217; CHECK-LABEL: test_v5i8( 218; CHECK-NEXT: .param .align 8 .b8 test_v5i8_param_0[8] 219; CHECK-DAG: ld.param.u8 [[E4:%rs[0-9]+]], [test_v5i8_param_0+4]; 220; CHECK-DAG: ld.param.v4.u8 {[[E0:%rs[0-9]+]], [[E1:%rs[0-9]+]], [[E2:%rs[0-9]+]], [[E3:%rs[0-9]+]]}, [test_v5i8_param_0] 221; CHECK: .param .align 8 .b8 param0[8]; 222; CHECK-DAG: st.param.v4.b8 [param0+0], {[[E0]], [[E1]], [[E2]], [[E3]]}; 223; CHECK-DAG: st.param.b8 [param0+4], [[E4]]; 224; CHECK: .param .align 8 .b8 retval0[8]; 225; CHECK: call.uni (retval0), 226; CHECK-NEXT: test_v5i8, 227; CHECK-DAG: ld.param.v4.b8 {[[RE0:%rs[0-9]+]], [[RE1:%rs[0-9]+]], [[RE2:%rs[0-9]+]], [[RE3:%rs[0-9]+]]}, [retval0+0]; 228; CHECK-DAG: ld.param.b8 [[RE4:%rs[0-9]+]], [retval0+4]; 229; CHECK-DAG: st.param.v4.b8 [func_retval0+0], {[[RE0]], [[RE1]], [[RE2]], [[RE3]]} 230; CHECK-DAG: st.param.b8 [func_retval0+4], [[RE4]]; 231; CHECK-NEXT: ret; 232define <5 x i8> @test_v5i8(<5 x i8> %a) { 233 %r = tail call <5 x i8> @test_v5i8(<5 x i8> %a); 234 ret <5 x i8> %r; 235} 236 237; CHECK: .func (.param .b32 func_retval0) 238; CHECK-LABEL: test_i16( 239; CHECK-NEXT: .param .b32 test_i16_param_0 240; CHECK: ld.param.u16 [[E16:%rs[0-9]+]], [test_i16_param_0]; 241; CHECK: cvt.u32.u16 [[E32:%r[0-9]+]], [[E16]]; 242; CHECK: .param .b32 param0; 243; CHECK: st.param.b32 [param0+0], [[E32]]; 244; CHECK: .param .b32 retval0; 245; CHECK: call.uni (retval0), 246; CHECK-NEXT: test_i16, 247; CHECK: ld.param.b32 [[RE32:%r[0-9]+]], [retval0+0]; 248; CHECK: and.b32 [[R:%r[0-9]+]], [[RE32]], 65535; 249; CHECK: st.param.b32 [func_retval0+0], [[R]]; 250; CHECK-NEXT: ret; 251define i16 @test_i16(i16 %a) { 252 %r = tail call i16 @test_i16(i16 %a); 253 ret i16 %r; 254} 255 256; CHECK: .func (.param .b32 func_retval0) 257; CHECK-LABEL: test_i16s( 258; CHECK-NEXT: .param .b32 test_i16s_param_0 259; CHECK: ld.param.u16 [[E16:%rs[0-9]+]], [test_i16s_param_0]; 260; CHECK: cvt.s32.s16 [[E32:%r[0-9]+]], [[E16]]; 261; CHECK: .param .b32 param0; 262; CHECK: st.param.b32 [param0+0], [[E32]]; 263; CHECK: .param .b32 retval0; 264; CHECK: call.uni (retval0), 265; CHECK-NEXT: test_i16s, 266; CHECK: ld.param.b32 [[RE32:%r[0-9]+]], [retval0+0]; 267; CHECK: cvt.s32.s16 [[R:%r[0-9]+]], [[RE32]]; 268; CHECK: st.param.b32 [func_retval0+0], [[R]]; 269; CHECK-NEXT: ret; 270define signext i16 @test_i16s(i16 signext %a) { 271 %r = tail call signext i16 @test_i16s(i16 signext %a); 272 ret i16 %r; 273} 274 275; CHECK: .func (.param .align 8 .b8 func_retval0[8]) 276; CHECK-LABEL: test_v3i16( 277; CHECK-NEXT: .param .align 8 .b8 test_v3i16_param_0[8] 278; CHECK-DAG: ld.param.u16 [[E2:%rs[0-9]+]], [test_v3i16_param_0+4]; 279; CHECK-DAG: ld.param.v2.u16 {[[E0:%rs[0-9]+]], [[E1:%rs[0-9]+]]}, [test_v3i16_param_0]; 280; CHECK: .param .align 8 .b8 param0[8]; 281; CHECK: st.param.v2.b16 [param0+0], {[[E0]], [[E1]]}; 282; CHECK: st.param.b16 [param0+4], [[E2]]; 283; CHECK: .param .align 8 .b8 retval0[8]; 284; CHECK: call.uni (retval0), 285; CHECK-NEXT: test_v3i16, 286; CHECK: ld.param.v2.b16 {[[RE0:%rs[0-9]+]], [[RE1:%rs[0-9]+]]}, [retval0+0]; 287; CHECK: ld.param.b16 [[RE2:%rs[0-9]+]], [retval0+4]; 288; CHECK-DAG: st.param.v2.b16 [func_retval0+0], {[[RE0]], [[RE1]]}; 289; CHECK-DAG: st.param.b16 [func_retval0+4], [[RE2]]; 290; CHECK-NEXT: ret; 291define <3 x i16> @test_v3i16(<3 x i16> %a) { 292 %r = tail call <3 x i16> @test_v3i16(<3 x i16> %a); 293 ret <3 x i16> %r; 294} 295 296; CHECK: .func (.param .align 8 .b8 func_retval0[8]) 297; CHECK-LABEL: test_v4i16( 298; CHECK-NEXT: .param .align 8 .b8 test_v4i16_param_0[8] 299; CHECK: ld.param.v4.u16 {[[E0:%rs[0-9]+]], [[E1:%rs[0-9]+]], [[E2:%rs[0-9]+]], [[E3:%rs[0-9]+]]}, [test_v4i16_param_0] 300; CHECK: .param .align 8 .b8 param0[8]; 301; CHECK: st.param.v4.b16 [param0+0], {[[E0]], [[E1]], [[E2]], [[E3]]}; 302; CHECK: .param .align 8 .b8 retval0[8]; 303; CHECK: call.uni (retval0), 304; CHECK-NEXT: test_v4i16, 305; CHECK: ld.param.v4.b16 {[[RE0:%rs[0-9]+]], [[RE1:%rs[0-9]+]], [[RE2:%rs[0-9]+]], [[RE3:%rs[0-9]+]]}, [retval0+0]; 306; CHECK: st.param.v4.b16 [func_retval0+0], {[[RE0]], [[RE1]], [[RE2]], [[RE3]]} 307; CHECK-NEXT: ret; 308define <4 x i16> @test_v4i16(<4 x i16> %a) { 309 %r = tail call <4 x i16> @test_v4i16(<4 x i16> %a); 310 ret <4 x i16> %r; 311} 312 313; CHECK: .func (.param .align 16 .b8 func_retval0[16]) 314; CHECK-LABEL: test_v5i16( 315; CHECK-NEXT: .param .align 16 .b8 test_v5i16_param_0[16] 316; CHECK-DAG: ld.param.u16 [[E4:%rs[0-9]+]], [test_v5i16_param_0+8]; 317; CHECK-DAG: ld.param.v4.u16 {[[E0:%rs[0-9]+]], [[E1:%rs[0-9]+]], [[E2:%rs[0-9]+]], [[E3:%rs[0-9]+]]}, [test_v5i16_param_0] 318; CHECK: .param .align 16 .b8 param0[16]; 319; CHECK-DAG: st.param.v4.b16 [param0+0], {[[E0]], [[E1]], [[E2]], [[E3]]}; 320; CHECK-DAG: st.param.b16 [param0+8], [[E4]]; 321; CHECK: .param .align 16 .b8 retval0[16]; 322; CHECK: call.uni (retval0), 323; CHECK-NEXT: test_v5i16, 324; CHECK-DAG: ld.param.v4.b16 {[[RE0:%rs[0-9]+]], [[RE1:%rs[0-9]+]], [[RE2:%rs[0-9]+]], [[RE3:%rs[0-9]+]]}, [retval0+0]; 325; CHECK-DAG: ld.param.b16 [[RE4:%rs[0-9]+]], [retval0+8]; 326; CHECK-DAG: st.param.v4.b16 [func_retval0+0], {[[RE0]], [[RE1]], [[RE2]], [[RE3]]} 327; CHECK-DAG: st.param.b16 [func_retval0+8], [[RE4]]; 328; CHECK-NEXT: ret; 329define <5 x i16> @test_v5i16(<5 x i16> %a) { 330 %r = tail call <5 x i16> @test_v5i16(<5 x i16> %a); 331 ret <5 x i16> %r; 332} 333 334; CHECK: .func (.param .b32 func_retval0) 335; CHECK-LABEL: test_f16( 336; CHECK-NEXT: .param .b32 test_f16_param_0 337; CHECK: ld.param.b16 [[E:%h[0-9]+]], [test_f16_param_0]; 338; CHECK: .param .b32 param0; 339; CHECK: st.param.b16 [param0+0], [[E]]; 340; CHECK: .param .b32 retval0; 341; CHECK: call.uni (retval0), 342; CHECK-NEXT: test_f16, 343; CHECK: ld.param.b16 [[R:%h[0-9]+]], [retval0+0]; 344; CHECK: st.param.b16 [func_retval0+0], [[R]] 345; CHECK-NEXT: ret; 346define half @test_f16(half %a) { 347 %r = tail call half @test_f16(half %a); 348 ret half %r; 349} 350 351; CHECK: .func (.param .align 4 .b8 func_retval0[4]) 352; CHECK-LABEL: test_v2f16( 353; CHECK-NEXT: .param .align 4 .b8 test_v2f16_param_0[4] 354; CHECK: ld.param.b32 [[E:%hh[0-9]+]], [test_v2f16_param_0]; 355; CHECK: .param .align 4 .b8 param0[4]; 356; CHECK: st.param.b32 [param0+0], [[E]]; 357; CHECK: .param .align 4 .b8 retval0[4]; 358; CHECK: call.uni (retval0), 359; CHECK-NEXT: test_v2f16, 360; CHECK: ld.param.b32 [[R:%hh[0-9]+]], [retval0+0]; 361; CHECK: st.param.b32 [func_retval0+0], [[R]] 362; CHECK-NEXT: ret; 363define <2 x half> @test_v2f16(<2 x half> %a) { 364 %r = tail call <2 x half> @test_v2f16(<2 x half> %a); 365 ret <2 x half> %r; 366} 367 368; CHECK:.func (.param .align 8 .b8 func_retval0[8]) 369; CHECK-LABEL: test_v3f16( 370; CHECK: .param .align 8 .b8 test_v3f16_param_0[8] 371; CHECK-DAG: ld.param.b32 [[HH01:%hh[0-9]+]], [test_v3f16_param_0]; 372; CHECK-DAG: mov.b32 {[[E0:%h[0-9]+]], [[E1:%h[0-9]+]]}, [[HH01]]; 373; CHECK-DAG: ld.param.b16 [[E2:%h[0-9]+]], [test_v3f16_param_0+4]; 374; CHECK: .param .align 8 .b8 param0[8]; 375; CHECK-DAG: st.param.v2.b16 [param0+0], {[[E0]], [[E1]]}; 376; CHECK-DAG: st.param.b16 [param0+4], [[E2]]; 377; CHECK: .param .align 8 .b8 retval0[8]; 378; CHECK: call.uni (retval0), 379; CHECK: test_v3f16, 380; CHECK-DAG: ld.param.v2.b16 {[[R0:%h[0-9]+]], [[R1:%h[0-9]+]]}, [retval0+0]; 381; CHECK-DAG: ld.param.b16 [[R2:%h[0-9]+]], [retval0+4]; 382; CHECK-DAG: st.param.v2.b16 [func_retval0+0], {[[R0]], [[R1]]}; 383; CHECK-DAG: st.param.b16 [func_retval0+4], [[R2]]; 384; CHECK: ret; 385define <3 x half> @test_v3f16(<3 x half> %a) { 386 %r = tail call <3 x half> @test_v3f16(<3 x half> %a); 387 ret <3 x half> %r; 388} 389 390; CHECK:.func (.param .align 8 .b8 func_retval0[8]) 391; CHECK-LABEL: test_v4f16( 392; CHECK: .param .align 8 .b8 test_v4f16_param_0[8] 393; CHECK: ld.param.v2.u32 {[[R01:%r[0-9]+]], [[R23:%r[0-9]+]]}, [test_v4f16_param_0]; 394; CHECK-DAG: mov.b32 [[HH01:%hh[0-9]+]], [[R01]]; 395; CHECK-DAG: mov.b32 [[HH23:%hh[0-9]+]], [[R23]]; 396; CHECK: .param .align 8 .b8 param0[8]; 397; CHECK: st.param.v2.b32 [param0+0], {[[HH01]], [[HH23]]}; 398; CHECK: .param .align 8 .b8 retval0[8]; 399; CHECK: call.uni (retval0), 400; CHECK: test_v4f16, 401; CHECK: ld.param.v2.b32 {[[RH01:%hh[0-9]+]], [[RH23:%hh[0-9]+]]}, [retval0+0]; 402; CHECK: st.param.v2.b32 [func_retval0+0], {[[RH01]], [[RH23]]}; 403; CHECK: ret; 404define <4 x half> @test_v4f16(<4 x half> %a) { 405 %r = tail call <4 x half> @test_v4f16(<4 x half> %a); 406 ret <4 x half> %r; 407} 408 409; CHECK:.func (.param .align 16 .b8 func_retval0[16]) 410; CHECK-LABEL: test_v5f16( 411; CHECK: .param .align 16 .b8 test_v5f16_param_0[16] 412; CHECK-DAG: ld.param.v4.b16 {[[E0:%h[0-9]+]], [[E1:%h[0-9]+]], [[E2:%h[0-9]+]], [[E3:%h[0-9]+]]}, [test_v5f16_param_0]; 413; CHECK-DAG: mov.b32 {[[E0:%h[0-9]+]], [[E1:%h[0-9]+]]}, [[HH01]]; 414; CHECK-DAG: ld.param.b16 [[E4:%h[0-9]+]], [test_v5f16_param_0+8]; 415; CHECK: .param .align 16 .b8 param0[16]; 416; CHECK-DAG: st.param.v4.b16 [param0+0], 417; CHECK-DAG: st.param.b16 [param0+8], [[E4]]; 418; CHECK: .param .align 16 .b8 retval0[16]; 419; CHECK: call.uni (retval0), 420; CHECK: test_v5f16, 421; CHECK-DAG: ld.param.v4.b16 {[[R0:%h[0-9]+]], [[R1:%h[0-9]+]], [[R2:%h[0-9]+]], [[R3:%h[0-9]+]]}, [retval0+0]; 422; CHECK-DAG: ld.param.b16 [[R4:%h[0-9]+]], [retval0+8]; 423; CHECK-DAG: st.param.v4.b16 [func_retval0+0], {[[R0]], [[R1]], [[R2]], [[R3]]}; 424; CHECK-DAG: st.param.b16 [func_retval0+8], [[R4]]; 425; CHECK: ret; 426define <5 x half> @test_v5f16(<5 x half> %a) { 427 %r = tail call <5 x half> @test_v5f16(<5 x half> %a); 428 ret <5 x half> %r; 429} 430 431; CHECK:.func (.param .align 16 .b8 func_retval0[16]) 432; CHECK-LABEL: test_v8f16( 433; CHECK: .param .align 16 .b8 test_v8f16_param_0[16] 434; CHECK: ld.param.v4.u32 {[[R01:%r[0-9]+]], [[R23:%r[0-9]+]], [[R45:%r[0-9]+]], [[R67:%r[0-9]+]]}, [test_v8f16_param_0]; 435; CHECK-DAG: mov.b32 [[HH01:%hh[0-9]+]], [[R01]]; 436; CHECK-DAG: mov.b32 [[HH23:%hh[0-9]+]], [[R23]]; 437; CHECK-DAG: mov.b32 [[HH45:%hh[0-9]+]], [[R45]]; 438; CHECK-DAG: mov.b32 [[HH67:%hh[0-9]+]], [[R67]]; 439; CHECK: .param .align 16 .b8 param0[16]; 440; CHECK: st.param.v4.b32 [param0+0], {[[HH01]], [[HH23]], [[HH45]], [[HH67]]}; 441; CHECK: .param .align 16 .b8 retval0[16]; 442; CHECK: call.uni (retval0), 443; CHECK: test_v8f16, 444; CHECK: ld.param.v4.b32 {[[RH01:%hh[0-9]+]], [[RH23:%hh[0-9]+]], [[RH45:%hh[0-9]+]], [[RH67:%hh[0-9]+]]}, [retval0+0]; 445; CHECK: st.param.v4.b32 [func_retval0+0], {[[RH01]], [[RH23]], [[RH45]], [[RH67]]}; 446; CHECK: ret; 447define <8 x half> @test_v8f16(<8 x half> %a) { 448 %r = tail call <8 x half> @test_v8f16(<8 x half> %a); 449 ret <8 x half> %r; 450} 451 452; CHECK:.func (.param .align 32 .b8 func_retval0[32]) 453; CHECK-LABEL: test_v9f16( 454; CHECK: .param .align 32 .b8 test_v9f16_param_0[32] 455; CHECK-DAG: ld.param.v4.b16 {[[E0:%h[0-9]+]], [[E1:%h[0-9]+]], [[E2:%h[0-9]+]], [[E3:%h[0-9]+]]}, [test_v9f16_param_0]; 456; CHECK-DAG: ld.param.v4.b16 {[[E4:%h[0-9]+]], [[E5:%h[0-9]+]], [[E6:%h[0-9]+]], [[E7:%h[0-9]+]]}, [test_v9f16_param_0+8]; 457; CHECK-DAG: ld.param.b16 [[E8:%h[0-9]+]], [test_v9f16_param_0+16]; 458; CHECK: .param .align 32 .b8 param0[32]; 459; CHECK-DAG: st.param.v4.b16 [param0+0], 460; CHECK-DAG: st.param.v4.b16 [param0+8], 461; CHECK-DAG: st.param.b16 [param0+16], [[E8]]; 462; CHECK: .param .align 32 .b8 retval0[32]; 463; CHECK: call.uni (retval0), 464; CHECK: test_v9f16, 465; CHECK-DAG: ld.param.v4.b16 {[[R0:%h[0-9]+]], [[R1:%h[0-9]+]], [[R2:%h[0-9]+]], [[R3:%h[0-9]+]]}, [retval0+0]; 466; CHECK-DAG: ld.param.v4.b16 {[[R4:%h[0-9]+]], [[R5:%h[0-9]+]], [[R6:%h[0-9]+]], [[R7:%h[0-9]+]]}, [retval0+8]; 467; CHECK-DAG: ld.param.b16 [[R8:%h[0-9]+]], [retval0+16]; 468; CHECK-DAG: st.param.v4.b16 [func_retval0+0], {[[R0]], [[R1]], [[R2]], [[R3]]}; 469; CHECK-DAG: st.param.v4.b16 [func_retval0+8], {[[R4]], [[R5]], [[R6]], [[R7]]}; 470; CHECK-DAG: st.param.b16 [func_retval0+16], [[R8]]; 471; CHECK: ret; 472define <9 x half> @test_v9f16(<9 x half> %a) { 473 %r = tail call <9 x half> @test_v9f16(<9 x half> %a); 474 ret <9 x half> %r; 475} 476 477; CHECK: .func (.param .b32 func_retval0) 478; CHECK-LABEL: test_i32( 479; CHECK-NEXT: .param .b32 test_i32_param_0 480; CHECK: ld.param.u32 [[E:%r[0-9]+]], [test_i32_param_0]; 481; CHECK: .param .b32 param0; 482; CHECK: st.param.b32 [param0+0], [[E]]; 483; CHECK: .param .b32 retval0; 484; CHECK: call.uni (retval0), 485; CHECK-NEXT: test_i32, 486; CHECK: ld.param.b32 [[R:%r[0-9]+]], [retval0+0]; 487; CHECK: st.param.b32 [func_retval0+0], [[R]]; 488; CHECK-NEXT: ret; 489define i32 @test_i32(i32 %a) { 490 %r = tail call i32 @test_i32(i32 %a); 491 ret i32 %r; 492} 493 494; CHECK: .func (.param .align 16 .b8 func_retval0[16]) 495; CHECK-LABEL: test_v3i32( 496; CHECK-NEXT: .param .align 16 .b8 test_v3i32_param_0[16] 497; CHECK-DAG: ld.param.u32 [[E2:%r[0-9]+]], [test_v3i32_param_0+8]; 498; CHECK-DAG: ld.param.v2.u32 {[[E0:%r[0-9]+]], [[E1:%r[0-9]+]]}, [test_v3i32_param_0]; 499; CHECK: .param .align 16 .b8 param0[16]; 500; CHECK: st.param.v2.b32 [param0+0], {[[E0]], [[E1]]}; 501; CHECK: st.param.b32 [param0+8], [[E2]]; 502; CHECK: .param .align 16 .b8 retval0[16]; 503; CHECK: call.uni (retval0), 504; CHECK-NEXT: test_v3i32, 505; CHECK: ld.param.v2.b32 {[[RE0:%r[0-9]+]], [[RE1:%r[0-9]+]]}, [retval0+0]; 506; CHECK: ld.param.b32 [[RE2:%r[0-9]+]], [retval0+8]; 507; CHECK-DAG: st.param.v2.b32 [func_retval0+0], {[[RE0]], [[RE1]]}; 508; CHECK-DAG: st.param.b32 [func_retval0+8], [[RE2]]; 509; CHECK-NEXT: ret; 510define <3 x i32> @test_v3i32(<3 x i32> %a) { 511 %r = tail call <3 x i32> @test_v3i32(<3 x i32> %a); 512 ret <3 x i32> %r; 513} 514 515; CHECK: .func (.param .align 16 .b8 func_retval0[16]) 516; CHECK-LABEL: test_v4i32( 517; CHECK-NEXT: .param .align 16 .b8 test_v4i32_param_0[16] 518; CHECK: ld.param.v4.u32 {[[E0:%r[0-9]+]], [[E1:%r[0-9]+]], [[E2:%r[0-9]+]], [[E3:%r[0-9]+]]}, [test_v4i32_param_0] 519; CHECK: .param .align 16 .b8 param0[16]; 520; CHECK: st.param.v4.b32 [param0+0], {[[E0]], [[E1]], [[E2]], [[E3]]}; 521; CHECK: .param .align 16 .b8 retval0[16]; 522; CHECK: call.uni (retval0), 523; CHECK-NEXT: test_v4i32, 524; CHECK: ld.param.v4.b32 {[[RE0:%r[0-9]+]], [[RE1:%r[0-9]+]], [[RE2:%r[0-9]+]], [[RE3:%r[0-9]+]]}, [retval0+0]; 525; CHECK: st.param.v4.b32 [func_retval0+0], {[[RE0]], [[RE1]], [[RE2]], [[RE3]]} 526; CHECK-NEXT: ret; 527define <4 x i32> @test_v4i32(<4 x i32> %a) { 528 %r = tail call <4 x i32> @test_v4i32(<4 x i32> %a); 529 ret <4 x i32> %r; 530} 531 532; CHECK: .func (.param .align 32 .b8 func_retval0[32]) 533; CHECK-LABEL: test_v5i32( 534; CHECK-NEXT: .param .align 32 .b8 test_v5i32_param_0[32] 535; CHECK-DAG: ld.param.u32 [[E4:%r[0-9]+]], [test_v5i32_param_0+16]; 536; CHECK-DAG: ld.param.v4.u32 {[[E0:%r[0-9]+]], [[E1:%r[0-9]+]], [[E2:%r[0-9]+]], [[E3:%r[0-9]+]]}, [test_v5i32_param_0] 537; CHECK: .param .align 32 .b8 param0[32]; 538; CHECK-DAG: st.param.v4.b32 [param0+0], {[[E0]], [[E1]], [[E2]], [[E3]]}; 539; CHECK-DAG: st.param.b32 [param0+16], [[E4]]; 540; CHECK: .param .align 32 .b8 retval0[32]; 541; CHECK: call.uni (retval0), 542; CHECK-NEXT: test_v5i32, 543; CHECK-DAG: ld.param.v4.b32 {[[RE0:%r[0-9]+]], [[RE1:%r[0-9]+]], [[RE2:%r[0-9]+]], [[RE3:%r[0-9]+]]}, [retval0+0]; 544; CHECK-DAG: ld.param.b32 [[RE4:%r[0-9]+]], [retval0+16]; 545; CHECK-DAG: st.param.v4.b32 [func_retval0+0], {[[RE0]], [[RE1]], [[RE2]], [[RE3]]} 546; CHECK-DAG: st.param.b32 [func_retval0+16], [[RE4]]; 547; CHECK-NEXT: ret; 548define <5 x i32> @test_v5i32(<5 x i32> %a) { 549 %r = tail call <5 x i32> @test_v5i32(<5 x i32> %a); 550 ret <5 x i32> %r; 551} 552 553; CHECK: .func (.param .b32 func_retval0) 554; CHECK-LABEL: test_f32( 555; CHECK-NEXT: .param .b32 test_f32_param_0 556; CHECK: ld.param.f32 [[E:%f[0-9]+]], [test_f32_param_0]; 557; CHECK: .param .b32 param0; 558; CHECK: st.param.f32 [param0+0], [[E]]; 559; CHECK: .param .b32 retval0; 560; CHECK: call.uni (retval0), 561; CHECK-NEXT: test_f32, 562; CHECK: ld.param.f32 [[R:%f[0-9]+]], [retval0+0]; 563; CHECK: st.param.f32 [func_retval0+0], [[R]]; 564; CHECK-NEXT: ret; 565define float @test_f32(float %a) { 566 %r = tail call float @test_f32(float %a); 567 ret float %r; 568} 569 570; CHECK: .func (.param .b64 func_retval0) 571; CHECK-LABEL: test_i64( 572; CHECK-NEXT: .param .b64 test_i64_param_0 573; CHECK: ld.param.u64 [[E:%rd[0-9]+]], [test_i64_param_0]; 574; CHECK: .param .b64 param0; 575; CHECK: st.param.b64 [param0+0], [[E]]; 576; CHECK: .param .b64 retval0; 577; CHECK: call.uni (retval0), 578; CHECK-NEXT: test_i64, 579; CHECK: ld.param.b64 [[R:%rd[0-9]+]], [retval0+0]; 580; CHECK: st.param.b64 [func_retval0+0], [[R]]; 581; CHECK-NEXT: ret; 582define i64 @test_i64(i64 %a) { 583 %r = tail call i64 @test_i64(i64 %a); 584 ret i64 %r; 585} 586 587; CHECK: .func (.param .align 32 .b8 func_retval0[32]) 588; CHECK-LABEL: test_v3i64( 589; CHECK-NEXT: .param .align 32 .b8 test_v3i64_param_0[32] 590; CHECK-DAG: ld.param.u64 [[E2:%rd[0-9]+]], [test_v3i64_param_0+16]; 591; CHECK-DAG: ld.param.v2.u64 {[[E0:%rd[0-9]+]], [[E1:%rd[0-9]+]]}, [test_v3i64_param_0]; 592; CHECK: .param .align 32 .b8 param0[32]; 593; CHECK: st.param.v2.b64 [param0+0], {[[E0]], [[E1]]}; 594; CHECK: st.param.b64 [param0+16], [[E2]]; 595; CHECK: .param .align 32 .b8 retval0[32]; 596; CHECK: call.uni (retval0), 597; CHECK-NEXT: test_v3i64, 598; CHECK: ld.param.v2.b64 {[[RE0:%rd[0-9]+]], [[RE1:%rd[0-9]+]]}, [retval0+0]; 599; CHECK: ld.param.b64 [[RE2:%rd[0-9]+]], [retval0+16]; 600; CHECK-DAG: st.param.v2.b64 [func_retval0+0], {[[RE0]], [[RE1]]}; 601; CHECK-DAG: st.param.b64 [func_retval0+16], [[RE2]]; 602; CHECK-DAG: st.param.v2.b64 [func_retval0+0], {[[RE0]], [[RE1]]}; 603; CHECK-DAG: st.param.b64 [func_retval0+16], [[RE2]]; 604; CHECK-NEXT: ret; 605define <3 x i64> @test_v3i64(<3 x i64> %a) { 606 %r = tail call <3 x i64> @test_v3i64(<3 x i64> %a); 607 ret <3 x i64> %r; 608} 609 610; For i64 vector loads are limited by PTX to 2 elements. 611; CHECK: .func (.param .align 32 .b8 func_retval0[32]) 612; CHECK-LABEL: test_v4i64( 613; CHECK-NEXT: .param .align 32 .b8 test_v4i64_param_0[32] 614; CHECK-DAG: ld.param.v2.u64 {[[E2:%rd[0-9]+]], [[E3:%rd[0-9]+]]}, [test_v4i64_param_0+16]; 615; CHECK-DAG: ld.param.v2.u64 {[[E0:%rd[0-9]+]], [[E1:%rd[0-9]+]]}, [test_v4i64_param_0]; 616; CHECK: .param .align 32 .b8 param0[32]; 617; CHECK: st.param.v2.b64 [param0+0], {[[E0]], [[E1]]}; 618; CHECK: st.param.v2.b64 [param0+16], {[[E2]], [[E3]]}; 619; CHECK: .param .align 32 .b8 retval0[32]; 620; CHECK: call.uni (retval0), 621; CHECK-NEXT: test_v4i64, 622; CHECK: ld.param.v2.b64 {[[RE0:%rd[0-9]+]], [[RE1:%rd[0-9]+]]}, [retval0+0]; 623; CHECK: ld.param.v2.b64 {[[RE2:%rd[0-9]+]], [[RE3:%rd[0-9]+]]}, [retval0+16]; 624; CHECK-DAG: st.param.v2.b64 [func_retval0+16], {[[RE2]], [[RE3]]}; 625; CHECK-DAG: st.param.v2.b64 [func_retval0+0], {[[RE0]], [[RE1]]}; 626; CHECK-NEXT: ret; 627define <4 x i64> @test_v4i64(<4 x i64> %a) { 628 %r = tail call <4 x i64> @test_v4i64(<4 x i64> %a); 629 ret <4 x i64> %r; 630} 631 632; Aggregates, on the other hand, do not get extended. 633 634; CHECK: .func (.param .align 1 .b8 func_retval0[1]) 635; CHECK-LABEL: test_s_i1( 636; CHECK-NEXT: .align 1 .b8 test_s_i1_param_0[1] 637; CHECK: ld.param.u8 [[A:%rs[0-9]+]], [test_s_i1_param_0]; 638; CHECK: .param .align 1 .b8 param0[1]; 639; CHECK: st.param.b8 [param0+0], [[A]] 640; CHECK: .param .align 1 .b8 retval0[1]; 641; CHECK: call.uni 642; CHECK-NEXT: test_s_i1, 643; CHECK: ld.param.b8 [[R:%rs[0-9]+]], [retval0+0]; 644; CHECK: st.param.b8 [func_retval0+0], [[R]]; 645; CHECK-NEXT: ret; 646define %s_i1 @test_s_i1(%s_i1 %a) { 647 %r = tail call %s_i1 @test_s_i1(%s_i1 %a); 648 ret %s_i1 %r; 649} 650 651; CHECK: .func (.param .align 1 .b8 func_retval0[1]) 652; CHECK-LABEL: test_s_i8( 653; CHECK-NEXT: .param .align 1 .b8 test_s_i8_param_0[1] 654; CHECK: ld.param.u8 [[A:%rs[0-9]+]], [test_s_i8_param_0]; 655; CHECK: .param .align 1 .b8 param0[1]; 656; CHECK: st.param.b8 [param0+0], [[A]] 657; CHECK: .param .align 1 .b8 retval0[1]; 658; CHECK: call.uni 659; CHECK-NEXT: test_s_i8, 660; CHECK: ld.param.b8 [[R:%rs[0-9]+]], [retval0+0]; 661; CHECK: st.param.b8 [func_retval0+0], [[R]]; 662; CHECK-NEXT: ret; 663define %s_i8 @test_s_i8(%s_i8 %a) { 664 %r = tail call %s_i8 @test_s_i8(%s_i8 %a); 665 ret %s_i8 %r; 666} 667 668; CHECK: .func (.param .align 2 .b8 func_retval0[2]) 669; CHECK-LABEL: test_s_i16( 670; CHECK-NEXT: .param .align 2 .b8 test_s_i16_param_0[2] 671; CHECK: ld.param.u16 [[A:%rs[0-9]+]], [test_s_i16_param_0]; 672; CHECK: .param .align 2 .b8 param0[2]; 673; CHECK: st.param.b16 [param0+0], [[A]] 674; CHECK: .param .align 2 .b8 retval0[2]; 675; CHECK: call.uni 676; CHECK-NEXT: test_s_i16, 677; CHECK: ld.param.b16 [[R:%rs[0-9]+]], [retval0+0]; 678; CHECK: st.param.b16 [func_retval0+0], [[R]]; 679; CHECK-NEXT: ret; 680define %s_i16 @test_s_i16(%s_i16 %a) { 681 %r = tail call %s_i16 @test_s_i16(%s_i16 %a); 682 ret %s_i16 %r; 683} 684 685; CHECK: .func (.param .align 2 .b8 func_retval0[2]) 686; CHECK-LABEL: test_s_f16( 687; CHECK-NEXT: .param .align 2 .b8 test_s_f16_param_0[2] 688; CHECK: ld.param.b16 [[A:%h[0-9]+]], [test_s_f16_param_0]; 689; CHECK: .param .align 2 .b8 param0[2]; 690; CHECK: st.param.b16 [param0+0], [[A]] 691; CHECK: .param .align 2 .b8 retval0[2]; 692; CHECK: call.uni 693; CHECK-NEXT: test_s_f16, 694; CHECK: ld.param.b16 [[R:%h[0-9]+]], [retval0+0]; 695; CHECK: st.param.b16 [func_retval0+0], [[R]]; 696; CHECK-NEXT: ret; 697define %s_f16 @test_s_f16(%s_f16 %a) { 698 %r = tail call %s_f16 @test_s_f16(%s_f16 %a); 699 ret %s_f16 %r; 700} 701 702; CHECK: .func (.param .align 4 .b8 func_retval0[4]) 703; CHECK-LABEL: test_s_i32( 704; CHECK-NEXT: .param .align 4 .b8 test_s_i32_param_0[4] 705; CHECK: ld.param.u32 [[E:%r[0-9]+]], [test_s_i32_param_0]; 706; CHECK: .param .align 4 .b8 param0[4] 707; CHECK: st.param.b32 [param0+0], [[E]]; 708; CHECK: .param .align 4 .b8 retval0[4]; 709; CHECK: call.uni (retval0), 710; CHECK-NEXT: test_s_i32, 711; CHECK: ld.param.b32 [[R:%r[0-9]+]], [retval0+0]; 712; CHECK: st.param.b32 [func_retval0+0], [[R]]; 713; CHECK-NEXT: ret; 714define %s_i32 @test_s_i32(%s_i32 %a) { 715 %r = tail call %s_i32 @test_s_i32(%s_i32 %a); 716 ret %s_i32 %r; 717} 718 719; CHECK: .func (.param .align 4 .b8 func_retval0[4]) 720; CHECK-LABEL: test_s_f32( 721; CHECK-NEXT: .param .align 4 .b8 test_s_f32_param_0[4] 722; CHECK: ld.param.f32 [[E:%f[0-9]+]], [test_s_f32_param_0]; 723; CHECK: .param .align 4 .b8 param0[4] 724; CHECK: st.param.f32 [param0+0], [[E]]; 725; CHECK: .param .align 4 .b8 retval0[4]; 726; CHECK: call.uni (retval0), 727; CHECK-NEXT: test_s_f32, 728; CHECK: ld.param.f32 [[R:%f[0-9]+]], [retval0+0]; 729; CHECK: st.param.f32 [func_retval0+0], [[R]]; 730; CHECK-NEXT: ret; 731define %s_f32 @test_s_f32(%s_f32 %a) { 732 %r = tail call %s_f32 @test_s_f32(%s_f32 %a); 733 ret %s_f32 %r; 734} 735 736; CHECK: .func (.param .align 8 .b8 func_retval0[8]) 737; CHECK-LABEL: test_s_i64( 738; CHECK-NEXT: .param .align 8 .b8 test_s_i64_param_0[8] 739; CHECK: ld.param.u64 [[E:%rd[0-9]+]], [test_s_i64_param_0]; 740; CHECK: .param .align 8 .b8 param0[8]; 741; CHECK: st.param.b64 [param0+0], [[E]]; 742; CHECK: .param .align 8 .b8 retval0[8]; 743; CHECK: call.uni (retval0), 744; CHECK-NEXT: test_s_i64, 745; CHECK: ld.param.b64 [[R:%rd[0-9]+]], [retval0+0]; 746; CHECK: st.param.b64 [func_retval0+0], [[R]]; 747; CHECK-NEXT: ret; 748define %s_i64 @test_s_i64(%s_i64 %a) { 749 %r = tail call %s_i64 @test_s_i64(%s_i64 %a); 750 ret %s_i64 %r; 751} 752 753; Fields that have different types, but identical sizes are not vectorized. 754; CHECK: .func (.param .align 8 .b8 func_retval0[24]) 755; CHECK-LABEL: test_s_i32f32( 756; CHECK: .param .align 8 .b8 test_s_i32f32_param_0[24] 757; CHECK-DAG: ld.param.u64 [[E4:%rd[0-9]+]], [test_s_i32f32_param_0+16]; 758; CHECK-DAG: ld.param.f32 [[E3:%f[0-9]+]], [test_s_i32f32_param_0+12]; 759; CHECK-DAG: ld.param.u32 [[E2:%r[0-9]+]], [test_s_i32f32_param_0+8]; 760; CHECK-DAG: ld.param.f32 [[E1:%f[0-9]+]], [test_s_i32f32_param_0+4]; 761; CHECK-DAG: ld.param.u32 [[E0:%r[0-9]+]], [test_s_i32f32_param_0]; 762; CHECK: .param .align 8 .b8 param0[24]; 763; CHECK-DAG: st.param.b32 [param0+0], [[E0]]; 764; CHECK-DAG: st.param.f32 [param0+4], [[E1]]; 765; CHECK-DAG: st.param.b32 [param0+8], [[E2]]; 766; CHECK-DAG: st.param.f32 [param0+12], [[E3]]; 767; CHECK-DAG: st.param.b64 [param0+16], [[E4]]; 768; CHECK: .param .align 8 .b8 retval0[24]; 769; CHECK: call.uni (retval0), 770; CHECK-NEXT: test_s_i32f32, 771; CHECK-DAG: ld.param.b32 [[RE0:%r[0-9]+]], [retval0+0]; 772; CHECK-DAG: ld.param.f32 [[RE1:%f[0-9]+]], [retval0+4]; 773; CHECK-DAG: ld.param.b32 [[RE2:%r[0-9]+]], [retval0+8]; 774; CHECK-DAG: ld.param.f32 [[RE3:%f[0-9]+]], [retval0+12]; 775; CHECK-DAG: ld.param.b64 [[RE4:%rd[0-9]+]], [retval0+16]; 776; CHECK-DAG: st.param.b32 [func_retval0+0], [[RE0]]; 777; CHECK-DAG: st.param.f32 [func_retval0+4], [[RE1]]; 778; CHECK-DAG: st.param.b32 [func_retval0+8], [[RE2]]; 779; CHECK-DAG: st.param.f32 [func_retval0+12], [[RE3]]; 780; CHECK-DAG: st.param.b64 [func_retval0+16], [[RE4]]; 781; CHECK: ret; 782define %s_i32f32 @test_s_i32f32(%s_i32f32 %a) { 783 %r = tail call %s_i32f32 @test_s_i32f32(%s_i32f32 %a); 784 ret %s_i32f32 %r; 785} 786 787; We do vectorize consecutive fields with matching types. 788; CHECK:.visible .func (.param .align 8 .b8 func_retval0[24]) 789; CHECK-LABEL: test_s_i32x4( 790; CHECK: .param .align 8 .b8 test_s_i32x4_param_0[24] 791; CHECK-DAG: ld.param.u64 [[RD1:%rd[0-9]+]], [test_s_i32x4_param_0+16]; 792; CHECK-DAG: ld.param.v2.u32 {[[E2:%r[0-9]+]], [[E3:%r[0-9]+]]}, [test_s_i32x4_param_0+8]; 793; CHECK-DAG: ld.param.v2.u32 {[[E0:%r[0-9]+]], [[E1:%r[0-9]+]]}, [test_s_i32x4_param_0]; 794; CHECK: .param .align 8 .b8 param0[24]; 795; CHECK: st.param.v2.b32 [param0+0], {[[E0]], [[E1]]}; 796; CHECK: st.param.v2.b32 [param0+8], {[[E2]], [[E3]]}; 797; CHECK: st.param.b64 [param0+16], [[E4]]; 798; CHECK: .param .align 8 .b8 retval0[24]; 799; CHECK: call.uni (retval0), 800; CHECK-NEXT: test_s_i32x4, 801; CHECK: ld.param.v2.b32 {[[RE0:%r[0-9]+]], [[RE1:%r[0-9]+]]}, [retval0+0]; 802; CHECK: ld.param.v2.b32 {[[RE2:%r[0-9]+]], [[RE3:%r[0-9]+]]}, [retval0+8]; 803; CHECK: ld.param.b64 [[RE4:%rd[0-9]+]], [retval0+16]; 804; CHECK-DAG: st.param.v2.b32 [func_retval0+0], {[[RE0]], [[RE1]]}; 805; CHECK-DAG: st.param.v2.b32 [func_retval0+8], {[[RE2]], [[RE3]]}; 806; CHECK-DAG: st.param.b64 [func_retval0+16], [[RE4]]; 807; CHECK: ret; 808 809define %s_i32x4 @test_s_i32x4(%s_i32x4 %a) { 810 %r = tail call %s_i32x4 @test_s_i32x4(%s_i32x4 %a); 811 ret %s_i32x4 %r; 812} 813 814; CHECK:.visible .func (.param .align 8 .b8 func_retval0[32]) 815; CHECK-LABEL: test_s_i1i32x4( 816; CHECK: .param .align 8 .b8 test_s_i1i32x4_param_0[32] 817; CHECK: ld.param.u64 [[E5:%rd[0-9]+]], [test_s_i1i32x4_param_0+24]; 818; CHECK: ld.param.u32 [[E4:%r[0-9]+]], [test_s_i1i32x4_param_0+16]; 819; CHECK: ld.param.u32 [[E3:%r[0-9]+]], [test_s_i1i32x4_param_0+12]; 820; CHECK: ld.param.u8 [[E2:%rs[0-9]+]], [test_s_i1i32x4_param_0+8]; 821; CHECK: ld.param.v2.u32 {[[E0:%r[0-9]+]], [[E1:%r[0-9]+]]}, [test_s_i1i32x4_param_0]; 822; CHECK: .param .align 8 .b8 param0[32]; 823; CHECK: st.param.v2.b32 [param0+0], {[[E0]], [[E1]]}; 824; CHECK: st.param.b8 [param0+8], [[E2]]; 825; CHECK: st.param.b32 [param0+12], [[E3]]; 826; CHECK: st.param.b32 [param0+16], [[E4]]; 827; CHECK: st.param.b64 [param0+24], [[E5]]; 828; CHECK: .param .align 8 .b8 retval0[32]; 829; CHECK: call.uni (retval0), 830; CHECK: test_s_i1i32x4, 831; CHECK: ( 832; CHECK: param0 833; CHECK: ); 834; CHECK: ld.param.v2.b32 {[[RE0:%r[0-9]+]], [[RE1:%r[0-9]+]]}, [retval0+0]; 835; CHECK: ld.param.b8 [[RE2:%rs[0-9]+]], [retval0+8]; 836; CHECK: ld.param.b32 [[RE3:%r[0-9]+]], [retval0+12]; 837; CHECK: ld.param.b32 [[RE4:%r[0-9]+]], [retval0+16]; 838; CHECK: ld.param.b64 [[RE5:%rd[0-9]+]], [retval0+24]; 839; CHECK: st.param.v2.b32 [func_retval0+0], {[[RE0]], [[RE1]]}; 840; CHECK: st.param.b8 [func_retval0+8], [[RE2]]; 841; CHECK: st.param.b32 [func_retval0+12], [[RE3]]; 842; CHECK: st.param.b32 [func_retval0+16], [[RE4]]; 843; CHECK: st.param.b64 [func_retval0+24], [[RE5]]; 844; CHECK: ret; 845 846define %s_i8i32x4 @test_s_i1i32x4(%s_i8i32x4 %a) { 847 %r = tail call %s_i8i32x4 @test_s_i1i32x4(%s_i8i32x4 %a); 848 ret %s_i8i32x4 %r; 849} 850 851; -- All loads/stores from parameters aligned by one must be done one 852; -- byte at a time. 853; CHECK:.visible .func (.param .align 1 .b8 func_retval0[25]) 854; CHECK-LABEL: test_s_i1i32x4p( 855; CHECK-DAG: .param .align 1 .b8 test_s_i1i32x4p_param_0[25] 856; CHECK-DAG: ld.param.u8 %r{{.*}}, [test_s_i1i32x4p_param_0+24]; 857; CHECK-DAG: ld.param.u8 %r{{.*}}, [test_s_i1i32x4p_param_0+23]; 858; CHECK-DAG: ld.param.u8 %r{{.*}}, [test_s_i1i32x4p_param_0+22]; 859; CHECK-DAG: ld.param.u8 %r{{.*}}, [test_s_i1i32x4p_param_0+21]; 860; CHECK-DAG: ld.param.u8 %r{{.*}}, [test_s_i1i32x4p_param_0+20]; 861; CHECK-DAG: ld.param.u8 %r{{.*}}, [test_s_i1i32x4p_param_0+19]; 862; CHECK-DAG: ld.param.u8 %r{{.*}}, [test_s_i1i32x4p_param_0+18]; 863; CHECK-DAG: ld.param.u8 %r{{.*}}, [test_s_i1i32x4p_param_0+17]; 864; CHECK-DAG: ld.param.u8 %r{{.*}}, [test_s_i1i32x4p_param_0+16]; 865; CHECK-DAG: ld.param.u8 %r{{.*}}, [test_s_i1i32x4p_param_0+15]; 866; CHECK-DAG: ld.param.u8 %r{{.*}}, [test_s_i1i32x4p_param_0+14]; 867; CHECK-DAG: ld.param.u8 %r{{.*}}, [test_s_i1i32x4p_param_0+13]; 868; CHECK-DAG: ld.param.u8 %r{{.*}}, [test_s_i1i32x4p_param_0+12]; 869; CHECK-DAG: ld.param.u8 %r{{.*}}, [test_s_i1i32x4p_param_0+11]; 870; CHECK-DAG: ld.param.u8 %r{{.*}}, [test_s_i1i32x4p_param_0+10]; 871; CHECK-DAG: ld.param.u8 %r{{.*}}, [test_s_i1i32x4p_param_0+9]; 872; CHECK-DAG: ld.param.u8 %r{{.*}}, [test_s_i1i32x4p_param_0+8]; 873; CHECK-DAG: ld.param.u8 %r{{.*}}, [test_s_i1i32x4p_param_0+7]; 874; CHECK-DAG: ld.param.u8 %r{{.*}}, [test_s_i1i32x4p_param_0+6]; 875; CHECK-DAG: ld.param.u8 %r{{.*}}, [test_s_i1i32x4p_param_0+5]; 876; CHECK-DAG: ld.param.u8 %r{{.*}}, [test_s_i1i32x4p_param_0+4]; 877; CHECK-DAG: ld.param.u8 %r{{.*}}, [test_s_i1i32x4p_param_0+3]; 878; CHECK-DAG: ld.param.u8 %r{{.*}}, [test_s_i1i32x4p_param_0+2]; 879; CHECK-DAG: ld.param.u8 %r{{.*}}, [test_s_i1i32x4p_param_0+1]; 880; CHECK-DAG: ld.param.u8 %r{{.*}}, [test_s_i1i32x4p_param_0]; 881; --- TODO 882; --- Unaligned parameter store/ return value load is broken in both nvcc 883; --- and llvm and needs to be fixed. 884; CHECK: .param .align 1 .b8 param0[25]; 885; CHECK-DAG: st.param.b32 [param0+0], 886; CHECK-DAG: st.param.b32 [param0+4], 887; CHECK-DAG: st.param.b8 [param0+8], 888; CHECK-DAG: st.param.b32 [param0+9], 889; CHECK-DAG: st.param.b32 [param0+13], 890; CHECK-DAG: st.param.b64 [param0+17], 891; CHECK: .param .align 1 .b8 retval0[25]; 892; CHECK: call.uni (retval0), 893; CHECK-NEXT: test_s_i1i32x4p, 894; CHECK-DAG: ld.param.b32 %r41, [retval0+0]; 895; CHECK-DAG: ld.param.b32 %r42, [retval0+4]; 896; CHECK-DAG: ld.param.b8 %rs2, [retval0+8]; 897; CHECK-DAG: ld.param.b32 %r43, [retval0+9]; 898; CHECK-DAG: ld.param.b32 %r44, [retval0+13]; 899; CHECK-DAG: ld.param.b64 %rd23, [retval0+17]; 900; CHECK-DAG: st.param.b32 [func_retval0+0], 901; CHECK-DAG: st.param.b32 [func_retval0+4], 902; CHECK-DAG: st.param.b8 [func_retval0+8], 903; CHECK-DAG: st.param.b32 [func_retval0+9], 904; CHECK-DAG: st.param.b32 [func_retval0+13], 905; CHECK-DAG: st.param.b64 [func_retval0+17], 906 907define %s_i8i32x4p @test_s_i1i32x4p(%s_i8i32x4p %a) { 908 %r = tail call %s_i8i32x4p @test_s_i1i32x4p(%s_i8i32x4p %a); 909 ret %s_i8i32x4p %r; 910} 911 912; Check that we can vectorize loads that span multiple aggregate fields. 913; CHECK:.visible .func (.param .align 16 .b8 func_retval0[80]) 914; CHECK-LABEL: test_s_crossfield( 915; CHECK: .param .align 16 .b8 test_s_crossfield_param_0[80] 916; CHECK: ld.param.u32 [[E15:%r[0-9]+]], [test_s_crossfield_param_0+64]; 917; CHECK: ld.param.v4.u32 {[[E11:%r[0-9]+]], [[E12:%r[0-9]+]], [[E13:%r[0-9]+]], [[E14:%r[0-9]+]]}, [test_s_crossfield_param_0+48]; 918; CHECK: ld.param.v4.u32 {[[E7:%r[0-9]+]], [[E8:%r[0-9]+]], [[E9:%r[0-9]+]], [[E10:%r[0-9]+]]}, [test_s_crossfield_param_0+32]; 919; CHECK: ld.param.v4.u32 {[[E3:%r[0-9]+]], [[E4:%r[0-9]+]], [[E5:%r[0-9]+]], [[E6:%r[0-9]+]]}, [test_s_crossfield_param_0+16]; 920; CHECK: ld.param.u32 [[E2:%r[0-9]+]], [test_s_crossfield_param_0+8]; 921; CHECK: ld.param.v2.u32 {[[E0:%r[0-9]+]], [[E1:%r[0-9]+]]}, [test_s_crossfield_param_0]; 922; CHECK: .param .align 16 .b8 param0[80]; 923; CHECK: st.param.v2.b32 [param0+0], {[[E0]], [[E1]]}; 924; CHECK: st.param.b32 [param0+8], [[E2]]; 925; CHECK: st.param.v4.b32 [param0+16], {[[E3]], [[E4]], [[E5]], [[E6]]}; 926; CHECK: st.param.v4.b32 [param0+32], {[[E7]], [[E8]], [[E9]], [[E10]]}; 927; CHECK: st.param.v4.b32 [param0+48], {[[E11]], [[E12]], [[E13]], [[E14]]}; 928; CHECK: st.param.b32 [param0+64], [[E15]]; 929; CHECK: .param .align 16 .b8 retval0[80]; 930; CHECK: call.uni (retval0), 931; CHECK: test_s_crossfield, 932; CHECK: ld.param.v2.b32 {[[RE0:%r[0-9]+]], [[RE1:%r[0-9]+]]}, [retval0+0]; 933; CHECK: ld.param.b32 [[RE2:%r[0-9]+]], [retval0+8]; 934; CHECK: ld.param.v4.b32 {[[RE3:%r[0-9]+]], [[RE4:%r[0-9]+]], [[RE5:%r[0-9]+]], [[RE6:%r[0-9]+]]}, [retval0+16]; 935; CHECK: ld.param.v4.b32 {[[RE7:%r[0-9]+]], [[RE8:%r[0-9]+]], [[RE9:%r[0-9]+]], [[RE10:%r[0-9]+]]}, [retval0+32]; 936; CHECK: ld.param.v4.b32 {[[RE11:%r[0-9]+]], [[RE12:%r[0-9]+]], [[RE13:%r[0-9]+]], [[RE14:%r[0-9]+]]}, [retval0+48]; 937; CHECK: ld.param.b32 [[RE15:%r[0-9]+]], [retval0+64]; 938; CHECK: st.param.v2.b32 [func_retval0+0], {[[RE0]], [[RE1]]}; 939; CHECK: st.param.b32 [func_retval0+8], [[RE2]]; 940; CHECK: st.param.v4.b32 [func_retval0+16], {[[RE3]], [[RE4]], [[RE5]], [[RE6]]}; 941; CHECK: st.param.v4.b32 [func_retval0+32], {[[RE7]], [[RE8]], [[RE9]], [[RE10]]}; 942; CHECK: st.param.v4.b32 [func_retval0+48], {[[RE11]], [[RE12]], [[RE13]], [[RE14]]}; 943; CHECK: st.param.b32 [func_retval0+64], [[RE15]]; 944; CHECK: ret; 945 946define %s_crossfield @test_s_crossfield(%s_crossfield %a) { 947 %r = tail call %s_crossfield @test_s_crossfield(%s_crossfield %a); 948 ret %s_crossfield %r; 949} 950