[llvm-branch-commits] [llvm] 3d0470a - [AArch64][SVE] Fix CFA calculation in presence of SVE objects.
Hans Wennborg via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Mon Aug 17 05:06:06 PDT 2020
Author: Sander de Smalen
Date: 2020-08-17T13:58:09+02:00
New Revision: 3d0470ae802ae443a2df39f495d2ddd92805c8f8
URL: https://github.com/llvm/llvm-project/commit/3d0470ae802ae443a2df39f495d2ddd92805c8f8
DIFF: https://github.com/llvm/llvm-project/commit/3d0470ae802ae443a2df39f495d2ddd92805c8f8.diff
LOG: [AArch64][SVE] Fix CFA calculation in presence of SVE objects.
The CFA is calculated as (SP/FP + offset), but when there are
SVE objects on the stack the SP offset is partly scalable and
should instead be expressed as the DWARF expression:
SP + offset + scalable_offset * VG
where VG is the Vector Granule register, containing the
number of 64bits 'granules' in a scalable vector.
Reviewed By: efriedma
Differential Revision: https://reviews.llvm.org/D84043
(cherry picked from commit fd6584a22043b254a323635c142b28ce80ae5b5b)
Added:
Modified:
llvm/include/llvm/MC/MCDwarf.h
llvm/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp
llvm/lib/Target/AArch64/AArch64FrameLowering.cpp
llvm/lib/Target/AArch64/AArch64FrameLowering.h
llvm/lib/Target/AArch64/AArch64RegisterInfo.td
llvm/lib/Target/AArch64/AArch64StackOffset.h
llvm/test/CodeGen/AArch64/framelayout-sve.mir
llvm/test/CodeGen/AArch64/sve-trunc.ll
Removed:
################################################################################
diff --git a/llvm/include/llvm/MC/MCDwarf.h b/llvm/include/llvm/MC/MCDwarf.h
index e3cea0ae64cf..70da5f76e766 100644
--- a/llvm/include/llvm/MC/MCDwarf.h
+++ b/llvm/include/llvm/MC/MCDwarf.h
@@ -467,10 +467,12 @@ class MCCFIInstruction {
unsigned Register2;
};
std::vector<char> Values;
+ std::string Comment;
- MCCFIInstruction(OpType Op, MCSymbol *L, unsigned R, int O, StringRef V)
+ MCCFIInstruction(OpType Op, MCSymbol *L, unsigned R, int O, StringRef V,
+ StringRef Comment = "")
: Operation(Op), Label(L), Register(R), Offset(O),
- Values(V.begin(), V.end()) {
+ Values(V.begin(), V.end()), Comment(Comment) {
assert(Op != OpRegister);
}
@@ -570,8 +572,9 @@ class MCCFIInstruction {
/// .cfi_escape Allows the user to add arbitrary bytes to the unwind
/// info.
- static MCCFIInstruction createEscape(MCSymbol *L, StringRef Vals) {
- return MCCFIInstruction(OpEscape, L, 0, 0, Vals);
+ static MCCFIInstruction createEscape(MCSymbol *L, StringRef Vals,
+ StringRef Comment = "") {
+ return MCCFIInstruction(OpEscape, L, 0, 0, Vals, Comment);
}
/// A special wrapper for .cfi_escape that indicates GNU_ARGS_SIZE
@@ -606,6 +609,10 @@ class MCCFIInstruction {
assert(Operation == OpEscape);
return StringRef(&Values[0], Values.size());
}
+
+ StringRef getComment() const {
+ return Comment;
+ }
};
struct MCDwarfFrameInfo {
diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp
index d81a9be26d39..b6a9a9568360 100644
--- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp
@@ -241,6 +241,7 @@ void AsmPrinter::emitCFIInstruction(const MCCFIInstruction &Inst) const {
OutStreamer->emitCFIGnuArgsSize(Inst.getOffset());
break;
case MCCFIInstruction::OpEscape:
+ OutStreamer->AddComment(Inst.getComment());
OutStreamer->emitCFIEscape(Inst.getValues());
break;
case MCCFIInstruction::OpRestore:
diff --git a/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp b/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp
index 4789a9f02937..177d5e24fdb3 100644
--- a/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp
@@ -148,6 +148,7 @@
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/LEB128.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetMachine.h"
@@ -399,6 +400,64 @@ static bool ShouldSignReturnAddress(MachineFunction &MF) {
return false;
}
+// Convenience function to create a DWARF expression for
+// Expr + NumBytes + NumVGScaledBytes * AArch64::VG
+static void appendVGScaledOffsetExpr(SmallVectorImpl<char> &Expr,
+ int NumBytes, int NumVGScaledBytes, unsigned VG,
+ llvm::raw_string_ostream &Comment) {
+ uint8_t buffer[16];
+
+ if (NumBytes) {
+ Expr.push_back(dwarf::DW_OP_consts);
+ Expr.append(buffer, buffer + encodeSLEB128(NumBytes, buffer));
+ Expr.push_back((uint8_t)dwarf::DW_OP_plus);
+ Comment << (NumBytes < 0 ? " - " : " + ") << std::abs(NumBytes);
+ }
+
+ if (NumVGScaledBytes) {
+ Expr.push_back((uint8_t)dwarf::DW_OP_consts);
+ Expr.append(buffer, buffer + encodeSLEB128(NumVGScaledBytes, buffer));
+
+ Expr.push_back((uint8_t)dwarf::DW_OP_bregx);
+ Expr.append(buffer, buffer + encodeULEB128(VG, buffer));
+ Expr.push_back(0);
+
+ Expr.push_back((uint8_t)dwarf::DW_OP_mul);
+ Expr.push_back((uint8_t)dwarf::DW_OP_plus);
+
+ Comment << (NumVGScaledBytes < 0 ? " - " : " + ")
+ << std::abs(NumVGScaledBytes) << " * VG";
+ }
+}
+
+// Creates an MCCFIInstruction:
+// { DW_CFA_def_cfa_expression, ULEB128 (sizeof expr), expr }
+MCCFIInstruction AArch64FrameLowering::createDefCFAExpressionFromSP(
+ const TargetRegisterInfo &TRI, const StackOffset &OffsetFromSP) const {
+ int64_t NumBytes, NumVGScaledBytes;
+ OffsetFromSP.getForDwarfOffset(NumBytes, NumVGScaledBytes);
+
+ std::string CommentBuffer = "sp";
+ llvm::raw_string_ostream Comment(CommentBuffer);
+
+ // Build up the expression (SP + NumBytes + NumVGScaledBytes * AArch64::VG)
+ SmallString<64> Expr;
+ Expr.push_back(dwarf::DW_OP_breg0 + /*SP*/ 31);
+ Expr.push_back(0);
+ appendVGScaledOffsetExpr(Expr, NumBytes, NumVGScaledBytes,
+ TRI.getDwarfRegNum(AArch64::VG, true), Comment);
+
+ // Wrap this into DW_CFA_def_cfa.
+ SmallString<64> DefCfaExpr;
+ DefCfaExpr.push_back(dwarf::DW_CFA_def_cfa_expression);
+ uint8_t buffer[16];
+ DefCfaExpr.append(buffer,
+ buffer + encodeULEB128(Expr.size(), buffer));
+ DefCfaExpr.append(Expr.str());
+ return MCCFIInstruction::createEscape(nullptr, DefCfaExpr.str(),
+ Comment.str());
+}
+
void AArch64FrameLowering::emitCalleeSavedFrameMoves(
MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI) const {
MachineFunction &MF = *MBB.getParent();
@@ -1383,9 +1442,18 @@ void AArch64FrameLowering::emitPrologue(MachineFunction &MF,
.addCFIIndex(CFIIndex)
.setMIFlags(MachineInstr::FrameSetup);
} else {
- // Encode the stack size of the leaf function.
- unsigned CFIIndex = MF.addFrameInst(
- MCCFIInstruction::cfiDefCfaOffset(nullptr, MFI.getStackSize()));
+ unsigned CFIIndex;
+ if (SVEStackSize) {
+ const TargetSubtargetInfo &STI = MF.getSubtarget();
+ const TargetRegisterInfo &TRI = *STI.getRegisterInfo();
+ StackOffset TotalSize =
+ SVEStackSize + StackOffset((int64_t)MFI.getStackSize(), MVT::i8);
+ CFIIndex = MF.addFrameInst(createDefCFAExpressionFromSP(TRI, TotalSize));
+ } else {
+ // Encode the stack size of the leaf function.
+ CFIIndex = MF.addFrameInst(
+ MCCFIInstruction::cfiDefCfaOffset(nullptr, MFI.getStackSize()));
+ }
BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
.addCFIIndex(CFIIndex)
.setMIFlags(MachineInstr::FrameSetup);
diff --git a/llvm/lib/Target/AArch64/AArch64FrameLowering.h b/llvm/lib/Target/AArch64/AArch64FrameLowering.h
index 444740cb50ab..753593df2b4d 100644
--- a/llvm/lib/Target/AArch64/AArch64FrameLowering.h
+++ b/llvm/lib/Target/AArch64/AArch64FrameLowering.h
@@ -18,6 +18,8 @@
namespace llvm {
+class MCCFIInstruction;
+
class AArch64FrameLowering : public TargetFrameLowering {
public:
explicit AArch64FrameLowering()
@@ -119,6 +121,11 @@ class AArch64FrameLowering : public TargetFrameLowering {
int64_t assignSVEStackObjectOffsets(MachineFrameInfo &MF,
int &MinCSFrameIndex,
int &MaxCSFrameIndex) const;
+ MCCFIInstruction
+ createDefCFAExpressionFromSP(const TargetRegisterInfo &TRI,
+ const StackOffset &OffsetFromSP) const;
+ MCCFIInstruction createCfaOffset(const MCRegisterInfo &MRI, unsigned DwarfReg,
+ const StackOffset &OffsetFromDefCFA) const;
bool shouldCombineCSRLocalStackBumpInEpilogue(MachineBasicBlock &MBB,
unsigned StackBumpBytes) const;
};
diff --git a/llvm/lib/Target/AArch64/AArch64RegisterInfo.td b/llvm/lib/Target/AArch64/AArch64RegisterInfo.td
index bd05c56009a1..54b351fda053 100644
--- a/llvm/lib/Target/AArch64/AArch64RegisterInfo.td
+++ b/llvm/lib/Target/AArch64/AArch64RegisterInfo.td
@@ -133,6 +133,9 @@ def NZCV : AArch64Reg<0, "nzcv">;
// First fault status register
def FFR : AArch64Reg<0, "ffr">, DwarfRegNum<[47]>;
+// Purely virtual Vector Granule (VG) Dwarf register
+def VG : AArch64Reg<0, "vg">, DwarfRegNum<[46]>;
+
// GPR register classes with the intersections of GPR32/GPR32sp and
// GPR64/GPR64sp for use by the coalescer.
def GPR32common : RegisterClass<"AArch64", [i32], 32, (sequence "W%u", 0, 30)> {
diff --git a/llvm/lib/Target/AArch64/AArch64StackOffset.h b/llvm/lib/Target/AArch64/AArch64StackOffset.h
index 6fa1c744f77e..24751a81797d 100644
--- a/llvm/lib/Target/AArch64/AArch64StackOffset.h
+++ b/llvm/lib/Target/AArch64/AArch64StackOffset.h
@@ -123,6 +123,18 @@ class StackOffset {
}
}
+ void getForDwarfOffset(int64_t &ByteSized, int64_t &VGSized) const {
+ assert(isValid() && "Invalid frame offset");
+
+ // VGSized offsets are divided by '2', because the VG register is the
+ // the number of 64bit granules as opposed to 128bit vector chunks,
+ // which is how the 'n' in e.g. MVT::nxv1i8 is modelled.
+ // So, for a stack offset of 16 MVT::nxv1i8's, the size is n x 16 bytes.
+ // VG = n * 2 and the dwarf offset must be VG * 8 bytes.
+ ByteSized = Bytes;
+ VGSized = ScalableBytes / 2;
+ }
+
/// Returns whether the offset is known zero.
explicit operator bool() const { return Bytes || ScalableBytes; }
diff --git a/llvm/test/CodeGen/AArch64/framelayout-sve.mir b/llvm/test/CodeGen/AArch64/framelayout-sve.mir
index 668b243dd79e..9e2077855c11 100644
--- a/llvm/test/CodeGen/AArch64/framelayout-sve.mir
+++ b/llvm/test/CodeGen/AArch64/framelayout-sve.mir
@@ -1,4 +1,8 @@
# RUN: llc -mattr=+sve -mtriple=aarch64-none-linux-gnu -run-pass=prologepilog %s -o - | FileCheck %s
+# RUN: llc -mtriple=aarch64-none-linux-gnu -mattr=+sve -start-before=prologepilog %s -o - | FileCheck %s --check-prefix=ASM
+# RUN: llc -mtriple=aarch64-none-linux-gnu -mattr=+sve -start-before=prologepilog %s -filetype=obj -o %t
+# RUN: llvm-objdump --dwarf=frames %t | FileCheck %s --check-prefix=UNWINDINFO
+# RUN: rm -rf %t
#
# Test allocation and deallocation of SVE objects on the stack,
# as well as using a combination of scalable and non-scalable
@@ -23,19 +27,19 @@
#
--- |
- define void @test_allocate_sve() nounwind { entry: unreachable }
- define void @test_allocate_sve_gpr_callee_saves() nounwind { entry: unreachable }
- define void @test_allocate_sve_gpr_realigned() nounwind { entry: unreachable }
- define void @test_address_sve() nounwind { entry: unreachable }
- define void @test_address_sve_fp() nounwind { entry: unreachable }
- define void @test_stack_arg_sve() nounwind { entry: unreachable }
- define void @test_address_sve_out_of_range() nounwind { entry: unreachable }
- define void @test_address_gpr_vla() nounwind { entry: unreachable }
- define aarch64_sve_vector_pcs void @save_restore_pregs_sve() nounwind { entry: unreachable }
- define aarch64_sve_vector_pcs void @save_restore_zregs_sve() nounwind { entry: unreachable }
- define aarch64_sve_vector_pcs void @save_restore_sve() nounwind { entry: unreachable }
- define aarch64_sve_vector_pcs void @save_restore_sve_realign() nounwind { entry: unreachable }
- define aarch64_sve_vector_pcs void @frame_layout() nounwind { entry: unreachable }
+ define void @test_allocate_sve() { entry: unreachable }
+ define void @test_allocate_sve_gpr_callee_saves() { entry: unreachable }
+ define void @test_allocate_sve_gpr_realigned() { entry: unreachable }
+ define void @test_address_sve() { entry: unreachable }
+ define void @test_address_sve_fp() { entry: unreachable }
+ define void @test_stack_arg_sve() { entry: unreachable }
+ define void @test_address_sve_out_of_range() { entry: unreachable }
+ define void @test_address_gpr_vla() { entry: unreachable }
+ define aarch64_sve_vector_pcs void @save_restore_pregs_sve() { entry: unreachable }
+ define aarch64_sve_vector_pcs void @save_restore_zregs_sve() { entry: unreachable }
+ define aarch64_sve_vector_pcs void @save_restore_sve() { entry: unreachable }
+ define aarch64_sve_vector_pcs void @save_restore_sve_realign() { entry: unreachable }
+ define aarch64_sve_vector_pcs void @frame_layout() { entry: unreachable }
...
# +----------+
@@ -54,11 +58,19 @@
# CHECK-NEXT: $sp = frame-setup STRXpre killed $[[SCRATCH:[a-z0-9]+]], $sp, -16
# CHECK-NEXT: $sp = frame-setup ADDVL_XXI $sp, -2
# CHECK-NEXT: $sp = frame-setup SUBXri $sp, 16, 0
+# CHECK-COUNT-2: frame-setup CFI_INSTRUCTION
# CHECK-NEXT: $sp = frame-destroy ADDVL_XXI $sp, 2
# CHECK-NEXT: $sp = frame-destroy ADDXri $sp, 16, 0
# CHECK-NEXT: $sp, $[[SCRATCH]] = frame-destroy LDRXpost $sp, 16
# CHECK-NEXT: RET_ReallyLR
+
+# ASM-LABEL: test_allocate_sve:
+# ASM: .cfi_escape 0x0f, 0x0c, 0x8f, 0x00, 0x11, 0x20, 0x22, 0x11, 0x10, 0x92, 0x2e, 0x00, 0x1e, 0x22 // sp + 32 + 16 * VG
+# ASM-NEXT: .cfi_offset w29, -16
+#
+# UNWINDINFO: DW_CFA_def_cfa_expression: DW_OP_breg31 +0, DW_OP_consts +32, DW_OP_plus, DW_OP_consts +16, DW_OP_bregx 0x2e +0, DW_OP_mul, DW_OP_plus
+# UNWINDINFO-NEXT: DW_CFA_offset: reg29 -16
name: test_allocate_sve
stack:
- { id: 0, stack-id: sve-vec, size: 18, alignment: 2 }
@@ -85,6 +97,8 @@ body: |
# CHECK-NEXT: frame-setup STPXi killed $x21, killed $x20, $sp, 2
# CHECK-NEXT: $sp = frame-setup ADDVL_XXI $sp, -2
# CHECK-NEXT: $sp = frame-setup SUBXri $sp, 16, 0
+# CHECK-COUNT-4: frame-setup CFI_INSTRUCTION
+#
# CHECK-NEXT: $x20 = IMPLICIT_DEF
# CHECK-NEXT: $x21 = IMPLICIT_DEF
# CHECK-NEXT: $sp = frame-destroy ADDVL_XXI $sp, 2
@@ -92,6 +106,17 @@ body: |
# CHECK-NEXT: $x21, $x20 = frame-destroy LDPXi $sp, 2
# CHECK-NEXT: $sp, $[[SCRATCH]] = frame-destroy LDRXpost $sp, 32
# CHECK-NEXT: RET_ReallyLR
+#
+# ASM-LABEL: test_allocate_sve_gpr_callee_saves:
+# ASM: .cfi_escape 0x0f, 0x0c, 0x8f, 0x00, 0x11, 0x30, 0x22, 0x11, 0x10, 0x92, 0x2e, 0x00, 0x1e, 0x22 // sp + 48 + 16 * VG
+# ASM-NEXT: .cfi_offset w20, -8
+# ASM-NEXT: .cfi_offset w21, -16
+# ASM-NEXT: .cfi_offset w29, -32
+#
+# UNWINDINFO: DW_CFA_def_cfa_expression: DW_OP_breg31 +0, DW_OP_consts +48, DW_OP_plus, DW_OP_consts +16, DW_OP_bregx 0x2e +0, DW_OP_mul, DW_OP_plus
+# UNWINDINFO-NEXT: DW_CFA_offset: reg20 -8
+# UNWINDINFO-NEXT: DW_CFA_offset: reg21 -16
+# UNWINDINFO-NEXT: DW_CFA_offset: reg29 -32
name: test_allocate_sve_gpr_callee_saves
stack:
- { id: 0, stack-id: sve-vec, size: 18, alignment: 2 }
@@ -120,9 +145,20 @@ body: |
# CHECK-NEXT: $sp = frame-setup ADDVL_XXI $sp, -2
# CHECK-NEXT: $[[TMP:x[0-9]+]] = frame-setup SUBXri $sp, 16, 0
# CHECK-NEXT: $sp = ANDXri killed $[[TMP]]
+# CHECK-COUNT-3: frame-setup CFI_INSTRUCTION
# CHECK-NEXT: $sp = frame-destroy ADDXri $fp, 0, 0
# CHECK-NEXT: $sp, $fp, $lr = frame-destroy LDPXpost $sp, 2
# CHECK-NEXT: RET_ReallyLR
+#
+# ASM-LABEL: test_allocate_sve_gpr_realigned:
+# ASM: .cfi_def_cfa w29, 16
+# ASM-NEXT: .cfi_offset w30, -8
+# ASM-NEXT: .cfi_offset w29, -16
+#
+# UNWINDINFO: DW_CFA_def_cfa: reg29 +16
+# UNWINDINFO-NEXT: DW_CFA_offset: reg30 -8
+# UNWINDINFO-NEXT: DW_CFA_offset: reg29 -16
+
name: test_allocate_sve_gpr_realigned
stack:
- { id: 0, stack-id: sve-vec, size: 18, alignment: 2 }
@@ -149,6 +185,7 @@ body: |
# CHECK-NEXT: $sp = frame-setup STRXpre killed $[[SCRATCH:[a-z0-9]+]], $sp, -16
# CHECK-NEXT: $sp = frame-setup ADDVL_XXI $sp, -3
# CHECK-NEXT: $sp = frame-setup SUBXri $sp, 16, 0
+# CHECK-COUNT-2: frame-setup CFI_INSTRUCTION
# CHECK-NEXT: $[[TMP:x[0-9]+]] = ADDXri $sp, 16
# CHECK-NEXT: STR_ZXI $z0, killed $[[TMP]], 2
@@ -161,6 +198,14 @@ body: |
# CHECK-NEXT: $sp = frame-destroy ADDXri $sp, 16, 0
# CHECK-NEXT: $sp, $[[SCRATCH]] = frame-destroy LDRXpost $sp, 16
# CHECK-NEXT: RET_ReallyLR
+#
+# ASM-LABEL: test_address_sve:
+# ASM: .cfi_escape 0x0f, 0x0c, 0x8f, 0x00, 0x11, 0x20, 0x22, 0x11, 0x18, 0x92, 0x2e, 0x00, 0x1e, 0x22 // sp + 32 + 24 * VG
+# ASM-NEXT: .cfi_offset w29, -16
+#
+# UNWINDINFO: DW_CFA_def_cfa_expression: DW_OP_breg31 +0, DW_OP_consts +32, DW_OP_plus, DW_OP_consts +24, DW_OP_bregx 0x2e +0, DW_OP_mul, DW_OP_plus
+# UNWINDINFO-NEXT: DW_CFA_offset: reg29 -16
+
name: test_address_sve
frameInfo:
maxAlignment: 16
@@ -199,6 +244,7 @@ body: |
# CHECK-NEXT: $fp = frame-setup ADDXri $sp, 0, 0
# CHECK-NEXT: $sp = frame-setup ADDVL_XXI $sp, -3
# CHECK-NEXT: $sp = frame-setup SUBXri $sp, 16, 0
+# CHECK-COUNT-3: frame-setup CFI_INSTRUCTION
# CHECK-NEXT: STR_ZXI $z0, $fp, -1
# CHECK-NEXT: STR_ZXI $z1, $fp, -2
@@ -208,6 +254,15 @@ body: |
# CHECK: $sp = frame-destroy ADDXri $sp, 16, 0
# CHECK-NEXT: $sp, $fp, $lr = frame-destroy LDPXpost $sp, 2
# CHECK-NEXT: RET_ReallyLR
+#
+# ASM-LABEL: test_address_sve_fp:
+# ASM: .cfi_def_cfa w29, 16
+# ASM-NEXT: .cfi_offset w30, -8
+# ASM-NEXT: .cfi_offset w29, -16
+#
+# UNWINDINFO: DW_CFA_def_cfa: reg29 +16
+# UNWINDINFO-NEXT: DW_CFA_offset: reg30 -8
+# UNWINDINFO-NEXT: DW_CFA_offset: reg29 -16
name: test_address_sve_fp
frameInfo:
maxAlignment: 16
@@ -244,6 +299,7 @@ body: |
# CHECK-NEXT: $sp = frame-setup STRXpre killed $[[SCRATCH:[a-z0-9]+]], $sp, -16
# CHECK-NEXT: $sp = frame-setup ADDVL_XXI $sp, -1
# CHECK-NEXT: $sp = frame-setup SUBXri $sp, 16, 0
+# CHECK-COUNT-2: frame-setup CFI_INSTRUCTION
# CHECK: $[[TMP:x[0-9]+]] = ADDVL_XXI $sp, 1
# CHECK-NEXT: $x0 = LDRXui killed $[[TMP]], 4
@@ -252,6 +308,14 @@ body: |
# CHECK-NEXT: $sp = frame-destroy ADDXri $sp, 16, 0
# CHECK-NEXT: $sp, $[[SCRATCH]] = frame-destroy LDRXpost $sp, 16
# CHECK-NEXT: RET_ReallyLR
+#
+# ASM-LABEL: test_stack_arg_sve:
+# ASM: .cfi_escape 0x0f, 0x0c, 0x8f, 0x00, 0x11, 0x20, 0x22, 0x11, 0x08, 0x92, 0x2e, 0x00, 0x1e, 0x22 // sp + 32 + 8 * VG
+# ASM-NEXT: .cfi_offset w29, -16
+#
+# UNWINDINFO: DW_CFA_def_cfa_expression: DW_OP_breg31 +0, DW_OP_consts +32, DW_OP_plus, DW_OP_consts +8, DW_OP_bregx 0x2e +0, DW_OP_mul, DW_OP_plus
+# UNWINDINFO-NEXT: DW_CFA_offset: reg29 -16
+
name: test_stack_arg_sve
fixedStack:
- { id: 0, stack-id: default, size: 16, alignment: 16, offset: 0 }
@@ -292,6 +356,7 @@ body: |
# CHECK-NEXT: $sp = frame-setup ADDVL_XXI $sp, -32
# CHECK-NEXT: $sp = frame-setup ADDVL_XXI $sp, -32
# CHECK-NEXT: $sp = frame-setup ADDVL_XXI $sp, -1
+# CHECK-COUNT-2: frame-setup CFI_INSTRUCTION
# CHECK-NEXT: $[[TMP2:x[0-9]+]] = ADDVL_XXI $sp, 1
# CHECK-NEXT: STR_ZXI $z0, killed $[[TMP2]], 255
@@ -310,6 +375,13 @@ body: |
# CHECK-NEXT: $sp = frame-destroy ADDVL_XXI $sp, 9
# CHECK-NEXT: $sp, $[[SCRATCH]] = frame-destroy LDRXpost $sp, 16
# CHECK-NEXT: RET_ReallyLR
+#
+# ASM-LABEL: test_address_sve_out_of_range:
+# ASM: .cfi_escape 0x0f, 0x0d, 0x8f, 0x00, 0x11, 0x10, 0x22, 0x11, 0x88, 0x10, 0x92, 0x2e, 0x00, 0x1e, 0x22 // sp + 16 + 2056 * VG
+# ASM-NEXT: .cfi_offset w29, -16
+#
+# UNWINDINFO: DW_CFA_def_cfa_expression: DW_OP_breg31 +0, DW_OP_consts +16, DW_OP_plus, DW_OP_consts +2056, DW_OP_bregx 0x2e +0, DW_OP_mul, DW_OP_plus
+# UNWINDINFO-NEXT: DW_CFA_offset: reg29 -16
name: test_address_sve_out_of_range
frameInfo:
maxAlignment: 16
@@ -344,6 +416,17 @@ body: |
# CHECK: bb.0.entry:
# CHECK: STRXui $xzr, $x19, 0
# CHECK: RET_ReallyLR
+#
+# ASM-LABEL: test_address_gpr_vla:
+# ASM: .cfi_def_cfa w29, 32
+# ASM-NEXT: .cfi_offset w19, -16
+# ASM-NEXT: .cfi_offset w30, -24
+# ASM-NEXT: .cfi_offset w29, -32
+#
+# UNWINDINFO: DW_CFA_def_cfa: reg29 +32
+# UNWINDINFO-NEXT: DW_CFA_offset: reg19 -16
+# UNWINDINFO-NEXT: DW_CFA_offset: reg30 -24
+# UNWINDINFO-NEXT: DW_CFA_offset: reg29 -32
name: test_address_gpr_vla
frameInfo:
maxAlignment: 16
@@ -366,6 +449,7 @@ body: |
# CHECK: frame-setup STR_PXI killed $p5, $sp, 6
# CHECK: frame-setup STR_PXI killed $p4, $sp, 7
# CHECK: $sp = frame-setup SUBXri $sp, 32, 0
+# CHECK-COUNT-5: frame-setup CFI_INSTRUCTION
# CHECK: $sp = frame-destroy ADDXri $sp, 32, 0
# CHECK: $p6 = frame-destroy LDR_PXI $sp, 5
@@ -373,6 +457,15 @@ body: |
# CHECK: $p4 = frame-destroy LDR_PXI $sp, 7
# CHECK: $sp = frame-destroy ADDVL_XXI $sp, 1
# CHECK: RET_ReallyLR
+#
+# ASM-LABEL: save_restore_pregs_sve:
+# ASM: .cfi_escape 0x0f, 0x0c, 0x8f, 0x00, 0x11, 0x30, 0x22, 0x11, 0x08, 0x92, 0x2e, 0x00, 0x1e, 0x22 // sp + 48 + 8 * VG
+# ASM-COUNT-3: .cfi_offset
+# ASM-NEXT: .cfi_offset w29, -16
+#
+# UNWINDINFO: DW_CFA_def_cfa_expression: DW_OP_breg31 +0, DW_OP_consts +48, DW_OP_plus, DW_OP_consts +8, DW_OP_bregx 0x2e +0, DW_OP_mul, DW_OP_plus
+# UNWINDINFO-COUNT-3: DW_CFA_offset
+# UNWINDINFO-NEXT: DW_CFA_offset: reg29 -16
name: save_restore_pregs_sve
stack:
- { id: 0, stack-id: default, size: 32, alignment: 16 }
@@ -387,18 +480,29 @@ body: |
---
...
# CHECK-LABEL: name: save_restore_zregs_sve
-# CHECK: $sp = frame-setup ADDVL_XXI $sp, -3
-# CHECK: frame-setup STR_ZXI killed $z10, $sp, 0
-# CHECK: frame-setup STR_ZXI killed $z9, $sp, 1
-# CHECK: frame-setup STR_ZXI killed $z8, $sp, 2
-# CHECK: $sp = frame-setup SUBXri $sp, 32, 0
-
-# CHECK: $sp = frame-destroy ADDXri $sp, 32, 0
-# CHECK: $z10 = frame-destroy LDR_ZXI $sp, 0
-# CHECK: $z9 = frame-destroy LDR_ZXI $sp, 1
-# CHECK: $z8 = frame-destroy LDR_ZXI $sp, 2
-# CHECK: $sp = frame-destroy ADDVL_XXI $sp, 3
-# CHECK: RET_ReallyLR
+# CHECK: $sp = frame-setup STRXpre killed $fp, $sp, -16
+# CHECK-NEXT: $sp = frame-setup ADDVL_XXI $sp, -3
+# CHECK-NEXT: frame-setup STR_ZXI killed $z10, $sp, 0
+# CHECK-NEXT: frame-setup STR_ZXI killed $z9, $sp, 1
+# CHECK-NEXT: frame-setup STR_ZXI killed $z8, $sp, 2
+# CHECK-NEXT: $sp = frame-setup SUBXri $sp, 32, 0
+# CHECK-COUNT-5: frame-setup CFI_INSTRUCTION
+
+# CHECK: $sp = frame-destroy ADDXri $sp, 32, 0
+# CHECK-NEXT: $z10 = frame-destroy LDR_ZXI $sp, 0
+# CHECK-NEXT: $z9 = frame-destroy LDR_ZXI $sp, 1
+# CHECK-NEXT: $z8 = frame-destroy LDR_ZXI $sp, 2
+# CHECK-NEXT: $sp = frame-destroy ADDVL_XXI $sp, 3
+# CHECK-NEXT: $sp, $fp = frame-destroy LDRXpost $sp, 16
+# CHECK-NEXT: RET_ReallyLR
+#
+# ASM-LABEL: save_restore_zregs_sve:
+# ASM: .cfi_escape 0x0f, 0x0c, 0x8f, 0x00, 0x11, 0x30, 0x22, 0x11, 0x18, 0x92, 0x2e, 0x00, 0x1e, 0x22 // sp + 48 + 24 * VG
+# ASM-COUNT-3: .cfi_offset
+#
+# UNWINDINFO: DW_CFA_def_cfa_expression: DW_OP_breg31 +0, DW_OP_consts +48, DW_OP_plus, DW_OP_consts +24, DW_OP_bregx 0x2e +0, DW_OP_mul, DW_OP_plus
+# UNWINDINFO-COUNT-3: DW_CFA_offset
+# UNWINDINFO-NEXT: DW_CFA_offset: reg29 -16
name: save_restore_zregs_sve
stack:
- { id: 0, stack-id: default, size: 32, alignment: 16 }
@@ -432,6 +536,7 @@ body: |
# CHECK: frame-setup STR_ZXI killed $z8, $sp, 17
# CHECK: $sp = frame-setup ADDVL_XXI $sp, -1
# CHECK: $sp = frame-setup SUBXri $sp, 32, 0
+# CHECK-COUNT-33: frame-setup CFI_INSTRUCTION
# CHECK: $sp = frame-destroy ADDXri $sp, 32, 0
# CHECK: $sp = frame-destroy ADDVL_XXI $sp, 1
@@ -447,6 +552,22 @@ body: |
# CHECK: $x20, $x19 = frame-destroy LDPXi $sp, 2
# CHECK: $sp, ${{[a-z0-9]+}}, $x21 = frame-destroy LDPXpost $sp, 4
# CHECK: RET_ReallyLR
+#
+# ASM-LABEL: save_restore_sve:
+# ASM: .cfi_escape 0x0f, 0x0e, 0x8f, 0x00, 0x11, 0xc0, 0x00, 0x22, 0x11, 0x98, 0x01, 0x92, 0x2e, 0x00, 0x1e, 0x22 // sp + 64 + 152 * VG
+# ASM-COUNT-28: .cfi_offset
+# ASM-NEXT: .cfi_offset w19, -8
+# ASM-NEXT: .cfi_offset w20, -16
+# ASM-NEXT: .cfi_offset w21, -24
+# ASM-NEXT: .cfi_offset w29, -32
+#
+# UNWINDINFO: DW_CFA_def_cfa_expression: DW_OP_breg31 +0, DW_OP_consts +64, DW_OP_plus, DW_OP_consts +152, DW_OP_bregx 0x2e +0, DW_OP_mul, DW_OP_plus
+# UNWINDINFO-COUNT-28: DW_CFA_offset
+# UNWINDINFO-NEXT: DW_CFA_offset: reg19 -8
+# UNWINDINFO-NEXT: DW_CFA_offset: reg20 -16
+# UNWINDINFO-NEXT: DW_CFA_offset: reg21 -24
+# UNWINDINFO-NEXT: DW_CFA_offset: reg29 -32
+
name: save_restore_sve
stack:
- { id: 0, stack-id: sve-vec, size: 16, alignment: 16 }
@@ -499,6 +620,7 @@ body: |
# CHECK-NEXT: $sp = frame-setup ADDVL_XXI $sp, -1
# CHECK-NEXT: $[[TMP:x[0-9]+]] = frame-setup SUBXri $sp, 16, 0
# CHECK-NEXT: $sp = ANDXri killed $[[TMP]]
+# CHECK-COUNT-31: frame-setup CFI_INSTRUCTION
# CHECK: $sp = frame-destroy ADDVL_XXI $fp, -18
# CHECK-NEXT: $p15 = frame-destroy LDR_PXI $sp, 4
@@ -512,6 +634,11 @@ body: |
# CHECK-NEXT: $sp = frame-destroy ADDXri $fp, 0, 0
# CHECK-NEXT: $sp, $fp, $lr = frame-destroy LDPXpost $sp, 2
# CHECK-NEXT: RET_ReallyLR
+#
+# UNWINDINFO: DW_CFA_def_cfa: reg29 +16
+# UNWINDINFO-COUNT-28: DW_CFA_offset
+# UNWINDINFO-NEXT: DW_CFA_offset: reg30 -8
+# UNWINDINFO-NEXT: DW_CFA_offset: reg29 -16
name: save_restore_sve_realign
stack:
- { id: 0, stack-id: sve-vec, size: 16, alignment: 16 }
@@ -586,6 +713,15 @@ body: |
# CHECK-NEXT: STR_ZXI killed $z23, $sp, 1
# CHECK-NEXT: STR_ZXI killed $z8, $sp, 2
# CHECK-NEXT: $sp = frame-setup ADDVL_XXI $sp, -7
+# CHECK-COUNT-6: frame-setup CFI_INSTRUCTION
+# ASM-LABEL: frame_layout:
+# ASM: .cfi_escape 0x0f, 0x0d, 0x8f, 0x00, 0x11, 0x10, 0x22, 0x11, 0xd0, 0x00, 0x92, 0x2e, 0x00, 0x1e, 0x22 // sp + 16 + 80 * VG
+# ASM-COUNT-4: .cfi_offset
+# ASM-NEXT: .cfi_offset w29, -16
+#
+# UNWINDINFO: DW_CFA_def_cfa_expression: DW_OP_breg31 +0, DW_OP_consts +16, DW_OP_plus, DW_OP_consts +80, DW_OP_bregx 0x2e +0, DW_OP_mul, DW_OP_plus
+# UNWINDINFO-COUNT-4: DW_CFA_offset
+# UNWINDINFO-NEXT: DW_CFA_offset: reg29 -16
name: frame_layout
stack:
- { id: 0, type: default, size: 32, alignment: 16, stack-id: sve-vec }
diff --git a/llvm/test/CodeGen/AArch64/sve-trunc.ll b/llvm/test/CodeGen/AArch64/sve-trunc.ll
index af50176f6b10..191df22eda50 100644
--- a/llvm/test/CodeGen/AArch64/sve-trunc.ll
+++ b/llvm/test/CodeGen/AArch64/sve-trunc.ll
@@ -116,7 +116,7 @@ define <vscale x 16 x i1> @trunc_i64toi1_split3(<vscale x 16 x i64> %in) {
; CHECK-NEXT: str x29, [sp, #-16]! // 8-byte Folded Spill
; CHECK-NEXT: addvl sp, sp, #-1
; CHECK-NEXT: str p4, [sp, #7, mul vl] // 2-byte Folded Spill
-; CHECK-NEXT: .cfi_def_cfa_offset 16
+; CHECK-NEXT: .cfi_escape 0x0f, 0x0c, 0x8f, 0x00, 0x11, 0x10, 0x22, 0x11, 0x08, 0x92, 0x2e, 0x00, 0x1e, 0x22 // sp + 16 + 8 * VG
; CHECK-NEXT: .cfi_offset p4, -2
; CHECK-NEXT: .cfi_offset w29, -16
; CHECK-NEXT: ptrue p0.d
More information about the llvm-branch-commits
mailing list