Skip to content

Commit 75664e4

Browse files
[InstrRef] Preserve debug instr num in aarch64-ldst-opt.
The aarch64-ldst-opt pass tries to merge two load instructions (LDR*) to a load pair instruction (LDP*). When merging the instructions, there is a case where one of the loads would have to also be sign extended. In either case, (sign extend or not), the pass needs to preserve the debug-instr-number from the original loads to the load pair instruction to make sure debug info isn't loast in the case where instruction referencing is being used. This patch addresses that problem.
1 parent 08b4c52 commit 75664e4

File tree

2 files changed

+160
-0
lines changed

2 files changed

+160
-0
lines changed

llvm/lib/Target/AArch64/AArch64LoadStoreOptimizer.cpp

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -965,6 +965,40 @@ static void updateDefinedRegisters(MachineInstr &MI, LiveRegUnits &Units,
965965
Units.addReg(MOP.getReg());
966966
}
967967

968+
/// Find the DBG_INSTR_REF instruction that references the \p InstrNum
969+
static std::optional<MachineInstr *> findDebugInstrRef(MachineBasicBlock *MBB,
970+
unsigned InstrNum) {
971+
972+
for (auto &MI : *MBB) {
973+
if (MI.isDebugRef())
974+
if (MI.getOperand(2).getInstrRefInstrIndex() == InstrNum)
975+
return &MI;
976+
}
977+
return std::nullopt;
978+
}
979+
980+
/// Set the correct debug-instr-number and the operand index in case of a merge.
981+
static void setDebugInstrNum(MachineBasicBlock::iterator OriginalInstr,
982+
MachineInstrBuilder &MIB, unsigned InstrNumToFind,
983+
unsigned InstrNumToSet, MachineBasicBlock *MBB) {
984+
985+
auto InstrRefMI = findDebugInstrRef(MBB, InstrNumToFind);
986+
if (InstrRefMI) {
987+
auto *MI = *InstrRefMI;
988+
MI->getOperand(2).setInstrRefInstrIndex(InstrNumToSet);
989+
// Set the Instruction Reference Op Index to be the same as the operand of
990+
// the new merged pair instruction.
991+
auto Reg = OriginalInstr->getOperand(0).getReg();
992+
unsigned OperandNo = 0;
993+
for (auto Op : MIB->operands()) {
994+
if (Op.getReg() == Reg)
995+
break;
996+
OperandNo++;
997+
}
998+
MI->getOperand(2).setInstrRefOpIndex(OperandNo);
999+
}
1000+
}
1001+
9681002
MachineBasicBlock::iterator
9691003
AArch64LoadStoreOpt::mergePairedInsns(MachineBasicBlock::iterator I,
9701004
MachineBasicBlock::iterator Paired,
@@ -1227,6 +1261,30 @@ AArch64LoadStoreOpt::mergePairedInsns(MachineBasicBlock::iterator I,
12271261
.addImm(0)
12281262
.addImm(31);
12291263
(void)MIBSXTW;
1264+
1265+
if (I->peekDebugInstrNum()) {
1266+
auto InstrNum = I->peekDebugInstrNum();
1267+
// If I is the instruction which got sign extended, restore the debug
1268+
// instruction number from I to the SBFMXri instruction
1269+
if (DstRegX == I->getOperand(0).getReg())
1270+
MIBSXTW->setDebugInstrNum(InstrNum);
1271+
else {
1272+
MIB->setDebugInstrNum(InstrNum);
1273+
setDebugInstrNum(I, MIB, InstrNum, InstrNum, MBB);
1274+
}
1275+
}
1276+
if (Paired->peekDebugInstrNum()) {
1277+
auto InstrNum = Paired->peekDebugInstrNum();
1278+
// If Paired is the instruction which got sign extended, restore the debug
1279+
// instruction number from Paired to the SBFMXri instruction
1280+
if (DstRegX == Paired->getOperand(0).getReg())
1281+
MIBSXTW->setDebugInstrNum(InstrNum);
1282+
else {
1283+
MIB->setDebugInstrNum(InstrNum);
1284+
setDebugInstrNum(Paired, MIB, InstrNum, InstrNum, MBB);
1285+
}
1286+
}
1287+
12301288
LLVM_DEBUG(dbgs() << " Extend operand:\n ");
12311289
LLVM_DEBUG(((MachineInstr *)MIBSXTW)->print(dbgs()));
12321290
} else if (Opc == AArch64::LDR_ZXI || Opc == AArch64::STR_ZXI) {
@@ -1240,6 +1298,29 @@ AArch64LoadStoreOpt::mergePairedInsns(MachineBasicBlock::iterator I,
12401298
MOp1.setReg(AArch64::Q0 + (MOp1.getReg() - AArch64::Z0));
12411299
LLVM_DEBUG(((MachineInstr *)MIB)->print(dbgs()));
12421300
} else {
1301+
1302+
// Restore the debug instruction numbers to the merged instruction.
1303+
bool UseNewDebugInstrNum = false;
1304+
unsigned NewDebugInstrNum;
1305+
if (I->peekDebugInstrNum() && Paired->peekDebugInstrNum()) {
1306+
// Both instructions contain debug instruction numbers. We need to set a
1307+
// new instruction number for the paired instruction and update the
1308+
// DBG_INSTR_REFs that reference the instruction numbers of both
1309+
// instructions and update them.
1310+
NewDebugInstrNum = MIB->getDebugInstrNum();
1311+
UseNewDebugInstrNum = true;
1312+
}
1313+
if (I->peekDebugInstrNum())
1314+
setDebugInstrNum(
1315+
I, MIB, I->peekDebugInstrNum(),
1316+
UseNewDebugInstrNum ? NewDebugInstrNum : I->peekDebugInstrNum(), MBB);
1317+
1318+
if (Paired->peekDebugInstrNum())
1319+
setDebugInstrNum(Paired, MIB, Paired->peekDebugInstrNum(),
1320+
UseNewDebugInstrNum ? NewDebugInstrNum
1321+
: Paired->peekDebugInstrNum(),
1322+
MBB);
1323+
12431324
LLVM_DEBUG(((MachineInstr *)MIB)->print(dbgs()));
12441325
}
12451326
LLVM_DEBUG(dbgs() << "\n");
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
# RUN: llc -mtriple=aarch64-unknown-linux-gnu -o - %s -run-pass=aarch64-ldst-opt | FileCheck %s
2+
3+
# This testcase was obtained by looking at FileCheck.cpp and reducing it down via llvm-reduce
4+
5+
# The aarch64-ldst-opt pass tries to merge load instructions from LDR* to a load pair or LDP* instruction, in such a case, we must ensure that the debug-instr-number is properly preserved for instruction referencing.
6+
7+
# Check that in the case of a sign extend, the debug instruction number is transferred to the sign extend instruction (SBFMXri in this case), whereas the LDP instruction gets the other debug instruction number for the load that doesn't get sign extended.
8+
9+
# CHECK: $w[[REG1:[0-9]+]], renamable $w[[REG2:[0-9]+]] = LDPWi renamable ${{[a-z0-9]+}}, 0, debug-instr-number [[DBG_INSTR_NUM1:[0-9]+]]
10+
# CHECK-NEXT: $w[[REG1]] = KILL $w[[REG1]], implicit-def $x[[REG1]]
11+
# CHECK-NEXT: $x[[REG1]] = SBFMXri $x[[REG1]], 0, 31, debug-instr-number [[DBG_INSTR_NUM2:[0-9]+]]
12+
# CHECK-NEXT: DBG_INSTR_REF ![[DBG1:[0-9]+]], !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_fragment, 64, 64), dbg-instr-ref([[DBG_INSTR_NUM1]], 1), debug-location ![[DBG2:[0-9]+]]
13+
# CHECK-NEXT: DBG_INSTR_REF ![[DBG1]], !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_fragment, 64, 32), dbg-instr-ref([[DBG_INSTR_NUM2]], 0), debug-location ![[DBG2]]
14+
15+
# Check that in the case there is no sign extend, the LDP instruction gets a new debug instruction number and both the DBG_INSTR_REFs use the new instruction number.
16+
17+
# CHECK: renamable $x[[REG3:[0-9]+]], renamable $x[[REG4:[0-9]+]] = LDPXi renamable ${{[a-z0-9]+}}, 0, debug-instr-number [[DBG_INSTR_NUM3:[0-9]+]]
18+
# CHECK-NEXT: DBG_INSTR_REF ![[DBG3:[0-9]+]], !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_fragment, 64, 64), dbg-instr-ref([[DBG_INSTR_NUM3]], 1), debug-location ![[DBG4:[0-9]+]]
19+
# CHECK-NEXT: DBG_INSTR_REF ![[DBG3]], !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_fragment, 64, 32), dbg-instr-ref([[DBG_INSTR_NUM3]], 0), debug-location ![[DBG4]]
20+
21+
--- |
22+
define i64 @_ZNK4llvm9StringRef4sizeEv(ptr readonly captures(none) %this) local_unnamed_addr #0 {
23+
entry:
24+
%Length = getelementptr i8, ptr %this, i64 8
25+
%0 = load i64, ptr %Length, align 4
26+
ret i64 %0
27+
}
28+
define ptr @_ZNK4llvm9StringRef4dataEv(ptr readonly captures(none) %this) local_unnamed_addr #0 {
29+
entry:
30+
%0 = load ptr, ptr %this, align 8
31+
ret ptr %0
32+
}
33+
define void @_ZNK4llvm7Pattern5matchENS_9StringRefERKNS_9SourceMgrE(ptr readonly captures(none) %agg.result) local_unnamed_addr !dbg !3 {
34+
%call1541 = load volatile ptr, ptr null, align 4294967296, !dbg !9
35+
%FullMatch.sroa.1.0.agg.result.sroa_idx = getelementptr inbounds nuw i8, ptr %agg.result, i64 8
36+
ret void
37+
}
38+
define void @_ZNK4llvm7Pattern5matchENS_9StringRefERKNS_9SourceMgrE2(ptr readonly captures(none) %agg.result) local_unnamed_addr !dbg !10 {
39+
%call1541 = load volatile ptr, ptr null, align 4294967296, !dbg !11
40+
%FullMatch.sroa.1.0.agg.result.sroa_idx = getelementptr inbounds nuw i8, ptr %agg.result, i64 8
41+
ret void
42+
}
43+
!llvm.module.flags = !{!0}
44+
!llvm.dbg.cu = !{!1}
45+
!0 = !{i32 2, !"Debug Info Version", i32 3}
46+
!1 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !2, isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, sdk: "MacOSX15.3.sdk")
47+
!2 = !DIFile(filename: "/Users/shubhamrastogi/Development/llvm-project-instr-ref/llvm-project/llvm/lib/FileCheck/FileCheck.cpp", directory: "/Users/shubhamrastogi/Development/llvm-project-instr-ref/llvm-project/build-baseline-stage2", checksumkind: CSK_MD5, checksum: "ac1d2352ab68b965fe7993c780cf92d7")
48+
!3 = distinct !DISubprogram(scope: null, type: !4, spFlags: DISPFlagDefinition, unit: !1, retainedNodes: !6)
49+
!4 = distinct !DISubroutineType(types: !5)
50+
!5 = !{}
51+
!6 = !{!7}
52+
!7 = !DILocalVariable(name: "FullMatch", scope: !3, line: 1152, type: !8)
53+
!8 = distinct !DICompositeType(tag: DW_TAG_class_type, size: 128, identifier: "_ZTSN4llvm9StringRefE")
54+
!9 = !DILocation(line: 0, scope: !3)
55+
!10 = distinct !DISubprogram(scope: null, type: !4, spFlags: DISPFlagDefinition, unit: !1, retainedNodes: !12)
56+
!11 = !DILocation(line: 0, scope: !10)
57+
!12 = !{!13}
58+
!13 = !DILocalVariable(name: "FullMatch", scope: !10, line: 1152, type: !14)
59+
!14 = distinct !DICompositeType(tag: DW_TAG_class_type, size: 128, identifier: "_ZTSN4llvm9StringRefE")
60+
61+
name: _ZNK4llvm9StringRef4sizeEv
62+
---
63+
name: _ZNK4llvm9StringRef4dataEv
64+
...
65+
name: _ZNK4llvm7Pattern5matchENS_9StringRefERKNS_9SourceMgrE
66+
body: |
67+
bb.0 (%ir-block.0):
68+
renamable $w1 = LDRWui renamable $x0, 1, debug-instr-number 1 :: (load (s64) from %ir.FullMatch.sroa.1.0.agg.result.sroa_idx, align 1)
69+
DBG_INSTR_REF !7, !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_fragment, 64, 64), dbg-instr-ref(1, 0), debug-location !9
70+
renamable $x0 = LDRSWui killed renamable $x0, 0, debug-instr-number 2 :: (load (s64) from %ir.agg.result)
71+
DBG_INSTR_REF !7, !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_fragment, 64, 32), dbg-instr-ref(2, 0), debug-location !9
72+
...
73+
name: _ZNK4llvm7Pattern5matchENS_9StringRefERKNS_9SourceMgrE2
74+
body: |
75+
bb.0 (%ir-block.0):
76+
renamable $x1 = LDRXui renamable $x0, 1, debug-instr-number 1 :: (load (s64) from %ir.FullMatch.sroa.1.0.agg.result.sroa_idx, align 1)
77+
DBG_INSTR_REF !13, !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_fragment, 64, 64), dbg-instr-ref(1, 0), debug-location !11
78+
renamable $x0 = LDRXui killed renamable $x0, 0, debug-instr-number 2 :: (load (s64) from %ir.agg.result)
79+
DBG_INSTR_REF !13, !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_fragment, 64, 32), dbg-instr-ref(2, 0), debug-location !11

0 commit comments

Comments
 (0)