Files
clang-p2996/llvm/test/CodeGen/AArch64/live-debugvalues-sve.mir
Jeremy Morse 30cce54dad [X86] Return src/dest register from stack spill/restore recogniser
LLVM provides target hooks to recognise stack spill and restore
instructions, such as isLoadFromStackSlot, and it also provides post frame
elimination versions such as isLoadFromStackSlotPostFE. These are supposed
to return the store-source and load-destination registers; unfortunately on
X86, the PostFE recognisers just return "1", apparently to signify "yes
it's a spill/load". This patch alters the hooks to correctly return the
store-source and load-destination registers:

This is really useful for debug-info as we it helps follow variable values
as they move on/off the stack. There should be no codegen changes: the only
other users of these PostFE target hooks are MachineInstr::getRestoreSize
and MachineInstr::getSpillSize, which don't attempt to interpret the
returned register location.

While we're here, delete the (InstrRef) LiveDebugValues heuristic that
tries to find the spill source register by looking for a killed reg -- we
should be able to rely on the target hooks for that. This involves
temporarily turning off a n InstrRef LivedDebugValues test on aarch64
(patch to re-enable it is in D104521).

Differential Revision: https://reviews.llvm.org/D105428
2021-07-09 18:12:30 +01:00

178 lines
9.4 KiB
YAML

