[llvm] [DebugInfo][InstrRef] Treat ORRWrr as a copy instr (PR #123102)
Shubham Sandeep Rastogi via llvm-commits
llvm-commits at lists.llvm.org
Wed Jan 15 14:32:49 PST 2025
https://github.com/rastogishubham updated https://github.com/llvm/llvm-project/pull/123102
>From 5d2206f0013184c9b1fa6b1700fb2bdf17de3ce4 Mon Sep 17 00:00:00 2001
From: Shubham Sandeep Rastogi <srastogi22 at apple.com>
Date: Tue, 14 Jan 2025 12:13:58 -0800
Subject: [PATCH] [DebugInfo][InstrRef] Treat ORRWrr as a copy instr
The insturction selector uses the MachineFunction::copySalvageSSA
function to insert DBG_PHIs or identify a defining instruction for a
copy-like instruction when finalizing Instruction References.
AArch64 has the ORR instruction which is a logical OR with the variants
ORRWrr which refers to a register to register variant, and ORRWrs which
is a register to a shifted register variant.
An ORRWrs where the shift amount is 0, and the zero register ($wzr) is
used is considered a copy, for example:
$w0 = ORRWrs $wzr, killed $w3, 0
however an ORRWrr with a zero register is not considered a copy
$w0 = ORRWr $wzr, killed $w3
This causes an issue in the livedebugvalues pass because in aarch64-isel
the instruction is the ORRWrr variant, but is then changed to the ORRWrs
variant before the livedebugvalues pass.
This causes a mismatch between the two passes which leads to a crash in
the livedebugvalues pass.
This patch fixes the issue.
---
llvm/lib/Target/AArch64/AArch64InstrInfo.cpp | 16 +++--
llvm/test/CodeGen/AArch64/instr-ref-ldv.ll | 70 ++++++++++++++++++++
2 files changed, 80 insertions(+), 6 deletions(-)
create mode 100644 llvm/test/CodeGen/AArch64/instr-ref-ldv.ll
diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp
index 8a3ed10b8e0bd2..e3f60f6cd7253c 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp
+++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp
@@ -9722,9 +9722,11 @@ AArch64InstrInfo::isCopyInstrImpl(const MachineInstr &MI) const {
// AArch64::ORRWrs and AArch64::ORRXrs with WZR/XZR reg
// and zero immediate operands used as an alias for mov instruction.
- if (MI.getOpcode() == AArch64::ORRWrs &&
- MI.getOperand(1).getReg() == AArch64::WZR &&
- MI.getOperand(3).getImm() == 0x0 &&
+ if (((MI.getOpcode() == AArch64::ORRWrs &&
+ MI.getOperand(1).getReg() == AArch64::WZR &&
+ MI.getOperand(3).getImm() == 0x0) ||
+ (MI.getOpcode() == AArch64::ORRWrr &&
+ MI.getOperand(1).getReg() == AArch64::WZR)) &&
// Check that the w->w move is not a zero-extending w->x mov.
(!MI.getOperand(0).getReg().isVirtual() ||
MI.getOperand(0).getSubReg() == 0) &&
@@ -9744,9 +9746,11 @@ AArch64InstrInfo::isCopyInstrImpl(const MachineInstr &MI) const {
std::optional<DestSourcePair>
AArch64InstrInfo::isCopyLikeInstrImpl(const MachineInstr &MI) const {
- if (MI.getOpcode() == AArch64::ORRWrs &&
- MI.getOperand(1).getReg() == AArch64::WZR &&
- MI.getOperand(3).getImm() == 0x0)
+ if ((MI.getOpcode() == AArch64::ORRWrs &&
+ MI.getOperand(1).getReg() == AArch64::WZR &&
+ MI.getOperand(3).getImm() == 0x0) ||
+ (MI.getOpcode() == AArch64::ORRWrr &&
+ MI.getOperand(1).getReg() == AArch64::WZR))
return DestSourcePair{MI.getOperand(0), MI.getOperand(2)};
return std::nullopt;
}
diff --git a/llvm/test/CodeGen/AArch64/instr-ref-ldv.ll b/llvm/test/CodeGen/AArch64/instr-ref-ldv.ll
new file mode 100644
index 00000000000000..e41f4d62ac27ed
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/instr-ref-ldv.ll
@@ -0,0 +1,70 @@
+; RUN: llc -O2 -experimental-debug-variable-locations %s -stop-after=livedebugvalues -mtriple=arm64-apple-macosx15.0.0 -o - | FileCheck %s
+
+; CHECK: $w{{[0-9]+}} = ORRWrs $wzr, killed $w{{[0-9]+}}, 0
+; CHECK-NEXT: DBG_INSTR_REF !{{[0-9]+}}, !DIExpression(DW_OP_LLVM_arg, 0), dbg-instr-ref({{[0-9]+}}, 0), debug-location !{{[0-9]+}}
+
+; This test makes sure that instruction referenced livedebugvalues pass doesn't crash when an ORRWrr is present before
+; aarch64-isel and is converted to an ORRWrs with a shift amount immediate value of 0 before livedebugvalues, in this
+; test case the MIR before both passes is shown below:
+
+; Before aarch64-isel
+; %11:gpr32 = ORRWrr $wzr, killed %10:gpr32, debug-location !5; :0
+; %0:gpr64all = SUBREG_TO_REG 0, killed %11:gpr32, %subreg.sub_32, debug-location !5; :0
+; DBG_INSTR_REF !7, !DIExpression(DW_OP_LLVM_arg, 0), %0:gpr64all, debug-location !11; :0 @[ :0 ] line no:0
+
+; Before livedebugvalues
+; $w0 = ORRWrs $wzr, killed $w3, 0
+; DBG_INSTR_REF !7, !DIExpression(DW_OP_LLVM_arg, 0), dbg-instr-ref(3, 0), debug-location !11; :0 @[ :0 ] line no:0
+
+; The livedebugvalues pass will consider the ORRWrs variant as a copy, therefore the aarch64-isel call to
+; salvageCopySSA should do the same.
+
+%"class.llvm::iterator_range.53" = type { %"class.llvm::opt::arg_iterator.54", %"class.llvm::opt::arg_iterator.54" }
+%"class.llvm::opt::arg_iterator.54" = type { %"class.std::__1::reverse_iterator", %"class.std::__1::reverse_iterator", [2 x %"class.llvm::opt::OptSpecifier"] }
+%"class.std::__1::reverse_iterator" = type { ptr, ptr }
+%"class.llvm::opt::OptSpecifier" = type { i32 }
+declare noundef zeroext i1 @_ZNK4llvm3opt6Option7matchesENS0_12OptSpecifierE(ptr noundef nonnull align 8 dereferenceable(16), i64) local_unnamed_addr #1
+define noundef zeroext i1 @_ZNK4llvm3opt7ArgList14hasFlagNoClaimENS0_12OptSpecifierES2_b(ptr noundef nonnull align 8 dereferenceable(184) %this, i64 %Pos.coerce, i64 %Neg.coerce, i1 noundef zeroext %Default) local_unnamed_addr #2 !dbg !9383 {
+entry:
+ %ref.tmp.i = alloca %"class.llvm::iterator_range.53", align 8
+ %coerce.val.ii6 = and i64 %Pos.coerce, 4294967295, !dbg !9393
+ #dbg_value(i64 %coerce.val.ii6, !9452, !DIExpression(), !9480)
+ %__begin0.sroa.4.0.ref.tmp.sroa_idx.i = getelementptr inbounds i8, ptr %ref.tmp.i, i64 8, !dbg !9480
+ %__begin0.sroa.4.0.copyload.i = load ptr, ptr %__begin0.sroa.4.0.ref.tmp.sroa_idx.i, align 8, !dbg !9480
+ %__end0.sroa.4.0.end_iterator.i.sroa_idx.i = getelementptr inbounds i8, ptr %ref.tmp.i, i64 48, !dbg !9480
+ %__end0.sroa.4.0.copyload.i = load ptr, ptr %__end0.sroa.4.0.end_iterator.i.sroa_idx.i, align 8, !dbg !9480
+ %cmp.i.i.i.not.i = icmp eq ptr %__begin0.sroa.4.0.copyload.i, %__end0.sroa.4.0.copyload.i, !dbg !9480
+ br i1 %cmp.i.i.i.not.i, label %_ZNK4llvm3opt7ArgList17getLastArgNoClaimIJNS0_12OptSpecifierES3_EEEPNS0_3ArgEDpT_.exit.thread, label %_ZNK4llvm3opt7ArgList17getLastArgNoClaimIJNS0_12OptSpecifierES3_EEEPNS0_3ArgEDpT_.exit, !dbg !9480
+_ZNK4llvm3opt7ArgList17getLastArgNoClaimIJNS0_12OptSpecifierES3_EEEPNS0_3ArgEDpT_.exit.thread: ; preds = %entry
+ br label %1, !dbg !9480
+_ZNK4llvm3opt7ArgList17getLastArgNoClaimIJNS0_12OptSpecifierES3_EEEPNS0_3ArgEDpT_.exit: ; preds = %entry
+ %incdec.ptr.i.i.i = getelementptr inbounds i8, ptr %__begin0.sroa.4.0.copyload.i, i64 -8, !dbg !9480
+ %0 = load ptr, ptr %incdec.ptr.i.i.i, align 8, !dbg !9527, !tbaa !9528
+ %tobool.not.not = icmp eq ptr %0, null, !dbg !9480
+ br i1 %tobool.not.not, label %1, label %cleanup, !dbg !9480
+cleanup: ; preds = %_ZNK4llvm3opt7ArgList17getLastArgNoClaimIJNS0_12OptSpecifierES3_EEEPNS0_3ArgEDpT_.exit
+ %call13 = call noundef zeroext i1 @_ZNK4llvm3opt6Option7matchesENS0_12OptSpecifierE(ptr noundef nonnull align 8 dereferenceable(16) %0, i64 %coerce.val.ii6) #3, !dbg !9480
+ br label %1
+ %2 = phi i1 [ %call13, %cleanup ], [ %Default, %_ZNK4llvm3opt7ArgList17getLastArgNoClaimIJNS0_12OptSpecifierES3_EEEPNS0_3ArgEDpT_.exit ], [ %Default, %_ZNK4llvm3opt7ArgList17getLastArgNoClaimIJNS0_12OptSpecifierES3_EEEPNS0_3ArgEDpT_.exit.thread ]
+ ret i1 %2, !dbg !9480
+}
+!llvm.module.flags = !{!2, !6}
+ !llvm.dbg.cu = !{!7}
+ !2 = !{i32 2, !"Debug Info Version", i32 3}
+ !6 = !{i32 7, !"frame-pointer", i32 1}
+ !7 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !8, emissionKind: FullDebug, sdk: "MacOSX15.3.sdk")
+ !8 = !DIFile(filename: "/Users/shubhamrastogi/Development/llvm-project-instr-ref/llvm-project/llvm/lib/Option/ArgList.cpp", directory: "/Users/shubhamrastogi/Development/llvm-project-instr-ref/llvm-project/build-instr-ref-stage2", checksumkind: CSK_MD5, checksum: "a3198e8ace679c7b1581a26b5583c658")
+ !3116 = distinct !DICompositeType(tag: DW_TAG_class_type, size: 32)
+ !9383 = distinct !DISubprogram(unit: !7, flags: DIFlagArtificial | DIFlagObjectPointer)
+ !9391 = distinct !DILexicalBlock(scope: !9383, line: 80, column: 12)
+ !9393 = !DILocation(scope: !9391)
+ !9440 = distinct !DILexicalBlock(scope: !9441, line: 269, column: 5)
+ !9441 = distinct !DILexicalBlock(scope: !9442, line: 269, column: 5)
+ !9442 = distinct !DISubprogram(unit: !7, retainedNodes: !9450)
+ !9450 = !{}
+ !9452 = !DILocalVariable(scope: !9442, type: !3116)
+ !9478 = distinct !DILocation(scope: !9391)
+ !9480 = !DILocation(scope: !9441, inlinedAt: !9478)
+ !9527 = !DILocation(scope: !9440, inlinedAt: !9478)
+ !9528 = !{!"any pointer", !9530, i64 0}
+ !9530 = !{}
More information about the llvm-commits
mailing list