-
-
Notifications
You must be signed in to change notification settings - Fork 14.7k
Inline assembly with tied operands of different sizes #65452
Copy link
Copy link
Closed
Labels
A-inline-assemblyArea: Inline assembly (`asm!(…)`)Area: Inline assembly (`asm!(…)`)P-lowLow priorityLow priorityT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.requires-nightlyThis issue requires a nightly compiler in some way. When possible, use a F-* label instead.This issue requires a nightly compiler in some way. When possible, use a F-* label instead.
Metadata
Metadata
Assignees
Labels
A-inline-assemblyArea: Inline assembly (`asm!(…)`)Area: Inline assembly (`asm!(…)`)P-lowLow priorityLow priorityT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.requires-nightlyThis issue requires a nightly compiler in some way. When possible, use a F-* label instead.This issue requires a nightly compiler in some way. When possible, use a F-* label instead.
Type
Fields
Give feedbackNo fields configured for issues without a type.
When transpiling (or manually translating) the following C code from
/usr/include/bits/select.h:into Rust, we get approximately the following code (manually rewritten to make it cleaner):
the resulting Rust inline assembly works fine in release mode, but crashes in debug mode.
Link to Playground
The issue here is that the
"0"(&mut x)input operand is tied to the same register as the"={di}"(y)output operand, but they have different types and sizes (&mut u32vsu32). LLVM assigns both operands to theediregister in debug mode (which is wrong) but tordiin release mode (which is the expected assignment).gcc and clang compile the original C code correctly because they extend both operands to the larger size in the front end (link to clang code). The equivalent correct Rust code would be something like
Should rustc expect to never see this input (I think it's LLVM UB), or replicate clang's behavior? If it's the latter, I could implement that myself and submit a PR, but I'm trying to get some feedback before writing any code.