[llvm] Add debug location to strlen in LoopIdiomRecognize pass (PR #140164)
Amy Huang via llvm-commits
llvm-commits at lists.llvm.org
Fri May 16 14:15:44 PDT 2025
https://github.com/amykhuang updated https://github.com/llvm/llvm-project/pull/140164
>From 35fb19b7d71d60115c8d7eafa698018f152f7f05 Mon Sep 17 00:00:00 2001
From: Amy Huang <akhuang at google.com>
Date: Wed, 14 May 2025 23:27:49 +0000
Subject: [PATCH 1/3] Add debug location to strlen in LoopIdiomRecognize pass
---
.../Transforms/Scalar/LoopIdiomRecognize.cpp | 3 ++
llvm/test/Transforms/LoopIdiom/strlen.ll | 48 +++++++++++++++++++
2 files changed, 51 insertions(+)
diff --git a/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp b/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp
index 8f5d1ecba982d..2b94686ae7ba5 100644
--- a/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp
+++ b/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp
@@ -1778,6 +1778,9 @@ bool LoopIdiomRecognize::recognizeAndInsertStrLen() {
}
assert(StrLenFunc && "Failed to emit strlen function.");
+ // Set debug location to the start of the loop.
+ cast<Instruction>(StrLenFunc)->setDebugLoc(CurLoop->getStartLoc());
+
const SCEV *StrlenEv = SE->getSCEV(StrLenFunc);
SmallVector<PHINode *, 4> Cleanup;
for (PHINode &PN : LoopExitBB->phis()) {
diff --git a/llvm/test/Transforms/LoopIdiom/strlen.ll b/llvm/test/Transforms/LoopIdiom/strlen.ll
index 3b9d33ebdc74e..3d53b10be3e9b 100644
--- a/llvm/test/Transforms/LoopIdiom/strlen.ll
+++ b/llvm/test/Transforms/LoopIdiom/strlen.ll
@@ -612,3 +612,51 @@ while.end:
ret i64 %sub.ptr.sub
}
+define i64 @valid_basic_strlen_with_dbg(ptr %str) {
+; CHECK-LABEL: define i64 @valid_basic_strlen_with_dbg(
+; CHECK-SAME: ptr [[STR:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*]]:
+; CHECK-NEXT: [[STRLEN:%.*]] = call i64 @strlen(ptr [[STR]]), !dbg !{{[0-9]+}}
+; CHECK-NEXT: [[SCEVGEP:%.*]] = getelementptr i8, ptr [[STR]], i64 [[STRLEN]]
+; CHECK-NEXT: br label %[[WHILE_COND:.*]]
+; CHECK: [[WHILE_COND]]:
+; CHECK-NEXT: [[STR_ADDR_0:%.*]] = phi ptr [ [[STR]], %[[ENTRY]] ], [ [[INCDEC_PTR:%.*]], %[[WHILE_COND]] ]
+; CHECK-NEXT: [[TMP0:%.*]] = load i8, ptr [[STR_ADDR_0]], align 1
+; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp eq i8 [[TMP0]], 0
+; CHECK-NEXT: [[INCDEC_PTR]] = getelementptr i8, ptr [[STR_ADDR_0]], i64 1
+; CHECK-NEXT: br i1 true, label %[[WHILE_END:.*]], label %[[WHILE_COND]]
+; CHECK: [[WHILE_END]]:
+; CHECK-NEXT: [[SUB_PTR_LHS_CAST:%.*]] = ptrtoint ptr [[SCEVGEP]] to i64
+; CHECK-NEXT: [[SUB_PTR_RHS_CAST:%.*]] = ptrtoint ptr [[STR]] to i64
+; CHECK-NEXT: [[SUB_PTR_SUB:%.*]] = sub i64 [[SUB_PTR_LHS_CAST]], [[SUB_PTR_RHS_CAST]]
+; CHECK-NEXT: ret i64 [[SUB_PTR_SUB]]
+;
+entry:
+ br label %while.cond
+
+while.cond:
+ %str.addr.0 = phi ptr [ %str, %entry ], [ %incdec.ptr, %while.cond ]
+ %0 = load i8, ptr %str.addr.0, align 1, !dbg !6
+ %cmp.not = icmp eq i8 %0, 0, !dbg !6
+ %incdec.ptr = getelementptr i8, ptr %str.addr.0, i64 1
+ br i1 %cmp.not, label %while.end, label %while.cond, !dbg !6
+
+while.end:
+ %sub.ptr.lhs.cast = ptrtoint ptr %str.addr.0 to i64
+ %sub.ptr.rhs.cast = ptrtoint ptr %str to i64
+ %sub.ptr.sub = sub i64 %sub.ptr.lhs.cast, %sub.ptr.rhs.cast
+ ret i64 %sub.ptr.sub
+}
+
+
+!llvm.module.flags = !{!7}
+!llvm.dbg.cu = !{!2}
+
+!0 = distinct !DISubprogram(name: "foo", line: 2, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: false, unit: !2, file: !1, scope: !1, type: !3)
+!1 = !DIFile(filename: "strlen.c", directory: "/tmp")
+!2 = distinct !DICompileUnit(language: DW_LANG_C99, producer: "clang version 2.9 (trunk 127165:127174)", isOptimized: true, emissionKind: FullDebug, file: !1, enums: !4, retainedTypes: !4)
+!3 = !DISubroutineType(types: !4)
+!4 = !{}
+!5 = distinct !DILexicalBlock(line: 2, column: 21, file: !1, scope: !0)
+!6 = !DILocation(line: 3, column: 3, scope: !5)
+!7 = !{i32 1, !"Debug Info Version", i32 3}
>From 276b5525892b960f4a762d48a5e429cbc89afd93 Mon Sep 17 00:00:00 2001
From: Amy Huang <akhuang at google.com>
Date: Fri, 16 May 2025 00:09:35 +0000
Subject: [PATCH 2/3] Set debug loc on the IRBuilder instead of instruction
---
llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp b/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp
index 2b94686ae7ba5..b5519dfa8b5c0 100644
--- a/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp
+++ b/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp
@@ -1764,6 +1764,7 @@ bool LoopIdiomRecognize::recognizeAndInsertStrLen() {
}
IRBuilder<> Builder(Preheader->getTerminator());
+ Builder.SetCurrentDebugLocation(CurLoop->getStartLoc());
SCEVExpander Expander(*SE, Preheader->getModule()->getDataLayout(),
"strlen_idiom");
Value *MaterialzedBase = Expander.expandCodeFor(
@@ -1778,9 +1779,6 @@ bool LoopIdiomRecognize::recognizeAndInsertStrLen() {
}
assert(StrLenFunc && "Failed to emit strlen function.");
- // Set debug location to the start of the loop.
- cast<Instruction>(StrLenFunc)->setDebugLoc(CurLoop->getStartLoc());
-
const SCEV *StrlenEv = SE->getSCEV(StrLenFunc);
SmallVector<PHINode *, 4> Cleanup;
for (PHINode &PN : LoopExitBB->phis()) {
>From d2e863e3017ba4b6727753809b7cc9205d6509ac Mon Sep 17 00:00:00 2001
From: Amy Huang <akhuang at google.com>
Date: Fri, 16 May 2025 21:12:39 +0000
Subject: [PATCH 3/3] Edit test case debug info
---
llvm/test/Transforms/LoopIdiom/strlen.ll | 59 ++++++++++++------------
1 file changed, 30 insertions(+), 29 deletions(-)
diff --git a/llvm/test/Transforms/LoopIdiom/strlen.ll b/llvm/test/Transforms/LoopIdiom/strlen.ll
index 3d53b10be3e9b..cb50dbb247d12 100644
--- a/llvm/test/Transforms/LoopIdiom/strlen.ll
+++ b/llvm/test/Transforms/LoopIdiom/strlen.ll
@@ -613,50 +613,51 @@ while.end:
}
define i64 @valid_basic_strlen_with_dbg(ptr %str) {
+; Make sure that the call to strlen has debug info attached.
; CHECK-LABEL: define i64 @valid_basic_strlen_with_dbg(
; CHECK-SAME: ptr [[STR:%.*]]) {
; CHECK-NEXT: [[ENTRY:.*]]:
-; CHECK-NEXT: [[STRLEN:%.*]] = call i64 @strlen(ptr [[STR]]), !dbg !{{[0-9]+}}
+; CHECK-NEXT: [[STRLEN:%.*]] = call i64 @strlen(ptr [[STR]]), !dbg !4
; CHECK-NEXT: [[SCEVGEP:%.*]] = getelementptr i8, ptr [[STR]], i64 [[STRLEN]]
; CHECK-NEXT: br label %[[WHILE_COND:.*]]
; CHECK: [[WHILE_COND]]:
; CHECK-NEXT: [[STR_ADDR_0:%.*]] = phi ptr [ [[STR]], %[[ENTRY]] ], [ [[INCDEC_PTR:%.*]], %[[WHILE_COND]] ]
-; CHECK-NEXT: [[TMP0:%.*]] = load i8, ptr [[STR_ADDR_0]], align 1
-; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp eq i8 [[TMP0]], 0
-; CHECK-NEXT: [[INCDEC_PTR]] = getelementptr i8, ptr [[STR_ADDR_0]], i64 1
-; CHECK-NEXT: br i1 true, label %[[WHILE_END:.*]], label %[[WHILE_COND]]
+; CHECK-NEXT: [[TMP0:%.*]] = load i8, ptr [[STR_ADDR_0]], align 1, !dbg !8
+; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp eq i8 [[TMP0]], 0, !dbg !8
+; CHECK-NEXT: [[INCDEC_PTR]] = getelementptr i8, ptr [[STR_ADDR_0]], i64 1, !dbg !8
+; CHECK-NEXT: br i1 true, label %[[WHILE_END:.*]], label %[[WHILE_COND]], !dbg !4
; CHECK: [[WHILE_END]]:
-; CHECK-NEXT: [[SUB_PTR_LHS_CAST:%.*]] = ptrtoint ptr [[SCEVGEP]] to i64
-; CHECK-NEXT: [[SUB_PTR_RHS_CAST:%.*]] = ptrtoint ptr [[STR]] to i64
-; CHECK-NEXT: [[SUB_PTR_SUB:%.*]] = sub i64 [[SUB_PTR_LHS_CAST]], [[SUB_PTR_RHS_CAST]]
-; CHECK-NEXT: ret i64 [[SUB_PTR_SUB]]
+; CHECK-NEXT: [[SUB_PTR_LHS_CAST:%.*]] = ptrtoint ptr [[SCEVGEP]] to i64, !dbg !8
+; CHECK-NEXT: [[SUB_PTR_RHS_CAST:%.*]] = ptrtoint ptr [[STR]] to i64, !dbg !8
+; CHECK-NEXT: [[SUB_PTR_SUB:%.*]] = sub i64 [[SUB_PTR_LHS_CAST]], [[SUB_PTR_RHS_CAST]], !dbg !8
+; CHECK-NEXT: ret i64 [[SUB_PTR_SUB]], !dbg !8
;
entry:
br label %while.cond
while.cond:
%str.addr.0 = phi ptr [ %str, %entry ], [ %incdec.ptr, %while.cond ]
- %0 = load i8, ptr %str.addr.0, align 1, !dbg !6
- %cmp.not = icmp eq i8 %0, 0, !dbg !6
- %incdec.ptr = getelementptr i8, ptr %str.addr.0, i64 1
- br i1 %cmp.not, label %while.end, label %while.cond, !dbg !6
+ %0 = load i8, ptr %str.addr.0, align 1, !dbg !8
+ %cmp.not = icmp eq i8 %0, 0, !dbg !8
+ %incdec.ptr = getelementptr i8, ptr %str.addr.0, i64 1, !dbg !8
+ br i1 %cmp.not, label %while.end, label %while.cond, !dbg !4
while.end:
- %sub.ptr.lhs.cast = ptrtoint ptr %str.addr.0 to i64
- %sub.ptr.rhs.cast = ptrtoint ptr %str to i64
- %sub.ptr.sub = sub i64 %sub.ptr.lhs.cast, %sub.ptr.rhs.cast
- ret i64 %sub.ptr.sub
+ %sub.ptr.lhs.cast = ptrtoint ptr %str.addr.0 to i64, !dbg !8
+ %sub.ptr.rhs.cast = ptrtoint ptr %str to i64, !dbg !8
+ %sub.ptr.sub = sub i64 %sub.ptr.lhs.cast, %sub.ptr.rhs.cast, !dbg !8
+ ret i64 %sub.ptr.sub, !dbg !8
}
-
-!llvm.module.flags = !{!7}
-!llvm.dbg.cu = !{!2}
-
-!0 = distinct !DISubprogram(name: "foo", line: 2, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: false, unit: !2, file: !1, scope: !1, type: !3)
-!1 = !DIFile(filename: "strlen.c", directory: "/tmp")
-!2 = distinct !DICompileUnit(language: DW_LANG_C99, producer: "clang version 2.9 (trunk 127165:127174)", isOptimized: true, emissionKind: FullDebug, file: !1, enums: !4, retainedTypes: !4)
-!3 = !DISubroutineType(types: !4)
-!4 = !{}
-!5 = distinct !DILexicalBlock(line: 2, column: 21, file: !1, scope: !0)
-!6 = !DILocation(line: 3, column: 3, scope: !5)
-!7 = !{i32 1, !"Debug Info Version", i32 3}
+!llvm.module.flags = !{!0}
+!llvm.dbg.cu = !{!1}
+
+!0 = !{i32 1, !"Debug Info Version", i32 3}
+!1 = distinct !DICompileUnit(language: DW_LANG_C99, file: !2, producer: "clang version 2.9 (trunk 127165:127174)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !3, retainedTypes: !3)
+!2 = !DIFile(filename: "strlen.c", directory: "/tmp")
+!3 = !{}
+!4 = !DILocation(line: 3, column: 3, scope: !5)
+!5 = distinct !DILexicalBlock(scope: !6, file: !2, line: 2, column: 21)
+!6 = distinct !DISubprogram(name: "foo", scope: !2, file: !2, line: 2, type: !7, virtualIndex: 6, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !1)
+!7 = !DISubroutineType(types: !3)
+!8 = !DILocation(line: 5, column: 3, scope: !5)
More information about the llvm-commits
mailing list