Skip to content

Commit ecb84e2

Browse files
author
Kjetil Kjeka
committed
NVPTX: Avoid PassMode::Direct for args in C abi
1 parent e1fcecb commit ecb84e2

File tree

2 files changed

+322
-4
lines changed

2 files changed

+322
-4
lines changed

compiler/rustc_target/src/abi/call/nvptx64.rs

+6-4
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,16 @@ use crate::abi::call::{ArgAbi, FnAbi, PassMode, Reg, Size, Uniform};
22
use crate::abi::{HasDataLayout, TyAbiInterface};
33

44
fn classify_ret<Ty>(ret: &mut ArgAbi<'_, Ty>) {
5-
if ret.layout.is_aggregate() && ret.layout.size.bits() > 64 {
6-
ret.make_indirect();
5+
if !ret.layout.is_aggregate() && ret.layout.size.bits() < 32 {
6+
ret.extend_integer_width_to(32);
77
}
88
}
99

1010
fn classify_arg<Ty>(arg: &mut ArgAbi<'_, Ty>) {
11-
if arg.layout.is_aggregate() && arg.layout.size.bits() > 64 {
12-
arg.make_indirect();
11+
if arg.layout.is_aggregate() {
12+
arg.make_indirect_byval(None);
13+
} else if arg.layout.size.bits() < 32 {
14+
arg.extend_integer_width_to(32);
1315
}
1416
}
1517

tests/assembly/nvptx-c-abi-v7.rs

+316
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,316 @@
1+
// assembly-output: ptx-linker
2+
// compile-flags: --crate-type cdylib -C target-cpu=sm_86
3+
// only-nvptx64
4+
// ignore-nvptx64
5+
6+
// The PTX ABI stability is tied to major versions of the PTX ISA
7+
// These tests assume major version 7
8+
9+
// CHECK: .version 7
10+
11+
#![feature(abi_ptx, lang_items, no_core)]
12+
#![no_core]
13+
14+
#[lang = "sized"]
15+
trait Sized {}
16+
#[lang = "copy"]
17+
trait Copy {}
18+
19+
#[repr(C)]
20+
pub struct SingleU8 {
21+
f: u8,
22+
}
23+
24+
#[repr(C)]
25+
pub struct DoubleU8 {
26+
f: u8,
27+
g: u8,
28+
}
29+
30+
#[repr(C)]
31+
pub struct TripleU8 {
32+
f: u8,
33+
g: u8,
34+
h: u8,
35+
}
36+
37+
#[repr(C)]
38+
pub struct TripleU16 {
39+
f: u16,
40+
g: u16,
41+
h: u16,
42+
}
43+
#[repr(C)]
44+
pub struct TripleU32 {
45+
f: u32,
46+
g: u32,
47+
h: u32,
48+
}
49+
#[repr(C)]
50+
pub struct TripleU64 {
51+
f: u64,
52+
g: u64,
53+
h: u64,
54+
}
55+
56+
#[repr(C)]
57+
pub struct DoubleFloat {
58+
f: f32,
59+
g: f32,
60+
}
61+
62+
#[repr(C)]
63+
pub struct TripleFloat {
64+
f: f32,
65+
g: f32,
66+
h: f32,
67+
}
68+
69+
#[repr(C)]
70+
pub struct TripleDouble {
71+
f: f64,
72+
g: f64,
73+
h: f64,
74+
}
75+
76+
#[repr(C)]
77+
pub struct ManyIntegers {
78+
f: u8,
79+
g: u16,
80+
h: u32,
81+
i: u64,
82+
}
83+
84+
#[repr(C)]
85+
pub struct ManyNumerics {
86+
f: u8,
87+
g: u16,
88+
h: u32,
89+
i: u64,
90+
j: f32,
91+
k: f64,
92+
}
93+
94+
// CHECK: .visible .func f_u8_arg(
95+
// CHECK: .param .b32 f_u8_arg_param_0
96+
#[no_mangle]
97+
pub unsafe extern "C" fn f_u8_arg(_a: u8) {}
98+
99+
// CHECK: .visible .func f_u16_arg(
100+
// CHECK: .param .b32 f_u16_arg_param_0
101+
#[no_mangle]
102+
pub unsafe extern "C" fn f_u16_arg(_a: u16) {}
103+
104+
// CHECK: .visible .func f_u32_arg(
105+
// CHECK: .param .b32 f_u32_arg_param_0
106+
#[no_mangle]
107+
pub unsafe extern "C" fn f_u32_arg(_a: u32) {}
108+
109+
// CHECK: .visible .func f_u64_arg(
110+
// CHECK: .param .b64 f_u64_arg_param_0
111+
#[no_mangle]
112+
pub unsafe extern "C" fn f_u64_arg(_a: u64) {}
113+
114+
// CHECK: .visible .func f_u128_arg(
115+
// CHECK: .param .align 16 .b8 f_u128_arg_param_0[16]
116+
#[no_mangle]
117+
pub unsafe extern "C" fn f_u128_arg(_a: u128) {}
118+
119+
// CHECK: .visible .func f_i8_arg(
120+
// CHECK: .param .b32 f_i8_arg_param_0
121+
#[no_mangle]
122+
pub unsafe extern "C" fn f_i8_arg(_a: i8) {}
123+
124+
// CHECK: .visible .func f_i16_arg(
125+
// CHECK: .param .b32 f_i16_arg_param_0
126+
#[no_mangle]
127+
pub unsafe extern "C" fn f_i16_arg(_a: i16) {}
128+
129+
// CHECK: .visible .func f_i32_arg(
130+
// CHECK: .param .b32 f_i32_arg_param_0
131+
#[no_mangle]
132+
pub unsafe extern "C" fn f_i32_arg(_a: i32) {}
133+
134+
// CHECK: .visible .func f_i64_arg(
135+
// CHECK: .param .b64 f_i64_arg_param_0
136+
#[no_mangle]
137+
pub unsafe extern "C" fn f_i64_arg(_a: i64) {}
138+
139+
// CHECK: .visible .func f_i128_arg(
140+
// CHECK: .param .align 16 .b8 f_i128_arg_param_0[16]
141+
#[no_mangle]
142+
pub unsafe extern "C" fn f_i128_arg(_a: i128) {}
143+
144+
// CHECK: .visible .func f_f32_arg(
145+
// CHECK: .param .b32 f_f32_arg_param_0
146+
#[no_mangle]
147+
pub unsafe extern "C" fn f_f32_arg(_a: f32) {}
148+
149+
// CHECK: .visible .func f_f64_arg(
150+
// CHECK: .param .b64 f_f64_arg_param_0
151+
#[no_mangle]
152+
pub unsafe extern "C" fn f_f64_arg(_a: f64) {}
153+
154+
// CHECK: .visible .func f_single_u8_arg(
155+
// CHECK: .param .align 1 .b8 f_single_u8_arg_param_0[1]
156+
#[no_mangle]
157+
pub unsafe extern "C" fn f_single_u8_arg(_a: SingleU8) {}
158+
159+
// CHECK: .visible .func f_double_u8_arg(
160+
// CHECK: .param .align 1 .b8 f_double_u8_arg_param_0[2]
161+
#[no_mangle]
162+
pub unsafe extern "C" fn f_double_u8_arg(_a: DoubleU8) {}
163+
164+
// CHECK: .visible .func f_triple_u8_arg(
165+
// CHECK: .param .align 1 .b8 f_triple_u8_arg_param_0[3]
166+
#[no_mangle]
167+
pub unsafe extern "C" fn f_triple_u8_arg(_a: TripleU8) {}
168+
169+
// CHECK: .visible .func f_triple_u16_arg(
170+
// CHECK: .param .align 2 .b8 f_triple_u16_arg_param_0[6]
171+
#[no_mangle]
172+
pub unsafe extern "C" fn f_triple_u16_arg(_a: TripleU16) {}
173+
174+
// CHECK: .visible .func f_triple_u32_arg(
175+
// CHECK: .param .align 4 .b8 f_triple_u32_arg_param_0[12]
176+
#[no_mangle]
177+
pub unsafe extern "C" fn f_triple_u32_arg(_a: TripleU32) {}
178+
179+
// CHECK: .visible .func f_triple_u64_arg(
180+
// CHECK: .param .align 8 .b8 f_triple_u64_arg_param_0[24]
181+
#[no_mangle]
182+
pub unsafe extern "C" fn f_triple_u64_arg(_a: TripleU64) {}
183+
184+
// CHECK: .visible .func f_many_integers_arg(
185+
// CHECK: .param .align 8 .b8 f_many_integers_arg_param_0[16]
186+
#[no_mangle]
187+
pub unsafe extern "C" fn f_many_integers_arg(_a: ManyIntegers) {}
188+
189+
// CHECK: .visible .func f_double_float_arg(
190+
// CHECK: .param .align 4 .b8 f_double_float_arg_param_0[8]
191+
#[no_mangle]
192+
pub unsafe extern "C" fn f_double_float_arg(_a: DoubleFloat) {}
193+
194+
// CHECK: .visible .func f_triple_float_arg(
195+
// CHECK: .param .align 4 .b8 f_triple_float_arg_param_0[12]
196+
#[no_mangle]
197+
pub unsafe extern "C" fn f_triple_float_arg(_a: TripleFloat) {}
198+
199+
// CHECK: .visible .func f_triple_double_arg(
200+
// CHECK: .param .align 8 .b8 f_triple_double_arg_param_0[24]
201+
#[no_mangle]
202+
pub unsafe extern "C" fn f_triple_double_arg(_a: TripleDouble) {}
203+
204+
// CHECK: .visible .func f_many_numerics_arg(
205+
// CHECK: .param .align 8 .b8 f_many_numerics_arg_param_0[32]
206+
#[no_mangle]
207+
pub unsafe extern "C" fn f_many_numerics_arg(_a: ManyNumerics) {}
208+
209+
// CHECK: .visible .func (.param .b32 func_retval0) f_u8_ret(
210+
#[no_mangle]
211+
pub unsafe extern "C" fn f_u8_ret() -> u8{0}
212+
213+
// CHECK: .visible .func (.param .b32 func_retval0) f_u16_ret(
214+
#[no_mangle]
215+
pub unsafe extern "C" fn f_u16_ret() -> u16 {1}
216+
217+
// CHECK: .visible .func (.param .b32 func_retval0) f_u32_ret(
218+
#[no_mangle]
219+
pub unsafe extern "C" fn f_u32_ret() -> u32 {2}
220+
221+
// CHECK: .visible .func (.param .b64 func_retval0) f_u64_ret(
222+
#[no_mangle]
223+
pub unsafe extern "C" fn f_u64_ret() -> u64 {3}
224+
225+
// CHECK: .visible .func (.param .align 16 .b8 func_retval0[16]) f_u128_ret(
226+
#[no_mangle]
227+
pub unsafe extern "C" fn f_u128_ret() -> u128 {4}
228+
229+
// CHECK: .visible .func (.param .b32 func_retval0) f_i8_ret(
230+
#[no_mangle]
231+
pub unsafe extern "C" fn f_i8_ret() -> i8 {5}
232+
233+
// CHECK: .visible .func (.param .b32 func_retval0) f_i16_ret(
234+
#[no_mangle]
235+
pub unsafe extern "C" fn f_i16_ret() -> i16 {6}
236+
237+
// CHECK: .visible .func (.param .b32 func_retval0) f_i32_ret(
238+
#[no_mangle]
239+
pub unsafe extern "C" fn f_i32_ret() -> i32 {7}
240+
241+
// CHECK: .visible .func (.param .b64 func_retval0) f_i64_ret(
242+
#[no_mangle]
243+
pub unsafe extern "C" fn f_i64_ret() -> i64 {8}
244+
245+
// CHECK: .visible .func (.param .align 16 .b8 func_retval0[16]) f_i128_ret(
246+
#[no_mangle]
247+
pub unsafe extern "C" fn f_i128_ret() -> i128 {9}
248+
249+
// CHECK: .visible .func (.param .b32 func_retval0) f_f32_ret(
250+
#[no_mangle]
251+
pub unsafe extern "C" fn f_f32_ret() -> f32 {10.0}
252+
253+
// CHECK: .visible .func (.param .b64 func_retval0) f_f64_ret(
254+
#[no_mangle]
255+
pub unsafe extern "C" fn f_f64_ret() -> f64 {11.0}
256+
257+
// CHECK: .visible .func (.param .align 1 .b8 func_retval0[1]) f_single_u8_ret(
258+
#[no_mangle]
259+
pub unsafe extern "C" fn f_single_u8_ret() -> SingleU8 {SingleU8{f: 12}}
260+
261+
// CHECK: .visible .func (.param .align 1 .b8 func_retval0[2]) f_double_u8_ret(
262+
#[no_mangle]
263+
pub unsafe extern "C" fn f_double_u8_ret() -> DoubleU8 {DoubleU8{f: 13, g: 14}}
264+
265+
// CHECK: .visible .func (.param .align 1 .b8 func_retval0[3]) f_triple_u8_ret(
266+
#[no_mangle]
267+
pub unsafe extern "C" fn f_triple_u8_ret() -> TripleU8 {TripleU8{f: 15, g: 16, h: 17}}
268+
269+
// CHECK: .visible .func (.param .align 2 .b8 func_retval0[6]) f_triple_u16_ret(
270+
#[no_mangle]
271+
pub unsafe extern "C" fn f_triple_u16_ret() -> TripleU16 {TripleU16{f: 18, g: 19, h: 20}}
272+
273+
// CHECK: .visible .func (.param .align 4 .b8 func_retval0[12]) f_triple_u32_ret(
274+
#[no_mangle]
275+
pub unsafe extern "C" fn f_triple_u32_ret() -> TripleU32{TripleU32{f: 20, g: 21, h: 22}}
276+
277+
// CHECK: .visible .func (.param .align 8 .b8 func_retval0[24]) f_triple_u64_ret(
278+
#[no_mangle]
279+
pub unsafe extern "C" fn f_triple_u64_ret() -> TripleU64 {TripleU64 {f: 23, g: 24, h: 25}}
280+
281+
// CHECK: .visible .func (.param .align 8 .b8 func_retval0[16]) f_many_integers_ret(
282+
#[no_mangle]
283+
pub unsafe extern "C" fn f_many_integers_ret() -> ManyIntegers {
284+
ManyIntegers{f: 26, g: 27, h: 28, i: 29}
285+
}
286+
287+
// CHECK: .visible .func (.param .align 4 .b8 func_retval0[8]) f_double_float_ret(
288+
#[no_mangle]
289+
pub unsafe extern "C" fn f_double_float_ret() -> DoubleFloat {
290+
DoubleFloat{f: 29.0, g: 30.0}
291+
}
292+
293+
// CHECK: .visible .func (.param .align 4 .b8 func_retval0[12]) f_triple_float_ret(
294+
#[no_mangle]
295+
pub unsafe extern "C" fn f_triple_float_ret() -> TripleFloat {
296+
TripleFloat{f: 31.0, g: 32.0, h: 33.0}
297+
}
298+
299+
// CHECK: .visible .func (.param .align 8 .b8 func_retval0[24]) f_triple_double_ret(
300+
#[no_mangle]
301+
pub unsafe extern "C" fn f_triple_double_ret() -> TripleDouble {
302+
TripleDouble{f: 34.0, g: 35.0, h: 36.0}
303+
}
304+
305+
// CHECK: .visible .func (.param .align 8 .b8 func_retval0[32]) f_many_numerics_ret(
306+
#[no_mangle]
307+
pub unsafe extern "C" fn f_many_numerics_ret() -> ManyNumerics {
308+
ManyNumerics{
309+
f: 37,
310+
g: 38,
311+
h: 39,
312+
i: 40,
313+
j: 41.0,
314+
k: 43.0,
315+
}
316+
}

0 commit comments

Comments
 (0)