File: phi-coalescing.mir

package info (click to toggle)
llvm-toolchain-14 1%3A14.0.6-12
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 1,496,180 kB
  • sloc: cpp: 5,593,972; ansic: 986,872; asm: 585,869; python: 184,223; objc: 72,530; lisp: 31,119; f90: 27,793; javascript: 9,780; pascal: 9,762; sh: 9,482; perl: 7,468; ml: 5,432; awk: 3,523; makefile: 2,538; xml: 953; cs: 573; fortran: 567
file content (160 lines) | stat: -rw-r--r-- 7,522 bytes parent folder | download | duplicates (4)
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
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
# RUN: llc %s -o - -mtriple=x86_64-unknown-unknown \
# RUN:    -experimental-debug-variable-locations \
# RUN:    -run-pass=phi-node-elimination,simple-register-coalescing \
# RUN:    | FileCheck %s --check-prefix=DOESCOALESCE
# RUN: llc %s -o - -mtriple=x86_64-unknown-unknown \
# RUN:    -experimental-debug-variable-locations \
# RUN:    -run-pass=phi-node-elimination,simple-register-coalescing,livedebugvars,greedy,virtregrewriter \
# RUN:    | FileCheck %s --check-prefix=CHECK
#
# Test that a PHI with a debug instruction number attached survives register
# coalescing, when its vreg gets coalesced. This test comes in two parts, first
# that coalescing actually happens, second that a DBG_PHI is still produced
# afterwards.
#
# Original C code, the PHI is of the value of 'bar' after the control flow.
# Compiled at -O0, applied -mem2reg, llc -O0, then manually added the PHI
# instruction label. Additional variable locations removed.
#
#    void ext(long);
#    long getlong(void);
#    int foo(long bar, long baz) {
#      ext(bar);
#      bar += 12;
#      ext(bar);
#    
#      if (getlong())
#        bar += 1;
#    
#      bar += baz;
#      ext(bar);
#      return bar;
#    }
#
--- |
  ; ModuleID = 'promoted.ll'
  source_filename = "test.c"
  target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
  target triple = "x86_64-unknown-linux-gnu"
  
  define dso_local i32 @foo(i64 %bar, i64 %baz) !dbg !7 {
  entry:
    call void @llvm.dbg.value(metadata i64 %bar, metadata !12, metadata !DIExpression()), !dbg !13
    call void @llvm.dbg.value(metadata i64 %baz, metadata !14, metadata !DIExpression()), !dbg !13
    call void @ext(i64 %bar), !dbg !13
    %add = add nsw i64 %bar, 12, !dbg !13
    call void @llvm.dbg.value(metadata i64 %add, metadata !12, metadata !DIExpression()), !dbg !13
    call void @ext(i64 %add), !dbg !13
    %call = call i64 @getlong(), !dbg !13
    %tobool = icmp ne i64 %call, 0, !dbg !13
    br i1 %tobool, label %if.then, label %if.end, !dbg !13
  
  if.then:                                          ; preds = %entry
    %add1 = add nsw i64 %add, 1, !dbg !13
    call void @llvm.dbg.value(metadata i64 %add1, metadata !12, metadata !DIExpression()), !dbg !13
    br label %if.end, !dbg !13
  
  if.end:                                           ; preds = %if.then, %entry
    %bar.addr.0 = phi i64 [ %add1, %if.then ], [ %add, %entry ], !dbg !13
    call void @llvm.dbg.value(metadata i64 %bar.addr.0, metadata !12, metadata !DIExpression()), !dbg !13
    %add2 = add nsw i64 %bar.addr.0, %baz, !dbg !13
    call void @llvm.dbg.value(metadata i64 %add2, metadata !12, metadata !DIExpression()), !dbg !13
    call void @ext(i64 %add2), !dbg !13
    %conv = trunc i64 %add2 to i32, !dbg !13
    ret i32 %conv, !dbg !13
  }
  
  ; Function Attrs: nounwind readnone speculatable willreturn
  declare void @llvm.dbg.declare(metadata, metadata, metadata)
  
  declare dso_local void @ext(i64)
  
  declare dso_local i64 @getlong()
  
  ; Function Attrs: nounwind readnone speculatable willreturn
  declare void @llvm.dbg.value(metadata, metadata, metadata)
  
  !llvm.dbg.cu = !{!0}
  !llvm.module.flags = !{!3, !4, !5}
  !llvm.ident = !{!6}
  
  !0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, splitDebugInlining: false, nameTableKind: None)
  !1 = !DIFile(filename: "test.c", directory: "/tmp/out.c")
  !2 = !{}
  !3 = !{i32 7, !"Dwarf Version", i32 4}
  !4 = !{i32 2, !"Debug Info Version", i32 3}
  !5 = !{i32 1, !"wchar_size", i32 4}
  !6 = !{!""}
  !7 = distinct !DISubprogram(name: "foo", scope: !1, file: !1, line: 3, type: !8, scopeLine: 3, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !2)
  !8 = !DISubroutineType(types: !9)
  !9 = !{!10, !11, !11}
  !10 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
  !11 = !DIBasicType(name: "long int", size: 64, encoding: DW_ATE_signed)
  !12 = !DILocalVariable(name: "bar", arg: 1, scope: !7, file: !1, line: 3, type: !11)
  !13 = !DILocation(line: 0, scope: !7)
  !14 = !DILocalVariable(name: "baz", arg: 2, scope: !7, file: !1, line: 3, type: !11)
  !15 = distinct !DILexicalBlock(scope: !7, file: !1, line: 8, column: 7)

