Skip to content

Conversation

@Mel-Chen
Copy link
Contributor

No description provided.

@llvmbot
Copy link
Member

llvmbot commented Dec 16, 2025

@llvm/pr-subscribers-backend-risc-v

@llvm/pr-subscribers-llvm-transforms

Author: Mel Chen (Mel-Chen)

Changes

Full diff: https://github.com/llvm/llvm-project/pull/172429.diff

1 Files Affected:

  • (added) llvm/test/Transforms/LoopVectorize/RISCV/dbg-tail-folding-by-evl.ll (+133)
diff --git a/llvm/test/Transforms/LoopVectorize/RISCV/dbg-tail-folding-by-evl.ll b/llvm/test/Transforms/LoopVectorize/RISCV/dbg-tail-folding-by-evl.ll
new file mode 100644
index 0000000000000..229af48d9086c
--- /dev/null
+++ b/llvm/test/Transforms/LoopVectorize/RISCV/dbg-tail-folding-by-evl.ll
@@ -0,0 +1,133 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
+; RUN: opt -passes=loop-vectorize \
+; RUN: -prefer-predicate-over-epilogue=predicate-else-scalar-epilogue \
+; RUN: -mtriple=riscv64 -mattr=+v -S < %s | FileCheck %s
+
+target datalayout = "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128"
+
+define void @reverse_store(ptr %a, i64 %n) !dbg !4 {
+; CHECK-LABEL: define void @reverse_store(
+; CHECK-SAME: ptr [[A:%.*]], i64 [[N:%.*]]) #[[ATTR0:[0-9]+]] !dbg [[DBG4:![0-9]+]] {
+; CHECK-NEXT:  [[ENTRY:.*:]]
+; CHECK-NEXT:      #dbg_value(ptr [[A]], [[META11:![0-9]+]], !DIExpression(), [[META15:![0-9]+]])
+; CHECK-NEXT:      #dbg_value(i64 [[N]], [[META12:![0-9]+]], !DIExpression(), [[META15]])
+; CHECK-NEXT:      #dbg_value(i64 [[N]], [[META13:![0-9]+]], !DIExpression(DW_OP_constu, 1, DW_OP_minus, DW_OP_stack_value), [[META16:![0-9]+]])
+; CHECK-NEXT:    [[TMP0:%.*]] = add i64 [[N]], 1, !dbg [[DBG17:![0-9]+]]
+; CHECK-NEXT:    [[UMIN:%.*]] = call i64 @llvm.umin.i64(i64 [[N]], i64 1), !dbg [[DBG17]]
+; CHECK-NEXT:    [[TMP1:%.*]] = sub i64 [[TMP0]], [[UMIN]], !dbg [[DBG17]]
+; CHECK-NEXT:    br label %[[VECTOR_PH:.*]], !dbg [[DBG17]]
+; CHECK:       [[VECTOR_PH]]:
+; CHECK-NEXT:    [[TMP2:%.*]] = call <vscale x 4 x i64> @llvm.stepvector.nxv4i64()
+; CHECK-NEXT:    [[BROADCAST_SPLATINSERT:%.*]] = insertelement <vscale x 4 x i64> poison, i64 [[N]], i64 0
+; CHECK-NEXT:    [[BROADCAST_SPLAT:%.*]] = shufflevector <vscale x 4 x i64> [[BROADCAST_SPLATINSERT]], <vscale x 4 x i64> poison, <vscale x 4 x i32> zeroinitializer
+; CHECK-NEXT:    [[TMP3:%.*]] = mul nsw <vscale x 4 x i64> [[TMP2]], splat (i64 -1)
+; CHECK-NEXT:    [[INDUCTION:%.*]] = add nsw <vscale x 4 x i64> [[BROADCAST_SPLAT]], [[TMP3]]
+; CHECK-NEXT:    br label %[[VECTOR_BODY:.*]], !dbg [[DBG17]]
+; CHECK:       [[VECTOR_BODY]]:
+; CHECK-NEXT:    [[VEC_IND:%.*]] = phi <vscale x 4 x i64> [ [[INDUCTION]], %[[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], %[[VECTOR_BODY]] ]
+; CHECK-NEXT:    [[AVL:%.*]] = phi i64 [ [[TMP1]], %[[VECTOR_PH]] ], [ [[AVL_NEXT:%.*]], %[[VECTOR_BODY]] ]
+; CHECK-NEXT:    [[TMP4:%.*]] = call i32 @llvm.experimental.get.vector.length.i64(i64 [[AVL]], i32 4, i1 true)
+; CHECK-NEXT:    [[TMP5:%.*]] = zext i32 [[TMP4]] to i64
+; CHECK-NEXT:    [[TMP6:%.*]] = mul nsw i64 -1, [[TMP5]]
+; CHECK-NEXT:    [[BROADCAST_SPLATINSERT1:%.*]] = insertelement <vscale x 4 x i64> poison, i64 [[TMP6]], i64 0
+; CHECK-NEXT:    [[BROADCAST_SPLAT2:%.*]] = shufflevector <vscale x 4 x i64> [[BROADCAST_SPLATINSERT1]], <vscale x 4 x i64> poison, <vscale x 4 x i32> zeroinitializer
+; CHECK-NEXT:    [[TMP7:%.*]] = add nsw <vscale x 4 x i64> [[VEC_IND]], splat (i64 -1), !dbg [[DBG18:![0-9]+]]
+; CHECK-NEXT:    [[TMP8:%.*]] = extractelement <vscale x 4 x i64> [[TMP7]], i32 0
+; CHECK-NEXT:    [[TMP9:%.*]] = getelementptr inbounds nuw i32, ptr [[A]], i64 [[TMP8]], !dbg [[DBG19:![0-9]+]]
+; CHECK-NEXT:    [[TMP10:%.*]] = trunc nuw nsw <vscale x 4 x i64> [[TMP7]] to <vscale x 4 x i32>, !dbg [[DBG21:![0-9]+]]
+; CHECK-NEXT:    [[TMP11:%.*]] = zext i32 [[TMP4]] to i64, !dbg [[DBG21]]
+; CHECK-NEXT:    [[TMP12:%.*]] = mul i64 0, [[TMP11]], !dbg [[DBG21]]
+; CHECK-NEXT:    [[TMP13:%.*]] = sub i64 [[TMP11]], 1, !dbg [[DBG21]]
+; CHECK-NEXT:    [[TMP14:%.*]] = mul i64 -1, [[TMP13]], !dbg [[DBG21]]
+; CHECK-NEXT:    [[TMP15:%.*]] = getelementptr i32, ptr [[TMP9]], i64 [[TMP12]], !dbg [[DBG21]]
+; CHECK-NEXT:    [[TMP16:%.*]] = getelementptr i32, ptr [[TMP15]], i64 [[TMP14]], !dbg [[DBG21]]
+; CHECK-NEXT:    [[VP_REVERSE:%.*]] = call <vscale x 4 x i32> @llvm.experimental.vp.reverse.nxv4i32(<vscale x 4 x i32> [[TMP10]], <vscale x 4 x i1> splat (i1 true), i32 [[TMP4]]), !dbg [[DBG21]]
+; CHECK-NEXT:    call void @llvm.vp.store.nxv4i32.p0(<vscale x 4 x i32> [[VP_REVERSE]], ptr align 4 [[TMP16]], <vscale x 4 x i1> splat (i1 true), i32 [[TMP4]]), !dbg [[DBG21]]
+; CHECK-NEXT:    [[AVL_NEXT]] = sub nuw i64 [[AVL]], [[TMP5]]
+; CHECK-NEXT:    [[VEC_IND_NEXT]] = add nsw <vscale x 4 x i64> [[VEC_IND]], [[BROADCAST_SPLAT2]]
+; CHECK-NEXT:    [[TMP17:%.*]] = icmp eq i64 [[AVL_NEXT]], 0
+; CHECK-NEXT:    br i1 [[TMP17]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP22:![0-9]+]]
+; CHECK:       [[MIDDLE_BLOCK]]:
+; CHECK-NEXT:    br label %[[FOR_COND_CLEANUP:.*]]
+; CHECK:       [[FOR_COND_CLEANUP]]:
+; CHECK-NEXT:    ret void, !dbg [[DBG25:![0-9]+]]
+;
+entry:
+    #dbg_value(ptr %a, !11, !DIExpression(), !15)
+    #dbg_value(i64 %n, !12, !DIExpression(), !15)
+    #dbg_value(i64 %n, !13, !DIExpression(DW_OP_constu, 1, DW_OP_minus, DW_OP_stack_value), !16)
+  br label %for.body, !dbg !17
+
+for.cond.cleanup:                                 ; preds = %for.body
+  ret void, !dbg !18
+
+for.body:                                         ; preds = %entry, %for.body
+  %indvars.iv = phi i64 [ %n, %entry ], [ %indvars.iv.next, %for.body ]
+    #dbg_value(i64 %indvars.iv, !13, !DIExpression(DW_OP_constu, 1, DW_OP_minus, DW_OP_stack_value), !16)
+  %indvars.iv.next = add nsw i64 %indvars.iv, -1, !dbg !20
+    #dbg_value(i64 %indvars.iv.next, !13, !DIExpression(), !16)
+  %arrayidx = getelementptr inbounds nuw i32, ptr %a, i64 %indvars.iv.next, !dbg !21
+  %1 = trunc nuw nsw i64 %indvars.iv.next to i32, !dbg !22
+  store i32 %1, ptr %arrayidx, align 4, !dbg !22
+    #dbg_value(i64 %indvars.iv.next, !13, !DIExpression(DW_OP_constu, 1, DW_OP_minus, DW_OP_stack_value), !16)
+  %cmp = icmp samesign ugt i64 %indvars.iv, 1, !dbg !23
+  br i1 %cmp, label %for.body, label %for.cond.cleanup, !dbg !24, !llvm.loop !25
+}
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!2, !3}
+
+!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1, producer: "clang", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None)
+!1 = !DIFile(filename: "dbg-tail-folding-by-evl.cpp", directory: "/test/file/path")
+!2 = !{i32 2, !"Debug Info Version", i32 3}
+!3 = !{i32 7, !"debug-info-assignment-tracking", i1 true}
+!4 = distinct !DISubprogram(name: "reverse_store", linkageName: "_Z13reverse_storePil", scope: !1, file: !1, line: 1, type: !5, scopeLine: 1, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !10)
+!5 = !DISubroutineType(types: !6)
+!6 = !{null, !7, !8}
+!7 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !9, size: 64)
+!8 = !DIBasicType(name: "long", size: 64, encoding: DW_ATE_signed)
+!9 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+!10 = !{!11, !12, !13}
+!11 = !DILocalVariable(name: "a", arg: 1, scope: !4, file: !1, line: 1, type: !7)
+!12 = !DILocalVariable(name: "n", arg: 2, scope: !4, file: !1, line: 1, type: !8)
+!13 = !DILocalVariable(name: "i", scope: !14, file: !1, line: 2, type: !9)
+!14 = distinct !DILexicalBlock(scope: !4, file: !1, line: 2, column: 5)
+!15 = !DILocation(line: 0, scope: !4)
+!16 = !DILocation(line: 0, scope: !14)
+!17 = !DILocation(line: 2, column: 5, scope: !14)
+!18 = !DILocation(line: 4, column: 1, scope: !4)
+!19 = distinct !DILexicalBlock(scope: !14, file: !1, line: 2, column: 5)
+!20 = !DILocation(line: 2, scope: !14)
+!21 = !DILocation(line: 3, column: 7, scope: !19)
+!22 = !DILocation(line: 3, column: 12, scope: !19)
+!23 = !DILocation(line: 2, column: 27, scope: !19)
+!24 = !DILocation(line: 2, column: 5, scope: !14)
+!25 = distinct !{!25, !17, !26, !27}
+!26 = !DILocation(line: 3, column: 14, scope: !14)
+!27 = !{!"llvm.loop.vectorize.enable", i1 true}
+;
+; CHECK: [[META0:![0-9]+]] = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: [[META1:![0-9]+]], producer: "clang", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None)
+; CHECK: [[META1]] = !DIFile(filename: "{{.*}}dbg-tail-folding-by-evl.cpp", directory: {{.*}})
+; CHECK: [[DBG4]] = distinct !DISubprogram(name: "reverse_store", linkageName: "_Z13reverse_storePil", scope: [[META1]], file: [[META1]], line: 1, type: [[META5:![0-9]+]], scopeLine: 1, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: [[META0]], retainedNodes: [[META10:![0-9]+]])
+; CHECK: [[META5]] = !DISubroutineType(types: [[META6:![0-9]+]])
+; CHECK: [[META6]] = !{null, [[META7:![0-9]+]], [[META9:![0-9]+]]}
+; CHECK: [[META7]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: [[META8:![0-9]+]], size: 64)
+; CHECK: [[META8]] = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+; CHECK: [[META9]] = !DIBasicType(name: "long", size: 64, encoding: DW_ATE_signed)
+; CHECK: [[META10]] = !{[[META11]], [[META12]], [[META13]]}
+; CHECK: [[META11]] = !DILocalVariable(name: "a", arg: 1, scope: [[DBG4]], file: [[META1]], line: 1, type: [[META7]])
+; CHECK: [[META12]] = !DILocalVariable(name: "n", arg: 2, scope: [[DBG4]], file: [[META1]], line: 1, type: [[META9]])
+; CHECK: [[META13]] = !DILocalVariable(name: "i", scope: [[META14:![0-9]+]], file: [[META1]], line: 2, type: [[META8]])
+; CHECK: [[META14]] = distinct !DILexicalBlock(scope: [[DBG4]], file: [[META1]], line: 2, column: 5)
+; CHECK: [[META15]] = !DILocation(line: 0, scope: [[DBG4]])
+; CHECK: [[META16]] = !DILocation(line: 0, scope: [[META14]])
+; CHECK: [[DBG17]] = !DILocation(line: 2, column: 5, scope: [[META14]])
+; CHECK: [[DBG18]] = !DILocation(line: 2, scope: [[META14]])
+; CHECK: [[DBG19]] = !DILocation(line: 3, column: 7, scope: [[META20:![0-9]+]])
+; CHECK: [[META20]] = distinct !DILexicalBlock(scope: [[META14]], file: [[META1]], line: 2, column: 5)
+; CHECK: [[DBG21]] = !DILocation(line: 3, column: 12, scope: [[META20]])
+; CHECK: [[LOOP22]] = distinct !{[[LOOP22]], [[META23:![0-9]+]], [[META24:![0-9]+]]}
+; CHECK: [[META23]] = !{!"llvm.loop.isvectorized", i32 1}
+; CHECK: [[META24]] = !{!"llvm.loop.unroll.runtime.disable"}
+; CHECK: [[DBG25]] = !DILocation(line: 4, column: 1, scope: [[DBG4]])
+;.

