Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[RemoveDIs] Update update_test_checks script to recognize dbg_records #87388

Merged
merged 2 commits into from
Apr 17, 2024

Conversation

SLTozer
Copy link
Contributor

@SLTozer SLTozer commented Apr 2, 2024

As we've added new IR elements, as described here and implemented here, we need the update_test_checks script to understand them. For the records themselves this is already done automatically, but their metadata arguments are not recognized as such due to lacking the metadata prefix, which means they won't be checked by the script. The fix I've added was to add a check for all ![0-9]+ patterns as long as they are not at the start of a line (which avoids matching global values).

I'm not well-acquainted with the update_test_checks scripts, so I'm not sure if this pattern is too broad for the update script's purposes; it appears to work without clashing with any existing patterns though.

@SLTozer SLTozer self-assigned this Apr 2, 2024
Copy link
Contributor

@OCHyams OCHyams left a comment

Choose a reason for hiding this comment

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

Seems reasonable to me. I'm also not familiar with update_test_checks though, so lets wait a bit to see if anyone else has any comments.

Comment on lines +67 to +95
br label %for.cond, !dbg !47

for.cond: ; preds = %for.inc, %entry
%0 = load i32, ptr %i, align 4, !dbg !49, !tbaa !24
%1 = load ptr, ptr %A.addr, align 8, !dbg !51, !tbaa !18
%2 = load i32, ptr %1, align 4, !dbg !52, !tbaa !24
%cmp = icmp slt i32 %0, %2, !dbg !53
br i1 %cmp, label %for.body, label %for.cond.cleanup, !dbg !54

for.cond.cleanup: ; preds = %for.cond
call void @llvm.lifetime.end.p0(i64 4, ptr %i) #2, !dbg !55
br label %for.end

for.body: ; preds = %for.cond
%3 = load ptr, ptr %A.addr, align 8, !dbg !56, !tbaa !18
%4 = load i32, ptr %i, align 4, !dbg !57, !tbaa !24
%idxprom = sext i32 %4 to i64, !dbg !56
%arrayidx = getelementptr inbounds i32, ptr %3, i64 %idxprom, !dbg !56
store i32 0, ptr %arrayidx, align 4, !dbg !58, !tbaa !24
br label %for.inc, !dbg !56

for.inc: ; preds = %for.body
%5 = load i32, ptr %i, align 4, !dbg !59, !tbaa !24
%inc = add nsw i32 %5, 1, !dbg !59
store i32 %inc, ptr %i, align 4, !dbg !59, !tbaa !24
br label %for.cond, !dbg !55, !llvm.loop !60

for.end: ; preds = %for.cond.cleanup
ret void, !dbg !62
Copy link
Contributor

Choose a reason for hiding this comment

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

Is all this needed? Can the test be simplified? Same again for the other tests.

Copy link
Contributor Author

@SLTozer SLTozer Apr 4, 2024

Choose a reason for hiding this comment

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

It may not be strictly necessary, but my preference is to have the tests for intrinsics vs records to be identical save for the intrinsics/records themselves - making them different increases dev complexity (not just in reducing the file initially, but in the need to verify the correctness of both files separately if future updates affect these tests), and probably doesn't save us much in return.
Edit: For clarity here in case it's not obvious, all the test files added here are carbon copies of existing tests, with the exception that debug intrinsics are replaced with debug values.

Copy link
Contributor

Choose a reason for hiding this comment

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

Oh I see this test is a DbgRecord mirror of various_ir_values.ll. Instead of duplicating tests is there a reason we can't replicate this test in various_ir_values.ll using flags in opt to force it to print the new format? I am not sure how these tests are set up.

Copy link
Contributor Author

@SLTozer SLTozer Apr 16, 2024

Choose a reason for hiding this comment

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

It would be awkward - this and the other .ll files (with names ending in .expected) are being cp and diffed against, and so rely on being exactly identical. We could only meaningfully remove the various_ir_values_dbgrecords.ll file, not any of the expected files, and I think on principle we should aim to keep the test as just cp, diff, and invoking update_test_checks, rather than adding extra calls to opt outside of the update tool.

Copy link
Collaborator

@nhaehnle nhaehnle left a comment

Choose a reason for hiding this comment

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

I think this is mostly okay, but see the remark inline. It is a bit unfortunate that you'll have META prefixes on the FileCheck variable names instead of DBG prefixes, but I see no easy and robust way to improve on that.

@@ -1079,6 +1079,7 @@ def get_value_use(self, var, match, var_prefix=None):
NamelessValue(r"META", "!", r"", r"![0-9]+", r"(?:distinct |)!.*"),
NamelessValue(r"ACC_GRP", "!", r"!llvm.access.group ", r"![0-9]+", None),
NamelessValue(r"META", "!", r"![a-z.]+ ", r"![0-9]+", None),
NamelessValue(r"META", "!", r".", r"![0-9]+", None),
Copy link
Collaborator

Choose a reason for hiding this comment

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

It would be good to make the prefix expression a little more specific if possible. It can probably be replaced with r" ", right? Or r"[( ]"?

And given that, can you remove the NamelessValue with the "metadata " prefix? It seems that this is now redundant.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Regarding brittleness - it would be syntactically correct to include , in the prefix expression ([(, ]) as well, since it's not a parser error if there is no whitespace betwen arguments(i.e. !1,!2), but the assembly writer will never omit the whitespace; since this should only be running on the output of the assembly writer, would you consider it safe/good practice for this tool to only check what will currently be written, and not what could potentially exist in a file?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Interesting point. The tool really is meant to look at tooling output, not human-written IR, so you can argue both ways. I don't feel very strongly about it -- I think either way is fine.

@llvmbot
Copy link
Collaborator

llvmbot commented Apr 17, 2024

@llvm/pr-subscribers-testing-tools

Author: Stephen Tozer (SLTozer)

Changes

As we've added new IR elements, as described here and implemented here, we need the update_test_checks script to understand them. For the records themselves this is already done automatically, but their metadata arguments are not recognized as such due to lacking the metadata prefix, which means they won't be checked by the script. The fix I've added was to add a check for all ![0-9]+ patterns as long as they are not at the start of a line (which avoids matching global values).

I'm not well-acquainted with the update_test_checks scripts, so I'm not sure if this pattern is too broad for the update script's purposes; it appears to work without clashing with any existing patterns though.


Patch is 94.32 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/87388.diff

8 Files Affected:

  • (added) llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/various_ir_values_dbgrecords.ll (+168)
  • (added) llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/various_ir_values_dbgrecords.ll.expected (+238)
  • (added) llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/various_ir_values_dbgrecords.ll.funcsig.expected (+240)
  • (added) llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/various_ir_values_dbgrecords.ll.funcsig.globals.expected (+309)
  • (added) llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/various_ir_values_dbgrecords.ll.funcsig.noglobals.expected (+238)
  • (added) llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/various_ir_values_dbgrecords.ll.funcsig.transitiveglobals.expected (+299)
  • (added) llvm/test/tools/UpdateTestChecks/update_test_checks/various_ir_values_dbgrecords.test (+24)
  • (modified) llvm/utils/UpdateTestChecks/common.py (+1-1)
diff --git a/llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/various_ir_values_dbgrecords.ll b/llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/various_ir_values_dbgrecords.ll
new file mode 100644
index 00000000000000..9a9cc0a06936f9
--- /dev/null
+++ b/llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/various_ir_values_dbgrecords.ll
@@ -0,0 +1,168 @@
+; Just run it through opt, no passes needed.
+; RUN: opt < %s -S --write-experimental-debuginfo=true | FileCheck %s
+
+; ModuleID = 'various_ir_values.c'
+source_filename = "various_ir_values.c"
+target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+; Function Attrs: nounwind uwtable
+define dso_local void @foo(ptr %A) #0 !dbg !7 {
+entry:
+  %A.addr = alloca ptr, align 8, !DIAssignID !16
+  %i = alloca i32, align 4
+    #dbg_assign(i1 undef, !13, !DIExpression(), !16, ptr %A.addr, !DIExpression(), !17)
+  store ptr %A, ptr %A.addr, align 8, !tbaa !18
+    #dbg_declare(ptr %A.addr, !13, !DIExpression(), !17)
+  call void @llvm.lifetime.start.p0(i64 4, ptr %i) #2, !dbg !22
+    #dbg_declare(ptr %i, !14, !DIExpression(), !23)
+  store i32 0, ptr %i, align 4, !dbg !23, !tbaa !24
+  br label %for.cond, !dbg !22
+
+for.cond:                                         ; preds = %for.inc, %entry
+  %0 = load i32, ptr %i, align 4, !dbg !26, !tbaa !24
+  %1 = load ptr, ptr %A.addr, align 8, !dbg !28, !tbaa !18
+  %2 = load i32, ptr %1, align 4, !dbg !29, !tbaa !24
+  %cmp = icmp slt i32 %0, %2, !dbg !30
+  br i1 %cmp, label %for.body, label %for.cond.cleanup, !dbg !31, !prof !32
+
+for.cond.cleanup:                                 ; preds = %for.cond
+  call void @llvm.lifetime.end.p0(i64 4, ptr %i) #2, !dbg !33
+  br label %for.end
+
+for.body:                                         ; preds = %for.cond
+  %3 = load ptr, ptr %A.addr, align 8, !dbg !34, !tbaa !18
+  %4 = load i32, ptr %i, align 4, !dbg !35, !tbaa !24
+  %idxprom = sext i32 %4 to i64, !dbg !34
+  %arrayidx = getelementptr inbounds i32, ptr %3, i64 %idxprom, !dbg !34
+  store i32 0, ptr %arrayidx, align 4, !dbg !36, !tbaa !24
+  br label %for.inc, !dbg !34
+
+for.inc:                                          ; preds = %for.body
+  %5 = load i32, ptr %i, align 4, !dbg !37, !tbaa !24
+  %inc = add nsw i32 %5, 1, !dbg !37
+  store i32 %inc, ptr %i, align 4, !dbg !37, !tbaa !24
+  br label %for.cond, !dbg !33, !llvm.loop !38
+
+for.end:                                          ; preds = %for.cond.cleanup
+  ret void, !dbg !40
+}
+
+; Function Attrs: nocallback nofree nosync nounwind willreturn memory(argmem: readwrite)
+declare void @llvm.lifetime.start.p0(i64 immarg, ptr nocapture) #1
+
+; Function Attrs: nocallback nofree nosync nounwind willreturn memory(argmem: readwrite)
+declare void @llvm.lifetime.end.p0(i64 immarg, ptr nocapture) #1
+
+; Function Attrs: nounwind uwtable
+define dso_local void @bar(ptr %A) #0 !dbg !41 {
+entry:
+  %A.addr = alloca ptr, align 8
+  %i = alloca i32, align 4
+  store ptr %A, ptr %A.addr, align 8, !tbaa !18
+    #dbg_declare(ptr %A.addr, !43, !DIExpression(), !46)
+  call void @llvm.lifetime.start.p0(i64 4, ptr %i) #2, !dbg !47
+    #dbg_declare(ptr %i, !44, !DIExpression(), !48)
+  store i32 0, ptr %i, align 4, !dbg !48, !tbaa !24
+  br label %for.cond, !dbg !47
+
+for.cond:                                         ; preds = %for.inc, %entry
+  %0 = load i32, ptr %i, align 4, !dbg !49, !tbaa !24
+  %1 = load ptr, ptr %A.addr, align 8, !dbg !51, !tbaa !18
+  %2 = load i32, ptr %1, align 4, !dbg !52, !tbaa !24
+  %cmp = icmp slt i32 %0, %2, !dbg !53
+  br i1 %cmp, label %for.body, label %for.cond.cleanup, !dbg !54
+
+for.cond.cleanup:                                 ; preds = %for.cond
+  call void @llvm.lifetime.end.p0(i64 4, ptr %i) #2, !dbg !55
+  br label %for.end
+
+for.body:                                         ; preds = %for.cond
+  %3 = load ptr, ptr %A.addr, align 8, !dbg !56, !tbaa !18
+  %4 = load i32, ptr %i, align 4, !dbg !57, !tbaa !24
+  %idxprom = sext i32 %4 to i64, !dbg !56
+  %arrayidx = getelementptr inbounds i32, ptr %3, i64 %idxprom, !dbg !56
+  store i32 0, ptr %arrayidx, align 4, !dbg !58, !tbaa !24
+  br label %for.inc, !dbg !56
+
+for.inc:                                          ; preds = %for.body
+  %5 = load i32, ptr %i, align 4, !dbg !59, !tbaa !24
+  %inc = add nsw i32 %5, 1, !dbg !59
+  store i32 %inc, ptr %i, align 4, !dbg !59, !tbaa !24
+  br label %for.cond, !dbg !55, !llvm.loop !60
+
+for.end:                                          ; preds = %for.cond.cleanup
+  ret void, !dbg !62
+}
+
+attributes #0 = { nounwind uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "disable-tail-calls"="false" "frame-pointer"="none" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
+attributes #1 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }
+attributes #2 = { nounwind }
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!3, !4, !5}
+!llvm.ident = !{!6}
+
+!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 11.0.0 (git@github.com:llvm/llvm-project.git 1d5da8cd30fce1c0a2c2fa6ba656dbfaa36192c8)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, splitDebugInlining: false, nameTableKind: None)
+!1 = !DIFile(filename: "various_ir_values.c", directory: "/data/build/llvm-project")
+!2 = !{}
+!3 = !{i32 7, !"Dwarf Version", i32 4}
+!4 = !{i32 2, !"Debug Info Version", i32 3}
+!5 = !{i32 1, !"wchar_size", i32 4}
+!6 = !{!"clang version 11.0.0 (git@github.com:llvm/llvm-project.git 1d5da8cd30fce1c0a2c2fa6ba656dbfaa36192c8)"}
+!7 = distinct !DISubprogram(name: "foo", scope: !1, file: !1, line: 1, type: !8, scopeLine: 1, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !12)
+!8 = !DISubroutineType(types: !9)
+!9 = !{null, !10}
+!10 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !11, size: 64)
+!11 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+!12 = !{!13, !14}
+!13 = !DILocalVariable(name: "A", arg: 1, scope: !7, file: !1, line: 1, type: !10)
+!14 = !DILocalVariable(name: "i", scope: !15, file: !1, line: 3, type: !11)
+!15 = distinct !DILexicalBlock(scope: !7, file: !1, line: 3, column: 3)
+!16 = distinct !DIAssignID()
+!17 = !DILocation(line: 1, column: 15, scope: !7)
+!18 = !{!19, !19, i64 0}
+!19 = !{!"any pointer", !20, i64 0}
+!20 = !{!"omnipotent char", !21, i64 0}
+!21 = !{!"Simple C/C++ TBAA"}
+!22 = !DILocation(line: 3, column: 8, scope: !15)
+!23 = !DILocation(line: 3, column: 12, scope: !15)
+!24 = !{!25, !25, i64 0}
+!25 = !{!"int", !20, i64 0}
+!26 = !DILocation(line: 3, column: 19, scope: !27)
+!27 = distinct !DILexicalBlock(scope: !15, file: !1, line: 3, column: 3)
+!28 = !DILocation(line: 3, column: 24, scope: !27)
+!29 = !DILocation(line: 3, column: 23, scope: !27)
+!30 = !DILocation(line: 3, column: 21, scope: !27)
+!31 = !DILocation(line: 3, column: 3, scope: !15)
+!32 = !{!"branch_weights", i32 1, i32 1048575}
+!33 = !DILocation(line: 3, column: 3, scope: !27)
+!34 = !DILocation(line: 4, column: 5, scope: !27)
+!35 = !DILocation(line: 4, column: 7, scope: !27)
+!36 = !DILocation(line: 4, column: 10, scope: !27)
+!37 = !DILocation(line: 3, column: 27, scope: !27)
+!38 = distinct !{!38, !31, !39}
+!39 = !DILocation(line: 4, column: 12, scope: !15)
+!40 = !DILocation(line: 5, column: 1, scope: !7)
+!41 = distinct !DISubprogram(name: "bar", scope: !1, file: !1, line: 7, type: !8, scopeLine: 7, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !42)
+!42 = !{!43, !44}
+!43 = !DILocalVariable(name: "A", arg: 1, scope: !41, file: !1, line: 7, type: !10)
+!44 = !DILocalVariable(name: "i", scope: !45, file: !1, line: 9, type: !11)
+!45 = distinct !DILexicalBlock(scope: !41, file: !1, line: 9, column: 3)
+!46 = !DILocation(line: 7, column: 15, scope: !41)
+!47 = !DILocation(line: 9, column: 8, scope: !45)
+!48 = !DILocation(line: 9, column: 12, scope: !45)
+!49 = !DILocation(line: 9, column: 19, scope: !50)
+!50 = distinct !DILexicalBlock(scope: !45, file: !1, line: 9, column: 3)
+!51 = !DILocation(line: 9, column: 24, scope: !50)
+!52 = !DILocation(line: 9, column: 23, scope: !50)
+!53 = !DILocation(line: 9, column: 21, scope: !50)
+!54 = !DILocation(line: 9, column: 3, scope: !45)
+!55 = !DILocation(line: 9, column: 3, scope: !50)
+!56 = !DILocation(line: 10, column: 5, scope: !50)
+!57 = !DILocation(line: 10, column: 7, scope: !50)
+!58 = !DILocation(line: 10, column: 10, scope: !50)
+!59 = !DILocation(line: 9, column: 27, scope: !50)
+!60 = distinct !{!60, !54, !61}
+!61 = !DILocation(line: 10, column: 12, scope: !45)
+!62 = !DILocation(line: 11, column: 1, scope: !41)
diff --git a/llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/various_ir_values_dbgrecords.ll.expected b/llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/various_ir_values_dbgrecords.ll.expected
new file mode 100644
index 00000000000000..1f9c37ccfbd889
--- /dev/null
+++ b/llvm/test/tools/UpdateTestChecks/update_test_checks/Inputs/various_ir_values_dbgrecords.ll.expected
@@ -0,0 +1,238 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; Just run it through opt, no passes needed.
+; RUN: opt < %s -S --write-experimental-debuginfo=true | FileCheck %s
+
+; ModuleID = 'various_ir_values.c'
+source_filename = "various_ir_values.c"
+target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+; Function Attrs: nounwind uwtable
+define dso_local void @foo(ptr %A) #0 !dbg !7 {
+; CHECK-LABEL: @foo(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[A_ADDR:%.*]] = alloca ptr, align 8, !DIAssignID [[DIASSIGNID16:![0-9]+]]
+; CHECK-NEXT:    [[I:%.*]] = alloca i32, align 4
+; CHECK-NEXT:      #dbg_assign(i1 undef, [[META13:![0-9]+]], !DIExpression(), [[DIASSIGNID16]], ptr [[A_ADDR]], !DIExpression(), [[META17:![0-9]+]])
+; CHECK-NEXT:    store ptr [[A:%.*]], ptr [[A_ADDR]], align 8, !tbaa [[TBAA18:![0-9]+]]
+; CHECK-NEXT:      #dbg_declare(ptr [[A_ADDR]], [[META13]], !DIExpression(), [[META17]])
+; CHECK-NEXT:    call void @llvm.lifetime.start.p0(i64 4, ptr [[I]]) #[[ATTR2:[0-9]+]], !dbg [[DBG22:![0-9]+]]
+; CHECK-NEXT:      #dbg_declare(ptr [[I]], [[META14:![0-9]+]], !DIExpression(), [[META23:![0-9]+]])
+; CHECK-NEXT:    store i32 0, ptr [[I]], align 4, !dbg [[META23]], !tbaa [[TBAA24:![0-9]+]]
+; CHECK-NEXT:    br label [[FOR_COND:%.*]], !dbg [[DBG22]]
+; CHECK:       for.cond:
+; CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[I]], align 4, !dbg [[DBG26:![0-9]+]], !tbaa [[TBAA24]]
+; CHECK-NEXT:    [[TMP1:%.*]] = load ptr, ptr [[A_ADDR]], align 8, !dbg [[DBG28:![0-9]+]], !tbaa [[TBAA18]]
+; CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[TMP1]], align 4, !dbg [[DBG29:![0-9]+]], !tbaa [[TBAA24]]
+; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[TMP0]], [[TMP2]], !dbg [[DBG30:![0-9]+]]
+; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_COND_CLEANUP:%.*]], !dbg [[DBG31:![0-9]+]], !prof [[PROF32:![0-9]+]]
+; CHECK:       for.cond.cleanup:
+; CHECK-NEXT:    call void @llvm.lifetime.end.p0(i64 4, ptr [[I]]) #[[ATTR2]], !dbg [[DBG33:![0-9]+]]
+; CHECK-NEXT:    br label [[FOR_END:%.*]]
+; CHECK:       for.body:
+; CHECK-NEXT:    [[TMP3:%.*]] = load ptr, ptr [[A_ADDR]], align 8, !dbg [[DBG34:![0-9]+]], !tbaa [[TBAA18]]
+; CHECK-NEXT:    [[TMP4:%.*]] = load i32, ptr [[I]], align 4, !dbg [[DBG35:![0-9]+]], !tbaa [[TBAA24]]
+; CHECK-NEXT:    [[IDXPROM:%.*]] = sext i32 [[TMP4]] to i64, !dbg [[DBG34]]
+; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[TMP3]], i64 [[IDXPROM]], !dbg [[DBG34]]
+; CHECK-NEXT:    store i32 0, ptr [[ARRAYIDX]], align 4, !dbg [[DBG36:![0-9]+]], !tbaa [[TBAA24]]
+; CHECK-NEXT:    br label [[FOR_INC:%.*]], !dbg [[DBG34]]
+; CHECK:       for.inc:
+; CHECK-NEXT:    [[TMP5:%.*]] = load i32, ptr [[I]], align 4, !dbg [[DBG37:![0-9]+]], !tbaa [[TBAA24]]
+; CHECK-NEXT:    [[INC:%.*]] = add nsw i32 [[TMP5]], 1, !dbg [[DBG37]]
+; CHECK-NEXT:    store i32 [[INC]], ptr [[I]], align 4, !dbg [[DBG37]], !tbaa [[TBAA24]]
+; CHECK-NEXT:    br label [[FOR_COND]], !dbg [[DBG33]], !llvm.loop [[LOOP38:![0-9]+]]
+; CHECK:       for.end:
+; CHECK-NEXT:    ret void, !dbg [[DBG40:![0-9]+]]
+;
+entry:
+  %A.addr = alloca ptr, align 8, !DIAssignID !16
+  %i = alloca i32, align 4
+  #dbg_assign(i1 undef, !13, !DIExpression(), !16, ptr %A.addr, !DIExpression(), !17)
+  store ptr %A, ptr %A.addr, align 8, !tbaa !18
+  #dbg_declare(ptr %A.addr, !13, !DIExpression(), !17)
+  call void @llvm.lifetime.start.p0(i64 4, ptr %i) #2, !dbg !22
+  #dbg_declare(ptr %i, !14, !DIExpression(), !23)
+  store i32 0, ptr %i, align 4, !dbg !23, !tbaa !24
+  br label %for.cond, !dbg !22
+
+for.cond:                                         ; preds = %for.inc, %entry
+  %0 = load i32, ptr %i, align 4, !dbg !26, !tbaa !24
+  %1 = load ptr, ptr %A.addr, align 8, !dbg !28, !tbaa !18
+  %2 = load i32, ptr %1, align 4, !dbg !29, !tbaa !24
+  %cmp = icmp slt i32 %0, %2, !dbg !30
+  br i1 %cmp, label %for.body, label %for.cond.cleanup, !dbg !31, !prof !32
+
+for.cond.cleanup:                                 ; preds = %for.cond
+  call void @llvm.lifetime.end.p0(i64 4, ptr %i) #2, !dbg !33
+  br label %for.end
+
+for.body:                                         ; preds = %for.cond
+  %3 = load ptr, ptr %A.addr, align 8, !dbg !34, !tbaa !18
+  %4 = load i32, ptr %i, align 4, !dbg !35, !tbaa !24
+  %idxprom = sext i32 %4 to i64, !dbg !34
+  %arrayidx = getelementptr inbounds i32, ptr %3, i64 %idxprom, !dbg !34
+  store i32 0, ptr %arrayidx, align 4, !dbg !36, !tbaa !24
+  br label %for.inc, !dbg !34
+
+for.inc:                                          ; preds = %for.body
+  %5 = load i32, ptr %i, align 4, !dbg !37, !tbaa !24
+  %inc = add nsw i32 %5, 1, !dbg !37
+  store i32 %inc, ptr %i, align 4, !dbg !37, !tbaa !24
+  br label %for.cond, !dbg !33, !llvm.loop !38
+
+for.end:                                          ; preds = %for.cond.cleanup
+  ret void, !dbg !40
+}
+
+; Function Attrs: nocallback nofree nosync nounwind willreturn memory(argmem: readwrite)
+declare void @llvm.lifetime.start.p0(i64 immarg, ptr nocapture) #1
+
+; Function Attrs: nocallback nofree nosync nounwind willreturn memory(argmem: readwrite)
+declare void @llvm.lifetime.end.p0(i64 immarg, ptr nocapture) #1
+
+; Function Attrs: nounwind uwtable
+define dso_local void @bar(ptr %A) #0 !dbg !41 {
+; CHECK-LABEL: @bar(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[A_ADDR:%.*]] = alloca ptr, align 8
+; CHECK-NEXT:    [[I:%.*]] = alloca i32, align 4
+; CHECK-NEXT:    store ptr [[A:%.*]], ptr [[A_ADDR]], align 8, !tbaa [[TBAA18]]
+; CHECK-NEXT:      #dbg_declare(ptr [[A_ADDR]], [[META43:![0-9]+]], !DIExpression(), [[META46:![0-9]+]])
+; CHECK-NEXT:    call void @llvm.lifetime.start.p0(i64 4, ptr [[I]]) #[[ATTR2]], !dbg [[DBG47:![0-9]+]]
+; CHECK-NEXT:      #dbg_declare(ptr [[I]], [[META44:![0-9]+]], !DIExpression(), [[META48:![0-9]+]])
+; CHECK-NEXT:    store i32 0, ptr [[I]], align 4, !dbg [[META48]], !tbaa [[TBAA24]]
+; CHECK-NEXT:    br label [[FOR_COND:%.*]], !dbg [[DBG47]]
+; CHECK:       for.cond:
+; CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[I]], align 4, !dbg [[DBG49:![0-9]+]], !tbaa [[TBAA24]]
+; CHECK-NEXT:    [[TMP1:%.*]] = load ptr, ptr [[A_ADDR]], align 8, !dbg [[DBG51:![0-9]+]], !tbaa [[TBAA18]]
+; CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[TMP1]], align 4, !dbg [[DBG52:![0-9]+]], !tbaa [[TBAA24]]
+; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[TMP0]], [[TMP2]], !dbg [[DBG53:![0-9]+]]
+; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_COND_CLEANUP:%.*]], !dbg [[DBG54:![0-9]+]]
+; CHECK:       for.cond.cleanup:
+; CHECK-NEXT:    call void @llvm.lifetime.end.p0(i64 4, ptr [[I]]) #[[ATTR2]], !dbg [[DBG55:![0-9]+]]
+; CHECK-NEXT:    br label [[FOR_END:%.*]]
+; CHECK:       for.body:
+; CHECK-NEXT:    [[TMP3:%.*]] = load ptr, ptr [[A_ADDR]], align 8, !dbg [[DBG56:![0-9]+]], !tbaa [[TBAA18]]
+; CHECK-NEXT:    [[TMP4:%.*]] = load i32, ptr [[I]], align 4, !dbg [[DBG57:![0-9]+]], !tbaa [[TBAA24]]
+; CHECK-NEXT:    [[IDXPROM:%.*]] = sext i32 [[TMP4]] to i64, !dbg [[DBG56]]
+; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[TMP3]], i64 [[IDXPROM]], !dbg [[DBG56]]
+; CHECK-NEXT:    store i32 0, ptr [[ARRAYIDX]], align 4, !dbg [[DBG58:![0-9]+]], !tbaa [[TBAA24]]
+; CHECK-NEXT:    br label [[FOR_INC:%.*]], !dbg [[DBG56]]
+; CHECK:       for.inc:
+; CHECK-NEXT:    [[TMP5:%.*]] = load i32, ptr [[I]], align 4, !dbg [[DBG59:![0-9]+]], !tbaa [[TBAA24]]
+; CHECK-NEXT:    [[INC:%.*]] = add nsw i32 [[TMP5]], 1, !dbg [[DBG59]]
+; CHECK-NEXT:    store i32 [[INC]], ptr [[I]], align 4, !dbg [[DBG59]], !tbaa [[TBAA24]]
+; CHECK-NEXT:    br label [[FOR_COND]], !dbg [[DBG55]], !llvm.loop [[LOOP60:![0-9]+]]
+; CHECK:       for.end:
+; CHECK-NEXT:    ret void, !dbg [[DBG62:![0-9]+]]
+;
+entry:
+  %A.addr = alloca ptr, align 8
+  %i = alloca i32, align 4
+  store ptr %A, ptr %A.addr, align 8, !tbaa !18
+  #dbg_declare(ptr %A.addr, !43, !DIExpression(), !46)
+  call void @llvm.lifetime.start.p0(i64 4, ptr %i) #2, !dbg !47
+  #dbg_declare(ptr %i, !44, !DIExpression(), !48)
+  store i32 0, ptr %i, align 4, !dbg !48, !tbaa !24
+  br label %for.cond, !dbg !47
+
+for.cond:                                         ; preds = %for.inc, %entry
+  %0 = load i32, ptr %i, align 4, !dbg !49, !tbaa !24
+  %1 = load ptr, ptr %A.addr, align 8, !dbg !51, !tbaa !18
+  %2 = load i32, ptr %1, align 4, !dbg !52, !tbaa !24
+  %cmp = icmp slt i32 %0, %2, !dbg !53
+  br i1 %cmp, label %for.body, label %for.cond.cleanup, !dbg !54
+
+for.cond.cleanup:                                 ; preds = %for.cond
+  call void @llvm.lifetime.end.p0(i64 4, ptr %i) #2, !dbg !55
+  br label %for.end
+
+for.body:                                         ; preds = %for.cond
+  %3 = load ptr, ptr %A.addr, align 8, !dbg !56, !tbaa !18
+  %4 = load i32, ptr %i, align 4, !dbg !57, !tbaa !24
+  %idxprom = sext i32 %4 to i64, !dbg !56
+  %arrayidx = getelementptr inbounds i32, ptr %3, i64 %idxprom, !dbg !56
+  store i32 0, ptr %arrayidx, align 4, !dbg !58, !tbaa !24
+  br label %for.inc, !dbg !56
+
+for.inc:                                          ; preds = %for.body
+  %5 = load i32, ptr %i, align 4, !dbg !59, !tbaa !24
+  %inc = add nsw i32 %5, 1, !dbg !59
+  store i32 %inc, ptr %i, align 4, !dbg !59, !tbaa !24
+  br label %for.cond, !dbg !55, !llvm.loop !60
+
+for.end:                                          ; preds = %for.cond.cleanup
+  ret void, !dbg !62
+}
+
+attributes #0 = { nounwind uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "denormal-fp-math"="ieee,ieee" "denormal-fp-math-f32"="ieee,ieee" "disable-tail-calls"="false" "frame-pointer"="none" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
+attributes #1 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }
+attributes #2 = { nounwind }
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!3, !4, !5}
+!llvm.ident = !{!6}
+
+!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 11.0.0 (git@github.com:llvm/llvm-project.git 1d5da8cd30fce1c0a2c2fa6ba656dbfaa36192c8)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, splitDebugInlining: false, nameTableKind: None)
+!1 = !DIFile(filename: "various_ir_values.c", directory: "/data/build/llvm-project")
+!2 = !{}
+!3 = !{i32 7, !"Dwarf Version", i32 4}
+!4 = !{i32 2, !"Debug Info Version", i32 3}
+!5 = !{i32 1, !"wchar_size", i32 4}
+!6 = !{!"clang version 11.0.0 (git@github.com:llvm/llvm-project.git 1d5da8cd...
[truncated]

@SLTozer SLTozer merged commit a634f3e into llvm:main Apr 17, 2024
4 of 5 checks passed
@hnrklssn
Copy link
Member

LGTM!

@nhaehnle Would #88979 make it possible to dynamically select between emitting META or DBG based on whether the metadata definition has a = !DI suffix? E.g. !13 = !DILocalVariable -> DBG13 instead of META13.

@nhaehnle
Copy link
Collaborator

Not directly, although it would arguably be a stepping stone in that direction.

The major difficulty is that we emit check lines gradually before processing everything. So we emit check lines while processing a function, which commits us to using e.g. META13. We can't change our minds about it later when we see the global definition at the end of the file.

@SLTozer
Copy link
Contributor Author

SLTozer commented Apr 22, 2024

Perhaps a more sensible way for this specific case would be a more advanced pattern match for this line - all of the metadata in the line #dbg_record(i32 %x, !11, !12, !13) is guaranteed to be some kind of debug info metadata, but not being particularly well-versed in the pattern matching logic in update_test_checks I couldn't see a good way to match "![0-9]+ on lines that start with #dbg_record"; using a prefix of #dbg_record.+ or anything along those lines resulted in bad checks being generated, but if we can match that case correctly then we could use DBG here.

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.

None yet

5 participants