Skip to content

Commit 1c014d1

Browse files
authored
Cranelift: ensure ISA level needed for SIMD is present when SIMD is enabled. (#3816)
Addresses #3809: when we are asked to create a Cranelift backend with shared flags that indicate support for SIMD, we should check that the ISA level needed for our SIMD lowerings is present.
1 parent ef17a36 commit 1c014d1

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

55 files changed

+172
-84
lines changed

cranelift/codegen/meta/src/isa/x86.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,19 +17,22 @@ fn define_settings(shared: &SettingGroup) -> SettingGroup {
1717
"has_sse3",
1818
"Has support for SSE3.",
1919
"SSE3: CPUID.01H:ECX.SSE3[bit 0]",
20-
false,
20+
// Needed for default `enable_simd` setting.
21+
true,
2122
);
2223
let has_ssse3 = settings.add_bool(
2324
"has_ssse3",
2425
"Has support for SSSE3.",
2526
"SSSE3: CPUID.01H:ECX.SSSE3[bit 9]",
26-
false,
27+
// Needed for default `enable_simd` setting.
28+
true,
2729
);
2830
let has_sse41 = settings.add_bool(
2931
"has_sse41",
3032
"Has support for SSE4.1.",
3133
"SSE4.1: CPUID.01H:ECX.SSE4_1[bit 19]",
32-
false,
34+
// Needed for default `enable_simd` setting.
35+
true,
3336
);
3437
let has_sse42 = settings.add_bool(
3538
"has_sse42",

cranelift/codegen/src/isa/aarch64/inst/unwind/systemv.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,8 @@ mod tests {
8585
fn test_simple_func() {
8686
let isa = lookup(triple!("aarch64"))
8787
.expect("expect aarch64 ISA")
88-
.finish(Flags::new(builder()));
88+
.finish(Flags::new(builder()))
89+
.expect("Creating compiler backend");
8990

9091
let mut context = Context::for_function(create_function(
9192
CallConv::SystemV,
@@ -127,7 +128,8 @@ mod tests {
127128
fn test_multi_return_func() {
128129
let isa = lookup(triple!("aarch64"))
129130
.expect("expect aarch64 ISA")
130-
.finish(Flags::new(builder()));
131+
.finish(Flags::new(builder()))
132+
.expect("Creating compiler backend");
131133

132134
let mut context = Context::for_function(create_multi_return_function(CallConv::SystemV));
133135

cranelift/codegen/src/isa/aarch64/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ pub fn isa_builder(triple: Triple) -> IsaBuilder {
172172
constructor: |triple, shared_flags, builder| {
173173
let isa_flags = aarch64_settings::Flags::new(&shared_flags, builder);
174174
let backend = AArch64Backend::new_with_flags(triple, shared_flags, isa_flags);
175-
Box::new(backend)
175+
Ok(Box::new(backend))
176176
},
177177
}
178178
}

cranelift/codegen/src/isa/mod.rs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,8 @@ impl fmt::Display for LookupError {
139139
pub struct Builder {
140140
triple: Triple,
141141
setup: settings::Builder,
142-
constructor: fn(Triple, settings::Flags, settings::Builder) -> Box<dyn TargetIsa>,
142+
constructor:
143+
fn(Triple, settings::Flags, settings::Builder) -> CodegenResult<Box<dyn TargetIsa>>,
143144
}
144145

145146
impl Builder {
@@ -153,9 +154,13 @@ impl Builder {
153154
self.setup.iter()
154155
}
155156

156-
/// Combine the ISA-specific settings with the provided ISA-independent settings and allocate a
157-
/// fully configured `TargetIsa` trait object.
158-
pub fn finish(self, shared_flags: settings::Flags) -> Box<dyn TargetIsa> {
157+
/// Combine the ISA-specific settings with the provided
158+
/// ISA-independent settings and allocate a fully configured
159+
/// `TargetIsa` trait object. May return an error if some of the
160+
/// flags are inconsistent or incompatible: for example, some
161+
/// platform-independent features, like general SIMD support, may
162+
/// need certain ISA extensions to be enabled.
163+
pub fn finish(self, shared_flags: settings::Flags) -> CodegenResult<Box<dyn TargetIsa>> {
159164
(self.constructor)(self.triple, shared_flags, self.setup)
160165
}
161166
}

cranelift/codegen/src/isa/s390x/inst/unwind/systemv.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,8 @@ mod tests {
100100
fn test_simple_func() {
101101
let isa = lookup(triple!("s390x"))
102102
.expect("expect s390x ISA")
103-
.finish(Flags::new(builder()));
103+
.finish(Flags::new(builder()))
104+
.expect("Creating compiler backend");
104105

105106
let mut context = Context::for_function(create_function(
106107
CallConv::SystemV,
@@ -142,7 +143,8 @@ mod tests {
142143
fn test_multi_return_func() {
143144
let isa = lookup(triple!("s390x"))
144145
.expect("expect s390x ISA")
145-
.finish(Flags::new(builder()));
146+
.finish(Flags::new(builder()))
147+
.expect("Creating compiler backend");
146148

147149
let mut context = Context::for_function(create_multi_return_function(
148150
CallConv::SystemV,

cranelift/codegen/src/isa/s390x/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ pub fn isa_builder(triple: Triple) -> IsaBuilder {
179179
constructor: |triple, shared_flags, builder| {
180180
let isa_flags = s390x_settings::Flags::new(&shared_flags, builder);
181181
let backend = S390xBackend::new_with_flags(triple, shared_flags, isa_flags);
182-
Box::new(backend)
182+
Ok(Box::new(backend))
183183
},
184184
}
185185
}

cranelift/codegen/src/isa/x64/inst/unwind/systemv.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,8 @@ mod tests {
112112
fn test_simple_func() {
113113
let isa = lookup(triple!("x86_64"))
114114
.expect("expect x86 ISA")
115-
.finish(Flags::new(builder()));
115+
.finish(Flags::new(builder()))
116+
.expect("expect backend creation to succeed");
116117

117118
let mut context = Context::for_function(create_function(
118119
CallConv::SystemV,
@@ -154,7 +155,8 @@ mod tests {
154155
fn test_multi_return_func() {
155156
let isa = lookup(triple!("x86_64"))
156157
.expect("expect x86 ISA")
157-
.finish(Flags::new(builder()));
158+
.finish(Flags::new(builder()))
159+
.expect("expect backend creation to succeed");
158160

159161
let mut context = Context::for_function(create_multi_return_function(CallConv::SystemV));
160162

cranelift/codegen/src/isa/x64/mod.rs

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use crate::isa::Builder as IsaBuilder;
1111
use crate::machinst::{
1212
compile, MachCompileResult, MachTextSectionBuilder, TextSectionBuilder, VCode,
1313
};
14-
use crate::result::CodegenResult;
14+
use crate::result::{CodegenError, CodegenResult};
1515
use crate::settings::{self as shared_settings, Flags};
1616
use alloc::{boxed::Box, vec::Vec};
1717
use core::fmt;
@@ -174,10 +174,21 @@ fn isa_constructor(
174174
triple: Triple,
175175
shared_flags: Flags,
176176
builder: shared_settings::Builder,
177-
) -> Box<dyn TargetIsa> {
177+
) -> CodegenResult<Box<dyn TargetIsa>> {
178178
let isa_flags = x64_settings::Flags::new(&shared_flags, builder);
179+
180+
// Check for compatibility between flags and ISA level
181+
// requested. In particular, SIMD support requires SSE4.1.
182+
if shared_flags.enable_simd() {
183+
if !isa_flags.has_sse3() || !isa_flags.has_ssse3() || !isa_flags.has_sse41() {
184+
return Err(CodegenError::Unsupported(
185+
"SIMD support requires SSE3, SSSE3, and SSE4.1 on x86_64.".into(),
186+
));
187+
}
188+
}
189+
179190
let backend = X64Backend::new_with_flags(triple, shared_flags, isa_flags);
180-
Box::new(backend)
191+
Ok(Box::new(backend))
181192
}
182193

183194
#[cfg(test)]
@@ -332,4 +343,20 @@ mod test {
332343

333344
assert_eq!(code, &golden[..]);
334345
}
346+
347+
// Check that feature tests for SIMD work correctly.
348+
#[test]
349+
fn simd_required_features() {
350+
let mut shared_flags_builder = settings::builder();
351+
shared_flags_builder.set("enable_simd", "true").unwrap();
352+
let shared_flags = settings::Flags::new(shared_flags_builder);
353+
let mut isa_builder = crate::isa::lookup_by_name("x86_64").unwrap();
354+
isa_builder.set("has_sse3", "false").unwrap();
355+
isa_builder.set("has_ssse3", "false").unwrap();
356+
isa_builder.set("has_sse41", "false").unwrap();
357+
assert!(matches!(
358+
isa_builder.finish(shared_flags),
359+
Err(CodegenError::Unsupported(_)),
360+
));
361+
}
335362
}

cranelift/filetests/filetests/isa/x64/simd-lane-access-compile.clif

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
test compile precise-output
22
set enable_simd
3-
target x86_64 has_ssse3 has_sse41
3+
target x86_64 has_sse3 has_ssse3 has_sse41
44

55
;; shuffle
66

cranelift/filetests/filetests/runtests/simd-bitselect.clif

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
test run
22
set enable_simd
33
target aarch64
4-
target x86_64
4+
target x86_64 has_sse3 has_ssse3 has_sse41
55

66
function %bitselect_i32x4(i32x4, i32x4, i32x4) -> i32x4 {
77
block0(v0: i32x4, v1: i32x4, v2: i32x4):

cranelift/filetests/filetests/runtests/simd-comparison.clif

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ test run
22
target aarch64
33
; target s390x TODO: Not yet implemented on s390x
44
set enable_simd
5-
target x86_64
5+
target x86_64 has_sse3 has_ssse3 has_sse41
66

77
function %icmp_eq_i8x16() -> b8 {
88
block0:

cranelift/filetests/filetests/runtests/simd-conversion.clif

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ test run
22
target aarch64
33
; target s390x TODO: Not yet implemented on s390x
44
set enable_simd
5-
target x86_64
5+
target x86_64 has_sse3 has_ssse3 has_sse41
66

77
function %fcvt_from_sint(i32x4) -> f32x4 {
88
block0(v0: i32x4):

cranelift/filetests/filetests/runtests/simd-extractlane.clif

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ test interpret
22
test run
33
target aarch64
44
set enable_simd
5-
target x86_64
5+
target x86_64 has_sse3 has_ssse3 has_sse41
66

77
function %extractlane_4(i8x16) -> i8 {
88
block0(v0: i8x16):

cranelift/filetests/filetests/runtests/simd-iabs.clif

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ test interpret
22
test run
33
target aarch64
44
set enable_simd
5-
target x86_64
5+
target x86_64 has_sse3 has_ssse3 has_sse41
66

77
function %iabs_i8x16(i8x16) -> i8x16 {
88
block0(v0: i8x16):

cranelift/filetests/filetests/runtests/simd-insertlane.clif

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ test interpret
22
test run
33
target aarch64
44
set enable_simd
5-
target x86_64
5+
target x86_64 has_sse3 has_ssse3 has_sse41
66

77
function %insertlane_15(i8x16, i8) -> i8x16 {
88
block0(v0: i8x16, v1: i8):

cranelift/filetests/filetests/runtests/simd-lane-access.clif

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ test run
22
target aarch64
33
; target s390x TODO: Not yet implemented on s390x
44
set enable_simd
5-
target x86_64
5+
target x86_64 has_sse3 has_ssse3 has_sse41
66

77
;; shuffle
88

cranelift/filetests/filetests/runtests/simd-logical.clif

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ test run
22
target aarch64
33
; target s390x TODO: Not yet implemented on s390x
44
set enable_simd
5-
target x86_64
5+
target x86_64 has_sse3 has_ssse3 has_sse41
66

77
function %bnot() -> b32 {
88
block0:

cranelift/filetests/filetests/runtests/simd-saddsat.clif

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ test interpret
22
test run
33
target aarch64
44
set enable_simd
5-
target x86_64
5+
target x86_64 has_sse3 has_ssse3 has_sse41
66

77
function %saddsat_i8x16(i8x16, i8x16) -> i8x16 {
88
block0(v0: i8x16, v1: i8x16):

cranelift/filetests/filetests/runtests/simd-shuffle.clif

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ test interpret
22
test run
33
target aarch64
44
set enable_simd
5-
target x86_64
5+
target x86_64 has_sse3 has_ssse3 has_sse41
66

77
function %shuffle_i8x16(i8x16, i8x16) -> i8x16 {
88
block0(v0: i8x16, v1: i8x16):

cranelift/filetests/filetests/runtests/simd-snarrow.clif

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ test interpret
22
test run
33
target aarch64
44
set enable_simd
5-
target x86_64
5+
target x86_64 has_sse3 has_ssse3 has_sse41
66

77
function %snarrow_i16x8(i16x8, i16x8) -> i8x16 {
88
block0(v0: i16x8, v1: i16x8):

cranelift/filetests/filetests/runtests/simd-splat.clif

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ test interpret
22
test run
33
target aarch64
44
set enable_simd
5-
target x86_64
5+
target x86_64 has_sse3 has_ssse3 has_sse41
66

77
function %splat_i8x16(i8) -> i8x16 {
88
block0(v0: i8):

cranelift/filetests/filetests/runtests/simd-sqmulroundsat.clif

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ test interpret
22
test run
33
target aarch64
44
set enable_simd
5-
target x86_64
5+
target x86_64 has_sse3 has_ssse3 has_sse41
66

77
function %sqmulrs_i16x8(i16x8, i16x8) -> i16x8 {
88
block0(v0: i16x8, v1: i16x8):

cranelift/filetests/filetests/runtests/simd-ssubsat.clif

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ test interpret
22
test run
33
target aarch64
44
set enable_simd
5-
target x86_64
5+
target x86_64 has_sse3 has_ssse3 has_sse41
66

77
function %ssubsat_i8x16(i8x16, i8x16) -> i8x16 {
88
block0(v0: i8x16, v1: i8x16):

cranelift/filetests/filetests/runtests/simd-swidenhigh.clif

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ test interpret
22
test run
33
target aarch64
44
set enable_simd
5-
target x86_64
5+
target x86_64 has_sse3 has_ssse3 has_sse41
66

77
function %swidenhigh_i8x16(i8x16) -> i16x8 {
88
block0(v0: i8x16):

cranelift/filetests/filetests/runtests/simd-swidenlow.clif

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ test interpret
22
test run
33
target aarch64
44
set enable_simd
5-
target x86_64
5+
target x86_64 has_sse3 has_ssse3 has_sse41
66

77
function %swidenlow_i8x16(i8x16) -> i16x8 {
88
block0(v0: i8x16):

cranelift/filetests/filetests/runtests/simd-swizzle.clif

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ test interpret
22
test run
33
target aarch64
44
set enable_simd
5-
target x86_64
5+
target x86_64 has_sse3 has_ssse3 has_sse41
66

77
function %swizzle_i8x16(i8x16, i8x16) -> i8x16 {
88
block0(v0: i8x16, v1: i8x16):

cranelift/filetests/filetests/runtests/simd-uaddsat.clif

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ test interpret
22
test run
33
target aarch64
44
set enable_simd
5-
target x86_64
5+
target x86_64 has_sse3 has_ssse3 has_sse41
66

77
function %uaddsat_i8x16(i8x16, i8x16) -> i8x16 {
88
block0(v0: i8x16, v1: i8x16):

cranelift/filetests/filetests/runtests/simd-unarrow.clif

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ test interpret
22
test run
33
target aarch64
44
set enable_simd
5-
target x86_64
5+
target x86_64 has_sse3 has_ssse3 has_sse41
66

77
function %unarrow_i16x8(i16x8, i16x8) -> i8x16 {
88
block0(v0: i16x8, v1: i16x8):

cranelift/filetests/filetests/runtests/simd-usubsat.clif

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ test interpret
22
test run
33
target aarch64
44
set enable_simd
5-
target x86_64
5+
target x86_64 has_sse3 has_ssse3 has_sse41
66

77
function %usubsat_i8x16(i8x16, i8x16) -> i8x16 {
88
block0(v0: i8x16, v1: i8x16):

cranelift/filetests/filetests/runtests/simd-uwidenhigh.clif

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ test interpret
22
test run
33
target aarch64
44
set enable_simd
5-
target x86_64
5+
target x86_64 has_sse3 has_ssse3 has_sse41
66

77
function %uwidenhigh_i8x16(i8x16) -> i16x8 {
88
block0(v0: i8x16):

cranelift/filetests/filetests/runtests/simd-uwidenlow.clif

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ test interpret
22
test run
33
target aarch64
44
set enable_simd
5-
target x86_64
5+
target x86_64 has_sse3 has_ssse3 has_sse41
66

77
function %uwidenlow_i8x16(i8x16) -> i16x8 {
88
block0(v0: i8x16):

cranelift/filetests/filetests/runtests/simd-vconst.clif

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ test run
22
; target s390x TODO: Not yet implemented on s390x
33
target aarch64
44
set enable_simd
5-
target x86_64
5+
target x86_64 has_sse3 has_ssse3 has_sse41
66

77

88
function %vconst_zeroes() -> b1 {

0 commit comments

Comments
 (0)