!6 = !{null, !7, !8}
!7 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !9, size: 64)
!8 = !DIBasicType(name: "long", size: 64, encoding: DW_ATE_signed)
!9 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
Copy link
Contributor

Choose a reason for hiding this comment

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

Can this be simplified down to something like

!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang", isOptimized: true, runtimeVersion: 0, emissionKind: NoDebug, enums: !2)
!1 = !DIFile(filename: "/tmp/s.c", directory: "/tmp")
!2 = !{}
!3 = !{i32 2, !"Debug Info Version", i32 3}
!4 = !{i32 7, !"PIC Level", i32 2}
!5 = distinct !DISubprogram(name: "f", scope: !1, file: !1, line: 4, type: !6, scopeLine: 4, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !2)
!6 = !DISubroutineType(types: !2)
!7 = !DILocation(line: 0, column: 0, scope: !5)

And then just using !dbg !7 wherever we want to check the debug loc is preserved?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Cleared most of the metadata, thanks.

@Mel-Chen Mel-Chen force-pushed the nfc-test-for-evl-debug branch from 3fed076 to bdc55b1 Compare December 17, 2025 08:20
Copy link
Contributor

@fhahn fhahn left a comment

Choose a reason for hiding this comment

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

LGTM, thanks for adding the additional coverage!

Comment on lines 69 to 70
!2 = !{i32 2, !"Debug Info Version", i32 3}
!3 = !{i32 7, !"debug-info-assignment-tracking", i1 true}
Copy link
Contributor

Choose a reason for hiding this comment

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

I think you may be able to remove those

Copy link
Contributor Author

Choose a reason for hiding this comment

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

8dee92e
We can only remove debug-info-assignment-tracking. Removing the Debug Info Version causes all debug info to be ignored and dropped, and results in the warning:

warning: ignoring debug info with an invalid version (0) in <stdin>

@Mel-Chen Mel-Chen force-pushed the nfc-test-for-evl-debug branch from bdc55b1 to 8dee92e Compare December 18, 2025 08:33
@Mel-Chen Mel-Chen enabled auto-merge (squash) December 18, 2025 08:42
@Mel-Chen Mel-Chen merged commit e655317 into llvm:main Dec 18, 2025
9 of 10 checks passed
@Mel-Chen Mel-Chen deleted the nfc-test-for-evl-debug branch December 18, 2025 09:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants