[MCP] MachineCopyPropagation generates wrong code
- Dominant language
- LLVM
- Stars
- 40.5k
- Forks
- 18.7k
- PR merge metrics
- PR metrics pending
Description
Function ***MachineCopyPropagation::eliminateSpillageCopies*** generates wrong code with complex spill/reload chain.
Recently PR https://github.com/llvm/llvm-project/pull/186093 enabled *eliminateSpillageCopies* for AArch64 by default. It caused wrong code generated for one of our internal applications. The trigger of the error needs a complex spill/reload chain, so it needs a very high register pressure and usually a huge function body. So I don't have a small reproduce. But the problem can be described with the code snippet.
```
// Before MachineCopyPropagation
STRWui killed renamable $w11, %stack.84, 0 :: (store (s32) into %stack.84)
renamable $w11 = COPY killed renamable $w10 // S1
renamable $w10 = COPY killed renamable $w13 // S2
renamable $w13 = COPY killed renamable $w23 // S4
renamable $w23 = COPY killed renamable $w12
renamable $x12 = COPY killed renamable $x15
renamable $w15 = COPY killed renamable $w13
renamable $w13 = COPY killed renamable $w25 // S3
renamable $x25 = COPY killed renamable $x4
renamable $x4 = COPY killed renamable $x14
renamable $x6 = COPY killed renamable $x0
renamable $w0 = COPY killed renamable $w3
renamable $x3 = COPY killed renamable $x2
renamable $x2 = COPY killed renamable $x1
renamable $w1 = COPY killed renamable $w5
renamable $w5 = COPY killed renamable $w7
renamable $x7 = LDRXui %stack.69, 0 :: (load (s64) from %stack.69)
...
renamable $w7 = COPY killed renamable $w5
renamable $w5 = COPY killed renamable $w1
renamable $x1 = COPY killed renamable $x2
renamable $x2 = COPY killed renamable $x3
renamable $w3 = COPY killed renamable $w0
renamable $x0 = COPY killed renamable $x6
renamable $x6 = LDRXui %stack.85, 0 :: (load (s64) from %stack.85)
renamable $x14 = COPY killed renamable $x4
renamable $x4 = COPY killed renamable $x25
renamable $w25 = COPY killed renamable $w13 // R1
renamable $w13 = COPY killed renamable $w10 // R2
renamable $w8 = COPY killed renamable $w15
renamable $x15 = COPY killed renamable $x12
renamable $w12 = COPY killed renamable $w23
renamable $w23 = COPY killed renamable $w8
renamable $w10 = COPY killed renamable $w11 // R3
renamable $w11 = LDRWui %stack.84, 0 :: (load (s32) from %stack.84)
```
LLVM finds the spill chain S1,S2,S3 and reload chain R1, R2, R3 can be optimized. Then it changed instructions S3 and R1, deleted instructions S2 and R2.
```
// After MachineCopyPropagation
STRWui killed renamable $w11, %stack.84, 0 :: (store (s32) into %stack.84)
renamable $w11 = COPY killed renamable $w10
// ****** renamable $w10 = COPY killed renamable $w13 ****** This instruction is deleted!
renamable $w13 = COPY killed renamable $w23
renamable $w23 = COPY killed renamable $w12
renamable $x12 = COPY killed renamable $x15
renamable $w15 = COPY killed renamable $w13
$w10 = COPY killed renamable $w25 // Changed instruction
renamable $x25 = COPY killed renamable $x4
renamable $x4 = COPY killed renamable $x14
renamable $x6 = COPY killed renamable $x0
renamable $w0 = COPY killed renamable $w3
renamable $x3 = COPY killed renamable $x2
renamable $x2 = COPY killed renamable $x1
renamable $w1 = COPY killed renamable $w5
renamable $w5 = COPY killed renamable $w7
renamable $x7 = LDRXui %stack.69, 0 :: (load (s64) from %stack.69)
...
renamable $w7 = COPY killed renamable $w5
renamable $w5 = COPY killed renamable $w1
renamable $x1 = COPY killed renamable $x2
renamable $x2 = COPY killed renamable $x3
renamable $w3 = COPY killed renamable $w0
renamable $x0 = COPY killed renamable $x6
renamable $x6 = LDRXui %stack.85, 0 :: (load (s64) from %stack.85)
renamable $x14 = COPY killed renamable $x4
renamable $x4 = COPY killed renamable $x25
renamable $w25 = COPY killed $w10 // Changed instruction
// ***** renamable $w13 = COPY killed renamable $w10 ***** This instruction has been deleted!
renamable $w8 = COPY killed renamable $w15
renamable $x15 = COPY killed renamable $x12
renamable $w12 = COPY killed renamable $w23
renamable $w23 = COPY killed renamable $w8
renamable $w10 = COPY killed renamable $w11
renamable $w11 = LDRWui %stack.84, 0 :: (load (s32) from %stack.84)
```
But after deleting S2 and R2, the original value of $w13 is lost, instruction S4 overwrites $w13, at the end of the code snippet we get a wrong value in $w13.
Contributor guide
Research direction
Start at MachineCopyPropagation::eliminateSpillageCopies and compare the spill/reload-chain transformations shown in the issue, particularly S2/R2 and S3/R1. Confirm that the optimized sequence preserves the original $w13 value; done means correcting this wrong-code case and adding regression coverage for the chain.
Written by the indexing model from the issue text.
Assessment
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100