Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions llvm/lib/CodeGen/LiveRangeEdit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -190,9 +190,12 @@ SlotIndex LiveRangeEdit::rematerializeAt(MachineBasicBlock &MBB,
Rematted.insert(RM.ParentVNI);
++NumReMaterialization;

bool EarlyClobber = MI->getOperand(0).isEarlyClobber();
if (ReplaceIndexMI)
return LIS.ReplaceMachineInstrInMaps(*ReplaceIndexMI, *MI).getRegSlot();
return LIS.getSlotIndexes()->insertMachineInstrInMaps(*MI, Late).getRegSlot();
return LIS.ReplaceMachineInstrInMaps(*ReplaceIndexMI, *MI)
.getRegSlot(EarlyClobber);
return LIS.getSlotIndexes()->insertMachineInstrInMaps(*MI, Late).getRegSlot(
EarlyClobber);
}

void LiveRangeEdit::eraseVirtReg(Register Reg) {
Expand Down
76 changes: 76 additions & 0 deletions llvm/test/CodeGen/X86/early-clobber.mir
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 5
# RUN: llc -mtriple=i386-unknown-linux-gnu -start-before=twoaddressinstruction -stop-after=postrapseudos -verify-machineinstrs -o - %s | FileCheck %s

# Test register live range that is split from rematerializing. The live range should
# start with Slot_EarlyClobber instead of Slot_Register. Machineverifer can check it.

--- |

define void @test() nounwind {
ret void
}

...
---
name: test
alignment: 16
tracksRegLiveness: true
frameInfo:
maxAlignment: 4
fixedStack:
- { id: 0, size: 4, alignment: 16, isImmutable: true }
machineFunctionInfo: {}
body: |
; CHECK-LABEL: name: test
; CHECK: bb.0:
; CHECK-NEXT: successors: %bb.1(0x40000000), %bb.2(0x40000000)
; CHECK-NEXT: liveins: $ebp, $ebx, $edi, $esi
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: frame-setup PUSH32r killed $ebp, implicit-def $esp, implicit $esp
; CHECK-NEXT: frame-setup PUSH32r killed $ebx, implicit-def $esp, implicit $esp
; CHECK-NEXT: frame-setup PUSH32r killed $edi, implicit-def $esp, implicit $esp
; CHECK-NEXT: frame-setup PUSH32r killed $esi, implicit-def $esp, implicit $esp
; CHECK-NEXT: $esp = frame-setup SUB32ri $esp, 12, implicit-def dead $eflags
; CHECK-NEXT: INLINEASM &"", 1 /* sideeffect attdialect */, 12 /* clobber */, implicit-def dead early-clobber $ebp, 12 /* clobber */, implicit-def dead early-clobber $eax, 12 /* clobber */, implicit-def dead early-clobber $ebx, 12 /* clobber */, implicit-def dead early-clobber $ecx, 12 /* clobber */, implicit-def dead early-clobber $edx, 12 /* clobber */, implicit-def dead early-clobber $esi, 12 /* clobber */, implicit-def dead early-clobber $edi, 12 /* clobber */, implicit-def dead early-clobber $df, 12 /* clobber */, implicit-def early-clobber $fpsw, 12 /* clobber */, implicit-def dead early-clobber $eflags
; CHECK-NEXT: early-clobber renamable $eax = XOR32rr undef $eax, undef $eax, implicit-def dead $eflags
; CHECK-NEXT: TEST8rr renamable $al, renamable $al, implicit-def $eflags
; CHECK-NEXT: JCC_1 %bb.2, 5, implicit $eflags
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: bb.1:
; CHECK-NEXT: successors: %bb.2(0x80000000)
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: renamable $eax = MOV32ri 1
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: bb.2:
; CHECK-NEXT: liveins: $eax
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: $esp = frame-destroy ADD32ri $esp, 12, implicit-def dead $eflags
; CHECK-NEXT: $esi = frame-destroy POP32r implicit-def $esp, implicit $esp
; CHECK-NEXT: $edi = frame-destroy POP32r implicit-def $esp, implicit $esp
; CHECK-NEXT: $ebx = frame-destroy POP32r implicit-def $esp, implicit $esp
; CHECK-NEXT: $ebp = frame-destroy POP32r implicit-def $esp, implicit $esp
; CHECK-NEXT: RET 0, $eax
bb.0:
successors: %bb.1, %bb.2

early-clobber %0:gr32_abcd = MOV32r0 implicit-def dead $eflags
INLINEASM &"", 1 /* sideeffect attdialect */, 12 /* clobber */, implicit-def dead early-clobber $ebp, 12 /* clobber */, implicit-def dead early-clobber $eax, 12 /* clobber */, implicit-def dead early-clobber $ebx, 12 /* clobber */, implicit-def dead early-clobber $ecx, 12 /* clobber */, implicit-def dead early-clobber $edx, 12 /* clobber */, implicit-def dead early-clobber $esi, 12 /* clobber */, implicit-def dead early-clobber $edi, 12 /* clobber */, implicit-def dead early-clobber $df, 12 /* clobber */, implicit-def early-clobber $fpsw, 12 /* clobber */, implicit-def dead early-clobber $eflags
%4:gr8 = COPY %0.sub_8bit
TEST8rr killed %4, %4, implicit-def $eflags
JCC_1 %bb.2, 5, implicit killed $eflags
JMP_1 %bb.1

bb.1:
%1:gr32 = MOV32ri 1
%5:gr32 = COPY killed %1
JMP_1 %bb.3

bb.2:
%5:gr32 = COPY killed %0

bb.3:
%3:gr32 = COPY killed %5
$eax = COPY killed %3
RET 0, killed $eax

...