rust-lang / rustc_codegen_cranelift

Cranelift based backend for rustc
Apache License 2.0
1.52k stars 94 forks source link

Empty `target_features` confuses Miri #1438

Closed y21 closed 6 months ago

y21 commented 6 months ago

Running RUSTFLAGS="-Zcodegen-backend=cranelift" cargo miri test on the following test trips up Miri.

#[test]
fn f() {
    std::hint::spin_loop();
}
$ RUSTFLAGS="-Zcodegen-backend=cranelift" cargo miri test
test f ... error: Undefined Behavior: attempted to call intrinsic `llvm.x86.sse2.pause` that requires missing target feature sse2
  --> /home/timo/.rustup/toolchains/nightly-2023-12-16-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/../../stdarch/crates/core_arch/src/x86/sse2.rs:25:5
   |
25 |     pause()
   |     ^^^^^^^ attempted to call intrinsic `llvm.x86.sse2.pause` that requires missing target feature sse2

I'm guessing the problem is this FIXME here? https://github.com/rust-lang/rustc_codegen_cranelift/blob/289a27403645d95922c353e0953954ba00ec70cf/src/lib.rs#L191-L193

spin_loop has a #[cfg(target_arch = "x86_64")] (which evaluates to true) in which it executes an sse2 instruction

bjorn3 commented 6 months ago

I'm guessing the problem is this FIXME here?

Indeed. Fixing this is non-trivial as the logic to determine the final set of target features is split out between rustc and the LLVM in case of the LLVM backend. Getting everything to match with Cranelift is not that easy. I do intend to do it eventually and likely do some refactorings to rustc to simplify this, but other things have taken priority.

spin_loop has a #[cfg(target_arch = "x86_64")] (which evaluates to true) in which it executes an sse2 instruction

As it happens this intrinsic is not actually UB to execute without sse2. On x86 processors without sse2 support it decodes as a nop instruction. For many intrinsics it is indeed a problem to execute them when the cpu doesn't support it though.

bjorn3 commented 6 months ago

Should be fixed now by unconditionally returning SSE2 as supported.