File: regcoalescing-clears-dead-dbgvals.mir

package info (click to toggle)
swiftlang 6.0.3-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,519,992 kB
  • sloc: cpp: 9,107,863; ansic: 2,040,022; asm: 1,135,751; python: 296,500; objc: 82,456; f90: 60,502; lisp: 34,951; pascal: 19,946; sh: 18,133; perl: 7,482; ml: 4,937; javascript: 4,117; makefile: 3,840; awk: 3,535; xml: 914; fortran: 619; cs: 573; ruby: 573
file content (145 lines) | stat: -rw-r--r-- 4,655 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
# RUN: llc -mtriple=x86_64-unknown-unknown %s -o - -run-pass=register-coalescer | FileCheck %s
# PR40010: DBG_VALUEs do not contribute to the liveness of virtual registers,
# and the register coalescer would merge new live values on top of DBG_VALUEs,
# leading to them presenting new (wrong) values to the debugger. Test that
# when out of liveness, coalescing will mark DBG_VALUEs in non-live locations
# as undef.
--- |
  ; ModuleID = './test.ll'
  source_filename = "./test.ll"
  target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"

  ; Function Attrs: nounwind readnone speculatable
  declare void @llvm.dbg.value(metadata, metadata, metadata) #0

  ; Original IR source here:
  define i32 @test(i32* %pin) {
  entry:
    br label %start.test1

  start.test1:                                       ; preds = %start, %entry
    %foo = phi i32 [ 0, %entry ], [ %bar, %start.test1 ]
    %baz = load i32, i32* %pin, align 1
    %qux = xor i32 %baz, 1234
    %bar = add i32 %qux, %foo
    call void @llvm.dbg.value(metadata i32 %foo, metadata !3, metadata !DIExpression()), !dbg !5
    %cmp = icmp ugt i32 %bar, 1000000
    br i1 %cmp, label %leave, label %start.test1

  leave:                                            ; preds = %start
    ret i32 %bar
  }

  ; Stubs to appease the MIR parser
  define i32 @test2(i32* %pin) {
  entry:
    ret i32 0
  start.test2:
    ret i32 0
  leave:
    ret i32 0
  }

  ; Function Attrs: nounwind
  declare void @llvm.stackprotector(i8*, i8**) #1

  attributes #0 = { nounwind readnone speculatable }
  attributes #1 = { nounwind }

  !llvm.module.flags = !{!0}
  !llvm.dbg.cu = !{!1}

  !0 = !{i32 2, !"Debug Info Version", i32 3}
  !1 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !2, producer: "beards", isOptimized: true, runtimeVersion: 4, emissionKind: FullDebug)
  !2 = !DIFile(filename: "bees.cpp", directory: "")
  !3 = !DILocalVariable(name: "bees", scope: !4)
  !4 = distinct !DISubprogram(name: "nope", scope: !1, file: !2, line: 1, spFlags: DISPFlagDefinition, unit: !1)
  !5 = !DILocation(line: 0, scope: !4)

...
---
name:            test
tracksRegLiveness: true
body:             |
  bb.0.entry:
    successors: %bb.1(0x80000000)
    liveins: $rdi

    %2:gr64 = COPY killed $rdi
    %3:gr32 = MOV32r0 implicit-def dead $eflags
    %4:gr32 = MOV32ri 1234
    %7:gr32 = COPY killed %3

  bb.1.start.test1:
    successors: %bb.2(0x04000000), %bb.1(0x7c000000)

    ; CHECK-LABEL: name: test
    ;
    ; We currently expect %1 and %0 to merge into %7
    ;
    ; CHECK: %[[REG1:[0-9]+]]:gr32 = MOV32rm
    ; CHECK-NEXT: %[[REG2:[0-9]+]]:gr32 = XOR32rr %[[REG1]]
    ; CHECK-NEXT: %[[REG3:[0-9]+]]:gr32 = ADD32rr %[[REG3]], %[[REG2]]
    ; CHECK-NEXT: DBG_VALUE $noreg

    %0:gr32 = COPY killed %7
    %8:gr32 = MOV32rm %2, 1, $noreg, 0, $noreg :: (load (s32) from %ir.pin, align 1)
    %5:gr32 = COPY killed %8
    %5:gr32 = XOR32rr %5, %4, implicit-def dead $eflags
    %1:gr32 = COPY killed %0
    %1:gr32 = ADD32rr %1, killed %5, implicit-def dead $eflags
    DBG_VALUE %0, $noreg, !3, !DIExpression(), debug-location !5
    CMP32ri %1, 1000001, implicit-def $eflags
    %7:gr32 = COPY %1
    JCC_1 %bb.1, 2, implicit killed $eflags
    JMP_1 %bb.2

  bb.2.leave:
    $eax = COPY killed %1
    RET 0, killed $eax

...
---
name:            test2
tracksRegLiveness: true
body:             |
  bb.0.entry:
    successors: %bb.1(0x80000000)
    liveins: $rdi

    %2:gr64 = COPY killed $rdi
    %3:gr32 = MOV32r0 implicit-def dead $eflags
    %4:gr32 = MOV32ri 1234
    %7:gr32 = COPY killed %3

  bb.1.start.test2:
    successors: %bb.2(0x04000000), %bb.1(0x7c000000)

    ; CHECK-LABEL: name: test2
    ;
    ; %0 should be merged into %7, but as %0 is live at this location the
    ; DBG_VALUE should be preserved and point at the operand of ADD32rr.
    ; RegisterCoalescer resolves %0 as CR_Erase: %0 is a redundant copy and
    ; can be erased.
    ;
    ; CHECK: %[[REG11:[0-9]+]]:gr32 = MOV32rm
    ; CHECK-NEXT: %[[REG12:[0-9]+]]:gr32 = XOR32rr %[[REG11]]
    ; CHECK-NEXT: DBG_VALUE %[[REG13:[0-9]+]]
    ; CHECK-NEXT: %[[REG13]]:gr32 = ADD32rr %[[REG13]], %[[REG12]]

    %0:gr32 = COPY killed %7
    %8:gr32 = MOV32rm %2, 1, $noreg, 0, $noreg :: (load (s32) from %ir.pin, align 1)
    %8:gr32 = XOR32rr %8, %4, implicit-def dead $eflags
    DBG_VALUE %0, $noreg, !3, !DIExpression(), debug-location !5
    %0:gr32 = ADD32rr %0, killed %8, implicit-def dead $eflags
    CMP32ri %0, 1000001, implicit-def $eflags
    %7:gr32 = COPY %0
    JCC_1 %bb.1, 2, implicit killed $eflags
    JMP_1 %bb.2

  bb.2.leave:
    $eax = COPY killed %7
    RET 0, killed $eax

...