-
Notifications
You must be signed in to change notification settings - Fork 12.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Array as asm input generates wrong code #13366
Comments
I spent a while today poking at this. I'm not sure exactly how to fix this, but naive solutions (such as always loading from lvalues and by-ref rvalues) produced incorrect code. I think we want to keep them by-ref and change the |
Triage: no update that I'm aware of. |
The "m" memory constraint in inline assembly is broken (generates incorrect code or triggers LLVM asserts) and should not be used. Instead, indirect memory operands should be used with "\*m", "=\*m" and "+\*m". Clang does this transparently by transforming "m" constraints into "\*m" indirect constraints, but for now just being able to use "\*m" directly is enough since asm! isn't stable. While "\*m" works fine as an input operand, "=\*m" and "+\*m" need to be specified as input operands because they take a pointer value as an input. This PR relaxes the constraint checker to allow constraints starting with "=" or "+" if the constraint string contains a "\*", which indicates an indirect operand. This (indirectly) fixes these issues: #29382, #16383 and #13366. The code will need to be changed to use "\*m" instead of "m".
@kmcallister @steveklabnik I tested the OP code (slightly updated) as follows: #![feature(asm)]
#[inline(never)]
unsafe fn print_first_half(arr: [u8; 16]) {
let out: u64;
asm!("movups $1, %xmm0
pextrq $$0, %xmm0, $0"
: "=r"(out) : "m"(arr) : "xmm0");
println!("{:?}", out);
}
fn main() {
let arr: [u8; 16] = [0; 16];
unsafe { print_first_half(arr); }
} and we get an ICE on nightly when emitting ASM or LLVM IR. Generating MIR does not ICE. See code at https://is.gd/MQGiQN ICE report is here: #40187 |
Triage: ICE not fixed |
This issue does not apply to the new The legacy |
internal: ⬆️ xflags The main change here should be that flags are not inhereted, so $ rust-analyzer analysis-stats . -v -v would do what it should do We also no longer Don\'t
fix: Specifying reason in expect(clippy::needless_return) no longer triggers false positive fixes rust-lang#13366 changelog: none
This should be
0u64
; try replacing themovups
withxorps %xmm0, %xmm0
. Here's the generated code:So it copies the array to
0x40(%rsp)
(in two 64-bit pieces), then puts that address at0x8(%rsp)
, andmovups
loads 16 bytes from there rather than from the array itself.In GCC, I would do
which
gcc -O3
turns into the optimalAttempting to do the same in Rust
produces even wronger code
Workarounds:
When the array is a static with a name, just name it within the
asm!
. See pub static disappears if only used from asm #13365.which generates optimal code in this case, because the array is already pointed to by
%rdi
, but in general may clobber a register and emit a load when neither is necessary.The text was updated successfully, but these errors were encountered: