Skip to content

Commit ba43ee4

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 d4ce57c commit ba43ee4

File tree

2 files changed

+163
-0
lines changed

2 files changed

+163
-0
lines changed

llvm/lib/Target/AArch64/AArch64LoadStoreOptimizer.cpp

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -963,6 +963,43 @@ static void updateDefinedRegisters(MachineInstr &MI, LiveRegUnits &Units,
963963
Units.addReg(MOP.getReg());
964964
}
965965

966+
/// Find the DBG_INSTR_REF instruction that references the \p InstrNum
967+
static std::optional<MachineInstr *> findDebugInstrRef(MachineBasicBlock *MBB,
968+
unsigned InstrNum) {
969+
970+
for (auto &MI : *MBB) {
971+
if (MI.isDebugRef())
972+
if (MI.getOperand(2).getInstrRefInstrIndex() == InstrNum)
973+
return &MI;
974+
}
975+
return std::nullopt;
976+
}
977+
978+
/// Set the correct debug-instr-number and the operand index in case of a merge.
979+
static void setDebugInstrNum(MachineBasicBlock::iterator OriginalInstr,
980+
MachineInstrBuilder &MIB, unsigned InstrNumToFind,
981+
unsigned InstrNumToSet, MachineBasicBlock *MBB) {
982+
983+
auto InstrRefMI = findDebugInstrRef(MBB, InstrNumToFind);
984+
if (InstrRefMI) {
985+
auto *MI = *InstrRefMI;
986+
MI->getOperand(2).setInstrRefInstrIndex(InstrNumToSet);
987+
// Set the Instruction Reference Op Index to be the same as the operand of
988+
// the new merged pair instruction.
989+
auto Reg = OriginalInstr->getOperand(0).getReg();
990+
unsigned OperandNo = 0;
991+
for (auto Op : MIB->operands()) {
992+
if (OperandNo > 1)
993+
assert(false && "For a paired instruction, the operand number should "
994+
"always be 0 or 1");
995+
if (Op.getReg() == Reg)
996+
break;
997+
OperandNo++;
998+
}
999+
MI->getOperand(2).setInstrRefOpIndex(OperandNo);
1000+
}
1001+
}
1002+
9661003
MachineBasicBlock::iterator
9671004
AArch64LoadStoreOpt::mergePairedInsns(MachineBasicBlock::iterator I,
9681005
MachineBasicBlock::iterator Paired,
@@ -1225,9 +1262,56 @@ AArch64LoadStoreOpt::mergePairedInsns(MachineBasicBlock::iterator I,
12251262
.addImm(0)
12261263
.addImm(31);
12271264
(void)MIBSXTW;
1265+
1266+
if (I->peekDebugInstrNum()) {
1267+
auto InstrNum = I->peekDebugInstrNum();
1268+
// If I is the instruction which got sign extended, restore the debug
1269+
// instruction number from I to the SBFMXri instruction
1270+
if (DstRegX == I->getOperand(0).getReg())
1271+
MIBSXTW->setDebugInstrNum(InstrNum);
1272+
else {
1273+
MIB->setDebugInstrNum(InstrNum);
1274+
setDebugInstrNum(I, MIB, InstrNum, InstrNum, MBB);
1275+
}
1276+
}
1277+
if (Paired->peekDebugInstrNum()) {
1278+
auto InstrNum = Paired->peekDebugInstrNum();
1279+
// If Paired is the instruction which got sign extended, restore the debug
1280+
// instruction number from Paired to the SBFMXri instruction
1281+
if (DstRegX == Paired->getOperand(0).getReg())
1282+
MIBSXTW->setDebugInstrNum(InstrNum);
1283+
else {
1284+
MIB->setDebugInstrNum(InstrNum);
1285+
setDebugInstrNum(Paired, MIB, InstrNum, InstrNum, MBB);
1286+
}
1287+
}
1288+
12281289
LLVM_DEBUG(dbgs() << " Extend operand:\n ");
12291290
LLVM_DEBUG(((MachineInstr *)MIBSXTW)->print(dbgs()));
12301291
} else {
1292+
1293+
// Restore the debug instruction numbers to the merged instruction.
1294+
bool UseNewDebugInstrNum = false;
1295+
unsigned NewDebugInstrNum;
1296+
if (I->peekDebugInstrNum() && Paired->peekDebugInstrNum()) {
1297+
// Both instructions contain debug instruction numbers. We need to set a
1298+
// new instruction number for the paired instruction and update the
1299+
// DBG_INSTR_REFs that reference the instruction numbers of both
1300+
// instructions and update them.
1301+
NewDebugInstrNum = MIB->getDebugInstrNum();
1302+
UseNewDebugInstrNum = true;
1303+
}
1304+
if (I->peekDebugInstrNum())
1305+
setDebugInstrNum(
1306+
I, MIB, I->peekDebugInstrNum(),
1307+
UseNewDebugInstrNum ? NewDebugInstrNum : I->peekDebugInstrNum(), MBB);
1308+
1309+
if (Paired->peekDebugInstrNum())
1310+
setDebugInstrNum(Paired, MIB, Paired->peekDebugInstrNum(),
1311+
UseNewDebugInstrNum ? NewDebugInstrNum
1312+
: Paired->peekDebugInstrNum(),
1313+
MBB);
1314+
12311315
LLVM_DEBUG(((MachineInstr *)MIB)->print(dbgs()));
12321316
}
12331317
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)