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