[llvm] [MIR] Replace bespoke DIExpression parser (PR #96827)

Scott Linder via llvm-commits llvm-commits at lists.llvm.org
Wed Jul 3 11:50:21 PDT 2024


https://github.com/slinder1 updated https://github.com/llvm/llvm-project/pull/96827

>From c6cae2d66ef9cc999939659186cda8d2c82c13bb Mon Sep 17 00:00:00 2001
From: Scott Linder <Scott.Linder at amd.com>
Date: Wed, 26 Jun 2024 21:11:00 +0000
Subject: [PATCH 1/7] [NFC] Add DIExpression MIParser tests

Prepare for patch to replace MIParser implementation of DIExpression
parser with the LLParser version.
---
 .../CodeGen/MIR/Generic/diexpression-err.mir  | 152 ++++++++++++++++
 .../test/CodeGen/MIR/Generic/diexpression.mir | 167 ++++++++++++++++++
 2 files changed, 319 insertions(+)
 create mode 100644 llvm/test/CodeGen/MIR/Generic/diexpression-err.mir
 create mode 100644 llvm/test/CodeGen/MIR/Generic/diexpression.mir

diff --git a/llvm/test/CodeGen/MIR/Generic/diexpression-err.mir b/llvm/test/CodeGen/MIR/Generic/diexpression-err.mir
new file mode 100644
index 0000000000000..394c0d5d48eaa
--- /dev/null
+++ b/llvm/test/CodeGen/MIR/Generic/diexpression-err.mir
@@ -0,0 +1,152 @@
+# RUN: not llc -run-pass none -o - %s 2>&1 | FileCheck %s
+# Note: generated via:
+# printf 'extern long long sink; int func(int arg) { int purelocal = arg * 42; int pinnedlocal = arg * 43; sink = (long long)&pinnedlocal; return purelocal; }' | clang -cc1 -O1 -triple x86_64-unknown-linux-gnu -debug-info-kind=limited -S -mllvm -stop-after=x86-isel - -o -
+--- |
+  source_filename = "-"
+  target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
+  target triple = "x86_64-unknown-linux-gnu"
+
+  @sink = external local_unnamed_addr global i64, align 8
+
+  define dso_local i32 @func(i32 noundef %arg) local_unnamed_addr #0 !dbg !8 {
+  entry:
+    %pinnedlocal = alloca i32, align 4, !DIAssignID !16
+      #dbg_assign(i1 undef, !15, !DIExpression(), !16, ptr %pinnedlocal, !DIExpression(), !17)
+      #dbg_value(i32 %arg, !13, !DIExpression(), !17)
+    %mul = mul nsw i32 %arg, 42, !dbg !18
+      #dbg_value(i32 %mul, !14, !DIExpression(), !17)
+    call void @llvm.lifetime.start.p0(i64 4, ptr nonnull %pinnedlocal) #2, !dbg !19
+    %mul1 = mul nsw i32 %arg, 43, !dbg !20
+    store i32 %mul1, ptr %pinnedlocal, align 4, !dbg !21, !tbaa !22, !DIAssignID !26
+      #dbg_assign(i32 %mul1, !15, !DIExpression(), !26, ptr %pinnedlocal, !DIExpression(), !17)
+    %0 = ptrtoint ptr %pinnedlocal to i64, !dbg !27
+    store i64 %0, ptr @sink, align 8, !dbg !28, !tbaa !29
+    call void @llvm.lifetime.end.p0(i64 4, ptr nonnull %pinnedlocal) #2, !dbg !31
+    ret i32 %mul, !dbg !32
+  }
+
+  declare void @llvm.lifetime.start.p0(i64 immarg, ptr nocapture) #1
+
+  declare void @llvm.lifetime.end.p0(i64 immarg, ptr nocapture) #1
+
+  attributes #0 = { mustprogress nofree norecurse nosync nounwind willreturn memory(write, argmem: none, inaccessiblemem: none) "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+cx8,+mmx,+sse,+sse2,+x87" }
+  attributes #1 = { mustprogress nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }
+  attributes #2 = { nounwind }
+
+  !llvm.dbg.cu = !{!0}
+  !llvm.module.flags = !{!4, !5, !6}
+  !llvm.ident = !{!7}
+
+  !0 = distinct !DICompileUnit(language: DW_LANG_C11, file: !1, producer: "clang version 19.0.0git (git at github.com:slinder1/llvm-project.git a32b7199f0c15ea1c6c9490b6166c019c9d4bd2b)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, retainedTypes: !2, splitDebugInlining: false, nameTableKind: None)
+  !1 = !DIFile(filename: "<stdin>", directory: "/home/slinder1/llvm-project/main")
+  !2 = !{!3}
+  !3 = !DIBasicType(name: "long long", size: 64, encoding: DW_ATE_signed)
+  !4 = !{i32 2, !"Debug Info Version", i32 3}
+  !5 = !{i32 1, !"wchar_size", i32 4}
+  !6 = !{i32 7, !"debug-info-assignment-tracking", i1 true}
+  !7 = !{!"clang version 19.0.0git (git at github.com:slinder1/llvm-project.git a32b7199f0c15ea1c6c9490b6166c019c9d4bd2b)"}
+  !8 = distinct !DISubprogram(name: "func", scope: !1, file: !1, line: 1, type: !9, scopeLine: 1, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !12)
+  !9 = !DISubroutineType(types: !10)
+  !10 = !{!11, !11}
+  !11 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+  !12 = !{!13, !14, !15}
+  !13 = !DILocalVariable(name: "arg", arg: 1, scope: !8, file: !1, line: 1, type: !11)
+  !14 = !DILocalVariable(name: "purelocal", scope: !8, file: !1, line: 1, type: !11)
+  !15 = !DILocalVariable(name: "pinnedlocal", scope: !8, file: !1, line: 1, type: !11)
+  !16 = distinct !DIAssignID()
+  !17 = !DILocation(line: 0, scope: !8)
+  !18 = !DILocation(line: 1, column: 64, scope: !8)
+  !19 = !DILocation(line: 1, column: 70, scope: !8)
+  !20 = !DILocation(line: 1, column: 92, scope: !8)
+  !21 = !DILocation(line: 1, column: 74, scope: !8)
+  !22 = !{!23, !23, i64 0}
+  !23 = !{!"int", !24, i64 0}
+  !24 = !{!"omnipotent char", !25, i64 0}
+  !25 = !{!"Simple C/C++ TBAA"}
+  !26 = distinct !DIAssignID()
+  !27 = !DILocation(line: 1, column: 105, scope: !8)
+  !28 = !DILocation(line: 1, column: 103, scope: !8)
+  !29 = !{!30, !30, i64 0}
+  !30 = !{!"long long", !24, i64 0}
+  !31 = !DILocation(line: 1, column: 148, scope: !8)
+  !32 = !DILocation(line: 1, column: 130, scope: !8)
+
+...
+---
+name:            func
+alignment:       16
+exposesReturnsTwice: false
+legalized:       false
+regBankSelected: false
+selected:        false
+failedISel:      false
+tracksRegLiveness: true
+hasWinCFI:       false
+callsEHReturn:   false
+callsUnwindInit: false
+hasEHCatchret:   false
+hasEHScopes:     false
+hasEHFunclets:   false
+isOutlined:      false
+debugInstrRef:   true
+failsVerification: false
+tracksDebugUserValues: false
+registers:
+  - { id: 0, class: gr32, preferred-register: '' }
+  - { id: 1, class: gr32, preferred-register: '' }
+  - { id: 2, class: gr64, preferred-register: '' }
+  - { id: 3, class: gr64, preferred-register: '' }
+liveins:
+  - { reg: '$edi', virtual-reg: '%0' }
+frameInfo:
+  isFrameAddressTaken: false
+  isReturnAddressTaken: false
+  hasStackMap:     false
+  hasPatchPoint:   false
+  stackSize:       0
+  offsetAdjustment: 0
+  maxAlignment:    4
+  adjustsStack:    false
+  hasCalls:        false
+  stackProtector:  ''
+  functionContext: ''
+  maxCallFrameSize: 4294967295
+  cvBytesOfCalleeSavedRegisters: 0
+  hasOpaqueSPAdjustment: false
+  hasVAStart:      false
+  hasMustTailInVarArgFunc: false
+  hasTailCall:     false
+  isCalleeSavedInfoValid: false
+  localFrameSize:  0
+  savePoint:       ''
+  restorePoint:    ''
+fixedStack:      []
+stack:
+  - { id: 0, name: pinnedlocal, type: default, offset: 0, size: 4, alignment: 4,
+      stack-id: default, callee-saved-register: '', callee-saved-restored: true,
+      debug-info-variable: '!15', debug-info-expression: '!DIExpression()',
+      debug-info-location: '!17' }
+entry_values:    []
+callSites:       []
+debugValueSubstitutions: []
+constants:       []
+machineFunctionInfo:
+  amxProgModel:    None
+body:             |
+  bb.0.entry:
+    liveins: $edi
+
+    DBG_VALUE $edi, $noreg, !13, !DIExpression(), debug-location !17
+    %0:gr32 = COPY $edi
+    %1:gr32 = nsw IMUL32rri %0, 42, implicit-def dead $eflags, debug-instr-number 1, debug-location !18
+    ; CHECK: {{.*}}.mir:[[#@LINE+1]]:38: invalid DWARF op 'W_OP_LLVM_arg'
+    DBG_INSTR_REF !14, !DIExpression(W_OP_LLVM_arg, 0), dbg-instr-ref(1, 0), debug-location !17
+    LIFETIME_START %stack.0.pinnedlocal, debug-location !19
+    %2:gr64 = MOV64rm $rip, 1, $noreg, target-flags(x86-gotpcrel) @sink, $noreg, debug-location !28 :: (load (s64) from got)
+    %3:gr64 = LEA64r %stack.0.pinnedlocal, 1, $noreg, 0, $noreg
+    MOV64mr killed %2, 1, $noreg, 0, $noreg, killed %3, debug-location !28 :: (store (s64) into @sink, !tbaa !29)
+    LIFETIME_END %stack.0.pinnedlocal, debug-location !31
+    $eax = COPY %1, debug-location !32
+    RET 0, $eax, debug-location !32
+
+...
diff --git a/llvm/test/CodeGen/MIR/Generic/diexpression.mir b/llvm/test/CodeGen/MIR/Generic/diexpression.mir
new file mode 100644
index 0000000000000..085c16fd7d6d6
--- /dev/null
+++ b/llvm/test/CodeGen/MIR/Generic/diexpression.mir
@@ -0,0 +1,167 @@
+# NOTE: Hand-modified after being autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 5
+# RUN: llc -run-pass none -o - %s 2>&1 | FileCheck %s
+# Note: generated via:
+# printf 'extern long long sink; int func(int arg) { int purelocal = arg * 42; int pinnedlocal = arg * 43; sink = (long long)&pinnedlocal; return purelocal; }' | clang -cc1 -O1 -triple x86_64-unknown-linux-gnu -debug-info-kind=limited -S -mllvm -stop-after=x86-isel - -o -
+--- |
+  source_filename = "-"
+  target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
+  target triple = "x86_64-unknown-linux-gnu"
+
+  @sink = external local_unnamed_addr global i64, align 8
+
+  define dso_local i32 @func(i32 noundef %arg) local_unnamed_addr #0 !dbg !8 {
+  entry:
+    %pinnedlocal = alloca i32, align 4, !DIAssignID !16
+      #dbg_assign(i1 undef, !15, !DIExpression(), !16, ptr %pinnedlocal, !DIExpression(), !17)
+      #dbg_value(i32 %arg, !13, !DIExpression(), !17)
+    %mul = mul nsw i32 %arg, 42, !dbg !18
+      #dbg_value(i32 %mul, !14, !DIExpression(), !17)
+    call void @llvm.lifetime.start.p0(i64 4, ptr nonnull %pinnedlocal) #2, !dbg !19
+    %mul1 = mul nsw i32 %arg, 43, !dbg !20
+    store i32 %mul1, ptr %pinnedlocal, align 4, !dbg !21, !tbaa !22, !DIAssignID !26
+      #dbg_assign(i32 %mul1, !15, !DIExpression(), !26, ptr %pinnedlocal, !DIExpression(), !17)
+    %0 = ptrtoint ptr %pinnedlocal to i64, !dbg !27
+    store i64 %0, ptr @sink, align 8, !dbg !28, !tbaa !29
+    call void @llvm.lifetime.end.p0(i64 4, ptr nonnull %pinnedlocal) #2, !dbg !31
+    ret i32 %mul, !dbg !32
+  }
+
+  declare void @llvm.lifetime.start.p0(i64 immarg, ptr nocapture) #1
+
+  declare void @llvm.lifetime.end.p0(i64 immarg, ptr nocapture) #1
+
+  attributes #0 = { mustprogress nofree norecurse nosync nounwind willreturn memory(write, argmem: none, inaccessiblemem: none) "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+cx8,+mmx,+sse,+sse2,+x87" }
+  attributes #1 = { mustprogress nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }
+  attributes #2 = { nounwind }
+
+  !llvm.dbg.cu = !{!0}
+  !llvm.module.flags = !{!4, !5, !6}
+  !llvm.ident = !{!7}
+
+  !0 = distinct !DICompileUnit(language: DW_LANG_C11, file: !1, producer: "clang version 19.0.0git (git at github.com:slinder1/llvm-project.git a32b7199f0c15ea1c6c9490b6166c019c9d4bd2b)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, retainedTypes: !2, splitDebugInlining: false, nameTableKind: None)
+  !1 = !DIFile(filename: "<stdin>", directory: "/home/slinder1/llvm-project/main")
+  !2 = !{!3}
+  !3 = !DIBasicType(name: "long long", size: 64, encoding: DW_ATE_signed)
+  !4 = !{i32 2, !"Debug Info Version", i32 3}
+  !5 = !{i32 1, !"wchar_size", i32 4}
+  !6 = !{i32 7, !"debug-info-assignment-tracking", i1 true}
+  !7 = !{!"clang version 19.0.0git (git at github.com:slinder1/llvm-project.git a32b7199f0c15ea1c6c9490b6166c019c9d4bd2b)"}
+  !8 = distinct !DISubprogram(name: "func", scope: !1, file: !1, line: 1, type: !9, scopeLine: 1, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !12)
+  !9 = !DISubroutineType(types: !10)
+  !10 = !{!11, !11}
+  !11 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+  !12 = !{!13, !14, !15}
+  !13 = !DILocalVariable(name: "arg", arg: 1, scope: !8, file: !1, line: 1, type: !11)
+  !14 = !DILocalVariable(name: "purelocal", scope: !8, file: !1, line: 1, type: !11)
+  !15 = !DILocalVariable(name: "pinnedlocal", scope: !8, file: !1, line: 1, type: !11)
+  !16 = distinct !DIAssignID()
+  !17 = !DILocation(line: 0, scope: !8)
+  !18 = !DILocation(line: 1, column: 64, scope: !8)
+  !19 = !DILocation(line: 1, column: 70, scope: !8)
+  !20 = !DILocation(line: 1, column: 92, scope: !8)
+  !21 = !DILocation(line: 1, column: 74, scope: !8)
+  !22 = !{!23, !23, i64 0}
+  !23 = !{!"int", !24, i64 0}
+  !24 = !{!"omnipotent char", !25, i64 0}
+  !25 = !{!"Simple C/C++ TBAA"}
+  !26 = distinct !DIAssignID()
+  !27 = !DILocation(line: 1, column: 105, scope: !8)
+  !28 = !DILocation(line: 1, column: 103, scope: !8)
+  !29 = !{!30, !30, i64 0}
+  !30 = !{!"long long", !24, i64 0}
+  !31 = !DILocation(line: 1, column: 148, scope: !8)
+  !32 = !DILocation(line: 1, column: 130, scope: !8)
+
+...
+---
+name:            func
+alignment:       16
+exposesReturnsTwice: false
+legalized:       false
+regBankSelected: false
+selected:        false
+failedISel:      false
+tracksRegLiveness: true
+hasWinCFI:       false
+callsEHReturn:   false
+callsUnwindInit: false
+hasEHCatchret:   false
+hasEHScopes:     false
+hasEHFunclets:   false
+isOutlined:      false
+debugInstrRef:   true
+failsVerification: false
+tracksDebugUserValues: false
+registers:
+  - { id: 0, class: gr32, preferred-register: '' }
+  - { id: 1, class: gr32, preferred-register: '' }
+  - { id: 2, class: gr64, preferred-register: '' }
+  - { id: 3, class: gr64, preferred-register: '' }
+liveins:
+  - { reg: '$edi', virtual-reg: '%0' }
+frameInfo:
+  isFrameAddressTaken: false
+  isReturnAddressTaken: false
+  hasStackMap:     false
+  hasPatchPoint:   false
+  stackSize:       0
+  offsetAdjustment: 0
+  maxAlignment:    4
+  adjustsStack:    false
+  hasCalls:        false
+  stackProtector:  ''
+  functionContext: ''
+  maxCallFrameSize: 4294967295
+  cvBytesOfCalleeSavedRegisters: 0
+  hasOpaqueSPAdjustment: false
+  hasVAStart:      false
+  hasMustTailInVarArgFunc: false
+  hasTailCall:     false
+  isCalleeSavedInfoValid: false
+  localFrameSize:  0
+  savePoint:       ''
+  restorePoint:    ''
+fixedStack:      []
+stack:
+  - { id: 0, name: pinnedlocal, type: default, offset: 0, size: 4, alignment: 4,
+      stack-id: default, callee-saved-register: '', callee-saved-restored: true,
+      debug-info-variable: '!15', debug-info-expression: '!DIExpression()',
+      debug-info-location: '!17' }
+entry_values:    []
+callSites:       []
+debugValueSubstitutions: []
+constants:       []
+machineFunctionInfo:
+  amxProgModel:    None
+body:             |
+  bb.0.entry:
+    liveins: $edi
+
+    ; CHECK-LABEL: name: func
+    ; CHECK: debug-info-expression: '!DIExpression()',
+    ; CHECK: liveins: $edi
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: DBG_VALUE $edi, $noreg, !13, !DIExpression(), debug-location !17
+    ; CHECK-NEXT: [[COPY:%[0-9]+]]:gr32 = COPY $edi
+    ; CHECK-NEXT: [[IMUL32rri:%[0-9]+]]:gr32 = nsw IMUL32rri [[COPY]], 42, implicit-def dead $eflags, debug-instr-number 1, debug-location !18
+    ; CHECK-NEXT: DBG_INSTR_REF !14, !DIExpression(DW_OP_LLVM_arg, 0), dbg-instr-ref(1, 0), debug-location !17
+    ; CHECK-NEXT: LIFETIME_START %stack.0.pinnedlocal, debug-location !19
+    ; CHECK-NEXT: [[MOV64rm:%[0-9]+]]:gr64 = MOV64rm $rip, 1, $noreg, target-flags(x86-gotpcrel) @sink, $noreg, debug-location !28 :: (load (s64) from got)
+    ; CHECK-NEXT: [[LEA64r:%[0-9]+]]:gr64 = LEA64r %stack.0.pinnedlocal, 1, $noreg, 0, $noreg
+    ; CHECK-NEXT: MOV64mr killed [[MOV64rm]], 1, $noreg, 0, $noreg, killed [[LEA64r]], debug-location !28 :: (store (s64) into @sink, !tbaa !29)
+    ; CHECK-NEXT: LIFETIME_END %stack.0.pinnedlocal, debug-location !31
+    ; CHECK-NEXT: $eax = COPY [[IMUL32rri]], debug-location !32
+    ; CHECK-NEXT: RET 0, $eax, debug-location !32
+    DBG_VALUE $edi, $noreg, !13, !DIExpression(), debug-location !17
+    %0:gr32 = COPY $edi
+    %1:gr32 = nsw IMUL32rri %0, 42, implicit-def dead $eflags, debug-instr-number 1, debug-location !18
+    DBG_INSTR_REF !14, !DIExpression(DW_OP_LLVM_arg, 0), dbg-instr-ref(1, 0), debug-location !17
+    LIFETIME_START %stack.0.pinnedlocal, debug-location !19
+    %2:gr64 = MOV64rm $rip, 1, $noreg, target-flags(x86-gotpcrel) @sink, $noreg, debug-location !28 :: (load (s64) from got)
+    %3:gr64 = LEA64r %stack.0.pinnedlocal, 1, $noreg, 0, $noreg
+    MOV64mr killed %2, 1, $noreg, 0, $noreg, killed %3, debug-location !28 :: (store (s64) into @sink, !tbaa !29)
+    LIFETIME_END %stack.0.pinnedlocal, debug-location !31
+    $eax = COPY %1, debug-location !32
+    RET 0, $eax, debug-location !32
+
+...

>From e56ae029391783d2c505d0953b067394918fe787 Mon Sep 17 00:00:00 2001
From: Scott Linder <Scott.Linder at amd.com>
Date: Tue, 25 Jun 2024 17:40:33 +0000
Subject: [PATCH 2/7] [MIR] Replace bespoke DIExpression parser

Resolve FIXME by using the LLParser implementation of parseDIExpression
from the MIParser.
---
 llvm/include/llvm/AsmParser/LLParser.h        |  3 ++
 llvm/include/llvm/AsmParser/Parser.h          |  5 ++
 llvm/lib/AsmParser/LLParser.cpp               | 19 ++++++-
 llvm/lib/AsmParser/Parser.cpp                 | 17 +++++++
 llvm/lib/CodeGen/MIRParser/MIParser.cpp       | 50 +++----------------
 .../CodeGen/MIR/Generic/diexpression-err.mir  |  2 +-
 llvm/unittests/AsmParser/AsmParserTest.cpp    | 46 +++++++++++++++++
 7 files changed, 97 insertions(+), 45 deletions(-)

diff --git a/llvm/include/llvm/AsmParser/LLParser.h b/llvm/include/llvm/AsmParser/LLParser.h
index 2b08fcc7f16a0..1e93fc0f8cc7d 100644
--- a/llvm/include/llvm/AsmParser/LLParser.h
+++ b/llvm/include/llvm/AsmParser/LLParser.h
@@ -201,6 +201,9 @@ namespace llvm {
     bool parseTypeAtBeginning(Type *&Ty, unsigned &Read,
                               const SlotMapping *Slots);
 
+    bool parseDIExpressionAtBeginning(MDNode *&Result, unsigned &Read,
+                                      const SlotMapping *Slots);
+
     LLVMContext &getContext() { return Context; }
 
   private:
diff --git a/llvm/include/llvm/AsmParser/Parser.h b/llvm/include/llvm/AsmParser/Parser.h
index b3adfd7fd76cf..01193a0240b83 100644
--- a/llvm/include/llvm/AsmParser/Parser.h
+++ b/llvm/include/llvm/AsmParser/Parser.h
@@ -21,6 +21,7 @@
 namespace llvm {
 
 class Constant;
+class DIExpression;
 class LLVMContext;
 class MemoryBufferRef;
 class Module;
@@ -202,6 +203,10 @@ Type *parseType(StringRef Asm, SMDiagnostic &Err, const Module &M,
 Type *parseTypeAtBeginning(StringRef Asm, unsigned &Read, SMDiagnostic &Err,
                            const Module &M, const SlotMapping *Slots = nullptr);
 
+DIExpression *parseDIExpressionAtBeginning(StringRef Asm, unsigned &Read,
+                                           SMDiagnostic &Err, const Module &M,
+                                           const SlotMapping *Slots);
+
 } // End llvm namespace
 
 #endif
diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp
index 21d386097fc63..7486afc05a3c0 100644
--- a/llvm/lib/AsmParser/LLParser.cpp
+++ b/llvm/lib/AsmParser/LLParser.cpp
@@ -124,6 +124,21 @@ bool LLParser::parseTypeAtBeginning(Type *&Ty, unsigned &Read,
   return false;
 }
 
+bool LLParser::parseDIExpressionAtBeginning(MDNode *&Result, unsigned &Read,
+                                            const SlotMapping *Slots) {
+  restoreParsingState(Slots);
+  Lex.Lex();
+
+  Read = 0;
+  SMLoc Start = Lex.getLoc();
+  Result = nullptr;
+  bool Status = parseDIExpression(Result, /*IsDistinct=*/false);
+  SMLoc End = Lex.getLoc();
+  Read = End.getPointer() - Start.getPointer();
+
+  return Status;
+}
+
 void LLParser::restoreParsingState(const SlotMapping *Slots) {
   if (!Slots)
     return;
@@ -5827,8 +5842,8 @@ bool LLParser::parseDILabel(MDNode *&Result, bool IsDistinct) {
 /// parseDIExpression:
 ///   ::= !DIExpression(0, 7, -1)
 bool LLParser::parseDIExpression(MDNode *&Result, bool IsDistinct) {
-  assert(Lex.getKind() == lltok::MetadataVar && "Expected metadata type name");
-  Lex.Lex();
+  if (Lex.getKind() == lltok::MetadataVar)
+    Lex.Lex();
 
   if (parseToken(lltok::lparen, "expected '(' here"))
     return true;
diff --git a/llvm/lib/AsmParser/Parser.cpp b/llvm/lib/AsmParser/Parser.cpp
index eded892f358a8..17bdec3a090e7 100644
--- a/llvm/lib/AsmParser/Parser.cpp
+++ b/llvm/lib/AsmParser/Parser.cpp
@@ -12,6 +12,7 @@
 
 #include "llvm/AsmParser/Parser.h"
 #include "llvm/AsmParser/LLParser.h"
+#include "llvm/IR/DebugInfoMetadata.h"
 #include "llvm/IR/Module.h"
 #include "llvm/IR/ModuleSummaryIndex.h"
 #include "llvm/Support/MemoryBuffer.h"
@@ -224,3 +225,19 @@ Type *llvm::parseTypeAtBeginning(StringRef Asm, unsigned &Read,
     return nullptr;
   return Ty;
 }
+
+DIExpression *llvm::parseDIExpressionAtBeginning(StringRef Asm, unsigned &Read,
+                                                 SMDiagnostic &Err,
+                                                 const Module &M,
+                                                 const SlotMapping *Slots) {
+  SourceMgr SM;
+  std::unique_ptr<MemoryBuffer> Buf = MemoryBuffer::getMemBuffer(Asm);
+  SM.AddNewSourceBuffer(std::move(Buf), SMLoc());
+  MDNode *MD;
+  if (LLParser(Asm, SM, Err, const_cast<Module *>(&M), nullptr, M.getContext())
+          .parseDIExpressionAtBeginning(MD, Read, Slots))
+    return nullptr;
+  if (auto *Expr = dyn_cast<DIExpression>(MD))
+    return Expr;
+  return nullptr;
+}
diff --git a/llvm/lib/CodeGen/MIRParser/MIParser.cpp b/llvm/lib/CodeGen/MIRParser/MIParser.cpp
index 1a12eefc8675b..188d6c9bbcf15 100644
--- a/llvm/lib/CodeGen/MIRParser/MIParser.cpp
+++ b/llvm/lib/CodeGen/MIRParser/MIParser.cpp
@@ -2302,48 +2302,14 @@ bool MIParser::parseMDNode(MDNode *&Node) {
 }
 
 bool MIParser::parseDIExpression(MDNode *&Expr) {
-  assert(Token.is(MIToken::md_diexpr));
-  lex();
-
-  // FIXME: Share this parsing with the IL parser.
-  SmallVector<uint64_t, 8> Elements;
-
-  if (expectAndConsume(MIToken::lparen))
-    return true;
-
-  if (Token.isNot(MIToken::rparen)) {
-    do {
-      if (Token.is(MIToken::Identifier)) {
-        if (unsigned Op = dwarf::getOperationEncoding(Token.stringValue())) {
-          lex();
-          Elements.push_back(Op);
-          continue;
-        }
-        if (unsigned Enc = dwarf::getAttributeEncoding(Token.stringValue())) {
-          lex();
-          Elements.push_back(Enc);
-          continue;
-        }
-        return error(Twine("invalid DWARF op '") + Token.stringValue() + "'");
-      }
-
-      if (Token.isNot(MIToken::IntegerLiteral) ||
-          Token.integerValue().isSigned())
-        return error("expected unsigned integer");
-
-      auto &U = Token.integerValue();
-      if (U.ugt(UINT64_MAX))
-        return error("element too large, limit is " + Twine(UINT64_MAX));
-      Elements.push_back(U.getZExtValue());
-      lex();
-
-    } while (consumeIfPresent(MIToken::comma));
-  }
-
-  if (expectAndConsume(MIToken::rparen))
-    return true;
-
-  Expr = DIExpression::get(MF.getFunction().getContext(), Elements);
+  unsigned Read;
+  Expr = llvm::parseDIExpressionAtBeginning(CurrentSource, Read, Error,
+                                            *PFS.MF.getFunction().getParent(),
+                                            &PFS.IRSlots);
+  CurrentSource = CurrentSource.slice(Read, StringRef::npos);
+  lex();
+  if (!Expr)
+    return error(Error.getMessage());
   return false;
 }
 
diff --git a/llvm/test/CodeGen/MIR/Generic/diexpression-err.mir b/llvm/test/CodeGen/MIR/Generic/diexpression-err.mir
index 394c0d5d48eaa..f5c81411ede90 100644
--- a/llvm/test/CodeGen/MIR/Generic/diexpression-err.mir
+++ b/llvm/test/CodeGen/MIR/Generic/diexpression-err.mir
@@ -139,7 +139,7 @@ body:             |
     DBG_VALUE $edi, $noreg, !13, !DIExpression(), debug-location !17
     %0:gr32 = COPY $edi
     %1:gr32 = nsw IMUL32rri %0, 42, implicit-def dead $eflags, debug-instr-number 1, debug-location !18
-    ; CHECK: {{.*}}.mir:[[#@LINE+1]]:38: invalid DWARF op 'W_OP_LLVM_arg'
+    ; CHECK: {{.*}}.mir:[[#@LINE+1]]:38: expected unsigned integer
     DBG_INSTR_REF !14, !DIExpression(W_OP_LLVM_arg, 0), dbg-instr-ref(1, 0), debug-location !17
     LIFETIME_START %stack.0.pinnedlocal, debug-location !19
     %2:gr64 = MOV64rm $rip, 1, $noreg, target-flags(x86-gotpcrel) @sink, $noreg, debug-location !28 :: (load (s64) from got)
diff --git a/llvm/unittests/AsmParser/AsmParserTest.cpp b/llvm/unittests/AsmParser/AsmParserTest.cpp
index f296848ed665f..3749714fd4677 100644
--- a/llvm/unittests/AsmParser/AsmParserTest.cpp
+++ b/llvm/unittests/AsmParser/AsmParserTest.cpp
@@ -11,6 +11,7 @@
 #include "llvm/AsmParser/SlotMapping.h"
 #include "llvm/IR/Constants.h"
 #include "llvm/IR/DataLayout.h"
+#include "llvm/IR/DebugInfoMetadata.h"
 #include "llvm/IR/LLVMContext.h"
 #include "llvm/IR/Module.h"
 #include "llvm/Support/Error.h"
@@ -411,4 +412,49 @@ TEST(AsmParserTest, InvalidDataLayoutStringCallback) {
   EXPECT_EQ(Mod2->getDataLayout(), FixedDL);
 }
 
+TEST(AsmParserTest, DIExpressionAtBeginningWithSlotMappingParsing) {
+  LLVMContext Ctx;
+  SMDiagnostic Error;
+  StringRef Source =
+      "%st = type { i32, i32 }\n"
+      "@v = common global [50 x %st] zeroinitializer, align 16\n"
+      "%0 = type { i32, i32, i32, i32 }\n"
+      "@g = common global [50 x %0] zeroinitializer, align 16\n"
+      "define void @marker4(i64 %d) {\n"
+      "entry:\n"
+      "  %conv = trunc i64 %d to i32\n"
+      "  store i32 %conv, ptr getelementptr inbounds "
+      "    ([50 x %st], ptr @v, i64 0, i64 0, i32 0), align 16\n"
+      "  store i32 %conv, ptr getelementptr inbounds "
+      "    ([50 x %0], ptr @g, i64 0, i64 0, i32 0), align 16\n"
+      "  ret void\n"
+      "}";
+  SlotMapping Mapping;
+  auto Mod = parseAssemblyString(Source, Error, Ctx, &Mapping);
+  ASSERT_TRUE(Mod != nullptr);
+  auto &M = *Mod;
+  unsigned Read;
+
+  DIExpression *Expr;
+
+  Expr = parseDIExpressionAtBeginning("i32", Read, Error, M, &Mapping);
+  ASSERT_FALSE(Expr);
+
+  Expr = parseDIExpressionAtBeginning("!DIExpression()", Read, Error, M, &Mapping);
+  ASSERT_TRUE(Expr);
+  ASSERT_EQ(Expr->getNumElements(), 0);
+
+  Expr = parseDIExpressionAtBeginning("!DIExpression(0)", Read, Error, M, &Mapping);
+  ASSERT_TRUE(Expr);
+  ASSERT_EQ(Expr->getNumElements(), 1);
+
+  Expr = parseDIExpressionAtBeginning("!DIExpression(DW_OP_LLVM_fragment, 0, 1)", Read, Error, M, &Mapping);
+  ASSERT_TRUE(Expr);
+  ASSERT_EQ(Expr->getNumElements(), 3);
+
+  Expr = parseDIExpressionAtBeginning("(DW_OP_LLVM_fragment, 0, 1)", Read, Error, M, &Mapping);
+  ASSERT_TRUE(Expr);
+  ASSERT_EQ(Expr->getNumElements(), 3);
+}
+
 } // end anonymous namespace

>From 2656e0b5a692af49b379611072e95d40e9e02400 Mon Sep 17 00:00:00 2001
From: Scott Linder <scott.linder at amd.com>
Date: Thu, 27 Jun 2024 16:45:25 -0400
Subject: [PATCH 3/7] Fold redundant `if` into return statement.

Co-authored-by: Orlando Cazalet-Hyams <orlandoch.och at gmail.com>
---
 llvm/lib/AsmParser/Parser.cpp | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/llvm/lib/AsmParser/Parser.cpp b/llvm/lib/AsmParser/Parser.cpp
index 17bdec3a090e7..1446ad0bde9ea 100644
--- a/llvm/lib/AsmParser/Parser.cpp
+++ b/llvm/lib/AsmParser/Parser.cpp
@@ -237,7 +237,5 @@ DIExpression *llvm::parseDIExpressionAtBeginning(StringRef Asm, unsigned &Read,
   if (LLParser(Asm, SM, Err, const_cast<Module *>(&M), nullptr, M.getContext())
           .parseDIExpressionAtBeginning(MD, Read, Slots))
     return nullptr;
-  if (auto *Expr = dyn_cast<DIExpression>(MD))
-    return Expr;
-  return nullptr;
+  return dyn_cast<DIExpression>(MD);
 }

>From d0c1d00b59fb12757ba881d990d2f1f29787417a Mon Sep 17 00:00:00 2001
From: Scott Linder <Scott.Linder at amd.com>
Date: Mon, 1 Jul 2024 21:27:54 +0000
Subject: [PATCH 4/7] Exclusively support parsing the "body" of a DIExpression

Simplify and extend tests, and limit "AtBeginning" parsing
to strings which do not include the leading "!DIExpression".

Change-Id: I62764d7d55667cd9036e0f3c484a1ab1363ef48e
---
 llvm/include/llvm/AsmParser/LLParser.h        |   5 +-
 llvm/include/llvm/AsmParser/Parser.h          |   7 +-
 llvm/lib/AsmParser/LLParser.cpp               |  25 ++-
 llvm/lib/AsmParser/Parser.cpp                 |  11 +-
 llvm/lib/CodeGen/MIRParser/MIParser.cpp       |   6 +-
 .../test/CodeGen/MIR/Generic/diexpression.mir | 204 +++++-------------
 llvm/unittests/AsmParser/AsmParserTest.cpp    |  29 +--
 7 files changed, 98 insertions(+), 189 deletions(-)

diff --git a/llvm/include/llvm/AsmParser/LLParser.h b/llvm/include/llvm/AsmParser/LLParser.h
index 1e93fc0f8cc7d..e381295802009 100644
--- a/llvm/include/llvm/AsmParser/LLParser.h
+++ b/llvm/include/llvm/AsmParser/LLParser.h
@@ -201,8 +201,8 @@ namespace llvm {
     bool parseTypeAtBeginning(Type *&Ty, unsigned &Read,
                               const SlotMapping *Slots);
 
-    bool parseDIExpressionAtBeginning(MDNode *&Result, unsigned &Read,
-                                      const SlotMapping *Slots);
+    bool parseDIExpressionBodyAtBeginning(MDNode *&Result, unsigned &Read,
+                                          const SlotMapping *Slots);
 
     LLVMContext &getContext() { return Context; }
 
@@ -594,6 +594,7 @@ namespace llvm {
     template <class ParserTy>
     bool parseMDFieldsImpl(ParserTy ParseField, LocTy &ClosingLoc);
     bool parseSpecializedMDNode(MDNode *&N, bool IsDistinct = false);
+    bool parseDIExpressionBody(MDNode *&Result, bool IsDistinct);
 
 #define HANDLE_SPECIALIZED_MDNODE_LEAF(CLASS)                                  \
   bool parse##CLASS(MDNode *&Result, bool IsDistinct);
diff --git a/llvm/include/llvm/AsmParser/Parser.h b/llvm/include/llvm/AsmParser/Parser.h
index 01193a0240b83..15cc7b5af837c 100644
--- a/llvm/include/llvm/AsmParser/Parser.h
+++ b/llvm/include/llvm/AsmParser/Parser.h
@@ -203,9 +203,10 @@ Type *parseType(StringRef Asm, SMDiagnostic &Err, const Module &M,
 Type *parseTypeAtBeginning(StringRef Asm, unsigned &Read, SMDiagnostic &Err,
                            const Module &M, const SlotMapping *Slots = nullptr);
 
-DIExpression *parseDIExpressionAtBeginning(StringRef Asm, unsigned &Read,
-                                           SMDiagnostic &Err, const Module &M,
-                                           const SlotMapping *Slots);
+DIExpression *parseDIExpressionBodyAtBeginning(StringRef Asm, unsigned &Read,
+                                               SMDiagnostic &Err,
+                                               const Module &M,
+                                               const SlotMapping *Slots);
 
 } // End llvm namespace
 
diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp
index 7486afc05a3c0..e6aa6669e4c74 100644
--- a/llvm/lib/AsmParser/LLParser.cpp
+++ b/llvm/lib/AsmParser/LLParser.cpp
@@ -124,15 +124,15 @@ bool LLParser::parseTypeAtBeginning(Type *&Ty, unsigned &Read,
   return false;
 }
 
-bool LLParser::parseDIExpressionAtBeginning(MDNode *&Result, unsigned &Read,
-                                            const SlotMapping *Slots) {
+bool LLParser::parseDIExpressionBodyAtBeginning(MDNode *&Result, unsigned &Read,
+                                                const SlotMapping *Slots) {
   restoreParsingState(Slots);
   Lex.Lex();
 
   Read = 0;
   SMLoc Start = Lex.getLoc();
   Result = nullptr;
-  bool Status = parseDIExpression(Result, /*IsDistinct=*/false);
+  bool Status = parseDIExpressionBody(Result, /*IsDistinct=*/false);
   SMLoc End = Lex.getLoc();
   Read = End.getPointer() - Start.getPointer();
 
@@ -5839,12 +5839,9 @@ bool LLParser::parseDILabel(MDNode *&Result, bool IsDistinct) {
   return false;
 }
 
-/// parseDIExpression:
-///   ::= !DIExpression(0, 7, -1)
-bool LLParser::parseDIExpression(MDNode *&Result, bool IsDistinct) {
-  if (Lex.getKind() == lltok::MetadataVar)
-    Lex.Lex();
-
+/// parseDIExpressionBody:
+///   ::= (0, 7, -1)
+bool LLParser::parseDIExpressionBody(MDNode *&Result, bool IsDistinct) {
   if (parseToken(lltok::lparen, "expected '(' here"))
     return true;
 
@@ -5887,6 +5884,16 @@ bool LLParser::parseDIExpression(MDNode *&Result, bool IsDistinct) {
   return false;
 }
 
+/// parseDIExpression:
+///   ::= !DIExpression(0, 7, -1)
+bool LLParser::parseDIExpression(MDNode *&Result, bool IsDistinct) {
+  assert(Lex.getKind() == lltok::MetadataVar && "Expected metadata type name");
+  assert(Lex.getStrVal() == "DIExpression" && "Expected '!DIExpression'");
+  Lex.Lex();
+
+  return parseDIExpressionBody(Result, IsDistinct);
+}
+
 /// ParseDIArgList:
 ///   ::= !DIArgList(i32 7, i64 %0)
 bool LLParser::parseDIArgList(Metadata *&MD, PerFunctionState *PFS) {
diff --git a/llvm/lib/AsmParser/Parser.cpp b/llvm/lib/AsmParser/Parser.cpp
index 1446ad0bde9ea..07fdce981b084 100644
--- a/llvm/lib/AsmParser/Parser.cpp
+++ b/llvm/lib/AsmParser/Parser.cpp
@@ -226,16 +226,17 @@ Type *llvm::parseTypeAtBeginning(StringRef Asm, unsigned &Read,
   return Ty;
 }
 
-DIExpression *llvm::parseDIExpressionAtBeginning(StringRef Asm, unsigned &Read,
-                                                 SMDiagnostic &Err,
-                                                 const Module &M,
-                                                 const SlotMapping *Slots) {
+DIExpression *llvm::parseDIExpressionBodyAtBeginning(StringRef Asm,
+                                                     unsigned &Read,
+                                                     SMDiagnostic &Err,
+                                                     const Module &M,
+                                                     const SlotMapping *Slots) {
   SourceMgr SM;
   std::unique_ptr<MemoryBuffer> Buf = MemoryBuffer::getMemBuffer(Asm);
   SM.AddNewSourceBuffer(std::move(Buf), SMLoc());
   MDNode *MD;
   if (LLParser(Asm, SM, Err, const_cast<Module *>(&M), nullptr, M.getContext())
-          .parseDIExpressionAtBeginning(MD, Read, Slots))
+          .parseDIExpressionBodyAtBeginning(MD, Read, Slots))
     return nullptr;
   return dyn_cast<DIExpression>(MD);
 }
diff --git a/llvm/lib/CodeGen/MIRParser/MIParser.cpp b/llvm/lib/CodeGen/MIRParser/MIParser.cpp
index 188d6c9bbcf15..1d16729aa3387 100644
--- a/llvm/lib/CodeGen/MIRParser/MIParser.cpp
+++ b/llvm/lib/CodeGen/MIRParser/MIParser.cpp
@@ -2303,9 +2303,9 @@ bool MIParser::parseMDNode(MDNode *&Node) {
 
 bool MIParser::parseDIExpression(MDNode *&Expr) {
   unsigned Read;
-  Expr = llvm::parseDIExpressionAtBeginning(CurrentSource, Read, Error,
-                                            *PFS.MF.getFunction().getParent(),
-                                            &PFS.IRSlots);
+  Expr = llvm::parseDIExpressionBodyAtBeginning(
+      CurrentSource, Read, Error, *PFS.MF.getFunction().getParent(),
+      &PFS.IRSlots);
   CurrentSource = CurrentSource.slice(Read, StringRef::npos);
   lex();
   if (!Expr)
diff --git a/llvm/test/CodeGen/MIR/Generic/diexpression.mir b/llvm/test/CodeGen/MIR/Generic/diexpression.mir
index 085c16fd7d6d6..b85f153fde6cb 100644
--- a/llvm/test/CodeGen/MIR/Generic/diexpression.mir
+++ b/llvm/test/CodeGen/MIR/Generic/diexpression.mir
@@ -1,167 +1,63 @@
-# NOTE: Hand-modified after being autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 5
-# RUN: llc -run-pass none -o - %s 2>&1 | FileCheck %s
-# Note: generated via:
-# printf 'extern long long sink; int func(int arg) { int purelocal = arg * 42; int pinnedlocal = arg * 43; sink = (long long)&pinnedlocal; return purelocal; }' | clang -cc1 -O1 -triple x86_64-unknown-linux-gnu -debug-info-kind=limited -S -mllvm -stop-after=x86-isel - -o -
+# RUN: sed -e 's/STACK_EXPR//g' -e 's/BODY_EXPR//g' %s | llc -x mir -run-pass none -o - 2>&1 | FileCheck --check-prefix=EXPR-NONE %s
+# RUN: sed -e 's/STACK_EXPR/DW_OP_LLVM_arg, 0, DW_OP_dup, DW_OP_plus/g' -e 's/BODY_EXPR/DW_OP_LLVM_arg, 0, DW_OP_dup, DW_OP_plus/g' %s \
+# RUN:  | llc -x mir -run-pass none -o - 2>&1 | FileCheck --check-prefix=EXPR-SOME %s
+# RUN: sed -e 's/STACK_EXPR/DW_OP_foobar/g' -e 's/BODY_EXPR//g' %s | not llc -x mir -run-pass none -o - 2>&1 | FileCheck --check-prefix=EXPR-ERR-STACK-INVALID-OP %s
+# RUN: sed -e 's/STACK_EXPR//g' -e 's/BODY_EXPR/DW_OP_foobar/g' %s | not llc -x mir -run-pass none -o - 2>&1 | FileCheck --check-prefix=EXPR-ERR-BODY-INVALID-OP %s
+# RUN: sed -e 's/STACK_EXPR/DW_ATE_foobar/g' -e 's/BODY_EXPR//g' %s | not llc -x mir -run-pass none -o - 2>&1 | FileCheck --check-prefix=EXPR-ERR-STACK-INVALID-ATTR %s
+# RUN: sed -e 's/STACK_EXPR//g' -e 's/BODY_EXPR/DW_ATE_foobar/g' %s | not llc -x mir -run-pass none -o - 2>&1 | FileCheck --check-prefix=EXPR-ERR-BODY-INVALID-ATTR %s
+# RUN: sed -e 's/STACK_EXPR/foobar/g' -e 's/BODY_EXPR//g' %s | not llc -x mir -run-pass none -o - 2>&1 | FileCheck --check-prefix=EXPR-ERR-STACK-INVALID-INT %s
+# RUN: sed -e 's/STACK_EXPR//g' -e 's/BODY_EXPR/foobar/g' %s | not llc -x mir -run-pass none -o - 2>&1 | FileCheck --check-prefix=EXPR-ERR-BODY-INVALID-INT %s
 --- |
-  source_filename = "-"
-  target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
-  target triple = "x86_64-unknown-linux-gnu"
-
-  @sink = external local_unnamed_addr global i64, align 8
-
-  define dso_local i32 @func(i32 noundef %arg) local_unnamed_addr #0 !dbg !8 {
+  define void @func() #0 !dbg !6 {
   entry:
-    %pinnedlocal = alloca i32, align 4, !DIAssignID !16
-      #dbg_assign(i1 undef, !15, !DIExpression(), !16, ptr %pinnedlocal, !DIExpression(), !17)
-      #dbg_value(i32 %arg, !13, !DIExpression(), !17)
-    %mul = mul nsw i32 %arg, 42, !dbg !18
-      #dbg_value(i32 %mul, !14, !DIExpression(), !17)
-    call void @llvm.lifetime.start.p0(i64 4, ptr nonnull %pinnedlocal) #2, !dbg !19
-    %mul1 = mul nsw i32 %arg, 43, !dbg !20
-    store i32 %mul1, ptr %pinnedlocal, align 4, !dbg !21, !tbaa !22, !DIAssignID !26
-      #dbg_assign(i32 %mul1, !15, !DIExpression(), !26, ptr %pinnedlocal, !DIExpression(), !17)
-    %0 = ptrtoint ptr %pinnedlocal to i64, !dbg !27
-    store i64 %0, ptr @sink, align 8, !dbg !28, !tbaa !29
-    call void @llvm.lifetime.end.p0(i64 4, ptr nonnull %pinnedlocal) #2, !dbg !31
-    ret i32 %mul, !dbg !32
+    call void @llvm.dbg.value(metadata i32 0, metadata !10, metadata !DIExpression()), !dbg !12
+    ret void
   }
 
-  declare void @llvm.lifetime.start.p0(i64 immarg, ptr nocapture) #1
-
-  declare void @llvm.lifetime.end.p0(i64 immarg, ptr nocapture) #1
+  declare void @llvm.dbg.value(metadata, metadata, metadata) #1
+
+  attributes #0 = { noinline nounwind optnone }
+  attributes #1 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }
+
+  !llvm.module.flags = !{!0, !1}
+  !llvm.ident = !{!2}
+  !llvm.dbg.cu = !{!3}
+  !llvm.debugify = !{!5, !5}
+
+  !0 = !{i32 1, !"wchar_size", i32 4}
+  !1 = !{i32 2, !"Debug Info Version", i32 3}
+  !2 = !{!"clang"}
+  !3 = distinct !DICompileUnit(language: DW_LANG_C, file: !4, producer: "debugify", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug)
+  !4 = !DIFile(filename: "<stdin>", directory: "/")
+  !5 = !{i32 1}
+  !6 = distinct !DISubprogram(name: "func", linkageName: "func", scope: null, file: !4, line: 1, type: !7, scopeLine: 1, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !3, retainedNodes: !9)
+  !7 = !DISubroutineType(types: !8)
+  !8 = !{}
+  !9 = !{!10}
+  !10 = !DILocalVariable(name: "1", scope: !6, file: !4, line: 1, type: !11)
+  !11 = !DIBasicType(name: "ty32", size: 32, encoding: DW_ATE_unsigned)
+  !12 = !DILocation(line: 1, column: 1, scope: !6)
 
-  attributes #0 = { mustprogress nofree norecurse nosync nounwind willreturn memory(write, argmem: none, inaccessiblemem: none) "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+cx8,+mmx,+sse,+sse2,+x87" }
-  attributes #1 = { mustprogress nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }
-  attributes #2 = { nounwind }
+...
+---
 
-  !llvm.dbg.cu = !{!0}
-  !llvm.module.flags = !{!4, !5, !6}
-  !llvm.ident = !{!7}
+# EXPR-NONE: debug-info-expression: '!DIExpression()'
+# EXPR-NONE: DBG_VALUE 0, 0, ![[#]], !DIExpression(), debug-location ![[#]]
 
-  !0 = distinct !DICompileUnit(language: DW_LANG_C11, file: !1, producer: "clang version 19.0.0git (git at github.com:slinder1/llvm-project.git a32b7199f0c15ea1c6c9490b6166c019c9d4bd2b)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, retainedTypes: !2, splitDebugInlining: false, nameTableKind: None)
-  !1 = !DIFile(filename: "<stdin>", directory: "/home/slinder1/llvm-project/main")
-  !2 = !{!3}
-  !3 = !DIBasicType(name: "long long", size: 64, encoding: DW_ATE_signed)
-  !4 = !{i32 2, !"Debug Info Version", i32 3}
-  !5 = !{i32 1, !"wchar_size", i32 4}
-  !6 = !{i32 7, !"debug-info-assignment-tracking", i1 true}
-  !7 = !{!"clang version 19.0.0git (git at github.com:slinder1/llvm-project.git a32b7199f0c15ea1c6c9490b6166c019c9d4bd2b)"}
-  !8 = distinct !DISubprogram(name: "func", scope: !1, file: !1, line: 1, type: !9, scopeLine: 1, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !12)
-  !9 = !DISubroutineType(types: !10)
-  !10 = !{!11, !11}
-  !11 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
-  !12 = !{!13, !14, !15}
-  !13 = !DILocalVariable(name: "arg", arg: 1, scope: !8, file: !1, line: 1, type: !11)
-  !14 = !DILocalVariable(name: "purelocal", scope: !8, file: !1, line: 1, type: !11)
-  !15 = !DILocalVariable(name: "pinnedlocal", scope: !8, file: !1, line: 1, type: !11)
-  !16 = distinct !DIAssignID()
-  !17 = !DILocation(line: 0, scope: !8)
-  !18 = !DILocation(line: 1, column: 64, scope: !8)
-  !19 = !DILocation(line: 1, column: 70, scope: !8)
-  !20 = !DILocation(line: 1, column: 92, scope: !8)
-  !21 = !DILocation(line: 1, column: 74, scope: !8)
-  !22 = !{!23, !23, i64 0}
-  !23 = !{!"int", !24, i64 0}
-  !24 = !{!"omnipotent char", !25, i64 0}
-  !25 = !{!"Simple C/C++ TBAA"}
-  !26 = distinct !DIAssignID()
-  !27 = !DILocation(line: 1, column: 105, scope: !8)
-  !28 = !DILocation(line: 1, column: 103, scope: !8)
-  !29 = !{!30, !30, i64 0}
-  !30 = !{!"long long", !24, i64 0}
-  !31 = !DILocation(line: 1, column: 148, scope: !8)
-  !32 = !DILocation(line: 1, column: 130, scope: !8)
+# EXPR-SOME: debug-info-expression: '!DIExpression(DW_OP_LLVM_arg, 0, DW_OP_dup, DW_OP_plus)'
+# EXPR-SOME: DBG_VALUE 0, 0, ![[#]], !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_dup, DW_OP_plus), debug-location ![[#]]
 
-...
----
 name:            func
-alignment:       16
-exposesReturnsTwice: false
-legalized:       false
-regBankSelected: false
-selected:        false
-failedISel:      false
-tracksRegLiveness: true
-hasWinCFI:       false
-callsEHReturn:   false
-callsUnwindInit: false
-hasEHCatchret:   false
-hasEHScopes:     false
-hasEHFunclets:   false
-isOutlined:      false
-debugInstrRef:   true
-failsVerification: false
-tracksDebugUserValues: false
-registers:
-  - { id: 0, class: gr32, preferred-register: '' }
-  - { id: 1, class: gr32, preferred-register: '' }
-  - { id: 2, class: gr64, preferred-register: '' }
-  - { id: 3, class: gr64, preferred-register: '' }
-liveins:
-  - { reg: '$edi', virtual-reg: '%0' }
-frameInfo:
-  isFrameAddressTaken: false
-  isReturnAddressTaken: false
-  hasStackMap:     false
-  hasPatchPoint:   false
-  stackSize:       0
-  offsetAdjustment: 0
-  maxAlignment:    4
-  adjustsStack:    false
-  hasCalls:        false
-  stackProtector:  ''
-  functionContext: ''
-  maxCallFrameSize: 4294967295
-  cvBytesOfCalleeSavedRegisters: 0
-  hasOpaqueSPAdjustment: false
-  hasVAStart:      false
-  hasMustTailInVarArgFunc: false
-  hasTailCall:     false
-  isCalleeSavedInfoValid: false
-  localFrameSize:  0
-  savePoint:       ''
-  restorePoint:    ''
-fixedStack:      []
 stack:
-  - { id: 0, name: pinnedlocal, type: default, offset: 0, size: 4, alignment: 4,
-      stack-id: default, callee-saved-register: '', callee-saved-restored: true,
-      debug-info-variable: '!15', debug-info-expression: '!DIExpression()',
-      debug-info-location: '!17' }
-entry_values:    []
-callSites:       []
-debugValueSubstitutions: []
-constants:       []
-machineFunctionInfo:
-  amxProgModel:    None
+  # EXPR-ERR-STACK-INVALID-OP: <stdin>:[[#@LINE+4]]:45: invalid DWARF op 'DW_OP_foobar'
+  # EXPR-ERR-STACK-INVALID-ATTR: <stdin>:[[#@LINE+3]]:45: invalid DWARF attribute encoding 'DW_ATE_foobar'
+  # EXPR-ERR-STACK-INVALID-INT: <stdin>:[[#@LINE+2]]:45: expected unsigned integer
+  - { id: 0, size: 4, debug-info-variable: '!10', debug-info-location: '!12',
+      debug-info-expression: '!DIExpression(STACK_EXPR)' }
 body:             |
   bb.0.entry:
-    liveins: $edi
-
-    ; CHECK-LABEL: name: func
-    ; CHECK: debug-info-expression: '!DIExpression()',
-    ; CHECK: liveins: $edi
-    ; CHECK-NEXT: {{  $}}
-    ; CHECK-NEXT: DBG_VALUE $edi, $noreg, !13, !DIExpression(), debug-location !17
-    ; CHECK-NEXT: [[COPY:%[0-9]+]]:gr32 = COPY $edi
-    ; CHECK-NEXT: [[IMUL32rri:%[0-9]+]]:gr32 = nsw IMUL32rri [[COPY]], 42, implicit-def dead $eflags, debug-instr-number 1, debug-location !18
-    ; CHECK-NEXT: DBG_INSTR_REF !14, !DIExpression(DW_OP_LLVM_arg, 0), dbg-instr-ref(1, 0), debug-location !17
-    ; CHECK-NEXT: LIFETIME_START %stack.0.pinnedlocal, debug-location !19
-    ; CHECK-NEXT: [[MOV64rm:%[0-9]+]]:gr64 = MOV64rm $rip, 1, $noreg, target-flags(x86-gotpcrel) @sink, $noreg, debug-location !28 :: (load (s64) from got)
-    ; CHECK-NEXT: [[LEA64r:%[0-9]+]]:gr64 = LEA64r %stack.0.pinnedlocal, 1, $noreg, 0, $noreg
-    ; CHECK-NEXT: MOV64mr killed [[MOV64rm]], 1, $noreg, 0, $noreg, killed [[LEA64r]], debug-location !28 :: (store (s64) into @sink, !tbaa !29)
-    ; CHECK-NEXT: LIFETIME_END %stack.0.pinnedlocal, debug-location !31
-    ; CHECK-NEXT: $eax = COPY [[IMUL32rri]], debug-location !32
-    ; CHECK-NEXT: RET 0, $eax, debug-location !32
-    DBG_VALUE $edi, $noreg, !13, !DIExpression(), debug-location !17
-    %0:gr32 = COPY $edi
-    %1:gr32 = nsw IMUL32rri %0, 42, implicit-def dead $eflags, debug-instr-number 1, debug-location !18
-    DBG_INSTR_REF !14, !DIExpression(DW_OP_LLVM_arg, 0), dbg-instr-ref(1, 0), debug-location !17
-    LIFETIME_START %stack.0.pinnedlocal, debug-location !19
-    %2:gr64 = MOV64rm $rip, 1, $noreg, target-flags(x86-gotpcrel) @sink, $noreg, debug-location !28 :: (load (s64) from got)
-    %3:gr64 = LEA64r %stack.0.pinnedlocal, 1, $noreg, 0, $noreg
-    MOV64mr killed %2, 1, $noreg, 0, $noreg, killed %3, debug-location !28 :: (store (s64) into @sink, !tbaa !29)
-    LIFETIME_END %stack.0.pinnedlocal, debug-location !31
-    $eax = COPY %1, debug-location !32
-    RET 0, $eax, debug-location !32
-
+    ; EXPR-ERR-BODY-INVALID-OP: <stdin>:[[#@LINE+3]]:40: invalid DWARF op 'DW_OP_foobar'
+    ; EXPR-ERR-BODY-INVALID-ATTR: <stdin>:[[#@LINE+2]]:40: invalid DWARF attribute encoding 'DW_ATE_foobar'
+    ; EXPR-ERR-BODY-INVALID-INT: <stdin>:[[#@LINE+1]]:40: expected unsigned integer
+    DBG_VALUE 0, 0, !10, !DIExpression(BODY_EXPR), debug-location !12
 ...
diff --git a/llvm/unittests/AsmParser/AsmParserTest.cpp b/llvm/unittests/AsmParser/AsmParserTest.cpp
index 3749714fd4677..1cef212b70a74 100644
--- a/llvm/unittests/AsmParser/AsmParserTest.cpp
+++ b/llvm/unittests/AsmParser/AsmParserTest.cpp
@@ -412,7 +412,7 @@ TEST(AsmParserTest, InvalidDataLayoutStringCallback) {
   EXPECT_EQ(Mod2->getDataLayout(), FixedDL);
 }
 
-TEST(AsmParserTest, DIExpressionAtBeginningWithSlotMappingParsing) {
+TEST(AsmParserTest, DIExpressionBodyAtBeginningWithSlotMappingParsing) {
   LLVMContext Ctx;
   SMDiagnostic Error;
   StringRef Source =
@@ -437,24 +437,27 @@ TEST(AsmParserTest, DIExpressionAtBeginningWithSlotMappingParsing) {
 
   DIExpression *Expr;
 
-  Expr = parseDIExpressionAtBeginning("i32", Read, Error, M, &Mapping);
-  ASSERT_FALSE(Expr);
-
-  Expr = parseDIExpressionAtBeginning("!DIExpression()", Read, Error, M, &Mapping);
+  Expr = parseDIExpressionBodyAtBeginning("()", Read, Error, M, &Mapping);
   ASSERT_TRUE(Expr);
-  ASSERT_EQ(Expr->getNumElements(), 0);
+  ASSERT_EQ(Expr->getNumElements(), 0u);
 
-  Expr = parseDIExpressionAtBeginning("!DIExpression(0)", Read, Error, M, &Mapping);
+  Expr = parseDIExpressionBodyAtBeginning("(0)", Read, Error, M, &Mapping);
   ASSERT_TRUE(Expr);
-  ASSERT_EQ(Expr->getNumElements(), 1);
+  ASSERT_EQ(Expr->getNumElements(), 1u);
 
-  Expr = parseDIExpressionAtBeginning("!DIExpression(DW_OP_LLVM_fragment, 0, 1)", Read, Error, M, &Mapping);
+  Expr = parseDIExpressionBodyAtBeginning("(DW_OP_LLVM_fragment, 0, 1)", Read, Error, M, &Mapping);
   ASSERT_TRUE(Expr);
-  ASSERT_EQ(Expr->getNumElements(), 3);
+  ASSERT_EQ(Expr->getNumElements(), 3u);
 
-  Expr = parseDIExpressionAtBeginning("(DW_OP_LLVM_fragment, 0, 1)", Read, Error, M, &Mapping);
-  ASSERT_TRUE(Expr);
-  ASSERT_EQ(Expr->getNumElements(), 3);
+  Error = {};
+  Expr = parseDIExpressionBodyAtBeginning("i32", Read, Error, M, &Mapping);
+  ASSERT_FALSE(Expr);
+  ASSERT_EQ(Error.getMessage(), "expected '(' here");
+
+  Error = {};
+  Expr = parseDIExpressionBodyAtBeginning("!DIExpression(DW_OP_LLVM_fragment, 0, 1)", Read, Error, M, &Mapping);
+  ASSERT_FALSE(Expr);
+  ASSERT_EQ(Error.getMessage(), "expected '(' here");
 }
 
 } // end anonymous namespace

>From 02446c2ef9075c7367c35778383b2cdd477f0ae3 Mon Sep 17 00:00:00 2001
From: Scott Linder <Scott.Linder at amd.com>
Date: Mon, 1 Jul 2024 22:12:37 +0000
Subject: [PATCH 5/7] run clang-format

Change-Id: I0095ed73eed66d16b6ab35407bc655e76f06fead
---
 llvm/unittests/AsmParser/AsmParserTest.cpp | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/llvm/unittests/AsmParser/AsmParserTest.cpp b/llvm/unittests/AsmParser/AsmParserTest.cpp
index 1cef212b70a74..9e489e7eac5a0 100644
--- a/llvm/unittests/AsmParser/AsmParserTest.cpp
+++ b/llvm/unittests/AsmParser/AsmParserTest.cpp
@@ -445,7 +445,8 @@ TEST(AsmParserTest, DIExpressionBodyAtBeginningWithSlotMappingParsing) {
   ASSERT_TRUE(Expr);
   ASSERT_EQ(Expr->getNumElements(), 1u);
 
-  Expr = parseDIExpressionBodyAtBeginning("(DW_OP_LLVM_fragment, 0, 1)", Read, Error, M, &Mapping);
+  Expr = parseDIExpressionBodyAtBeginning("(DW_OP_LLVM_fragment, 0, 1)", Read,
+                                          Error, M, &Mapping);
   ASSERT_TRUE(Expr);
   ASSERT_EQ(Expr->getNumElements(), 3u);
 
@@ -455,7 +456,8 @@ TEST(AsmParserTest, DIExpressionBodyAtBeginningWithSlotMappingParsing) {
   ASSERT_EQ(Error.getMessage(), "expected '(' here");
 
   Error = {};
-  Expr = parseDIExpressionBodyAtBeginning("!DIExpression(DW_OP_LLVM_fragment, 0, 1)", Read, Error, M, &Mapping);
+  Expr = parseDIExpressionBodyAtBeginning(
+      "!DIExpression(DW_OP_LLVM_fragment, 0, 1)", Read, Error, M, &Mapping);
   ASSERT_FALSE(Expr);
   ASSERT_EQ(Error.getMessage(), "expected '(' here");
 }

>From 01705406e5901887527ce62b1d1afb5073e10354 Mon Sep 17 00:00:00 2001
From: Scott Linder <Scott.Linder at amd.com>
Date: Tue, 2 Jul 2024 23:06:28 +0000
Subject: [PATCH 6/7] Remove redundant diexpression-err.mir test

Change-Id: I274f51393f33920f1246d32d84e2e3ff36cb66d2
---
 .../CodeGen/MIR/Generic/diexpression-err.mir  | 152 ------------------
 1 file changed, 152 deletions(-)
 delete mode 100644 llvm/test/CodeGen/MIR/Generic/diexpression-err.mir

diff --git a/llvm/test/CodeGen/MIR/Generic/diexpression-err.mir b/llvm/test/CodeGen/MIR/Generic/diexpression-err.mir
deleted file mode 100644
index f5c81411ede90..0000000000000
--- a/llvm/test/CodeGen/MIR/Generic/diexpression-err.mir
+++ /dev/null
@@ -1,152 +0,0 @@
-# RUN: not llc -run-pass none -o - %s 2>&1 | FileCheck %s
-# Note: generated via:
-# printf 'extern long long sink; int func(int arg) { int purelocal = arg * 42; int pinnedlocal = arg * 43; sink = (long long)&pinnedlocal; return purelocal; }' | clang -cc1 -O1 -triple x86_64-unknown-linux-gnu -debug-info-kind=limited -S -mllvm -stop-after=x86-isel - -o -
---- |
-  source_filename = "-"
-  target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
-  target triple = "x86_64-unknown-linux-gnu"
-
-  @sink = external local_unnamed_addr global i64, align 8
-
-  define dso_local i32 @func(i32 noundef %arg) local_unnamed_addr #0 !dbg !8 {
-  entry:
-    %pinnedlocal = alloca i32, align 4, !DIAssignID !16
-      #dbg_assign(i1 undef, !15, !DIExpression(), !16, ptr %pinnedlocal, !DIExpression(), !17)
-      #dbg_value(i32 %arg, !13, !DIExpression(), !17)
-    %mul = mul nsw i32 %arg, 42, !dbg !18
-      #dbg_value(i32 %mul, !14, !DIExpression(), !17)
-    call void @llvm.lifetime.start.p0(i64 4, ptr nonnull %pinnedlocal) #2, !dbg !19
-    %mul1 = mul nsw i32 %arg, 43, !dbg !20
-    store i32 %mul1, ptr %pinnedlocal, align 4, !dbg !21, !tbaa !22, !DIAssignID !26
-      #dbg_assign(i32 %mul1, !15, !DIExpression(), !26, ptr %pinnedlocal, !DIExpression(), !17)
-    %0 = ptrtoint ptr %pinnedlocal to i64, !dbg !27
-    store i64 %0, ptr @sink, align 8, !dbg !28, !tbaa !29
-    call void @llvm.lifetime.end.p0(i64 4, ptr nonnull %pinnedlocal) #2, !dbg !31
-    ret i32 %mul, !dbg !32
-  }
-
-  declare void @llvm.lifetime.start.p0(i64 immarg, ptr nocapture) #1
-
-  declare void @llvm.lifetime.end.p0(i64 immarg, ptr nocapture) #1
-
-  attributes #0 = { mustprogress nofree norecurse nosync nounwind willreturn memory(write, argmem: none, inaccessiblemem: none) "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+cx8,+mmx,+sse,+sse2,+x87" }
-  attributes #1 = { mustprogress nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }
-  attributes #2 = { nounwind }
-
-  !llvm.dbg.cu = !{!0}
-  !llvm.module.flags = !{!4, !5, !6}
-  !llvm.ident = !{!7}
-
-  !0 = distinct !DICompileUnit(language: DW_LANG_C11, file: !1, producer: "clang version 19.0.0git (git at github.com:slinder1/llvm-project.git a32b7199f0c15ea1c6c9490b6166c019c9d4bd2b)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, retainedTypes: !2, splitDebugInlining: false, nameTableKind: None)
-  !1 = !DIFile(filename: "<stdin>", directory: "/home/slinder1/llvm-project/main")
-  !2 = !{!3}
-  !3 = !DIBasicType(name: "long long", size: 64, encoding: DW_ATE_signed)
-  !4 = !{i32 2, !"Debug Info Version", i32 3}
-  !5 = !{i32 1, !"wchar_size", i32 4}
-  !6 = !{i32 7, !"debug-info-assignment-tracking", i1 true}
-  !7 = !{!"clang version 19.0.0git (git at github.com:slinder1/llvm-project.git a32b7199f0c15ea1c6c9490b6166c019c9d4bd2b)"}
-  !8 = distinct !DISubprogram(name: "func", scope: !1, file: !1, line: 1, type: !9, scopeLine: 1, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !12)
-  !9 = !DISubroutineType(types: !10)
-  !10 = !{!11, !11}
-  !11 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
-  !12 = !{!13, !14, !15}
-  !13 = !DILocalVariable(name: "arg", arg: 1, scope: !8, file: !1, line: 1, type: !11)
-  !14 = !DILocalVariable(name: "purelocal", scope: !8, file: !1, line: 1, type: !11)
-  !15 = !DILocalVariable(name: "pinnedlocal", scope: !8, file: !1, line: 1, type: !11)
-  !16 = distinct !DIAssignID()
-  !17 = !DILocation(line: 0, scope: !8)
-  !18 = !DILocation(line: 1, column: 64, scope: !8)
-  !19 = !DILocation(line: 1, column: 70, scope: !8)
-  !20 = !DILocation(line: 1, column: 92, scope: !8)
-  !21 = !DILocation(line: 1, column: 74, scope: !8)
-  !22 = !{!23, !23, i64 0}
-  !23 = !{!"int", !24, i64 0}
-  !24 = !{!"omnipotent char", !25, i64 0}
-  !25 = !{!"Simple C/C++ TBAA"}
-  !26 = distinct !DIAssignID()
-  !27 = !DILocation(line: 1, column: 105, scope: !8)
-  !28 = !DILocation(line: 1, column: 103, scope: !8)
-  !29 = !{!30, !30, i64 0}
-  !30 = !{!"long long", !24, i64 0}
-  !31 = !DILocation(line: 1, column: 148, scope: !8)
-  !32 = !DILocation(line: 1, column: 130, scope: !8)
-
-...
----
-name:            func
-alignment:       16
-exposesReturnsTwice: false
-legalized:       false
-regBankSelected: false
-selected:        false
-failedISel:      false
-tracksRegLiveness: true
-hasWinCFI:       false
-callsEHReturn:   false
-callsUnwindInit: false
-hasEHCatchret:   false
-hasEHScopes:     false
-hasEHFunclets:   false
-isOutlined:      false
-debugInstrRef:   true
-failsVerification: false
-tracksDebugUserValues: false
-registers:
-  - { id: 0, class: gr32, preferred-register: '' }
-  - { id: 1, class: gr32, preferred-register: '' }
-  - { id: 2, class: gr64, preferred-register: '' }
-  - { id: 3, class: gr64, preferred-register: '' }
-liveins:
-  - { reg: '$edi', virtual-reg: '%0' }
-frameInfo:
-  isFrameAddressTaken: false
-  isReturnAddressTaken: false
-  hasStackMap:     false
-  hasPatchPoint:   false
-  stackSize:       0
-  offsetAdjustment: 0
-  maxAlignment:    4
-  adjustsStack:    false
-  hasCalls:        false
-  stackProtector:  ''
-  functionContext: ''
-  maxCallFrameSize: 4294967295
-  cvBytesOfCalleeSavedRegisters: 0
-  hasOpaqueSPAdjustment: false
-  hasVAStart:      false
-  hasMustTailInVarArgFunc: false
-  hasTailCall:     false
-  isCalleeSavedInfoValid: false
-  localFrameSize:  0
-  savePoint:       ''
-  restorePoint:    ''
-fixedStack:      []
-stack:
-  - { id: 0, name: pinnedlocal, type: default, offset: 0, size: 4, alignment: 4,
-      stack-id: default, callee-saved-register: '', callee-saved-restored: true,
-      debug-info-variable: '!15', debug-info-expression: '!DIExpression()',
-      debug-info-location: '!17' }
-entry_values:    []
-callSites:       []
-debugValueSubstitutions: []
-constants:       []
-machineFunctionInfo:
-  amxProgModel:    None
-body:             |
-  bb.0.entry:
-    liveins: $edi
-
-    DBG_VALUE $edi, $noreg, !13, !DIExpression(), debug-location !17
-    %0:gr32 = COPY $edi
-    %1:gr32 = nsw IMUL32rri %0, 42, implicit-def dead $eflags, debug-instr-number 1, debug-location !18
-    ; CHECK: {{.*}}.mir:[[#@LINE+1]]:38: expected unsigned integer
-    DBG_INSTR_REF !14, !DIExpression(W_OP_LLVM_arg, 0), dbg-instr-ref(1, 0), debug-location !17
-    LIFETIME_START %stack.0.pinnedlocal, debug-location !19
-    %2:gr64 = MOV64rm $rip, 1, $noreg, target-flags(x86-gotpcrel) @sink, $noreg, debug-location !28 :: (load (s64) from got)
-    %3:gr64 = LEA64r %stack.0.pinnedlocal, 1, $noreg, 0, $noreg
-    MOV64mr killed %2, 1, $noreg, 0, $noreg, killed %3, debug-location !28 :: (store (s64) into @sink, !tbaa !29)
-    LIFETIME_END %stack.0.pinnedlocal, debug-location !31
-    $eax = COPY %1, debug-location !32
-    RET 0, $eax, debug-location !32
-
-...

>From ea991d22e5e803c5223699dfe2290d2f8d941260 Mon Sep 17 00:00:00 2001
From: Scott Linder <Scott.Linder at amd.com>
Date: Wed, 3 Jul 2024 18:49:36 +0000
Subject: [PATCH 7/7] Improve tests and clang-format

---
 .../test/CodeGen/MIR/Generic/diexpression.mir |  4 ++++
 llvm/unittests/AsmParser/AsmParserTest.cpp    | 19 +++++--------------
 2 files changed, 9 insertions(+), 14 deletions(-)

diff --git a/llvm/test/CodeGen/MIR/Generic/diexpression.mir b/llvm/test/CodeGen/MIR/Generic/diexpression.mir
index b85f153fde6cb..92532bb0a8639 100644
--- a/llvm/test/CodeGen/MIR/Generic/diexpression.mir
+++ b/llvm/test/CodeGen/MIR/Generic/diexpression.mir
@@ -7,6 +7,10 @@
 # RUN: sed -e 's/STACK_EXPR//g' -e 's/BODY_EXPR/DW_ATE_foobar/g' %s | not llc -x mir -run-pass none -o - 2>&1 | FileCheck --check-prefix=EXPR-ERR-BODY-INVALID-ATTR %s
 # RUN: sed -e 's/STACK_EXPR/foobar/g' -e 's/BODY_EXPR//g' %s | not llc -x mir -run-pass none -o - 2>&1 | FileCheck --check-prefix=EXPR-ERR-STACK-INVALID-INT %s
 # RUN: sed -e 's/STACK_EXPR//g' -e 's/BODY_EXPR/foobar/g' %s | not llc -x mir -run-pass none -o - 2>&1 | FileCheck --check-prefix=EXPR-ERR-BODY-INVALID-INT %s
+
+# Test that we successfully parse valid DIExpression metadata in MIR, and that
+# we reject invalid DIExpression metadata in MIR.
+
 --- |
   define void @func() #0 !dbg !6 {
   entry:
diff --git a/llvm/unittests/AsmParser/AsmParserTest.cpp b/llvm/unittests/AsmParser/AsmParserTest.cpp
index 9e489e7eac5a0..6bff3dbec62ce 100644
--- a/llvm/unittests/AsmParser/AsmParserTest.cpp
+++ b/llvm/unittests/AsmParser/AsmParserTest.cpp
@@ -415,26 +415,15 @@ TEST(AsmParserTest, InvalidDataLayoutStringCallback) {
 TEST(AsmParserTest, DIExpressionBodyAtBeginningWithSlotMappingParsing) {
   LLVMContext Ctx;
   SMDiagnostic Error;
-  StringRef Source =
-      "%st = type { i32, i32 }\n"
-      "@v = common global [50 x %st] zeroinitializer, align 16\n"
-      "%0 = type { i32, i32, i32, i32 }\n"
-      "@g = common global [50 x %0] zeroinitializer, align 16\n"
-      "define void @marker4(i64 %d) {\n"
-      "entry:\n"
-      "  %conv = trunc i64 %d to i32\n"
-      "  store i32 %conv, ptr getelementptr inbounds "
-      "    ([50 x %st], ptr @v, i64 0, i64 0, i32 0), align 16\n"
-      "  store i32 %conv, ptr getelementptr inbounds "
-      "    ([50 x %0], ptr @g, i64 0, i64 0, i32 0), align 16\n"
-      "  ret void\n"
-      "}";
+  StringRef Source = "";
   SlotMapping Mapping;
   auto Mod = parseAssemblyString(Source, Error, Ctx, &Mapping);
   ASSERT_TRUE(Mod != nullptr);
   auto &M = *Mod;
   unsigned Read;
 
+  ASSERT_EQ(Mapping.MetadataNodes.size(), 0u);
+
   DIExpression *Expr;
 
   Expr = parseDIExpressionBodyAtBeginning("()", Read, Error, M, &Mapping);
@@ -460,6 +449,8 @@ TEST(AsmParserTest, DIExpressionBodyAtBeginningWithSlotMappingParsing) {
       "!DIExpression(DW_OP_LLVM_fragment, 0, 1)", Read, Error, M, &Mapping);
   ASSERT_FALSE(Expr);
   ASSERT_EQ(Error.getMessage(), "expected '(' here");
+
+  ASSERT_EQ(Mapping.MetadataNodes.size(), 0u);
 }
 
 } // end anonymous namespace



More information about the llvm-commits mailing list