
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.
66 lines
3.0 KiB
LLVM
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)
|