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

Reply via email to