[Live Intervals] Teach Greedy RA to recognize special case live-through

Statepoint instruction has a deopt section which is actually live-through the call.
Currently this is handled by special post pass after RA - fixup-statepoint-caller-saved.

This change teaches Greedy RA that if segment of live interval is ended with statepoint
instruction and its reg is used in deopt bundle then this live interval interferes regmask of this statepoint
and as a result caller-saved register cannot be assigned to this live interval.

Reviewers: reames, dantrushin
Reviewed By: reames
Subscribers: llvm-commits
Differential Revision: https://reviews.llvm.org/D100296
This commit is contained in:
Serguei Katkov 2021-04-12 15:12:28 +07:00
parent d9b03ef2e8
commit 02265ed7ad
2 changed files with 189 additions and 88 deletions

View File

@ -38,6 +38,7 @@
#include "llvm/CodeGen/VirtRegMap.h"
#include "llvm/Config/llvm-config.h"
#include "llvm/IR/InstrTypes.h"
#include "llvm/IR/Statepoint.h"
#include "llvm/MC/LaneBitmask.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/Pass.h"
@ -47,6 +48,7 @@
#include "llvm/Support/Debug.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/CodeGen/StackMaps.h"
#include <algorithm>
#include <cassert>
#include <cstdint>
@ -886,6 +888,23 @@ LiveIntervals::addSegmentToEndOfBlock(Register Reg, MachineInstr &startInst) {
//===----------------------------------------------------------------------===//
// Register mask functions
//===----------------------------------------------------------------------===//
/// Check whether use of reg in MI is live-through. Live-through means that
/// the value is alive on exit from Machine instruction. The example of such
/// use is a deopt value in statepoint instruction.
static bool hasLiveThroughUse(const MachineInstr *MI, Register Reg) {
if (MI->getOpcode() != TargetOpcode::STATEPOINT)
return false;
StatepointOpers SO(MI);
if (SO.getFlags() & (uint64_t)StatepointFlags::DeoptLiveIn)
return false;
for (unsigned Idx = SO.getNumDeoptArgsIdx(), E = SO.getNumGCPtrIdx(); Idx < E;
++Idx) {
const MachineOperand &MO = MI->getOperand(Idx);
if (MO.isReg() && MO.getReg() == Reg)
return true;
}
return false;
}
bool LiveIntervals::checkRegMaskInterference(LiveInterval &LI,
BitVector &UsableRegs) {
@ -934,10 +953,17 @@ bool LiveIntervals::checkRegMaskInterference(LiveInterval &LI,
if (++SlotI == SlotE)
return Found;
}
// If segment ends with live-through use we need to collect its regmask.
if (*SlotI == LiveI->end)
if (MachineInstr *MI = getInstructionFromIndex(*SlotI))
if (hasLiveThroughUse(MI, LI.reg()))
unionBitMask(SlotI++ - Slots.begin());
// *SlotI is beyond the current LI segment.
LiveI = LI.advanceTo(LiveI, *SlotI);
if (LiveI == LiveE)
// Special advance implementation to not miss next LiveI->end.
if (++LiveI == LiveE || SlotI == SlotE || *SlotI > LI.endIndex())
return Found;
while (LiveI->end < *SlotI)
++LiveI;
// Advance SlotI until it overlaps.
while (*SlotI < LiveI->start)
if (++SlotI == SlotE)

View File

@ -10,12 +10,13 @@ declare void @baz()
define void @test1(i32 %a) gc "statepoint-example" {
; CHECK-LABEL: test1:
; CHECK: ## %bb.0: ## %entry
; CHECK-NEXT: pushq %rax
; CHECK-NEXT: pushq %rbx
; CHECK-NEXT: .cfi_def_cfa_offset 16
; CHECK-NEXT: movl %edi, {{[-0-9]+}}(%r{{[sb]}}p) ## 4-byte Spill
; CHECK-NEXT: callq _bar ## 4-byte Folded Reload
; CHECK-NEXT: .cfi_offset %rbx, -16
; CHECK-NEXT: movl %edi, %ebx
; CHECK-NEXT: callq _bar
; CHECK-NEXT: Ltmp0:
; CHECK-NEXT: popq %rax
; CHECK-NEXT: popq %rbx
; CHECK-NEXT: retq
entry:
%statepoint_token1 = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @bar, i32 0, i32 0, i32 0, i32 0) ["deopt" (i32 %a)]
@ -54,17 +55,41 @@ entry:
define void @test3(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e, i32 %f, i32 %g, i32 %h, i32 %i) gc "statepoint-example" {
; CHECK-LABEL: test3:
; CHECK: ## %bb.0: ## %entry
; CHECK-NEXT: subq $24, %rsp
; CHECK-NEXT: pushq %rbp
; CHECK-NEXT: .cfi_def_cfa_offset 16
; CHECK-NEXT: pushq %r15
; CHECK-NEXT: .cfi_def_cfa_offset 24
; CHECK-NEXT: pushq %r14
; CHECK-NEXT: .cfi_def_cfa_offset 32
; CHECK-NEXT: movl %edi, {{[-0-9]+}}(%r{{[sb]}}p) ## 4-byte Spill
; CHECK-NEXT: movl %esi, {{[-0-9]+}}(%r{{[sb]}}p) ## 4-byte Spill
; CHECK-NEXT: movl %edx, {{[-0-9]+}}(%r{{[sb]}}p) ## 4-byte Spill
; CHECK-NEXT: movl %ecx, {{[-0-9]+}}(%r{{[sb]}}p) ## 4-byte Spill
; CHECK-NEXT: movl %r8d, {{[-0-9]+}}(%r{{[sb]}}p) ## 4-byte Spill
; CHECK-NEXT: movl %r9d, (%rsp) ## 4-byte Spill
; CHECK-NEXT: callq _bar ## 24-byte Folded Reload
; CHECK-NEXT: pushq %r13
; CHECK-NEXT: .cfi_def_cfa_offset 40
; CHECK-NEXT: pushq %r12
; CHECK-NEXT: .cfi_def_cfa_offset 48
; CHECK-NEXT: pushq %rbx
; CHECK-NEXT: .cfi_def_cfa_offset 56
; CHECK-NEXT: pushq %rax
; CHECK-NEXT: .cfi_def_cfa_offset 64
; CHECK-NEXT: .cfi_offset %rbx, -56
; CHECK-NEXT: .cfi_offset %r12, -48
; CHECK-NEXT: .cfi_offset %r13, -40
; CHECK-NEXT: .cfi_offset %r14, -32
; CHECK-NEXT: .cfi_offset %r15, -24
; CHECK-NEXT: .cfi_offset %rbp, -16
; CHECK-NEXT: movl %r9d, %r14d
; CHECK-NEXT: movl %r8d, %r15d
; CHECK-NEXT: movl %ecx, %r12d
; CHECK-NEXT: movl %edx, %r13d
; CHECK-NEXT: movl %esi, %ebx
; CHECK-NEXT: movl %edi, %ebp
; CHECK-NEXT: callq _bar
; CHECK-NEXT: Ltmp3:
; CHECK-NEXT: addq $24, %rsp
; CHECK-NEXT: addq $8, %rsp
; CHECK-NEXT: popq %rbx
; CHECK-NEXT: popq %r12
; CHECK-NEXT: popq %r13
; CHECK-NEXT: popq %r14
; CHECK-NEXT: popq %r15
; CHECK-NEXT: popq %rbp
; CHECK-NEXT: retq
entry:
%statepoint_token1 = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @bar, i32 0, i32 0, i32 0, i32 0) ["deopt" (i32 %a, i32 %b, i32 %c, i32 %d, i32 %e, i32 %f, i32 %g, i32 %h, i32 %i)]
@ -78,17 +103,41 @@ entry:
define void @test4(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e, i32 %f, i32 %g, i32 %h, i32 %i, i32 %j, i32 %k, i32 %l, i32 %m, i32 %n, i32 %o, i32 %p, i32 %q, i32 %r, i32 %s, i32 %t, i32 %u, i32 %v, i32 %w, i32 %x, i32 %y, i32 %z) gc "statepoint-example" {
; CHECK-LABEL: test4:
; CHECK: ## %bb.0: ## %entry
; CHECK-NEXT: subq $24, %rsp
; CHECK-NEXT: pushq %rbp
; CHECK-NEXT: .cfi_def_cfa_offset 16
; CHECK-NEXT: pushq %r15
; CHECK-NEXT: .cfi_def_cfa_offset 24
; CHECK-NEXT: pushq %r14
; CHECK-NEXT: .cfi_def_cfa_offset 32
; CHECK-NEXT: movl %edi, {{[-0-9]+}}(%r{{[sb]}}p) ## 4-byte Spill
; CHECK-NEXT: movl %esi, {{[-0-9]+}}(%r{{[sb]}}p) ## 4-byte Spill
; CHECK-NEXT: movl %edx, {{[-0-9]+}}(%r{{[sb]}}p) ## 4-byte Spill
; CHECK-NEXT: movl %ecx, {{[-0-9]+}}(%r{{[sb]}}p) ## 4-byte Spill
; CHECK-NEXT: movl %r8d, {{[-0-9]+}}(%r{{[sb]}}p) ## 4-byte Spill
; CHECK-NEXT: movl %r9d, (%rsp) ## 4-byte Spill
; CHECK-NEXT: callq _bar ## 24-byte Folded Reload
; CHECK-NEXT: pushq %r13
; CHECK-NEXT: .cfi_def_cfa_offset 40
; CHECK-NEXT: pushq %r12
; CHECK-NEXT: .cfi_def_cfa_offset 48
; CHECK-NEXT: pushq %rbx
; CHECK-NEXT: .cfi_def_cfa_offset 56
; CHECK-NEXT: pushq %rax
; CHECK-NEXT: .cfi_def_cfa_offset 64
; CHECK-NEXT: .cfi_offset %rbx, -56
; CHECK-NEXT: .cfi_offset %r12, -48
; CHECK-NEXT: .cfi_offset %r13, -40
; CHECK-NEXT: .cfi_offset %r14, -32
; CHECK-NEXT: .cfi_offset %r15, -24
; CHECK-NEXT: .cfi_offset %rbp, -16
; CHECK-NEXT: movl %r9d, %r14d
; CHECK-NEXT: movl %r8d, %r15d
; CHECK-NEXT: movl %ecx, %r12d
; CHECK-NEXT: movl %edx, %r13d
; CHECK-NEXT: movl %esi, %ebx
; CHECK-NEXT: movl %edi, %ebp
; CHECK-NEXT: callq _bar
; CHECK-NEXT: Ltmp4:
; CHECK-NEXT: addq $24, %rsp
; CHECK-NEXT: addq $8, %rsp
; CHECK-NEXT: popq %rbx
; CHECK-NEXT: popq %r12
; CHECK-NEXT: popq %r13
; CHECK-NEXT: popq %r14
; CHECK-NEXT: popq %r15
; CHECK-NEXT: popq %rbp
; CHECK-NEXT: retq
entry:
%statepoint_token1 = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @bar, i32 0, i32 0, i32 0, i32 0) ["deopt" (i32 %a, i32 %b, i32 %c, i32 %d, i32 %e, i32 %f, i32 %g, i32 %h, i32 %i, i32 %j, i32 %k, i32 %l, i32 %m, i32 %n, i32 %o, i32 %p, i32 %q, i32 %r, i32 %s, i32 %t, i32 %u, i32 %v, i32 %w, i32 %x, i32 %y, i32 %z)]
@ -185,34 +234,34 @@ define void @test7(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e, i32 %f, i32 %g, i32 %
; CHECK-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax
; CHECK-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
; CHECK-NEXT: movl %edi, %edi
; CHECK-NEXT: movl %esi, %esi
; CHECK-NEXT: movl %edx, %edx
; CHECK-NEXT: movl %ecx, %ecx
; CHECK-NEXT: movl %r8d, %r8d
; CHECK-NEXT: movl %r9d, %r9d
; CHECK-NEXT: movl %edi, %r13d
; CHECK-NEXT: movl %esi, %ebx
; CHECK-NEXT: movl %edx, %ebp
; CHECK-NEXT: movl %ecx, %r14d
; CHECK-NEXT: movl %r8d, %r15d
; CHECK-NEXT: movl %r9d, %r12d
; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax
; CHECK-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax
; CHECK-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax
; CHECK-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax
; CHECK-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax
; CHECK-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax
; CHECK-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax
; CHECK-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax
; CHECK-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax
; CHECK-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax
; CHECK-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %ebp
; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %r13d
; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %r12d
; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %r15d
; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %r14d
; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %ebx
; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %r11d
; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %r10d
; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax
; CHECK-NEXT: movq %rdi, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
; CHECK-NEXT: movq %rsi, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
; CHECK-NEXT: movq %rdx, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
; CHECK-NEXT: movq %rcx, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
; CHECK-NEXT: movq %r8, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
; CHECK-NEXT: movq %r9, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
; CHECK-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
; CHECK-NEXT: movq %r10, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
; CHECK-NEXT: movq %r11, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
; CHECK-NEXT: callq _bar ## 160-byte Folded Reload
; CHECK-NEXT: Ltmp9:
; CHECK-NEXT: addq $168, %rsp
@ -271,16 +320,34 @@ define void @test8(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e, i32 %f, i32 %g, i32 %
; CHECK-NEXT: .cfi_def_cfa_offset 48
; CHECK-NEXT: pushq %rbx
; CHECK-NEXT: .cfi_def_cfa_offset 56
; CHECK-NEXT: subq $104, %rsp
; CHECK-NEXT: .cfi_def_cfa_offset 160
; CHECK-NEXT: subq $136, %rsp
; CHECK-NEXT: .cfi_def_cfa_offset 192
; CHECK-NEXT: .cfi_offset %rbx, -56
; CHECK-NEXT: .cfi_offset %r12, -48
; CHECK-NEXT: .cfi_offset %r13, -40
; CHECK-NEXT: .cfi_offset %r14, -32
; CHECK-NEXT: .cfi_offset %r15, -24
; CHECK-NEXT: .cfi_offset %rbp, -16
; CHECK-NEXT: movl %r9d, %r10d
; CHECK-NEXT: movl %r8d, %r9d
; CHECK-NEXT: movl %r9d, {{[-0-9]+}}(%r{{[sb]}}p) ## 4-byte Spill
; CHECK-NEXT: movl %r8d, (%rsp) ## 4-byte Spill
; CHECK-NEXT: movl %ecx, %r12d
; CHECK-NEXT: movl %edx, %r13d
; CHECK-NEXT: movl %esi, %ebx
; CHECK-NEXT: movl %edi, %ebp
; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax
; CHECK-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax
; CHECK-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax
; CHECK-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax
; CHECK-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax
; CHECK-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax
; CHECK-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax
; CHECK-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax
; CHECK-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax
@ -299,27 +366,11 @@ define void @test8(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e, i32 %f, i32 %g, i32 %
; CHECK-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax
; CHECK-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %ebp
; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %r13d
; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %r12d
; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %r15d
; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %r14d
; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %ebx
; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %r11d
; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %r8d
; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %eax
; CHECK-NEXT: movb %dil, {{[-0-9]+}}(%r{{[sb]}}p) ## 1-byte Spill
; CHECK-NEXT: movb %sil, {{[-0-9]+}}(%r{{[sb]}}p) ## 1-byte Spill
; CHECK-NEXT: movb %dl, {{[-0-9]+}}(%r{{[sb]}}p) ## 1-byte Spill
; CHECK-NEXT: movb %cl, (%rsp) ## 1-byte Spill
; CHECK-NEXT: movw %r9w, {{[-0-9]+}}(%r{{[sb]}}p) ## 2-byte Spill
; CHECK-NEXT: movw %r10w, {{[-0-9]+}}(%r{{[sb]}}p) ## 2-byte Spill
; CHECK-NEXT: movq %rax, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
; CHECK-NEXT: movq %r8, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
; CHECK-NEXT: movq %r11, {{[-0-9]+}}(%r{{[sb]}}p) ## 8-byte Spill
; CHECK-NEXT: callq _bar ## 104-byte Folded Reload
; CHECK-NEXT: movl {{[0-9]+}}(%rsp), %r15d
; CHECK-NEXT: callq _bar ## 132-byte Folded Reload
; CHECK-NEXT: Ltmp10:
; CHECK-NEXT: addq $104, %rsp
; CHECK-NEXT: addq $136, %rsp
; CHECK-NEXT: popq %rbx
; CHECK-NEXT: popq %r12
; CHECK-NEXT: popq %r13
@ -363,17 +414,41 @@ entry:
define void @test9(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e, i32 %f, i32 %g, i32 %h, i32 %i, i32 %j, i32 %k, i32 %l, i32 %m, i32 %n, i32 %o, i32 %p, i32 %q, i32 %r, i32 %s, i32 %t, i32 %u, i32 %v, i32 %w, i32 %x, i32 %y, i32 %z) gc "statepoint-example" {
; CHECK-LABEL: test9:
; CHECK: ## %bb.0: ## %entry
; CHECK-NEXT: subq $24, %rsp
; CHECK-NEXT: pushq %rbp
; CHECK-NEXT: .cfi_def_cfa_offset 16
; CHECK-NEXT: pushq %r15
; CHECK-NEXT: .cfi_def_cfa_offset 24
; CHECK-NEXT: pushq %r14
; CHECK-NEXT: .cfi_def_cfa_offset 32
; CHECK-NEXT: movl %edi, {{[-0-9]+}}(%r{{[sb]}}p) ## 4-byte Spill
; CHECK-NEXT: movl %esi, {{[-0-9]+}}(%r{{[sb]}}p) ## 4-byte Spill
; CHECK-NEXT: movl %edx, {{[-0-9]+}}(%r{{[sb]}}p) ## 4-byte Spill
; CHECK-NEXT: movl %ecx, {{[-0-9]+}}(%r{{[sb]}}p) ## 4-byte Spill
; CHECK-NEXT: movl %r8d, {{[-0-9]+}}(%r{{[sb]}}p) ## 4-byte Spill
; CHECK-NEXT: movl %r9d, (%rsp) ## 4-byte Spill
; CHECK-NEXT: callq _bar ## 24-byte Folded Reload
; CHECK-NEXT: pushq %r13
; CHECK-NEXT: .cfi_def_cfa_offset 40
; CHECK-NEXT: pushq %r12
; CHECK-NEXT: .cfi_def_cfa_offset 48
; CHECK-NEXT: pushq %rbx
; CHECK-NEXT: .cfi_def_cfa_offset 56
; CHECK-NEXT: pushq %rax
; CHECK-NEXT: .cfi_def_cfa_offset 64
; CHECK-NEXT: .cfi_offset %rbx, -56
; CHECK-NEXT: .cfi_offset %r12, -48
; CHECK-NEXT: .cfi_offset %r13, -40
; CHECK-NEXT: .cfi_offset %r14, -32
; CHECK-NEXT: .cfi_offset %r15, -24
; CHECK-NEXT: .cfi_offset %rbp, -16
; CHECK-NEXT: movl %r9d, %r14d
; CHECK-NEXT: movl %r8d, %r15d
; CHECK-NEXT: movl %ecx, %r12d
; CHECK-NEXT: movl %edx, %r13d
; CHECK-NEXT: movl %esi, %ebx
; CHECK-NEXT: movl %edi, %ebp
; CHECK-NEXT: callq _bar
; CHECK-NEXT: Ltmp11:
; CHECK-NEXT: addq $24, %rsp
; CHECK-NEXT: addq $8, %rsp
; CHECK-NEXT: popq %rbx
; CHECK-NEXT: popq %r12
; CHECK-NEXT: popq %r13
; CHECK-NEXT: popq %r14
; CHECK-NEXT: popq %r15
; CHECK-NEXT: popq %rbp
; CHECK-NEXT: retq
entry:
@ -624,13 +699,13 @@ entry:
define void @addr_func() gc "statepoint-example" {
; CHECK-LABEL: addr_func:
; CHECK: ## %bb.0: ## %entry
; CHECK-NEXT: pushq %rax
; CHECK-NEXT: pushq %rbx
; CHECK-NEXT: .cfi_def_cfa_offset 16
; CHECK-NEXT: movq _bar@{{.*}}(%rip), %rax
; CHECK-NEXT: movq %rax, (%rsp) ## 8-byte Spill
; CHECK-NEXT: callq _bar ## 8-byte Folded Reload
; CHECK-NEXT: .cfi_offset %rbx, -16
; CHECK-NEXT: movq _bar@{{.*}}(%rip), %rbx
; CHECK-NEXT: callq _bar
; CHECK-NEXT: Ltmp15:
; CHECK-NEXT: popq %rax
; CHECK-NEXT: popq %rbx
; CHECK-NEXT: retq
entry:
%statepoint_token1 = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @bar, i32 0, i32 0, i64 0, i64 0) ["deopt" (void ()* @bar, void ()* @bar, void ()* @bar)]
@ -642,13 +717,13 @@ entry:
define void @addr_global() gc "statepoint-example" {
; CHECK-LABEL: addr_global:
; CHECK: ## %bb.0: ## %entry
; CHECK-NEXT: pushq %rax
; CHECK-NEXT: pushq %rbx
; CHECK-NEXT: .cfi_def_cfa_offset 16
; CHECK-NEXT: movq _G@{{.*}}(%rip), %rax
; CHECK-NEXT: movq %rax, (%rsp) ## 8-byte Spill
; CHECK-NEXT: callq _bar ## 8-byte Folded Reload
; CHECK-NEXT: .cfi_offset %rbx, -16
; CHECK-NEXT: movq _G@{{.*}}(%rip), %rbx
; CHECK-NEXT: callq _bar
; CHECK-NEXT: Ltmp16:
; CHECK-NEXT: popq %rax
; CHECK-NEXT: popq %rbx
; CHECK-NEXT: retq
entry:
%statepoint_token1 = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 2882400000, i32 0, void ()* @bar, i32 0, i32 0, i64 0, i64 0) ["deopt" (i32* @G, i32* @G, i32* @G)]