From 35fb19b7d71d60115c8d7eafa698018f152f7f05 Mon Sep 17 00:00:00 2001 From: Amy Huang Date: Wed, 14 May 2025 23:27:49 +0000 Subject: [PATCH 1/4] 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(StrLenFunc)->setDebugLoc(CurLoop->getStartLoc()); + const SCEV *StrlenEv = SE->getSCEV(StrLenFunc); SmallVector 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 Date: Fri, 16 May 2025 00:09:35 +0000 Subject: [PATCH 2/4] 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(StrLenFunc)->setDebugLoc(CurLoop->getStartLoc()); - const SCEV *StrlenEv = SE->getSCEV(StrLenFunc); SmallVector Cleanup; for (PHINode &PN : LoopExitBB->phis()) { From d2e863e3017ba4b6727753809b7cc9205d6509ac Mon Sep 17 00:00:00 2001 From: Amy Huang Date: Fri, 16 May 2025 21:12:39 +0000 Subject: [PATCH 3/4] 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) From 6a672ac9636a5503ef3d47abb2533905c39bec75 Mon Sep 17 00:00:00 2001 From: Amy Huang Date: Fri, 16 May 2025 21:39:35 +0000 Subject: [PATCH 4/4] Change debug location matching to a variable --- llvm/test/Transforms/LoopIdiom/strlen.ll | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/llvm/test/Transforms/LoopIdiom/strlen.ll b/llvm/test/Transforms/LoopIdiom/strlen.ll index cb50dbb247d12..eaafe6b162f28 100644 --- a/llvm/test/Transforms/LoopIdiom/strlen.ll +++ b/llvm/test/Transforms/LoopIdiom/strlen.ll @@ -617,20 +617,23 @@ 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 !4 +; CHECK-NEXT: [[STRLEN:%.*]] = call i64 @strlen(ptr [[STR]]), !dbg [[DBGLOC1:![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, !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-NEXT: [[TMP0:%.*]] = load i8, ptr [[STR_ADDR_0]], align 1, !dbg [[DBGLOC2:![0-9]+]] +; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp eq i8 [[TMP0]], 0, !dbg [[DBGLOC2]] +; CHECK-NEXT: [[INCDEC_PTR]] = getelementptr i8, ptr [[STR_ADDR_0]], i64 1, !dbg [[DBGLOC2]] +; CHECK-NEXT: br i1 true, label %[[WHILE_END:.*]], label %[[WHILE_COND]], !dbg [[DBGLOC1]] ; CHECK: [[WHILE_END]]: -; 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 +; CHECK-NEXT: [[SUB_PTR_LHS_CAST:%.*]] = ptrtoint ptr [[SCEVGEP]] to i64, !dbg [[DBGLOC2]] +; CHECK-NEXT: [[SUB_PTR_RHS_CAST:%.*]] = ptrtoint ptr [[STR]] to i64, !dbg [[DBGLOC2]] +; CHECK-NEXT: [[SUB_PTR_SUB:%.*]] = sub i64 [[SUB_PTR_LHS_CAST]], [[SUB_PTR_RHS_CAST]], !dbg [[DBGLOC2]] +; CHECK-NEXT: ret i64 [[SUB_PTR_SUB]], !dbg [[DBGLOC2]] +; +; CHECK: [[DBGLOC1]] = !DILocation(line: 3, column: 3 +; CHECK: [[DBGLOC2]] = !DILocation(line: 5, column: 3 ; entry: br label %while.cond