# RUN: llc -start-before=prologepilog -stop-after=livedebugvalues -mattr=+sve -o - %s | FileCheck %s
#
# FIXME: re-enable this run line when InstrRef LiveDebugValues is able to
# rely on the target spill/restore inst recognisers.
# run: llc -start-before=prologepilog -stop-after=livedebugvalues -experimental-debug-variable-locations -mattr=+sve -o - %s | FileCheck %s
#
# Test that the LiveDebugValues pass can correctly handle the address
# of the SVE spill (at a scalable address location) which is expressed
# with a complex DIExpression.
#
# CHECK: $z2 = ORR_ZZZ killed $z1, $z1
# CHECK: $z1 = ORR_ZZZ killed $z0, $z0
# CHECK-DAG: ST1W_IMM renamable $z1, killed renamable $p{{[0-9]+}}, $fp, -[[#%u,OFFSET:]], debug-location !{{[0-9]+}} :: (store unknown-size into %stack.0, align 16)
# CHECK-DAG: DBG_VALUE $fp, 0, !{{[0-9]+}}, !DIExpression(DW_OP_constu, [[#mul(OFFSET,8)]], DW_OP_bregx, 46, 0, DW_OP_mul, DW_OP_minus),
#
# TODO: When LiveDebugValues pass supports reloads for AArch64, it should
# correctly recognize debug-value !27 is in $z1 after the following reload:
#
# CHECK: renamable $z1 = LD1W_IMM renamable $p0, $fp, -[[#OFFSET]], debug-location !34 :: (load unknown-size from %stack.0, align 16)
# CHECK-DAG: ST1W_IMM killed renamable $z3, killed renamable $p0, $fp, -[[#OFFSET]] :: (store unknown-size into %stack.0, align 16)
# CHECK-DAG: DBG_VALUE $noreg, $noreg, !27, !DIExpression(), debug-location !30
--- |
; ModuleID = 't.c'
source_filename = "t.c"
target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
target triple = "aarch64-unknown-linux-gnu"
; Function Attrs: nounwind
define dso_local <vscale x 8 x i32> @foo(<vscale x 4 x i32> %z0, <vscale x 4 x i32> %z1, i32 %c) local_unnamed_addr #0 !dbg !11 {
entry:
call void @llvm.dbg.value(metadata <vscale x 4 x i32> %z0, metadata !27, metadata !DIExpression()), !dbg !30
call void @llvm.dbg.value(metadata <vscale x 4 x i32> %z1, metadata !28, metadata !DIExpression()), !dbg !30
call void @llvm.dbg.value(metadata i32 %c, metadata !29, metadata !DIExpression()), !dbg !30
%tobool.not = icmp eq i32 %c, 0, !dbg !31
br i1 %tobool.not, label %if.end, label %if.then, !dbg !33
if.then: ; preds = %entry
%call = call <vscale x 8 x i32> @bar(<vscale x 4 x i32> %z0, <vscale x 4 x i32> %z0, <vscale x 4 x i32> %z0, <vscale x 4 x i32> %z0, <vscale x 4 x i32> %z0, <vscale x 4 x i32> %z0, <vscale x 4 x i32> %z0, <vscale x 4 x i32> %z0, <vscale x 4 x i32> %z0) #0, !dbg !34
br label %return, !dbg !35
if.end: ; preds = %entry
%0 = call <vscale x 8 x i32> @llvm.aarch64.sve.tuple.create2.nxv8i32.nxv4i32(<vscale x 4 x i32> %z1, <vscale x 4 x i32> %z0), !dbg !36
br label %return, !dbg !37
return: ; preds = %if.end, %if.then
%retval.0 = phi <vscale x 8 x i32> [ %call, %if.then ], [ %0, %if.end ], !dbg !30
ret <vscale x 8 x i32> %retval.0, !dbg !38
}
declare !dbg !39 dso_local <vscale x 8 x i32> @bar(<vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32>) local_unnamed_addr
; Function Attrs: nounwind readonly
declare <vscale x 8 x i32> @llvm.aarch64.sve.tuple.create2.nxv8i32.nxv4i32(<vscale x 4 x i32>, <vscale x 4 x i32>)
; Function Attrs: nounwind readnone speculatable willreturn
declare void @llvm.dbg.value(metadata, metadata, metadata) #1
attributes #0 = { "frame-pointer"="non-leaf"}
attributes #1 = { readnone speculatable willreturn }
!llvm.dbg.cu = !{!0}
!llvm.module.flags = !{!3, !4, !5, !6, !7, !8, !9}
!llvm.ident = !{!10}
!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 12.0.0 (https://github.com/llvm/llvm-project.git b19275ba870a06c5ef0428af6264ffd28c7cde9e)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, splitDebugInlining: false, nameTableKind: None)
!1 = !DIFile(filename: "t.c", directory: "/tmp/")
!2 = !{}
!3 = !{i32 7, !"Dwarf Version", i32 4}
!4 = !{i32 2, !"Debug Info Version", i32 3}
!5 = !{i32 1, !"wchar_size", i32 4}
!6 = !{i32 1, !"branch-target-enforcement", i32 0}
!7 = !{i32 1, !"sign-return-address", i32 0}
!8 = !{i32 1, !"sign-return-address-all", i32 0}
!9 = !{i32 1, !"sign-return-address-with-bkey", i32 0}
!10 = !{!"clang version 12.0.0 (https://github.com/llvm/llvm-project.git b19275ba870a06c5ef0428af6264ffd28c7cde9e)"}
!11 = distinct !DISubprogram(name: "foo", scope: !1, file: !1, line: 6, type: !12, scopeLine: 6, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !26)
!12 = !DISubroutineType(types: !13)
!13 = !{!14, !21, !21, !18}
!14 = !DIDerivedType(tag: DW_TAG_typedef, name: "svint32x2_t", file: !15, line: 59, baseType: !16)
!15 = !DIFile(filename: "lib/clang/12.0.0/include/arm_sve.h", directory: "/tmp")
!16 = !DIDerivedType(tag: DW_TAG_typedef, name: "__clang_svint32x2_t", file: !1, baseType: !17)
!17 = !DICompositeType(tag: DW_TAG_array_type, baseType: !18, flags: DIFlagVector, elements: !19)
!18 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
!19 = !{!20}
!20 = !DISubrange(lowerBound: 0, upperBound: !DIExpression(DW_OP_constu, 4, DW_OP_bregx, 46, 0, DW_OP_mul, DW_OP_constu, 1, DW_OP_minus))
!21 = !DIDerivedType(tag: DW_TAG_typedef, name: "svint32_t", file: !15, line: 34, baseType: !22)
!22 = !DIDerivedType(tag: DW_TAG_typedef, name: "__SVInt32_t", file: !1, baseType: !23)
!23 = !DICompositeType(tag: DW_TAG_array_type, baseType: !18, flags: DIFlagVector, elements: !24)
!24 = !{!25}
!25 = !DISubrange(lowerBound: 0, upperBound: !DIExpression(DW_OP_constu, 2, DW_OP_bregx, 46, 0, DW_OP_mul, DW_OP_constu, 1, DW_OP_minus))
!26 = !{!27, !28, !29}
!27 = !DILocalVariable(name: "z0", arg: 1, scope: !11, file: !1, line: 6, type: !21)
!28 = !DILocalVariable(name: "z1", arg: 2, scope: !11, file: !1, line: 6, type: !21)
!29 = !DILocalVariable(name: "c", arg: 3, scope: !11, file: !1, line: 6, type: !18)
!30 = !DILocation(line: 0, scope: !11)
!31 = !DILocation(line: 7, column: 7, scope: !32)
!32 = distinct !DILexicalBlock(scope: !11, file: !1, line: 7, column: 7)
!33 = !DILocation(line: 7, column: 7, scope: !11)
!34 = !DILocation(line: 8, column: 12, scope: !32)
!35 = !DILocation(line: 8, column: 5, scope: !32)
!36 = !DILocation(line: 9, column: 10, scope: !11)
!37 = !DILocation(line: 9, column: 3, scope: !11)
!38 = !DILocation(line: 10, column: 1, scope: !11)
!39 = !DISubprogram(name: "bar", scope: !1, file: !1, line: 3, type: !40, flags: DIFlagPrototyped, spFlags: DISPFlagOptimized, retainedNodes: !2)
!40 = !DISubroutineType(types: !41)
!41 = !{!17, !23, !23, !23, !23, !23, !23, !23, !23, !23}
...
---
name: foo
alignment: 4
tracksRegLiveness: true
liveins:
- { reg: '$z0' }
- { reg: '$z1' }
- { reg: '$w0' }
frameInfo:
maxAlignment: 16
adjustsStack: true
hasCalls: true
maxCallFrameSize: 0
savePoint: '%bb.1'
restorePoint: '%bb.1'
stack:
- { id: 0, size: 16, alignment: 16, stack-id: scalable-vector }
machineFunctionInfo: {}
body: |
bb.0.entry:
successors: %bb.2(0x30000000), %bb.1(0x50000000)
liveins: $w0, $z0, $z1
DBG_VALUE $z0, $noreg, !27, !DIExpression(), debug-location !30
DBG_VALUE $z1, $noreg, !28, !DIExpression(), debug-location !30
DBG_VALUE $w0, $noreg, !29, !DIExpression(), debug-location !30
renamable $z2 = COPY $z1
renamable $z1 = COPY $z0
DBG_VALUE $w0, $noreg, !29, !DIExpression(), debug-location !30
DBG_VALUE $z2, $noreg, !28, !DIExpression(), debug-location !30
DBG_VALUE $z1, $noreg, !27, !DIExpression(), debug-location !30
CBZW killed renamable $w0, %bb.2, debug-location !33
B %bb.1, debug-location !33
bb.1.if.then:
liveins: $z1
ADJCALLSTACKDOWN 0, 0, implicit-def dead $sp, implicit $sp, debug-location !34
renamable $p0 = PTRUE_S 31, debug-location !34
$x0 = ADDXri %stack.0, 0, 0, debug-location !34
ST1W_IMM renamable $z1, killed renamable $p0, %stack.0, 0, debug-location !34 :: (store unknown-size into %stack.0, align 16)
$z0 = COPY renamable $z1, debug-location !34
$z2 = COPY renamable $z1, debug-location !34
$z3 = COPY renamable $z1, debug-location !34
$z4 = COPY renamable $z1, debug-location !34
$z5 = COPY renamable $z1, debug-location !34
$z6 = COPY renamable $z1, debug-location !34
$z7 = COPY renamable $z1, debug-location !34
BL @bar, csr_aarch64_sve_aapcs, implicit-def dead $lr, implicit $sp, implicit $z0, implicit $z1, implicit $z2, implicit $z3, implicit $z4, implicit $z5, implicit $z6, implicit $z7, implicit $x0, implicit-def $sp, implicit-def $z0, implicit-def $z1, debug-location !34
ADJCALLSTACKUP 0, 0, implicit-def dead $sp, implicit $sp, debug-location !34
renamable $p0 = PTRUE_S 31, debug-location !34
$z3 = IMPLICIT_DEF
renamable $z1 = LD1W_IMM renamable $p0, %stack.0, 0, debug-location !34 :: (load unknown-size from %stack.0, align 16)
ST1W_IMM renamable $z3, killed renamable $p0, %stack.0, 0 :: (store unknown-size into %stack.0, align 16)
renamable $z2 = COPY $z0, debug-location !34
B %bb.3, debug-location !35
bb.2.if.end:
liveins: $z1, $z2
bb.3.return:
liveins: $z1, $z2
$z0 = COPY killed renamable $z2, debug-location !38
RET_ReallyLR implicit $z0, implicit $z1, debug-location !38
...