...
---
name:            foo
alignment:       16
tracksRegLiveness: true
liveins:
  - { reg: '$rdi', virtual-reg: '%3' }
  - { reg: '$rsi', virtual-reg: '%5' }
frameInfo:
  maxAlignment:    1
  hasCalls:        true
machineFunctionInfo: {}
body:             |
  bb.0.entry:
    liveins: $rdi, $rsi
  
    %5:gr64 = COPY $rsi
    %3:gr64 = COPY $rdi
    %4:gr64 = COPY killed %3
    %6:gr64 = COPY killed %5
    ADJCALLSTACKDOWN64 0, 0, 0, implicit-def $rsp, implicit-def $eflags, implicit-def $ssp, implicit $rsp, implicit $ssp, debug-location !13
    $rdi = COPY %4, debug-location !13
    CALL64pcrel32 @ext, csr_64, implicit $rsp, implicit $ssp, implicit $rdi, debug-location !13
    ADJCALLSTACKUP64 0, 0, implicit-def $rsp, implicit-def $eflags, implicit-def $ssp, implicit $rsp, implicit $ssp, debug-location !13
    %9:gr64 = ADD64ri32 %4, 12, implicit-def $eflags, debug-location !13
    ADJCALLSTACKDOWN64 0, 0, 0, implicit-def $rsp, implicit-def $eflags, implicit-def $ssp, implicit $rsp, implicit $ssp, debug-location !13
    $rdi = COPY %9, debug-location !13
    CALL64pcrel32 @ext, csr_64, implicit $rsp, implicit $ssp, implicit $rdi, debug-location !13
    ADJCALLSTACKUP64 0, 0, implicit-def $rsp, implicit-def $eflags, implicit-def $ssp, implicit $rsp, implicit $ssp, debug-location !13
    ADJCALLSTACKDOWN64 0, 0, 0, implicit-def $rsp, implicit-def $eflags, implicit-def $ssp, implicit $rsp, implicit $ssp, debug-location !13
    CALL64pcrel32 @getlong, csr_64, implicit $rsp, implicit $ssp, implicit-def $rax, debug-location !13
    ADJCALLSTACKUP64 0, 0, implicit-def $rsp, implicit-def $eflags, implicit-def $ssp, implicit $rsp, implicit $ssp, debug-location !13
    %8:gr64 = COPY $rax, debug-location !13
    CMP64ri8 %8, 0, implicit-def $eflags, debug-location !13
    JCC_1 %bb.2, 4, implicit $eflags, debug-location !13
  
  ; DOESCOALESCE-LABEL: bb.1.if.then:
  ; CHECK-LABEL:        bb.1.if.then:
  bb.1.if.then:
    %10:gr64 = ADD64ri32 %9, 1, implicit-def $eflags, debug-location !13

  ; Verify that the vreg is different immediately after register coalescing.
  ; DOESCOALESCE-NOT:   %10:gr64 ADD64ri32
  ; DOESCOALESCE:       %{{[0-9]+}}:gr64 = ADD64ri32
  ; Verify that all these registers land in rbx.
  ; CHECK:              renamable $rbx = ADD64ri32 killed renamable $rbx
  
  ; DOESCOALESCE-LABEL: bb.2.if.end:
  ; CHECK-LABEL:        bb.2.if.end:
  bb.2.if.end:
    %2:gr64 = PHI %9, %bb.0, %10, %bb.1, debug-instr-number 1, debug-location !13
  ; CHECK:              DBG_PHI $rbx, 1
    DBG_INSTR_REF 1, 0, !12, !DIExpression(), debug-location !13
    %14:gr64 = ADD64rr killed %2, %6, implicit-def $eflags, debug-location !13
    ADJCALLSTACKDOWN64 0, 0, 0, implicit-def $rsp, implicit-def $eflags, implicit-def $ssp, implicit $rsp, implicit $ssp, debug-location !13
    $rdi = COPY %14, debug-location !13
    CALL64pcrel32 @ext, csr_64, implicit $rsp, implicit $ssp, implicit $rdi, debug-location !13
    ADJCALLSTACKUP64 0, 0, implicit-def $rsp, implicit-def $eflags, implicit-def $ssp, implicit $rsp, implicit $ssp, debug-location !13
    %13:gr32 = COPY %14.sub_32bit, debug-location !13
    $eax = COPY %13, debug-location !13
    RET64 implicit $eax, debug-location !13

...