Skip to content

Commit 20f7f9d

Browse files
committed
[SROA] Fix DIOp-DIExpression fragment handling
Change-Id: If1f73e941c227d74ebe563c2857f5df2d60e9225
1 parent 6c88f4d commit 20f7f9d

File tree

3 files changed

+82
-12
lines changed

3 files changed

+82
-12
lines changed

llvm/lib/Transforms/Scalar/SROA.cpp

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5086,6 +5086,15 @@ static DIExpression *createOrReplaceFragment(const DIExpression *Expr,
50865086
bool HasFragment = false;
50875087
bool HasBitExtract = false;
50885088

5089+
if (auto NewElems = Expr->getNewElementsRef()) {
5090+
DIExprBuilder B(Expr->getContext());
5091+
for (DIOp::Variant Op : *NewElems)
5092+
if (!std::holds_alternative<DIOp::Fragment>(Op))
5093+
B.append(Op);
5094+
B.append<DIOp::Fragment>(Frag.OffsetInBits, Frag.SizeInBits);
5095+
return B.intoExpression();
5096+
}
5097+
50895098
for (auto &Op : Expr->expr_ops()) {
50905099
if (Op.getOp() == dwarf::DW_OP_LLVM_fragment) {
50915100
HasFragment = true;
@@ -5255,6 +5264,19 @@ insertNewDbgInst(DIBuilder &DIB, DbgVariableRecord *Orig, AllocaInst *NewAddr,
52555264
(void)NewAssign;
52565265
}
52575266

5267+
static bool isNoOffsetDIOpExpr(const DIExpression *Expr) {
5268+
auto OptNewOps = Expr->getNewElementsRef();
5269+
if (!OptNewOps)
5270+
return false;
5271+
5272+
ArrayRef<DIOp::Variant> NewOps = *OptNewOps;
5273+
if (!NewOps.empty() && std::holds_alternative<DIOp::Fragment>(NewOps.back()))
5274+
NewOps = NewOps.drop_back();
5275+
5276+
return NewOps.size() == 2 && std::holds_alternative<DIOp::Arg>(NewOps[0]) &&
5277+
std::holds_alternative<DIOp::Deref>(NewOps[1]);
5278+
}
5279+
52585280
/// Walks the slices of an alloca and form partitions based on them,
52595281
/// rewriting each of their uses.
52605282
bool SROA::splitAlloca(AllocaInst &AI, AllocaSlices &AS) {
@@ -5368,7 +5390,12 @@ bool SROA::splitAlloca(AllocaInst &AI, AllocaSlices &AS) {
53685390
// that come after it.
53695391
int64_t CurrentExprOffsetInBytes = 0;
53705392
SmallVector<uint64_t> PostOffsetOps;
5371-
if (!getAddressExpression(DbgVariable)
5393+
const DIExpression *NoOffsetDIOpExpr = nullptr;
5394+
if (isNoOffsetDIOpExpr(getAddressExpression(DbgVariable))) {
5395+
NoOffsetDIOpExpr = getAddressExpression(DbgVariable);
5396+
ArrayRef<uint64_t> PoisonElems = NoOffsetDIOpExpr->getElements();
5397+
PostOffsetOps.append(PoisonElems.begin(), PoisonElems.end());
5398+
} else if (!getAddressExpression(DbgVariable)
53725399
->extractLeadingOffset(CurrentExprOffsetInBytes, PostOffsetOps))
53735400
return; // Couldn't interpret this DIExpression - drop the var.
53745401

@@ -5429,6 +5456,8 @@ bool SROA::splitAlloca(AllocaInst &AI, AllocaSlices &AS) {
54295456
if (OffestFromNewAllocaInBits > 0) {
54305457
int64_t OffsetInBytes = (OffestFromNewAllocaInBits + 7) / 8;
54315458
NewExpr = DIExpression::prepend(NewExpr, /*flags=*/0, OffsetInBytes);
5459+
} else if (NoOffsetDIOpExpr && OffestFromNewAllocaInBits == 0) {
5460+
NewExpr = const_cast<DIExpression *>(NoOffsetDIOpExpr);
54325461
}
54335462

54345463
// Remove any existing intrinsics on the new alloca describing

llvm/lib/Transforms/Utils/Local.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2507,6 +2507,9 @@ static Value *salvageNewDebugInfo(Instruction &I, uint64_t CurrentLocOps,
25072507
auto &M = *I.getModule();
25082508
auto &DL = M.getDataLayout();
25092509

2510+
if (I.getType()->isVectorTy())
2511+
return nullptr;
2512+
25102513
if (auto *CI = dyn_cast<CastInst>(&I)) {
25112514
Value *FromValue = CI->getOperand(0);
25122515
Type *Type = CI->getType();

llvm/test/Transforms/SROA/heterogeneous-poison.ll

Lines changed: 49 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -55,11 +55,8 @@ join: ; preds = %else, %then
5555
define void @t3() !dbg !19 {
5656
; CHECK-LABEL: define void @t3(
5757
; CHECK-SAME: ) !dbg [[DBG19:![0-9]+]] {
58-
; FIXME(diexpression-poison): A rework of SROA debug-info handling which adds a
59-
; bespoke variant of DIExpression::createFragmentExpression (57539418bae45e3c972e8f4f0a88577f807e8697)
60-
; breaks the support we added for newops.
61-
; FIXME(diexpression-poison): #dbg_value(i32 42, [[META20:![0-9]+]], !DIExpression(DIOpArg(0, i32), DIOpFragment(0, 32)), [[META25:![0-9]+]])
62-
; FIXME(diexpression-poison): #dbg_value(i32 43, [[META20]], !DIExpression(DIOpArg(0, i32), DIOpFragment(32, 32)), [[META25]])
58+
; CHECK-NEXT: #dbg_value(i32 42, [[META20:![0-9]+]], !DIExpression(DIOpArg(0, i32), DIOpFragment(0, 32)), [[META25:![0-9]+]])
59+
; CHECK-NEXT: #dbg_value(i32 43, [[META20]], !DIExpression(DIOpArg(0, i32), DIOpFragment(32, 32)), [[META25]])
6360
; CHECK-NEXT: ret void
6461
;
6562
%local = alloca %struct.pair, align 4
@@ -124,6 +121,33 @@ join: ; preds = %else, %then
124121
ret i16 %loaded
125122
}
126123

124+
%struct.pair.pair = type { %struct.pair, %struct.pair }
125+
126+
define void @t6() !dbg !32 {
127+
; CHECK-LABEL: define void @t6(
128+
; CHECK-SAME: ) !dbg [[DBG32:![0-9]+]] {
129+
; CHECK-NEXT: #dbg_value(i32 0, [[META33:![0-9]+]], !DIExpression(DIOpArg(0, i32), DIOpFragment(0, 32)), [[META38:![0-9]+]])
130+
; CHECK-NEXT: #dbg_value(i32 1, [[META33]], !DIExpression(DIOpArg(0, i32), DIOpFragment(32, 32)), [[META38]])
131+
; CHECK-NEXT: #dbg_value(i32 2, [[META33]], !DIExpression(DIOpArg(0, i32), DIOpFragment(64, 32)), [[META38]])
132+
; CHECK-NEXT: #dbg_value(i32 3, [[META33]], !DIExpression(DIOpArg(0, i32), DIOpFragment(96, 32)), [[META38]])
133+
; CHECK-NEXT: ret void
134+
;
135+
136+
%first = alloca %struct.pair, align 4
137+
%second = alloca %struct.pair, align 4
138+
tail call void @llvm.dbg.declare(metadata ptr %first, metadata !37, metadata !DIExpression(DIOpArg(0, ptr), DIOpDeref(%struct.pair), DIOpFragment(0, 64))), !dbg !38
139+
tail call void @llvm.dbg.declare(metadata ptr %second, metadata !37, metadata !DIExpression(DIOpArg(0, ptr), DIOpDeref(%struct.pair), DIOpFragment(64, 64))), !dbg !38
140+
%f0_ptr = getelementptr inbounds %struct.pair, ptr %first, i32 0, i32 0
141+
store i32 0, ptr %f0_ptr, align 4
142+
%f1_ptr = getelementptr inbounds %struct.pair, ptr %first, i32 0, i32 1
143+
store i32 1, ptr %f1_ptr, align 4
144+
%f2_ptr = getelementptr inbounds %struct.pair, ptr %second, i32 0, i32 0
145+
store i32 2, ptr %f2_ptr, align 4
146+
%f3_ptr = getelementptr inbounds %struct.pair, ptr %second, i32 0, i32 1
147+
store i32 3, ptr %f3_ptr, align 4
148+
ret void
149+
}
150+
127151
; Function Attrs: nocallback nofree nosync nounwind speculatable willreturn memory(none)
128152
declare void @llvm.dbg.declare(metadata, metadata, metadata) #0
129153

@@ -168,6 +192,13 @@ attributes #0 = { nocallback nofree nosync nounwind speculatable willreturn memo
168192
!29 = distinct !DISubprogram(name: "t5", linkageName: "t5", scope: !1, file: !1, line: 7, type: !10, scopeLine: 7, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !12)
169193
!30 = !DILocalVariable(name: "local_i16", scope: !29, file: !1, line: 1, type: !14)
170194
!31 = !DILocation(line: 1, column: 1, scope: !29)
195+
!32 = distinct !DISubprogram(name: "t6", linkageName: "t56", scope: !1, file: !1, line: 7, type: !10, scopeLine: 7, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !12)
196+
!33 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "pair_pair", file: !1, line: 2, size: 128, flags: DIFlagTypePassByValue, elements: !36, identifier: "pair_pair")
197+
!34 = !DIDerivedType(tag: DW_TAG_member, name: "s1", scope: !33, file: !1, line: 3, baseType: !21, size: 64)
198+
!35 = !DIDerivedType(tag: DW_TAG_member, name: "s2", scope: !33, file: !1, line: 4, baseType: !21, size: 64, offset: 64)
199+
!36 = !{!34, !35}
200+
!37 = !DILocalVariable(name: "local", scope: !32, file: !1, line: 1, type: !33)
201+
!38 = !DILocation(line: 1, column: 1, scope: !32)
171202

172203
;.
173204
; CHECK: [[META0:![0-9]+]] = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: [[META1:![0-9]+]], producer: "clang 19", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None)
@@ -183,16 +214,23 @@ attributes #0 = { nocallback nofree nosync nounwind speculatable willreturn memo
183214
; CHECK: [[META17]] = !DILocalVariable(name: "local", scope: [[DBG16]], file: [[META1]], line: 1, type: [[META14]])
184215
; CHECK: [[META18]] = !DILocation(line: 0, scope: [[DBG16]])
185216
; CHECK: [[DBG19]] = distinct !DISubprogram(name: "t3", linkageName: "t3", scope: [[META1]], file: [[META1]], line: 7, type: [[META10]], scopeLine: 7, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: [[META0]], retainedNodes: [[META12]])
186-
; FIXME(diexpression-poison): [[META20]] = !DILocalVariable(name: "local", scope: [[DBG19]], file: [[META1]], line: 1, type: [[META21:![0-9]+]])
187-
; FIXME(diexpression-poison): [[META21]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "pair", file: [[META1]], line: 2, size: 64, flags: DIFlagTypePassByValue, elements: [[META22:![0-9]+]], identifier: "pair")
188-
; FIXME(diexpression-poison): [[META22]] = !{[[META23:![0-9]+]], [[META24:![0-9]+]]}
189-
; FIXME(diexpression-poison): [[META23]] = !DIDerivedType(tag: DW_TAG_member, name: "s1", scope: [[META21]], file: [[META1]], line: 3, baseType: [[META14]], size: 32)
190-
; FIXME(diexpression-poison): [[META24]] = !DIDerivedType(tag: DW_TAG_member, name: "s2", scope: [[META21]], file: [[META1]], line: 4, baseType: [[META14]], size: 32, offset: 32)
191-
; FIXME(diexpression-poison): [[META25]] = !DILocation(line: 0, scope: [[DBG19]])
217+
; CHECK: [[META20]] = !DILocalVariable(name: "local", scope: [[DBG19]], file: [[META1]], line: 1, type: [[META21:![0-9]+]])
218+
; CHECK: [[META21]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "pair", file: [[META1]], line: 2, size: 64, flags: DIFlagTypePassByValue, elements: [[META22:![0-9]+]], identifier: "pair")
219+
; CHECK: [[META22]] = !{[[META23:![0-9]+]], [[META24:![0-9]+]]}
220+
; CHECK: [[META23]] = !DIDerivedType(tag: DW_TAG_member, name: "s1", scope: [[META21]], file: [[META1]], line: 3, baseType: [[META14]], size: 32)
221+
; CHECK: [[META24]] = !DIDerivedType(tag: DW_TAG_member, name: "s2", scope: [[META21]], file: [[META1]], line: 4, baseType: [[META14]], size: 32, offset: 32)
222+
; CHECK: [[META25]] = !DILocation(line: 0, scope: [[DBG19]])
192223
; CHECK: [[DBG26]] = distinct !DISubprogram(name: "t4", linkageName: "t4", scope: [[META1]], file: [[META1]], line: 7, type: [[META10]], scopeLine: 7, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: [[META0]], retainedNodes: [[META12]])
193224
; CHECK: [[META27]] = !DILocalVariable(name: "local", scope: [[DBG26]], file: [[META1]], line: 1, type: [[META14]])
194225
; CHECK: [[META28]] = !DILocation(line: 1, column: 1, scope: [[DBG26]])
195226
; CHECK: [[DBG29]] = distinct !DISubprogram(name: "t5", linkageName: "t5", scope: [[META1]], file: [[META1]], line: 7, type: [[META10]], scopeLine: 7, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: [[META0]], retainedNodes: [[META12]])
196227
; CHECK: [[META30]] = !DILocalVariable(name: "local_i16", scope: [[DBG29]], file: [[META1]], line: 1, type: [[META14]])
197228
; CHECK: [[META31]] = !DILocation(line: 0, scope: [[DBG29]])
229+
; CHECK: [[DBG32]] = distinct !DISubprogram(name: "t6", linkageName: "t56", scope: [[META1]], file: [[META1]], line: 7, type: [[META10]], scopeLine: 7, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: [[META0]], retainedNodes: [[META12]])
230+
; CHECK: [[META33]] = !DILocalVariable(name: "local", scope: [[DBG32]], file: [[META1]], line: 1, type: [[META34:![0-9]+]])
231+
; CHECK: [[META34]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "pair_pair", file: [[META1]], line: 2, size: 128, flags: DIFlagTypePassByValue, elements: [[META35:![0-9]+]], identifier: "pair_pair")
232+
; CHECK: [[META35]] = !{[[META36:![0-9]+]], [[META37:![0-9]+]]}
233+
; CHECK: [[META36]] = !DIDerivedType(tag: DW_TAG_member, name: "s1", scope: [[META34]], file: [[META1]], line: 3, baseType: [[META21]], size: 64)
234+
; CHECK: [[META37]] = !DIDerivedType(tag: DW_TAG_member, name: "s2", scope: [[META34]], file: [[META1]], line: 4, baseType: [[META21]], size: 64, offset: 64)
235+
; CHECK: [[META38]] = !DILocation(line: 0, scope: [[DBG32]])
198236
;.

0 commit comments

Comments
 (0)