Skip to content

Commit 627688d

Browse files
committed
attach naked function target features to module assembly
1 parent 58ae2c4 commit 627688d

12 files changed

Lines changed: 297 additions & 7 deletions

File tree

compiler/rustc_codegen_cranelift/src/global_asm.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ impl<'tcx> AsmCodegenMethods<'tcx> for GlobalAsmContext<'_, 'tcx> {
3030
operands: &[GlobalAsmOperandRef<'tcx>],
3131
options: InlineAsmOptions,
3232
_line_spans: &[Span],
33+
_target_features: &[String],
3334
) {
3435
codegen_global_asm_inner(self.tcx, self.global_asm, template, operands, options);
3536
}

compiler/rustc_codegen_gcc/src/asm.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -928,6 +928,7 @@ impl<'gcc, 'tcx> AsmCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
928928
operands: &[GlobalAsmOperandRef<'tcx>],
929929
options: InlineAsmOptions,
930930
line_spans: &[Span],
931+
_target_features: &[String],
931932
) {
932933
let asm_arch = self.tcx.sess.asm_arch.unwrap();
933934

compiler/rustc_codegen_llvm/src/asm.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -414,6 +414,7 @@ impl<'tcx> AsmCodegenMethods<'tcx> for CodegenCx<'_, 'tcx> {
414414
operands: &[GlobalAsmOperandRef<'tcx>],
415415
options: InlineAsmOptions,
416416
_line_spans: &[Span],
417+
target_features: &[String],
417418
) {
418419
let asm_arch = self.tcx.sess.asm_arch.unwrap();
419420

@@ -499,14 +500,11 @@ impl<'tcx> AsmCodegenMethods<'tcx> for CodegenCx<'_, 'tcx> {
499500
template_str.push_str("\n.att_syntax\n");
500501
}
501502

502-
let target_features = self.tcx.global_backend_features(()).join(",");
503-
let target_cpu = llvm_util::target_cpu(self.tcx.sess);
504-
505503
llvm::append_module_inline_asm(
506504
self.llmod,
507505
template_str.as_bytes(),
508-
&target_features,
509-
target_cpu,
506+
&target_features.join(","),
507+
llvm_util::target_cpu(self.tcx.sess),
510508
);
511509
}
512510

compiler/rustc_codegen_ssa/src/base.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -490,7 +490,14 @@ where
490490
})
491491
.collect();
492492

493-
cx.codegen_global_asm(asm.template, &operands, asm.options, asm.line_spans);
493+
let target_features = cx.tcx().global_backend_features(());
494+
cx.codegen_global_asm(
495+
asm.template,
496+
&operands,
497+
asm.options,
498+
asm.line_spans,
499+
&target_features,
500+
);
494501
} else {
495502
span_bug!(item.span, "Mismatch between hir::Item type and MonoItem type")
496503
}

compiler/rustc_codegen_ssa/src/mir/naked_asm.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,9 @@ pub fn codegen_naked_asm<
5454
template_vec.extend(template.iter().cloned());
5555
template_vec.push(rustc_ast::ast::InlineAsmTemplatePiece::String(end.into()));
5656

57-
cx.codegen_global_asm(&template_vec, &operands, options, line_spans);
57+
let target_features: Vec<_> =
58+
cx.tcx().asm_target_features(instance.def_id()).iter().map(|s| format!("+{s}")).collect();
59+
cx.codegen_global_asm(&template_vec, &operands, options, line_spans, &target_features);
5860
}
5961

