[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