| Issue |
165077
|
| Summary |
[m68k] Miscompilation: Move immediate to status register generates incorrect assembly
|
| Labels |
new issue
|
| Assignees |
|
| Reporter |
SpacePython12
|
Initially ran into this error in Rust:
```rust
unsafe fn set_int_level<const LEVEL: u8>() {
core::arch::asm!(
"move.w #{l},%sr",
l = const (0x2000i16 | (((LEVEL & 0x7) as i16) << 8)),
)
}
```
Tried a simpler case in C and compiled using clang:
https://godbolt.org/z/eMh7qWz6G
```c
/* Example usecase: Disabling interrupts by setting the interrupt mask bits of SR to 7. */
void disable_interrupts() {
asm("move.w #0x2700,%sr");
}
```
Both backends generated IR similar to this:
```ir
define dso_local void @disable_interrupts() {
entry:
call void asm sideeffect "move.w #0x2700,%sr", ""() #1
ret void
}
```
However, something goes wrong during codegen, and somehow the `move.w #imm,%sr` directive turns into `move.w #imm,%d0`:
```asm
disable_interrupts:
link.w %a6, #0
move.w #9984, %d0
unlk %a6
rts
```
The issue can technically be bypassed by moving the immediate value into a temporary register, and then into the status register, but it's still incorrect behavior by the codegen backend.
_______________________________________________
llvm-bugs mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs