diff --git a/llvm/lib/CodeGen/MachineSink.cpp b/llvm/lib/CodeGen/MachineSink.cpp index d0e119cb74706..9ed6b22eae972 100644 --- a/llvm/lib/CodeGen/MachineSink.cpp +++ b/llvm/lib/CodeGen/MachineSink.cpp @@ -510,30 +510,23 @@ bool MachineSinking::PerformSinkAndFold(MachineInstr &MI, LLVM_DEBUG(dbgs() << "Sinking copy of"; MI.dump(); dbgs() << "into"; SinkDst->dump()); if (SinkDst->isCopy()) { + // TODO: After performing the sink-and-fold, the original instruction is + // deleted. Its value is still available (in a hard register), so if there + // are debug instructions which refer to the (now deleted) virtual + // register they could be updated to refer to the hard register, in + // principle. However, it's not clear how to do that, moreover in some + // cases the debug instructions may need to be replicated proportionally + // to the number of the COPY instructions replaced and in some extreme + // cases we can end up with quadratic increase in the number of debug + // instructions. + // Sink a copy of the instruction, replacing a COPY instruction. MachineBasicBlock::iterator InsertPt = SinkDst->getIterator(); Register DstReg = SinkDst->getOperand(0).getReg(); TII->reMaterialize(*SinkDst->getParent(), InsertPt, DstReg, 0, MI, *TRI); - // If the original instruction did not have source location, reuse a one - // from the COPY. + // Reuse the source location from the COPY. New = &*std::prev(InsertPt); - if (const DebugLoc &NewLoc = New->getDebugLoc(); !NewLoc) - New->setDebugLoc(SinkDst->getDebugLoc()); - // Sink DBG_VALUEs, which refer to the original instruction's destination - // (DefReg). - MachineBasicBlock &SinkMBB = *SinkDst->getParent(); - auto &DbgUsers = SeenDbgUsers[DefReg]; - for (auto &U : DbgUsers) { - MachineInstr *DbgMI = U.getPointer(); - if (U.getInt()) - continue; - MachineInstr *NewDbgMI = SinkDst->getMF()->CloneMachineInstr(DbgMI); - SinkMBB.insertAfter(InsertPt, NewDbgMI); - for (auto &SrcMO : DbgMI->getDebugOperandsForReg(DefReg)) { - auto &DstMO = NewDbgMI->getOperand(SrcMO.getOperandNo()); - DstMO.setReg(DstReg); - } - } + New->setDebugLoc(SinkDst->getDebugLoc()); } else { // Fold instruction into the addressing mode of a memory instruction. New = TII->emitLdStWithAddr(*SinkDst, MaybeAM); diff --git a/llvm/test/CodeGen/AArch64/sink-and-fold-dbg-value-crash.mir b/llvm/test/CodeGen/AArch64/sink-and-fold-dbg-value-crash.mir deleted file mode 100644 index 82dae8a86ea2b..0000000000000 --- a/llvm/test/CodeGen/AArch64/sink-and-fold-dbg-value-crash.mir +++ /dev/null @@ -1,304 +0,0 @@ -# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 3 -# RUN: llc --aarch64-enable-sink-fold=true --run-pass=machine-sink %s -o - | FileCheck %s ---- | - source_filename = "x.ll" - target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128" - target triple = "aarch64-linux" - - %S = type <{ ptr, %T, i64, i64, i32, [4 x i8] }> - %T = type { ptr, ptr, ptr, ptr, i64 } - - define void @f(ptr %p, i1 %c0, i1 %c1) { - entry: - %a = getelementptr %S, ptr %p, i64 0, i32 1 - call void @llvm.dbg.value(metadata ptr %a, metadata !4, metadata !DIExpression()), !dbg !10 - br i1 %c0, label %if.then, label %if.end - - if.then: ; preds = %entry - %v0 = tail call ptr @g(ptr %a) - br i1 %c1, label %exit, label %if.end - - if.end: ; preds = %if.then, %entry - %v1 = load i64, ptr %a, align 8 - br label %exit - - exit: ; preds = %if.end, %if.then - ret void - } - - define ptr @g(ptr) { - entry: - br label %if.then - if.then: - br label %if.end - if.end: - br label %exit - exit: - ret ptr null - } - - declare void @llvm.dbg.value(metadata, metadata, metadata) #0 - - attributes #0 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) } - - !llvm.dbg.cu = !{!0} - !llvm.module.flags = !{!2, !3} - - !0 = distinct !DICompileUnit(language: DW_LANG_C11, file: !1, producer: "clang ", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None) - !1 = !DIFile(filename: "f.c", directory: "/usr/rms") - !2 = !{i32 7, !"Dwarf Version", i32 4} - !3 = !{i32 2, !"Debug Info Version", i32 3} - !4 = !DILocalVariable(name: "x", arg: 1, scope: !5, file: !1, line: 2, type: !8) - !5 = distinct !DISubprogram(name: "f", scope: !1, file: !1, line: 2, type: !6, scopeLine: 2, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !9) - !6 = !DISubroutineType(types: !7) - !7 = !{!8, !8} - !8 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) - !9 = !{} - !10 = !DILocation(line: 2, column: 11, scope: !5) - -... ---- -name: f -alignment: 4 -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: false -failsVerification: false -tracksDebugUserValues: false -registers: - - { id: 0, class: gpr64all, preferred-register: '' } - - { id: 1, class: gpr64common, preferred-register: '' } - - { id: 2, class: gpr32, preferred-register: '' } - - { id: 3, class: gpr32, preferred-register: '' } - - { id: 4, class: gpr32, preferred-register: '' } - - { id: 5, class: gpr64sp, preferred-register: '' } - - { id: 6, class: gpr64all, preferred-register: '' } -liveins: - - { reg: '$x0', virtual-reg: '%1' } - - { reg: '$w1', virtual-reg: '%2' } - - { reg: '$w2', virtual-reg: '%3' } -frameInfo: - isFrameAddressTaken: false - isReturnAddressTaken: false - hasStackMap: false - hasPatchPoint: false - stackSize: 0 - offsetAdjustment: 0 - maxAlignment: 1 - adjustsStack: true - hasCalls: true - stackProtector: '' - functionContext: '' - maxCallFrameSize: 0 - cvBytesOfCalleeSavedRegisters: 0 - hasOpaqueSPAdjustment: false - hasVAStart: false - hasMustTailInVarArgFunc: false - hasTailCall: false - localFrameSize: 0 - savePoint: '' - restorePoint: '' -fixedStack: [] -stack: [] -entry_values: [] -callSites: [] -debugValueSubstitutions: [] -constants: [] -machineFunctionInfo: {} -body: | - ; CHECK-LABEL: name: f - ; CHECK: bb.0.entry: - ; CHECK-NEXT: successors: %bb.1(0x40000000), %bb.2(0x40000000) - ; CHECK-NEXT: liveins: $x0, $w1, $w2 - ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr32 = COPY $w2 - ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr32 = COPY $w1 - ; CHECK-NEXT: [[COPY2:%[0-9]+]]:gpr64common = COPY $x0 - ; CHECK-NEXT: DBG_VALUE $noreg, $noreg, !4, !DIExpression(), debug-location !10 - ; CHECK-NEXT: TBZW [[COPY1]], 0, %bb.2 - ; CHECK-NEXT: B %bb.1 - ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: bb.1.if.then: - ; CHECK-NEXT: successors: %bb.3(0x40000000), %bb.2(0x40000000) - ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY3:%[0-9]+]]:gpr32 = COPY [[COPY]] - ; CHECK-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def dead $sp, implicit $sp - ; CHECK-NEXT: $x0 = ADDXri [[COPY2]], 8, 0 - ; CHECK-NEXT: DBG_VALUE $x0, $noreg, !4, !DIExpression(), debug-location !10 - ; CHECK-NEXT: BL @g, csr_aarch64_aapcs, implicit-def dead $lr, implicit $sp, implicit $x0, implicit-def $sp, implicit-def $x0 - ; CHECK-NEXT: ADJCALLSTACKUP 0, 0, implicit-def dead $sp, implicit $sp - ; CHECK-NEXT: TBNZW [[COPY3]], 0, %bb.3 - ; CHECK-NEXT: B %bb.2 - ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: bb.2.if.end: - ; CHECK-NEXT: successors: %bb.3(0x80000000) - ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: bb.3.exit: - ; CHECK-NEXT: RET_ReallyLR - bb.0.entry: - successors: %bb.1(0x40000000), %bb.2(0x40000000) - liveins: $x0, $w1, $w2 - - %3:gpr32 = COPY $w2 - %2:gpr32 = COPY $w1 - %1:gpr64common = COPY $x0 - %4:gpr32 = COPY %3 - %5:gpr64sp = ADDXri %1, 8, 0 - DBG_VALUE %5, $noreg, !4, !DIExpression(), debug-location !10 - %0:gpr64all = COPY %5 - TBZW %2, 0, %bb.2 - B %bb.1 - - bb.1.if.then: - successors: %bb.3(0x40000000), %bb.2(0x40000000) - - ADJCALLSTACKDOWN 0, 0, implicit-def dead $sp, implicit $sp - $x0 = COPY %0 - BL @g, csr_aarch64_aapcs, implicit-def dead $lr, implicit $sp, implicit $x0, implicit-def $sp, implicit-def $x0 - ADJCALLSTACKUP 0, 0, implicit-def dead $sp, implicit $sp - TBNZW %4, 0, %bb.3 - B %bb.2 - - bb.2.if.end: - successors: %bb.3(0x80000000) - - - bb.3.exit: - RET_ReallyLR - -... ---- -name: g -alignment: 4 -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: false -failsVerification: false -tracksDebugUserValues: false -registers: - - { id: 0, class: gpr64all, preferred-register: '' } - - { id: 1, class: gpr64common, preferred-register: '' } - - { id: 2, class: gpr32, preferred-register: '' } - - { id: 3, class: gpr32, preferred-register: '' } - - { id: 4, class: gpr32, preferred-register: '' } - - { id: 5, class: gpr64sp, preferred-register: '' } - - { id: 6, class: gpr64all, preferred-register: '' } -liveins: - - { reg: '$x0', virtual-reg: '%1' } - - { reg: '$w1', virtual-reg: '%2' } - - { reg: '$w2', virtual-reg: '%3' } -frameInfo: - isFrameAddressTaken: false - isReturnAddressTaken: false - hasStackMap: false - hasPatchPoint: false - stackSize: 0 - offsetAdjustment: 0 - maxAlignment: 1 - adjustsStack: true - hasCalls: true - stackProtector: '' - functionContext: '' - maxCallFrameSize: 0 - cvBytesOfCalleeSavedRegisters: 0 - hasOpaqueSPAdjustment: false - hasVAStart: false - hasMustTailInVarArgFunc: false - hasTailCall: false - localFrameSize: 0 - savePoint: '' - restorePoint: '' -fixedStack: [] -stack: [] -entry_values: [] -callSites: [] -debugValueSubstitutions: [] -constants: [] -machineFunctionInfo: {} -body: | - ; CHECK-LABEL: name: g - ; CHECK: bb.0.entry: - ; CHECK-NEXT: successors: %bb.1(0x40000000), %bb.2(0x40000000) - ; CHECK-NEXT: liveins: $x0, $w1, $w2 - ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr32 = COPY $w2 - ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr32 = COPY $w1 - ; CHECK-NEXT: [[COPY2:%[0-9]+]]:gpr64common = COPY $x0 - ; CHECK-NEXT: DBG_VALUE_LIST !4, !DIExpression(), [[COPY]], $noreg, debug-location !10 - ; CHECK-NEXT: TBZW [[COPY1]], 0, %bb.2 - ; CHECK-NEXT: B %bb.1 - ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: bb.1.if.then: - ; CHECK-NEXT: successors: %bb.3(0x40000000), %bb.2(0x40000000) - ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY3:%[0-9]+]]:gpr32 = COPY [[COPY]] - ; CHECK-NEXT: DBG_VALUE_LIST !4, !DIExpression(), [[COPY3]], $noreg, debug-location !10 - ; CHECK-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def dead $sp, implicit $sp - ; CHECK-NEXT: $x0 = ADDXri [[COPY2]], 8, 0 - ; CHECK-NEXT: DBG_VALUE_LIST !4, !DIExpression(), [[COPY3]], $x0, debug-location !10 - ; CHECK-NEXT: BL @g, csr_aarch64_aapcs, implicit-def dead $lr, implicit $sp, implicit $x0, implicit-def $sp, implicit-def $x0 - ; CHECK-NEXT: ADJCALLSTACKUP 0, 0, implicit-def dead $sp, implicit $sp - ; CHECK-NEXT: TBNZW [[COPY3]], 0, %bb.3 - ; CHECK-NEXT: B %bb.2 - ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: bb.2.if.end: - ; CHECK-NEXT: successors: %bb.3(0x80000000) - ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: bb.3.exit: - ; CHECK-NEXT: RET_ReallyLR - bb.0.entry: - successors: %bb.1(0x40000000), %bb.2(0x40000000) - liveins: $x0, $w1, $w2 - - %3:gpr32 = COPY $w2 - %2:gpr32 = COPY $w1 - %1:gpr64common = COPY $x0 - %4:gpr32 = COPY %3 - %5:gpr64sp = ADDXri %1, 8, 0 - DBG_VALUE_LIST !4, !DIExpression(), %4:gpr32, %5:gpr64sp, debug-location !10 - %0:gpr64all = COPY %5 - TBZW %2, 0, %bb.2 - B %bb.1 - - bb.1.if.then: - successors: %bb.3(0x40000000), %bb.2(0x40000000) - - ADJCALLSTACKDOWN 0, 0, implicit-def dead $sp, implicit $sp - $x0 = COPY %0 - BL @g, csr_aarch64_aapcs, implicit-def dead $lr, implicit $sp, implicit $x0, implicit-def $sp, implicit-def $x0 - ADJCALLSTACKUP 0, 0, implicit-def dead $sp, implicit $sp - TBNZW %4, 0, %bb.3 - B %bb.2 - - bb.2.if.end: - successors: %bb.3(0x80000000) - - - bb.3.exit: - RET_ReallyLR - -... diff --git a/llvm/test/CodeGen/AArch64/sink-and-fold-drop-dbg.mir b/llvm/test/CodeGen/AArch64/sink-and-fold-drop-dbg.mir new file mode 100644 index 0000000000000..3cf490474bdc4 --- /dev/null +++ b/llvm/test/CodeGen/AArch64/sink-and-fold-drop-dbg.mir @@ -0,0 +1,144 @@ +# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 3 +# RUN: llc --aarch64-enable-sink-fold=true --run-pass=machine-sink %s -o - | FileCheck %s +--- | + source_filename = "dbg.c" + target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128" + target triple = "aarch64-unknown-linux" + + define dso_local void @g(i32 noundef %x) local_unnamed_addr !dbg !11 { + entry: + call void @llvm.dbg.value(metadata i32 %x, metadata !16, metadata !DIExpression()), !dbg !20 + %add = add nsw i32 %x, 1, !dbg !21 + call void @llvm.dbg.value(metadata i32 %add, metadata !17, metadata !DIExpression()), !dbg !20 + call void @llvm.dbg.value(metadata i32 %add, metadata !18, metadata !DIExpression()), !dbg !20 + %call = tail call i32 @f(i32 noundef %add), !dbg !22 + call void @llvm.dbg.value(metadata i32 %add, metadata !19, metadata !DIExpression()), !dbg !20 + %call1 = tail call i32 @f(i32 noundef %add), !dbg !23 + ret void, !dbg !24 + } + + declare !dbg !25 i32 @f(i32 noundef) + + declare void @llvm.dbg.value(metadata, metadata, metadata) + + !llvm.dbg.cu = !{!0} + !llvm.module.flags = !{!2, !3, !4, !5, !6, !7, !8, !9} + !llvm.ident = !{!10} + + !0 = distinct !DICompileUnit(language: DW_LANG_C11, file: !1, producer: "clang version 18.0.0", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None) + !1 = !DIFile(filename: "dbg.c", directory: "/home/sweet", checksumkind: CSK_MD5, checksum: "b6bd7ad2140c696af9201a17ab73c918") + !2 = !{i32 7, !"Dwarf Version", i32 5} + !3 = !{i32 2, !"Debug Info Version", i32 3} + !4 = !{i32 1, !"wchar_size", i32 4} + !5 = !{i32 8, !"PIC Level", i32 2} + !6 = !{i32 7, !"PIE Level", i32 2} + !7 = !{i32 7, !"uwtable", i32 2} + !8 = !{i32 7, !"frame-pointer", i32 1} + !9 = !{i32 7, !"debug-info-assignment-tracking", i1 true} + !10 = !{!"clang version 18.0.0"} + !11 = distinct !DISubprogram(name: "g", scope: !1, file: !1, line: 3, type: !12, scopeLine: 3, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !15) + !12 = !DISubroutineType(types: !13) + !13 = !{null, !14} + !14 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) + !15 = !{!16, !17, !18, !19} + !16 = !DILocalVariable(name: "x", arg: 1, scope: !11, file: !1, line: 3, type: !14) + !17 = !DILocalVariable(name: "y", scope: !11, file: !1, line: 4, type: !14) + !18 = !DILocalVariable(name: "t0", scope: !11, file: !1, line: 6, type: !14) + !19 = !DILocalVariable(name: "t1", scope: !11, file: !1, line: 9, type: !14) + !20 = !DILocation(line: 0, scope: !11) + !21 = !DILocation(line: 4, column: 13, scope: !11) + !22 = !DILocation(line: 7, column: 3, scope: !11) + !23 = !DILocation(line: 10, column: 3, scope: !11) + !24 = !DILocation(line: 11, column: 1, scope: !11) + !25 = !DISubprogram(name: "f", scope: !1, file: !1, line: 1, type: !26, flags: DIFlagPrototyped, spFlags: DISPFlagOptimized) + !26 = !DISubroutineType(types: !27) + !27 = !{!14, !14} + +... +--- +name: g +alignment: 4 +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: false +failsVerification: false +tracksDebugUserValues: false +registers: + - { id: 0, class: gpr32common, preferred-register: '' } + - { id: 1, class: gpr32sp, preferred-register: '' } + - { id: 2, class: gpr32all, preferred-register: '' } +liveins: + - { reg: '$w0', virtual-reg: '%0' } +frameInfo: + isFrameAddressTaken: false + isReturnAddressTaken: false + hasStackMap: false + hasPatchPoint: false + stackSize: 0 + offsetAdjustment: 0 + maxAlignment: 1 + adjustsStack: true + hasCalls: true + stackProtector: '' + functionContext: '' + maxCallFrameSize: 0 + cvBytesOfCalleeSavedRegisters: 0 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false + hasTailCall: true + localFrameSize: 0 + savePoint: '' + restorePoint: '' +fixedStack: [] +stack: [] +entry_values: [] +callSites: [] +debugValueSubstitutions: [] +constants: [] +machineFunctionInfo: {} +body: | + bb.0.entry: + liveins: $w0 + + ; CHECK-LABEL: name: g + ; CHECK: liveins: $w0 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: DBG_VALUE $w0, $noreg, !16, !DIExpression(), debug-location !20 + ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr32common = COPY $w0 + ; CHECK-NEXT: DBG_VALUE [[COPY]], $noreg, !16, !DIExpression(), debug-location !20 + ; CHECK-NEXT: DBG_VALUE $noreg, $noreg, !17, !DIExpression(), debug-location !20 + ; CHECK-NEXT: DBG_VALUE $noreg, $noreg, !18, !DIExpression(), debug-location !20 + ; CHECK-NEXT: ADJCALLSTACKDOWN 0, 0, implicit-def dead $sp, implicit $sp, debug-location !22 + ; CHECK-NEXT: $w0 = nsw ADDWri [[COPY]], 1, 0, debug-location !22 + ; CHECK-NEXT: BL @f, csr_aarch64_aapcs, implicit-def dead $lr, implicit $sp, implicit $w0, implicit-def $sp, implicit-def $w0, debug-location !22 + ; CHECK-NEXT: ADJCALLSTACKUP 0, 0, implicit-def dead $sp, implicit $sp, debug-location !22 + ; CHECK-NEXT: DBG_VALUE $noreg, $noreg, !19, !DIExpression(), debug-location !20 + ; CHECK-NEXT: $w0 = nsw ADDWri [[COPY]], 1, 0, debug-location !23 + ; CHECK-NEXT: TCRETURNdi @f, 0, csr_aarch64_aapcs, implicit $sp, implicit $w0, debug-location !23 + DBG_VALUE $w0, $noreg, !16, !DIExpression(), debug-location !20 + %0:gpr32common = COPY $w0 + DBG_VALUE %0, $noreg, !16, !DIExpression(), debug-location !20 + %1:gpr32sp = nsw ADDWri %0, 1, 0, debug-location !21 + DBG_VALUE %1, $noreg, !17, !DIExpression(), debug-location !20 + DBG_VALUE %1, $noreg, !18, !DIExpression(), debug-location !20 + ADJCALLSTACKDOWN 0, 0, implicit-def dead $sp, implicit $sp, debug-location !22 + $w0 = COPY %1, debug-location !22 + BL @f, csr_aarch64_aapcs, implicit-def dead $lr, implicit $sp, implicit $w0, implicit-def $sp, implicit-def $w0, debug-location !22 + ADJCALLSTACKUP 0, 0, implicit-def dead $sp, implicit $sp, debug-location !22 + DBG_VALUE %1, $noreg, !19, !DIExpression(), debug-location !20 + $w0 = COPY %1, debug-location !23 + TCRETURNdi @f, 0, csr_aarch64_aapcs, implicit $sp, implicit $w0, debug-location !23 + +... diff --git a/llvm/test/DebugInfo/Generic/no-empty-child-vars.ll b/llvm/test/DebugInfo/Generic/no-empty-child-vars.ll index 1399b68b9b7f1..2b533968e3300 100644 --- a/llvm/test/DebugInfo/Generic/no-empty-child-vars.ll +++ b/llvm/test/DebugInfo/Generic/no-empty-child-vars.ll @@ -68,11 +68,14 @@ ; CHECK: DW_TAG_inlined_subroutine ; CHECK: NULL +; NOTE: Instructions below changed from `add` to `mul` to make them more expensive +; and unlikely to be sunk to replace COPYs into a return value register. + ; Function Attrs: norecurse nounwind readnone uwtable willreturn define dso_local i32 @foo(i32 %bar) local_unnamed_addr !dbg !7 { entry: call void @llvm.dbg.value(metadata i32 %bar, metadata !12, metadata !DIExpression()), !dbg !14 - %add = add nsw i32 %bar, 12, !dbg !15 + %add = mul nsw i32 %bar, 12, !dbg !15 call void @llvm.dbg.value(metadata i32 %add, metadata !13, metadata !DIExpression()), !dbg !14 ret i32 %add, !dbg !16 } @@ -80,7 +83,7 @@ entry: ; Function Attrs: norecurse nounwind readnone uwtable willreturn define dso_local i32 @qux(i32 %quux) local_unnamed_addr !dbg !17 { entry: - %add.i = add nsw i32 %quux, 12, !dbg !24 + %add.i = mul nsw i32 %quux, 12, !dbg !24 ret i32 %add.i, !dbg !25 } @@ -89,7 +92,7 @@ define dso_local i32 @croix(i32 %quux) local_unnamed_addr !dbg !26 { entry: call void @llvm.dbg.value(metadata i32 undef, metadata !28, metadata !DIExpression()), !dbg !30 call void @llvm.dbg.value(metadata i32 undef, metadata !12, metadata !DIExpression()), !dbg !31 - %add.i = add nsw i32 %quux, 12, !dbg !33 + %add.i = mul nsw i32 %quux, 12, !dbg !33 call void @llvm.dbg.value(metadata i32 undef, metadata !13, metadata !DIExpression()), !dbg !31 call void @llvm.dbg.value(metadata i32 undef, metadata !29, metadata !DIExpression()), !dbg !30 ret i32 %add.i, !dbg !34