6062
fn inline_to_global_operand<'a, 'tcx, Cx: LayoutOf<'tcx, LayoutOfResult = TyAndLayout<'tcx>>>(

compiler/rustc_codegen_ssa/src/traits/asm.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ pub trait AsmCodegenMethods<'tcx> {
7272
operands: &[GlobalAsmOperandRef<'tcx>],
7373
options: InlineAsmOptions,
7474
line_spans: &[Span],
75+
target_features: &[String],
7576
);
7677

7778
/// The mangled name of this instance
Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
//@ revisions: aarch64-elf aarch64-macho aarch64-coff x86_64 s390x riscv64 powerpc64 loongarch64
2+
//@ add-minicore
3+
//@ assembly-output: emit-asm
4+
//@ min-llvm-version: 23
5+
//
6+
//@ [x86_64] compile-flags: --target x86_64-unknown-linux-gnu
7+
//@ [x86_64] needs-llvm-components: x86
8+
//
9+
//@ [aarch64-elf] compile-flags: --target aarch64-unknown-linux-gnu
10+
//@ [aarch64-elf] needs-llvm-components: aarch64
11+
//@ [aarch64-macho] compile-flags: --target aarch64-apple-darwin
12+
//@ [aarch64-macho] needs-llvm-components: aarch64
13+
//@ [aarch64-coff] compile-flags: --target aarch64-pc-windows-gnullvm
14+
//@ [aarch64-coff] needs-llvm-components: aarch64
15+
//
16+
//@ [s390x] compile-flags: --target s390x-unknown-linux-gnu
17+
//@ [s390x] needs-llvm-components: systemz
18+
//
19+
//@ [powerpc64] compile-flags: --target powerpc64-unknown-linux-gnu
20+
//@ [powerpc64] needs-llvm-components: powerpc
21+
//
22+
//@ [riscv64] compile-flags: --target riscv64gc-unknown-linux-gnu
23+
//@ [riscv64] needs-llvm-components: riscv
24+
//
25+
// NOTE: loongarch64 does not error when using an instruction without enabling the corresponding
26+
// target feature.
27+
//@ [loongarch64] compile-flags: --target loongarch64-unknown-linux-gnu
28+
//@ [loongarch64] needs-llvm-components: loongarch
29+
30+
// Test that the #[target_feature(enable = ...)]` works on naked functions.
31+
32+
#![crate_type = "lib"]
33+
#![feature(no_core, naked_functions_target_feature, asm_experimental_arch)]
34+
#![feature(s390x_target_feature, powerpc_target_feature, loongarch_target_feature)]
35+
#![no_core]
36+
37+
extern crate minicore;
38+
use minicore::*;
39+
40+
// x86_64-LABEL: vpclmulqdq:
41+
// x86_64: vpclmulqdq
42+
#[no_mangle]
43+
#[unsafe(naked)]
44+
#[cfg(target_arch = "x86_64")]
45+
#[target_feature(enable = "vpclmulqdq")]
46+
unsafe extern "C" fn vpclmulqdq() {
47+
naked_asm!("vpclmulqdq zmm1, zmm2, zmm3, 4")
48+
}
49+
50+
// i8mm is not enabled by default
51+
//
52+
// note that aarch64-apple-darwin enables more features than aarch64-unknown-linux-gnu
53+
//
54+
// aarch64-elf-LABEL: i8mm:
55+
// aarch64-elf: usdot
56+
// aarch64-macho-LABEL: i8mm:
57+
// aarch64-macho: usdot
58+
// aarch64-coff-LABEL: i8mm:
59+
// aarch64-coff: usdot
60+
#[no_mangle]
61+
#[unsafe(naked)]
62+
#[cfg(target_arch = "aarch64")]
63+
#[target_feature(enable = "i8mm")]
64+
unsafe extern "C" fn i8mm() {
65+
naked_asm!("usdot v0.4s, v1.16b, v2.4b[3]")
66+
}
67+
68+
// riscv64: sh1add:
69+
// riscv64: sh1add
70+
#[no_mangle]
71+
#[unsafe(naked)]
72+
#[cfg(target_arch = "riscv64")]
73+
#[target_feature(enable = "zba")]
74+
unsafe extern "C" fn sh1add() {
75+
naked_asm!("sh1add a0, a1, a2", "ret");
76+
}
77+
78+
#[cfg(target_arch = "s390x")]
79+
mod s390x {
80+
use super::*;
81+
82+
// s390x: vector:
83+
// s390x: vavglg
84+
#[no_mangle]
85+
#[unsafe(naked)]
86+
#[target_feature(enable = "vector")]
87+
unsafe extern "C" fn vector() {
88+
naked_asm!("vavglg %v0, %v0, %v0")
89+
}
90+
91+
// s390x: vector_enhancements_1:
92+
// s390x: vfcesbs
93+
#[no_mangle]
94+
#[unsafe(naked)]
95+
#[target_feature(enable = "vector-enhancements-1")]
96+
unsafe extern "C" fn vector_enhancements_1() {
97+
naked_asm!("vfcesbs %v0, %v0, %v0")
98+
}
99+
100+
// s390x: vector_enhancements_2:
101+
// s390x: vclfp
102+
#[no_mangle]
103+
#[unsafe(naked)]
104+
#[target_feature(enable = "vector-enhancements-2")]
105+
unsafe extern "C" fn vector_enhancements_2() {
106+
naked_asm!("vclfp %v0, %v0, 0, 0, 0")
107+
}
108+
109+
// s390x: vector_packed_decimal:
110+
// s390x: vlrlr
111+
#[no_mangle]
112+
#[unsafe(naked)]
113+
#[target_feature(enable = "vector-packed-decimal")]
114+
unsafe extern "C" fn vector_packed_decimal() {
115+
naked_asm!("vlrlr %v24, %r3, 0(%r2)", "br %r14")
116+
}
117+
118+
// s390x: vector_packed_decimal_enhancement:
119+
// s390x: vcvbg
120+
#[no_mangle]
121+
#[unsafe(naked)]
122+
#[target_feature(enable = "vector-packed-decimal-enhancement")]
123+
unsafe extern "C" fn vector_packed_decimal_enhancement() {
124+
naked_asm!("vcvbg %r0, %v0, 0, 1")
125+
}
126+
127+
// s390x: vector_packed_decimal_enhancement_2:
128+
// s390x: vupkzl
129+
#[no_mangle]
130+
#[unsafe(naked)]
131+
#[target_feature(enable = "vector-packed-decimal-enhancement-2")]
132+
unsafe extern "C" fn vector_packed_decimal_enhancement_2() {
133+
naked_asm!("vupkzl %v0, %v0, 0")
134+
}
135+
}
136+
137+
// powerpc64: power10_vector:
138+
// powerpc64: xxpermx
139+
#[no_mangle]
140+
#[unsafe(naked)]
141+
#[cfg(target_arch = "powerpc64")]
142+
#[target_feature(enable = "power10-vector")]
143+
unsafe extern "C" fn power10_vector() {
144+
naked_asm!("xxpermx 34, 0, 1, 2, 0", "blr")
145+
}
146+
147+
// loongarch64: lasx:
148+
// loongarch64: xvadd.b
149+
#[no_mangle]
150+
#[unsafe(naked)]
151+
#[cfg(target_arch = "loongarch64")]
152+
#[target_feature(enable = "lasx")]
153+
unsafe extern "C" fn lasx() {
154+
naked_asm!("xvadd.b $xr0, $xr0, $xr1", "ret")
155+
}
156+
157+
// wasm32: simd128:
158+
// wasm32: i8x16.shuffle
159+
#[no_mangle]
160+
#[unsafe(naked)]
161+
#[cfg(target_arch = "wasm32")]
162+
#[target_feature(enable = "simd128")]
163+
unsafe extern "C" fn simd128() {
164+
naked_asm!("i8x16.shuffle 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15", "return");
165+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
//@ add-minicore
2+
//@ build-fail
3+
//@ revisions: vanilla sha3
4+
//@ compile-flags: --target aarch64-unknown-linux-gnu -Z deduplicate-diagnostics=yes
5+
//@[sha3] compile-flags: -Ctarget-feature=+sha3
6+
//@ needs-llvm-components: aarch64
7+
//@ min-llvm-version: 23
8+
9+
#![crate_type = "lib"]
10+
#![feature(no_core, naked_functions_target_feature)]
11+
#![no_core]
12+
13+
extern crate minicore;
14+
use minicore::*;
15+
16+
// check that a naked function using target features does not keep these features enabled
17+
// for subsequent asm blocks.
18+
19+
#[no_mangle]
20+
#[unsafe(naked)]
21+
#[target_feature(enable = "i8mm")]
22+
unsafe extern "C" fn a() {
23+
naked_asm!("usdot v0.4s, v1.16b, v2.4b[3]")
24+
}
25+
26+
//~? ERROR instruction requires: i8mm
27+
28+
#[no_mangle]
29+
#[unsafe(naked)]
30+
unsafe extern "C" fn c() {
31+
naked_asm!("usdot v0.4s, v2.16b, v2.4b[3]")
32+
}
33+
34+
#[no_mangle]
35+
#[unsafe(naked)]
36+
#[target_feature(enable = "sha3")]
37+
unsafe extern "C" fn d() {
38+
naked_asm!("eor3 v0.16b, v1.16b, v2.16b, v3.16b")
39+
}
40+
41+
//[vanilla]~? ERROR instruction requires: sha3
42+
43+
#[no_mangle]
44+
#[unsafe(naked)]
45+
unsafe extern "C" fn b() {
46+
naked_asm!("eor3 v0.16b, v1.16b, v2.16b, v3.16b")
47+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
error: instruction requires: i8mm
2+
|
3+
note: instantiated into assembly here
4+
--> <inline asm>:15:1
5+
|
6+
LL | usdot v0.4s, v2.16b, v2.4b[3]
7+
| ^
8+
9+
error: aborting due to 1 previous error
10+
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
error: instruction requires: sha3
2+
|
3+
note: instantiated into assembly here
4+
--> <inline asm>:6:1
5+
|
6+
LL | eor3 v0.16b, v1.16b, v2.16b, v3.16b
7+
| ^
8+
9+
error: instruction requires: i8mm
10+
|
11+
note: instantiated into assembly here
12+
--> <inline asm>:15:1
13+
|
14+
LL | usdot v0.4s, v2.16b, v2.4b[3]
15+
| ^
16+
17+
error: aborting due to 2 previous errors
18+

0 commit comments

Comments
 (0)