Skip to content

Commit

Permalink
RegisterCoalescer: Fix joinReservedPhysReg()
Browse files Browse the repository at this point in the history
Merging r294268:

joinReservedPhysReg() can only deal with a liverange in a single basic
block when copying from a vreg into a physreg.

See also rdar://30306405

Differential Revision: https://reviews.llvm.org/D29436

Fixes http://llvm.org/PR31889

llvm-svn: 294631
  • Loading branch information
MatzeB committed Feb 9, 2017
1 parent 23abc38 commit 9162f0c
Show file tree
Hide file tree
Showing 2 changed files with 88 additions and 12 deletions.
5 changes: 5 additions & 0 deletions llvm/lib/CodeGen/RegisterCoalescer.cpp
Expand Up @@ -1614,6 +1614,11 @@ bool RegisterCoalescer::joinReservedPhysReg(CoalescerPair &CP) {
return false;
}

if (!LIS->intervalIsInOneMBB(RHS)) {
DEBUG(dbgs() << "\t\tComplex control flow!\n");
return false;
}

MachineInstr &DestMI = *MRI->getVRegDef(SrcReg);
CopyMI = &*MRI->use_instr_nodbg_begin(SrcReg);
SlotIndex CopyRegIdx = LIS->getInstructionIndex(*CopyMI).getRegSlot();
Expand Down
95 changes: 83 additions & 12 deletions llvm/test/CodeGen/AArch64/regcoal-physreg.mir
@@ -1,19 +1,24 @@
# RUN: llc -mtriple=aarch64-apple-ios -run-pass=simple-register-coalescing %s -o - | FileCheck %s
--- |
define void @func() { ret void }
define void @func0() { ret void }
define void @func1() { ret void }
define void @func2() { ret void }
...
---
# Check coalescing of COPYs from reserved physregs.
# CHECK-LABEL: name: func
name: func
# CHECK-LABEL: name: func0
name: func0
registers:
- { id: 0, class: gpr32 }
- { id: 1, class: gpr64 }
- { id: 2, class: gpr64 }
- { id: 3, class: gpr32 }
- { id: 4, class: gpr64 }
- { id: 5, class: gpr32 }
- { id: 6, class: xseqpairsclass }
- { id: 0, class: gpr32 }
- { id: 1, class: gpr64 }
- { id: 2, class: gpr64 }
- { id: 3, class: gpr32 }
- { id: 4, class: gpr64 }
- { id: 5, class: gpr32 }
- { id: 6, class: xseqpairsclass }
- { id: 7, class: gpr64 }
- { id: 8, class: gpr64sp }
- { id: 9, class: gpr64sp }
body: |
bb.0:
; We usually should not coalesce copies from allocatable physregs.
Expand Down Expand Up @@ -60,8 +65,74 @@ body: |
; Only coalesce when the source register is reserved as a whole (this is
; a limitation of the current code which cannot update liveness information
; of the non-reserved part).
; CHECK: %6 = COPY %xzr_x0
; CHECK: %6 = COPY %x28_fp
; CHECK: HINT 0, implicit %6
%6 = COPY %xzr_x0
%6 = COPY %x28_fp
HINT 0, implicit %6
; This can be coalesced.
; CHECK: %fp = SUBXri %fp, 4, 0
%8 = SUBXri %fp, 4, 0
%fp = COPY %8
; Cannot coalesce when there are reads of the physreg.
; CHECK-NOT: %fp = SUBXri %fp, 8, 0
; CHECK: %9 = SUBXri %fp, 8, 0
; CHECK: STRXui %fp, %fp, 0
; CHECK: %fp = COPY %9
%9 = SUBXri %fp, 8, 0
STRXui %fp, %fp, 0
%fp = COPY %9
...
---
# Check coalescing of COPYs from reserved physregs.
# CHECK-LABEL: name: func1
name: func1
registers:
- { id: 0, class: gpr64sp }
body: |
bb.0:
successors: %bb.1, %bb.2
; Cannot coalesce physreg because we have reads on other CFG paths (we
; currently abort for any control flow)
; CHECK-NOT: %fp = SUBXri
; CHECK: %0 = SUBXri %fp, 12, 0
; CHECK: CBZX undef %x0, %bb.1
; CHECK: B %bb.2
%0 = SUBXri %fp, 12, 0
CBZX undef %x0, %bb.1
B %bb.2
bb.1:
%fp = COPY %0
RET_ReallyLR
bb.2:
STRXui %fp, %fp, 0
RET_ReallyLR
...
---
# CHECK-LABEL: name: func2
name: func2
registers:
- { id: 0, class: gpr64sp }
body: |
bb.0:
successors: %bb.1, %bb.2
; We can coalesce copies from physreg to vreg across multiple blocks.
; CHECK-NOT: COPY
; CHECK: CBZX undef %x0, %bb.1
; CHECK-NEXT: B %bb.2
%0 = COPY %fp
CBZX undef %x0, %bb.1
B %bb.2
bb.1:
; CHECK: STRXui undef %x0, %fp, 0
; CHECK-NEXT: RET_ReallyLR
STRXui undef %x0, %0, 0
RET_ReallyLR
bb.2:
RET_ReallyLR
...

0 comments on commit 9162f0c

Please sign in to comment.