Skip to content

Commit 8612417

Browse files
committed
[DebugInfo][InstrRef] Don't break up ret-sequences on debug-info instrs
When we have a terminator sequence (i.e. a tailcall or return), MIIsInTerminatorSequence is used to work out where the preceding ABI-setup instructions end, i.e. the parts that were glued to the terminator instruction. This allows LLVM to split blocks safely without having to worry about ABI stuff. The function only ignores DBG_VALUE instructions, meaning that the two debug instructions I recently added can end terminator sequences early, causing various MachineVerifier errors. This patch promotes the test for debug instructions from "isDebugValue" to "isDebugInstr", thus avoiding any debug-info interfering with this function. Differential Revision: https://reviews.llvm.org/D106660
1 parent 66ddac2 commit 8612417

File tree

2 files changed

+67
-1
lines changed

2 files changed

+67
-1
lines changed

llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1660,7 +1660,7 @@ static bool MIIsInTerminatorSequence(const MachineInstr &MI) {
16601660
// physical registers if there is debug info associated with the terminator
16611661
// of our mbb. We want to include said debug info in our terminator
16621662
// sequence, so we return true in that case.
1663-
return MI.isDebugValue();
1663+
return MI.isDebugInstr();
16641664

16651665
// We have left the terminator sequence if we are not doing one of the
16661666
// following:
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
; RUN: llc %s -o - -stop-after=finalize-isel -verify-machineinstrs -experimental-debug-variable-locations | FileCheck %s
2+
3+
; In the sequence below, the sdiv is converted to a function call to __divsi3,
4+
; which is then tail call optimised. The dbg.value is suddenly stuck between
5+
; terminators, and the corresponding DBG_INSTR_REF is forced-placed to be
6+
; immediately before the TCRETURN.
7+
; However, with the function having the sspstrong attribute, we then try to
8+
; peel apart the terminator sequence, DBG_INSTR_REF is interpreted as being
9+
; a "real" instruction, and the stack check is inserted at that point rather
10+
; than before the copies-to-physreg setting up the call. This breaks the
11+
; code, and MachineVerifier complains.
12+
;
13+
; Check that the tail sequence is stack-protected, and split at the correct
14+
; position, ignoring the DBG_INSTR_REF
15+
16+
target datalayout = "e-m:o-p:32:32-Fi8-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32"
17+
target triple = "thumbv7-apple-ios7.0.0"
18+
19+
; CHECK-LABEL: bb.0.entry:
20+
; CHECK: LOAD_STACK_GUARD
21+
22+
; CHECK-LABEL: bb.2.entry:
23+
; CHECK: tBL {{.*}} &__stack_chk_fail,
24+
25+
; CHECK-LABEL: bb.1.entry:
26+
; CHECK: $r0 = COPY %0
27+
; CHECK-NEXT: $r1 = COPY %1
28+
; CHECK-NEXT: DBG_INSTR_REF 1, 0
29+
; CHECK-NEXT: TCRETURNdi &__divsi3, 0, implicit $sp, implicit $r0, implicit $r1
30+
31+
declare i1 @ext()
32+
33+
define i32 @test(i32 %a1, i32 %a2) #1 !dbg !5 {
34+
entry:
35+
%foo = alloca i32, i32 %a1
36+
%bool = call i1 @ext()
37+
%res = sdiv i32 %a1, %a2
38+
call void @llvm.dbg.value(metadata i32 %a1, metadata !13, metadata !DIExpression()), !dbg !16
39+
ret i32 %res
40+
}
41+
42+
attributes #1 = {sspstrong}
43+
44+
; Function Attrs: nounwind readnone speculatable willreturn
45+
declare void @llvm.dbg.value(metadata, metadata, metadata)
46+
47+
!llvm.dbg.cu = !{!0}
48+
!llvm.module.flags = !{!3, !4}
49+
50+
!0 = distinct !DICompileUnit(language: DW_LANG_Swift, file: !1, producer: "Swift", isOptimized: true, runtimeVersion: 5, emissionKind: FullDebug)
51+
!1 = !DIFile(filename: "foo.swift", directory: "/tmp")
52+
!2 = !{}
53+
!3 = !{i32 2, !"Debug Info Version", i32 3}
54+
!4 = !{i32 1, !"Swift Minor Version", i8 3}
55+
!5 = distinct !DISubprogram(name: "n0", linkageName: "n1", scope: !7, file: !6, line: 86, type: !8, scopeLine: 86, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0)
56+
!6 = !DIFile(filename: "bar.swift", directory: "")
57+
!7 = !DIModule(scope: null, name: "Swift")
58+
!8 = !DISubroutineType(types: !9)
59+
!9 = !{!10, !12}
60+
!10 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "Int", scope: !7, file: !11, size: 32, elements: !2, runtimeLang: DW_LANG_Swift, identifier: "$i1")
61+
!11 = !DIFile(filename: "f1.swift", directory: "")
62+
!12 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "n2", scope: !7, file: !6, size: 32, elements: !2, runtimeLang: DW_LANG_Swift, identifier: "n3")
63+
!13 = !DILocalVariable(name: "n4", scope: !14, file: !1, line: 89, type: !15)
64+
!14 = distinct !DILexicalBlock(scope: !5, file: !6, line: 86, column: 34)
65+
!15 = !DIDerivedType(tag: DW_TAG_const_type, baseType: !10)
66+
!16 = !DILocation(line: 89, column: 9, scope: !14)

0 commit comments

Comments
 (0)