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