Skip to content
Open
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
64 changes: 53 additions & 11 deletions llvm/lib/Target/AArch64/AArch64InstrInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2357,11 +2357,10 @@ bool AArch64InstrInfo::isFPRCopy(const MachineInstr &MI) {
return false;
}

Register AArch64InstrInfo::isLoadFromStackSlot(const MachineInstr &MI,
int &FrameIndex) const {
switch (MI.getOpcode()) {
static bool isFrameLoadOpcode(int Opcode) {
switch (Opcode) {
default:
break;
return false;
case AArch64::LDRWui:
case AArch64::LDRXui:
case AArch64::LDRBui:
Expand All @@ -2370,22 +2369,26 @@ Register AArch64InstrInfo::isLoadFromStackSlot(const MachineInstr &MI,
case AArch64::LDRDui:
case AArch64::LDRQui:
case AArch64::LDR_PXI:
return true;
}
}

Register AArch64InstrInfo::isLoadFromStackSlot(const MachineInstr &MI,
int &FrameIndex) const {
if (isFrameLoadOpcode(MI.getOpcode())) {
if (MI.getOperand(0).getSubReg() == 0 && MI.getOperand(1).isFI() &&
MI.getOperand(2).isImm() && MI.getOperand(2).getImm() == 0) {
FrameIndex = MI.getOperand(1).getIndex();
return MI.getOperand(0).getReg();
}
break;
}

return 0;
}

Register AArch64InstrInfo::isStoreToStackSlot(const MachineInstr &MI,
int &FrameIndex) const {
switch (MI.getOpcode()) {
static bool isFrameStoreOpcode(int Opcode) {
switch (Opcode) {
default:
break;
return false;
case AArch64::STRWui:
case AArch64::STRXui:
case AArch64::STRBui:
Expand All @@ -2394,16 +2397,55 @@ Register AArch64InstrInfo::isStoreToStackSlot(const MachineInstr &MI,
case AArch64::STRDui:
case AArch64::STRQui:
case AArch64::STR_PXI:
return true;
}
}

Register AArch64InstrInfo::isStoreToStackSlot(const MachineInstr &MI,
int &FrameIndex) const {
if (isFrameStoreOpcode(MI.getOpcode())) {
if (MI.getOperand(0).getSubReg() == 0 && MI.getOperand(1).isFI() &&
MI.getOperand(2).isImm() && MI.getOperand(2).getImm() == 0) {
FrameIndex = MI.getOperand(1).getIndex();
return MI.getOperand(0).getReg();
}
break;
}
return 0;
}

Register AArch64InstrInfo::isStoreToStackSlotPostFE(const MachineInstr &MI,
int &FrameIndex) const {
if (isFrameStoreOpcode(MI.getOpcode())) {
SmallVector<const MachineMemOperand *, 1> Accesses;
if (Register Reg = isStoreToStackSlot(MI, FrameIndex))
return Reg;

if (hasStoreToStackSlot(MI, Accesses)) {
FrameIndex =
cast<FixedStackPseudoSourceValue>(Accesses.front()->getPseudoValue())
->getFrameIndex();
return 1;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm -- I understand this is how ARM works (versus aarch64), however I think this will run into difficulty with InstrRef. InstrRefBasedLDV::isLocationSpill stores the return value of this function into its Reg reference, which is then used to determine which register is being spilt. That's significant as it determines what value is being transferred onto the stack.

If it's impossible to determine that information this late in compilation, it might be sufficient to just use the earlier clause, those for which isStoreToStackSlot returns a register?

(Similarly for isLoadFromStackSlotPostFE).

}
}
return Register();
}

Register AArch64InstrInfo::isLoadFromStackSlotPostFE(const MachineInstr &MI,
int &FrameIndex) const {
if (isFrameLoadOpcode(MI.getOpcode())) {
if (Register Reg = isLoadFromStackSlot(MI, FrameIndex))
return Reg;
SmallVector<const MachineMemOperand *, 1> Accesses;
if (hasLoadFromStackSlot(MI, Accesses)) {
FrameIndex =
cast<FixedStackPseudoSourceValue>(Accesses.front()->getPseudoValue())
->getFrameIndex();
return 1;
}
}
return Register();
}

/// Check all MachineMemOperands for a hint to suppress pairing.
bool AArch64InstrInfo::isLdStPairSuppressed(const MachineInstr &MI) {
return llvm::any_of(MI.memoperands(), [](MachineMemOperand *MMO) {
Expand Down
9 changes: 9 additions & 0 deletions llvm/lib/Target/AArch64/AArch64InstrInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,15 @@ class AArch64InstrInfo final : public AArch64GenInstrInfo {
Register isStoreToStackSlot(const MachineInstr &MI,
int &FrameIndex) const override;

/// isStoreToStackSlotPostFE - Check for post-frame ptr elimination
/// stack locations as well. This uses a heuristic so it isn't
/// reliable for correctness.
Register isStoreToStackSlotPostFE(const MachineInstr &MI,
int &FrameIndex) const override;

Register isLoadFromStackSlotPostFE(const MachineInstr &MI,
int &FrameIndex) const override;

/// Does this instruction set its full destination register to zero?
static bool isGPRZero(const MachineInstr &MI);

Expand Down
72 changes: 36 additions & 36 deletions llvm/test/CodeGen/AArch64/GlobalISel/arm64-atomic-128.ll
Original file line number Diff line number Diff line change
Expand Up @@ -89,33 +89,33 @@ define void @val_compare_and_swap(ptr %p, i128 %oldval, i128 %newval) {
; CHECK-OUTLINE-LLSC-O0-LABEL: val_compare_and_swap:
; CHECK-OUTLINE-LLSC-O0: // %bb.0:
; CHECK-OUTLINE-LLSC-O0-NEXT: sub sp, sp, #32
; CHECK-OUTLINE-LLSC-O0-NEXT: str x30, [sp, #16] // 8-byte Folded Spill
; CHECK-OUTLINE-LLSC-O0-NEXT: str x30, [sp, #16] // 8-byte Spill
; CHECK-OUTLINE-LLSC-O0-NEXT: .cfi_def_cfa_offset 32
; CHECK-OUTLINE-LLSC-O0-NEXT: .cfi_offset w30, -16
; CHECK-OUTLINE-LLSC-O0-NEXT: str x0, [sp, #8] // 8-byte Folded Spill
; CHECK-OUTLINE-LLSC-O0-NEXT: str x0, [sp, #8] // 8-byte Spill
; CHECK-OUTLINE-LLSC-O0-NEXT: mov x0, x2
; CHECK-OUTLINE-LLSC-O0-NEXT: mov x1, x3
; CHECK-OUTLINE-LLSC-O0-NEXT: mov x2, x4
; CHECK-OUTLINE-LLSC-O0-NEXT: ldr x4, [sp, #8] // 8-byte Folded Reload
; CHECK-OUTLINE-LLSC-O0-NEXT: ldr x4, [sp, #8] // 8-byte Reload
; CHECK-OUTLINE-LLSC-O0-NEXT: mov x3, x5
; CHECK-OUTLINE-LLSC-O0-NEXT: bl __aarch64_cas16_acq
; CHECK-OUTLINE-LLSC-O0-NEXT: mov x8, x0
; CHECK-OUTLINE-LLSC-O0-NEXT: ldr x0, [sp, #8] // 8-byte Folded Reload
; CHECK-OUTLINE-LLSC-O0-NEXT: ldr x0, [sp, #8] // 8-byte Reload
; CHECK-OUTLINE-LLSC-O0-NEXT: // implicit-def: $q0
; CHECK-OUTLINE-LLSC-O0-NEXT: mov v0.d[0], x8
; CHECK-OUTLINE-LLSC-O0-NEXT: mov v0.d[1], x1
; CHECK-OUTLINE-LLSC-O0-NEXT: str q0, [x0]
; CHECK-OUTLINE-LLSC-O0-NEXT: ldr x30, [sp, #16] // 8-byte Folded Reload
; CHECK-OUTLINE-LLSC-O0-NEXT: ldr x30, [sp, #16] // 8-byte Reload
; CHECK-OUTLINE-LLSC-O0-NEXT: add sp, sp, #32
; CHECK-OUTLINE-LLSC-O0-NEXT: ret
;
; CHECK-CAS-O0-LABEL: val_compare_and_swap:
; CHECK-CAS-O0: // %bb.0:
; CHECK-CAS-O0-NEXT: sub sp, sp, #16
; CHECK-CAS-O0-NEXT: .cfi_def_cfa_offset 16
; CHECK-CAS-O0-NEXT: str x3, [sp, #8] // 8-byte Folded Spill
; CHECK-CAS-O0-NEXT: str x3, [sp, #8] // 8-byte Spill
; CHECK-CAS-O0-NEXT: mov x1, x5
; CHECK-CAS-O0-NEXT: ldr x5, [sp, #8] // 8-byte Folded Reload
; CHECK-CAS-O0-NEXT: ldr x5, [sp, #8] // 8-byte Reload
; CHECK-CAS-O0-NEXT: // kill: def $x2 killed $x2 def $x2_x3
; CHECK-CAS-O0-NEXT: mov x3, x5
; CHECK-CAS-O0-NEXT: // kill: def $x4 killed $x4 def $x4_x5
Expand Down Expand Up @@ -216,33 +216,33 @@ define void @val_compare_and_swap_monotonic_seqcst(ptr %p, i128 %oldval, i128 %n
; CHECK-OUTLINE-LLSC-O0-LABEL: val_compare_and_swap_monotonic_seqcst:
; CHECK-OUTLINE-LLSC-O0: // %bb.0:
; CHECK-OUTLINE-LLSC-O0-NEXT: sub sp, sp, #32
; CHECK-OUTLINE-LLSC-O0-NEXT: str x30, [sp, #16] // 8-byte Folded Spill
; CHECK-OUTLINE-LLSC-O0-NEXT: str x30, [sp, #16] // 8-byte Spill
; CHECK-OUTLINE-LLSC-O0-NEXT: .cfi_def_cfa_offset 32
; CHECK-OUTLINE-LLSC-O0-NEXT: .cfi_offset w30, -16
; CHECK-OUTLINE-LLSC-O0-NEXT: str x0, [sp, #8] // 8-byte Folded Spill
; CHECK-OUTLINE-LLSC-O0-NEXT: str x0, [sp, #8] // 8-byte Spill
; CHECK-OUTLINE-LLSC-O0-NEXT: mov x0, x2
; CHECK-OUTLINE-LLSC-O0-NEXT: mov x1, x3
; CHECK-OUTLINE-LLSC-O0-NEXT: mov x2, x4
; CHECK-OUTLINE-LLSC-O0-NEXT: ldr x4, [sp, #8] // 8-byte Folded Reload
; CHECK-OUTLINE-LLSC-O0-NEXT: ldr x4, [sp, #8] // 8-byte Reload
; CHECK-OUTLINE-LLSC-O0-NEXT: mov x3, x5
; CHECK-OUTLINE-LLSC-O0-NEXT: bl __aarch64_cas16_acq_rel
; CHECK-OUTLINE-LLSC-O0-NEXT: mov x8, x0
; CHECK-OUTLINE-LLSC-O0-NEXT: ldr x0, [sp, #8] // 8-byte Folded Reload
; CHECK-OUTLINE-LLSC-O0-NEXT: ldr x0, [sp, #8] // 8-byte Reload
; CHECK-OUTLINE-LLSC-O0-NEXT: // implicit-def: $q0
; CHECK-OUTLINE-LLSC-O0-NEXT: mov v0.d[0], x8
; CHECK-OUTLINE-LLSC-O0-NEXT: mov v0.d[1], x1
; CHECK-OUTLINE-LLSC-O0-NEXT: str q0, [x0]
; CHECK-OUTLINE-LLSC-O0-NEXT: ldr x30, [sp, #16] // 8-byte Folded Reload
; CHECK-OUTLINE-LLSC-O0-NEXT: ldr x30, [sp, #16] // 8-byte Reload
; CHECK-OUTLINE-LLSC-O0-NEXT: add sp, sp, #32
; CHECK-OUTLINE-LLSC-O0-NEXT: ret
;
; CHECK-CAS-O0-LABEL: val_compare_and_swap_monotonic_seqcst:
; CHECK-CAS-O0: // %bb.0:
; CHECK-CAS-O0-NEXT: sub sp, sp, #16
; CHECK-CAS-O0-NEXT: .cfi_def_cfa_offset 16
; CHECK-CAS-O0-NEXT: str x3, [sp, #8] // 8-byte Folded Spill
; CHECK-CAS-O0-NEXT: str x3, [sp, #8] // 8-byte Spill
; CHECK-CAS-O0-NEXT: mov x1, x5
; CHECK-CAS-O0-NEXT: ldr x5, [sp, #8] // 8-byte Folded Reload
; CHECK-CAS-O0-NEXT: ldr x5, [sp, #8] // 8-byte Reload
; CHECK-CAS-O0-NEXT: // kill: def $x2 killed $x2 def $x2_x3
; CHECK-CAS-O0-NEXT: mov x3, x5
; CHECK-CAS-O0-NEXT: // kill: def $x4 killed $x4 def $x4_x5
Expand Down Expand Up @@ -343,33 +343,33 @@ define void @val_compare_and_swap_release_acquire(ptr %p, i128 %oldval, i128 %ne
; CHECK-OUTLINE-LLSC-O0-LABEL: val_compare_and_swap_release_acquire:
; CHECK-OUTLINE-LLSC-O0: // %bb.0:
; CHECK-OUTLINE-LLSC-O0-NEXT: sub sp, sp, #32
; CHECK-OUTLINE-LLSC-O0-NEXT: str x30, [sp, #16] // 8-byte Folded Spill
; CHECK-OUTLINE-LLSC-O0-NEXT: str x30, [sp, #16] // 8-byte Spill
; CHECK-OUTLINE-LLSC-O0-NEXT: .cfi_def_cfa_offset 32
; CHECK-OUTLINE-LLSC-O0-NEXT: .cfi_offset w30, -16
; CHECK-OUTLINE-LLSC-O0-NEXT: str x0, [sp, #8] // 8-byte Folded Spill
; CHECK-OUTLINE-LLSC-O0-NEXT: str x0, [sp, #8] // 8-byte Spill
; CHECK-OUTLINE-LLSC-O0-NEXT: mov x0, x2
; CHECK-OUTLINE-LLSC-O0-NEXT: mov x1, x3
; CHECK-OUTLINE-LLSC-O0-NEXT: mov x2, x4
; CHECK-OUTLINE-LLSC-O0-NEXT: ldr x4, [sp, #8] // 8-byte Folded Reload
; CHECK-OUTLINE-LLSC-O0-NEXT: ldr x4, [sp, #8] // 8-byte Reload
; CHECK-OUTLINE-LLSC-O0-NEXT: mov x3, x5
; CHECK-OUTLINE-LLSC-O0-NEXT: bl __aarch64_cas16_acq_rel
; CHECK-OUTLINE-LLSC-O0-NEXT: mov x8, x0
; CHECK-OUTLINE-LLSC-O0-NEXT: ldr x0, [sp, #8] // 8-byte Folded Reload
; CHECK-OUTLINE-LLSC-O0-NEXT: ldr x0, [sp, #8] // 8-byte Reload
; CHECK-OUTLINE-LLSC-O0-NEXT: // implicit-def: $q0
; CHECK-OUTLINE-LLSC-O0-NEXT: mov v0.d[0], x8
; CHECK-OUTLINE-LLSC-O0-NEXT: mov v0.d[1], x1
; CHECK-OUTLINE-LLSC-O0-NEXT: str q0, [x0]
; CHECK-OUTLINE-LLSC-O0-NEXT: ldr x30, [sp, #16] // 8-byte Folded Reload
; CHECK-OUTLINE-LLSC-O0-NEXT: ldr x30, [sp, #16] // 8-byte Reload
; CHECK-OUTLINE-LLSC-O0-NEXT: add sp, sp, #32
; CHECK-OUTLINE-LLSC-O0-NEXT: ret
;
; CHECK-CAS-O0-LABEL: val_compare_and_swap_release_acquire:
; CHECK-CAS-O0: // %bb.0:
; CHECK-CAS-O0-NEXT: sub sp, sp, #16
; CHECK-CAS-O0-NEXT: .cfi_def_cfa_offset 16
; CHECK-CAS-O0-NEXT: str x3, [sp, #8] // 8-byte Folded Spill
; CHECK-CAS-O0-NEXT: str x3, [sp, #8] // 8-byte Spill
; CHECK-CAS-O0-NEXT: mov x1, x5
; CHECK-CAS-O0-NEXT: ldr x5, [sp, #8] // 8-byte Folded Reload
; CHECK-CAS-O0-NEXT: ldr x5, [sp, #8] // 8-byte Reload
; CHECK-CAS-O0-NEXT: // kill: def $x2 killed $x2 def $x2_x3
; CHECK-CAS-O0-NEXT: mov x3, x5
; CHECK-CAS-O0-NEXT: // kill: def $x4 killed $x4 def $x4_x5
Expand Down Expand Up @@ -470,33 +470,33 @@ define void @val_compare_and_swap_monotonic(ptr %p, i128 %oldval, i128 %newval)
; CHECK-OUTLINE-LLSC-O0-LABEL: val_compare_and_swap_monotonic:
; CHECK-OUTLINE-LLSC-O0: // %bb.0:
; CHECK-OUTLINE-LLSC-O0-NEXT: sub sp, sp, #32
; CHECK-OUTLINE-LLSC-O0-NEXT: str x30, [sp, #16] // 8-byte Folded Spill
; CHECK-OUTLINE-LLSC-O0-NEXT: str x30, [sp, #16] // 8-byte Spill
; CHECK-OUTLINE-LLSC-O0-NEXT: .cfi_def_cfa_offset 32
; CHECK-OUTLINE-LLSC-O0-NEXT: .cfi_offset w30, -16
; CHECK-OUTLINE-LLSC-O0-NEXT: str x0, [sp, #8] // 8-byte Folded Spill
; CHECK-OUTLINE-LLSC-O0-NEXT: str x0, [sp, #8] // 8-byte Spill
; CHECK-OUTLINE-LLSC-O0-NEXT: mov x0, x2
; CHECK-OUTLINE-LLSC-O0-NEXT: mov x1, x3
; CHECK-OUTLINE-LLSC-O0-NEXT: mov x2, x4
; CHECK-OUTLINE-LLSC-O0-NEXT: ldr x4, [sp, #8] // 8-byte Folded Reload
; CHECK-OUTLINE-LLSC-O0-NEXT: ldr x4, [sp, #8] // 8-byte Reload
; CHECK-OUTLINE-LLSC-O0-NEXT: mov x3, x5
; CHECK-OUTLINE-LLSC-O0-NEXT: bl __aarch64_cas16_acq_rel
; CHECK-OUTLINE-LLSC-O0-NEXT: mov x8, x0
; CHECK-OUTLINE-LLSC-O0-NEXT: ldr x0, [sp, #8] // 8-byte Folded Reload
; CHECK-OUTLINE-LLSC-O0-NEXT: ldr x0, [sp, #8] // 8-byte Reload
; CHECK-OUTLINE-LLSC-O0-NEXT: // implicit-def: $q0
; CHECK-OUTLINE-LLSC-O0-NEXT: mov v0.d[0], x8
; CHECK-OUTLINE-LLSC-O0-NEXT: mov v0.d[1], x1
; CHECK-OUTLINE-LLSC-O0-NEXT: str q0, [x0]
; CHECK-OUTLINE-LLSC-O0-NEXT: ldr x30, [sp, #16] // 8-byte Folded Reload
; CHECK-OUTLINE-LLSC-O0-NEXT: ldr x30, [sp, #16] // 8-byte Reload
; CHECK-OUTLINE-LLSC-O0-NEXT: add sp, sp, #32
; CHECK-OUTLINE-LLSC-O0-NEXT: ret
;
; CHECK-CAS-O0-LABEL: val_compare_and_swap_monotonic:
; CHECK-CAS-O0: // %bb.0:
; CHECK-CAS-O0-NEXT: sub sp, sp, #16
; CHECK-CAS-O0-NEXT: .cfi_def_cfa_offset 16
; CHECK-CAS-O0-NEXT: str x3, [sp, #8] // 8-byte Folded Spill
; CHECK-CAS-O0-NEXT: str x3, [sp, #8] // 8-byte Spill
; CHECK-CAS-O0-NEXT: mov x1, x5
; CHECK-CAS-O0-NEXT: ldr x5, [sp, #8] // 8-byte Folded Reload
; CHECK-CAS-O0-NEXT: ldr x5, [sp, #8] // 8-byte Reload
; CHECK-CAS-O0-NEXT: // kill: def $x2 killed $x2 def $x2_x3
; CHECK-CAS-O0-NEXT: mov x3, x5
; CHECK-CAS-O0-NEXT: // kill: def $x4 killed $x4 def $x4_x5
Expand Down Expand Up @@ -580,22 +580,22 @@ define void @atomic_load_relaxed(i64, i64, ptr %p, ptr %p2) {
; CHECK-OUTLINE-LLSC-O0-LABEL: atomic_load_relaxed:
; CHECK-OUTLINE-LLSC-O0: // %bb.0:
; CHECK-OUTLINE-LLSC-O0-NEXT: sub sp, sp, #32
; CHECK-OUTLINE-LLSC-O0-NEXT: str x30, [sp, #16] // 8-byte Folded Spill
; CHECK-OUTLINE-LLSC-O0-NEXT: str x30, [sp, #16] // 8-byte Spill
; CHECK-OUTLINE-LLSC-O0-NEXT: .cfi_def_cfa_offset 32
; CHECK-OUTLINE-LLSC-O0-NEXT: .cfi_offset w30, -16
; CHECK-OUTLINE-LLSC-O0-NEXT: mov x4, x2
; CHECK-OUTLINE-LLSC-O0-NEXT: str x3, [sp, #8] // 8-byte Folded Spill
; CHECK-OUTLINE-LLSC-O0-NEXT: str x3, [sp, #8] // 8-byte Spill
; CHECK-OUTLINE-LLSC-O0-NEXT: mov x3, xzr
; CHECK-OUTLINE-LLSC-O0-NEXT: mov x0, x3
; CHECK-OUTLINE-LLSC-O0-NEXT: mov x1, x3
; CHECK-OUTLINE-LLSC-O0-NEXT: mov x2, x3
; CHECK-OUTLINE-LLSC-O0-NEXT: bl __aarch64_cas16_relax
; CHECK-OUTLINE-LLSC-O0-NEXT: ldr x3, [sp, #8] // 8-byte Folded Reload
; CHECK-OUTLINE-LLSC-O0-NEXT: ldr x3, [sp, #8] // 8-byte Reload
; CHECK-OUTLINE-LLSC-O0-NEXT: // implicit-def: $q0
; CHECK-OUTLINE-LLSC-O0-NEXT: mov v0.d[0], x0
; CHECK-OUTLINE-LLSC-O0-NEXT: mov v0.d[1], x1
; CHECK-OUTLINE-LLSC-O0-NEXT: str q0, [x3]
; CHECK-OUTLINE-LLSC-O0-NEXT: ldr x30, [sp, #16] // 8-byte Folded Reload
; CHECK-OUTLINE-LLSC-O0-NEXT: ldr x30, [sp, #16] // 8-byte Reload
; CHECK-OUTLINE-LLSC-O0-NEXT: add sp, sp, #32
; CHECK-OUTLINE-LLSC-O0-NEXT: ret
;
Expand Down Expand Up @@ -690,17 +690,17 @@ define i128 @val_compare_and_swap_return(ptr %p, i128 %oldval, i128 %newval) {
; CHECK-OUTLINE-LLSC-O0-LABEL: val_compare_and_swap_return:
; CHECK-OUTLINE-LLSC-O0: // %bb.0:
; CHECK-OUTLINE-LLSC-O0-NEXT: sub sp, sp, #32
; CHECK-OUTLINE-LLSC-O0-NEXT: str x30, [sp, #16] // 8-byte Folded Spill
; CHECK-OUTLINE-LLSC-O0-NEXT: str x30, [sp, #16] // 8-byte Spill
; CHECK-OUTLINE-LLSC-O0-NEXT: .cfi_def_cfa_offset 32
; CHECK-OUTLINE-LLSC-O0-NEXT: .cfi_offset w30, -16
; CHECK-OUTLINE-LLSC-O0-NEXT: str x0, [sp, #8] // 8-byte Folded Spill
; CHECK-OUTLINE-LLSC-O0-NEXT: str x0, [sp, #8] // 8-byte Spill
; CHECK-OUTLINE-LLSC-O0-NEXT: mov x0, x2
; CHECK-OUTLINE-LLSC-O0-NEXT: mov x1, x3
; CHECK-OUTLINE-LLSC-O0-NEXT: mov x2, x4
; CHECK-OUTLINE-LLSC-O0-NEXT: ldr x4, [sp, #8] // 8-byte Folded Reload
; CHECK-OUTLINE-LLSC-O0-NEXT: ldr x4, [sp, #8] // 8-byte Reload
; CHECK-OUTLINE-LLSC-O0-NEXT: mov x3, x5
; CHECK-OUTLINE-LLSC-O0-NEXT: bl __aarch64_cas16_acq
; CHECK-OUTLINE-LLSC-O0-NEXT: ldr x30, [sp, #16] // 8-byte Folded Reload
; CHECK-OUTLINE-LLSC-O0-NEXT: ldr x30, [sp, #16] // 8-byte Reload
; CHECK-OUTLINE-LLSC-O0-NEXT: add sp, sp, #32
; CHECK-OUTLINE-LLSC-O0-NEXT: ret
;
Expand Down
Loading
Loading