llvm-project/llvm/test/CodeGen/RISCV/di-assignment-tracking-vector.ll
Stephen Tozer 928c33354e
[DebugInfo] Handle additional types of stores in assignment tracking (#129070)
Fixes #126417.

Currently, assignment tracking recognizes allocas, stores, and mem
intrinsics as valid instructions to tag with DIAssignID, with allocas
representing the allocation for a variable and the others representing
instructions that may assign to the variable. There are other intrinsics
that can perform these assignments however, and if we transform a store
instruction into one of these intrinsics and correctly transfer the
DIAssignID over, this results in a verifier error. The
AssignmentTrackingAnalysis pass also does not know how to handle these
intrinsics if they are untagged, as it does not know how to extract
assignment information (base address, offset, size) from them.

This patch adds _some_ support for some intrinsics that may perform
assignments: masked store/scatter, and vp store/strided store/scatter.
This patch does not add support for extracting assignment information
from these, as they may store with either non-constant size or to
non-contiguous blocks of memory; instead it adds support for recognizing
untagged stores with "unknown" assignment info, for which we assume that
the memory location of the associated variable should not be used, as we
can't determine which fragments of it should or should not be used.

In principle, it should be possible to handle the more complex cases
mentioned above, but it would require more substantial changes to
AssignmentTrackingAnalysis, and it is mostly only needed as a fallback
if the DIAssignID is not preserved on these alternative stores.
2025-04-22 17:14:25 +01:00

66 lines
3.0 KiB
LLVM

; RUN: llc -mtriple=riscv64 < %s | FileCheck %s --implicit-check-not=DEBUG_VALUE
;; Verify that tagged and untagged non-contiguous stores are handled correctly
;; by assignment tracking.
;; * The store to "i" is untagged, and results in the memory location being
;; dropped in favour of the debug value 1010 after the store.
;; * The store to "j" is tagged with a corresponding dbg_assign, which allows
;; us to keep using the memory location.
; CHECK-LABEL: foo:
; CHECK-NEXT: .Lfunc_begin0:
; CHECK: # %bb.0
; CHECK: addi a1, sp, 48
; CHECK-NEXT: #DEBUG_VALUE: foo:i <- [DW_OP_deref] $x12
; CHECK-NEXT: #DEBUG_VALUE: foo:j <- [DW_OP_deref] $x12
; CHECK: vsse32.v
; CHECK-NEXT: #DEBUG_VALUE: foo:i <- 1010
; CHECK-NEXT: vsse32.v
target datalayout = "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128"
target triple = "riscv64-unknown-linux-gnu"
define void @foo() #0 !dbg !5 {
entry:
%i = alloca i64, align 8, !DIAssignID !6
%j = alloca i64, align 8, !DIAssignID !12
%sar_height.i = getelementptr i8, ptr %i, i64 24
store ptr %sar_height.i, ptr null, align 8
%vui.i = getelementptr i8, ptr %i, i64 44
%0 = load i32, ptr %vui.i, align 4
%sar_width.i = getelementptr i8, ptr %i, i64 20
%i_sar_width.i = getelementptr i8, ptr %i, i64 48
%j_sar_width.j = getelementptr i8, ptr %j, i64 48
#dbg_assign(i32 1010, !7, !DIExpression(), !6, ptr %i_sar_width.i, !DIExpression(), !9)
#dbg_assign(i32 2121, !17, !DIExpression(), !12, ptr %i_sar_width.i, !DIExpression(), !9)
%1 = load <2 x i32>, ptr %sar_width.i, align 4
call void @llvm.experimental.vp.strided.store.v2i32.p0.i64(<2 x i32> %1, ptr align 4 %i_sar_width.i, i64 -4, <2 x i1> splat (i1 true), i32 2)
call void @llvm.experimental.vp.strided.store.v2i32.p0.i64(<2 x i32> %1, ptr align 4 %j_sar_width.j, i64 -4, <2 x i1> splat (i1 true), i32 2), !DIAssignID !13
#dbg_assign(i32 1010, !7, !DIExpression(), !14, ptr %i_sar_width.i, !DIExpression(), !9)
#dbg_assign(i32 2121, !17, !DIExpression(), !13, ptr %i_sar_width.i, !DIExpression(), !9)
ret void
}
attributes #0 = { "target-features"="+v" }
!llvm.dbg.cu = !{!0}
!llvm.module.flags = !{!3, !4}
!0 = distinct !DICompileUnit(language: DW_LANG_C11, file: !1, isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, producer: "clang version 21.0.0git")
!1 = !DIFile(filename: "test.c", directory: "/")
!2 = !{}
!3 = !{i32 2, !"Debug Info Version", i32 3}
!4 = !{i32 7, !"debug-info-assignment-tracking", i1 true}
!5 = distinct !DISubprogram(name: "foo", linkageName: "foo", scope: !1, file: !1, line: 1, scopeLine: 1, type: !10, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !11)
!6 = distinct !DIAssignID()
!7 = !DILocalVariable(name: "i", scope: !5, file: !1, line: 7, type: !8)
!8 = !DIBasicType(name: "int32_t", size: 32, encoding: DW_ATE_signed)
!9 = !DILocation(line: 5, scope: !5)
!10 = !DISubroutineType(types: !2)
!11 = !{!7, !17}
!12 = distinct !DIAssignID()
!13 = distinct !DIAssignID()
!14 = distinct !DIAssignID()
!17 = !DILocalVariable(name: "j", scope: !5, file: !1, line: 7, type: !8)