xref: /llvm-project/llvm/test/DebugInfo/MIR/X86/machine-cse.mir (revision 1469d82e1cb3edc939d6b93089046edfef0cf36c)
1# RUN: llc %s -o - -run-pass=machine-cse -mtriple=x86_64-- | FileCheck %s
2# RUN: llc %s -o - -passes=machine-cse -mtriple=x86_64-- | FileCheck %s
3#
4# This test examines machine-cse's behaviour when dealing with copy propagation,
5# the code for which is lifted from test/CodeGen/X86/machine-cse.ll. There are
6# two (MIR) function that have SHL/LEA instructions CSE'd in the bb.1.bb1 block.
7# They both depend on the COPY of a vreg to %100 in the entry block.
8#
9# In the first (@t) there's only one use of %100, and that gets CSE'd away. The
10# corresponding COPY is deleted, and all DBG_VALUEs that refer to it must be
11# updated.
12#
13# In the second (@u) there are two uses of %100, one of which isn't deleted. The
14# DBG_VALUE users of %100 don't need to be updated -- test that they're not.
15--- |
16  target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
17  target triple = "x86_64-unknown-unknown"
18
19  %struct.s2 = type { i32, ptr, ptr, [256 x ptr], [8 x i32], i64, ptr, i32, i64, i64, i32, ptr, ptr, [49 x i64] }
20  %struct.s1 = type { %ptr, %ptr }
21  %ptr = type { ptr }
22  %struct.s3 = type { ptr, ptr, i32, i32, i32 }
23
24  ; Function Attrs: nounwind readnone speculatable
25  declare void @llvm.dbg.value(metadata, metadata, metadata) #0
26
27  define fastcc ptr @t(i32 %base, i1 %arg) !dbg !3 {
28  entry:
29    %0 = zext i32 %base to i64
30    %1 = getelementptr inbounds %struct.s2, ptr null, i64 %0
31    br i1 %arg, label %bb1, label %bb2
32
33  bb1:                                              ; preds = %entry
34    %2 = getelementptr inbounds %struct.s2, ptr null, i64 %0, i32 0
35    call void @llvm.dbg.value(metadata ptr %2, metadata !4, metadata !DIExpression()), !dbg !7
36    call void @bar(ptr %2)
37    unreachable
38
39  bb2:                                              ; preds = %entry
40    %3 = ptrtoint ptr %1 to i64
41    call void @baz(i64 %3)
42    unreachable
43  }
44
45  ; This is a stub replicating bb structure of @t
46  define fastcc ptr @u(i32 %base, i1 %arg) !dbg !33 {
47  entry:
48    br i1 %arg, label %bb1, label %bb2
49
50  bb1:                                              ; preds = %entry
51    unreachable
52
53  bb2:                                              ; preds = %entry
54    unreachable
55  }
56
57
58  declare void @bar(ptr)
59
60  declare void @baz(i64)
61
62  declare ptr @foo(ptr)
63
64  ; Function Attrs: nounwind
65  declare void @llvm.stackprotector(ptr, ptr) #1
66
67  attributes #0 = { nounwind readnone speculatable }
68  attributes #1 = { nounwind }
69
70  !llvm.module.flags = !{!0}
71  !llvm.dbg.cu = !{!1}
72
73  !0 = !{i32 2, !"Debug Info Version", i32 3}
74  !1 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !2, producer: "beards", isOptimized: true, runtimeVersion: 4, emissionKind: FullDebug)
75  !2 = !DIFile(filename: "bees.cpp", directory: "")
76  !3 = distinct !DISubprogram(name: "nope", scope: !1, file: !2, line: 1, spFlags: DISPFlagDefinition, unit: !1, retainedNodes: !8)
77  !33 = distinct !DISubprogram(name: "alsonope", scope: !1, file: !2, line: 1, spFlags: DISPFlagDefinition, unit: !1, retainedNodes: !8)
78  !4 = !DILocalVariable(name: "bees", scope: !3, type: !5)
79  !5 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !6, size: 64)
80  !6 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
81  !7 = !DILocation(line: 0, scope: !3)
82  !8 = !{!4}
83
84
85  ; CHECK: ![[METAVAR:[0-9]+]] = !DILocalVariable(name: "bees",
86
87...
88---
89name:            t
90# CHECK-LABEL: name: t
91tracksRegLiveness: true
92liveins:
93  - { reg: '$edi', virtual-reg: '%2' }
94frameInfo:
95  hasCalls:        true
96body:             |
97  bb.0.entry:
98    successors: %bb.1(0x40000000), %bb.2(0x40000000)
99    liveins: $edi
100
101    ; Capture vreg num for subreg move for later checks; test that the COPY
102    ; of that vreg is optimized out.
103    ; CHECK-LABEL: bb.0.entry:
104    ; CHECK:       %[[BASEVREG:[0-9]+]]:gr64 = SUBREG_TO_REG
105    ; CHECK-NOT:   COPY %[[BASEVREG]]:gr64
106
107    %2:gr32 = COPY $edi
108    %3:gr32 = MOV32rr %2
109    %0:gr64 = SUBREG_TO_REG 0, killed %3, %subreg.sub_32bit
110    %4:gr64_nosp = SHL64ri %0, 9, implicit-def dead $eflags
111    %1:gr64 = LEA64r %4, 4, %4, 0, $noreg
112    %5:gr32 = MOV32r0 implicit-def dead $eflags
113    %6:gr8 = COPY %5.sub_8bit
114    %100:gr64 = COPY %0:gr64
115    TEST8rr %6, %6, implicit-def $eflags
116    JCC_1 %bb.2, 5, implicit $eflags
117    JMP_1 %bb.1
118
119  bb.1.bb1:
120    successors:
121
122    ; Check for CSE happening and DBG_VALUE updating.
123    ; CHECK-LABEL: bb.1.bb1:
124    ; CHECK-NOT:   SHL64ri
125    ; CHECK-NOT:   LEA64r
126    ; CHECK:       DBG_VALUE %[[BASEVREG]], $noreg, ![[METAVAR]],
127    ; CHECK-NEXT:  ADJCALLSTACKDOWN64
128
129    %7:gr64_nosp = SHL64ri %100, 9, implicit-def dead $eflags
130    %8:gr64 = LEA64r %7, 4, %7, 0, $noreg
131    DBG_VALUE %100, $noreg, !4, !DIExpression(), debug-location !7
132    ADJCALLSTACKDOWN64 0, 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
133    $rdi = COPY %8
134    CALL64pcrel32 @bar, csr_64, implicit $rsp, implicit $ssp, implicit $rdi, implicit-def $rsp, implicit-def $ssp
135    ADJCALLSTACKUP64 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
136
137  bb.2.bb2:
138    ; As the COPY to %100 dies, the DBG_VALUE below should be updated too.
139    ; CHECK-LABEL: bb.2.bb2:
140    ; CHECK:       ADJCALLSTACKDOWN64
141    ; CHECK-NEXT:  $rdi = COPY
142    ; CHECK-NEXT:  DBG_VALUE %[[BASEVREG]], $noreg, ![[METAVAR]],
143    ; CHECK-NEXT:  CALL64pcrel32
144
145    ADJCALLSTACKDOWN64 0, 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
146    $rdi = COPY %1
147    DBG_VALUE %100, $noreg, !4, !DIExpression(), debug-location !7
148    CALL64pcrel32 @baz, csr_64, implicit $rsp, implicit $ssp, implicit $rdi, implicit-def $rsp, implicit-def $ssp
149    ADJCALLSTACKUP64 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
150
151...
152---
153name:            u
154# CHECK-LABEL: name: u
155tracksRegLiveness: true
156liveins:
157  - { reg: '$edi', virtual-reg: '%2' }
158frameInfo:
159  hasCalls:        true
160body:             |
161  bb.0.entry:
162    successors: %bb.1(0x40000000), %bb.2(0x40000000)
163    liveins: $edi
164
165    ; In this function, the COPY to %100 should not be optimized out, and as a
166    ; result the DBG_VALUEs should not be rewritten.
167    ; CHECK-LABEL: bb.0.entry:
168    ; CHECK:       %[[BASEVREG:[0-9]+]]:gr64 = SUBREG_TO_REG
169    ; CHECK:       %[[COPIEDVREG:[0-9]+]]:gr64 = COPY %[[BASEVREG]]
170
171    %2:gr32 = COPY $edi
172    %3:gr32 = MOV32rr %2
173    %0:gr64 = SUBREG_TO_REG 0, killed %3, %subreg.sub_32bit
174    %4:gr64_nosp = SHL64ri %0, 9, implicit-def dead $eflags
175    %1:gr64 = LEA64r %4, 4, %4, 0, $noreg
176    %5:gr32 = MOV32r0 implicit-def dead $eflags
177    %6:gr8 = COPY %5.sub_8bit
178    %100:gr64 = COPY %0:gr64
179    TEST8rr %6, %6, implicit-def $eflags
180    JCC_1 %bb.2, 5, implicit $eflags
181    JMP_1 %bb.1
182
183  bb.1.bb1:
184    successors:
185
186    ; CSE should happen, DBG_VALUE updating should not.
187    ; CHECK-LABEL: bb.1.bb1:
188    ; CHECK-NOT:   SHL64ri
189    ; CHECK-NOT:   LEA64r
190    ; CHECK:       DBG_VALUE %[[COPIEDVREG]], $noreg, ![[METAVAR]],
191    ; CHECK-NEXT:  ADJCALLSTACKDOWN64
192
193
194
195    %7:gr64_nosp = SHL64ri %100, 9, implicit-def dead $eflags
196    %8:gr64 = LEA64r %7, 4, %7, 0, $noreg
197    DBG_VALUE %100, $noreg, !4, !DIExpression(), debug-location !7
198    ADJCALLSTACKDOWN64 0, 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
199    $rdi = COPY %8
200    CALL64pcrel32 @bar, csr_64, implicit $rsp, implicit $ssp, implicit $rdi, implicit-def $rsp, implicit-def $ssp
201    ADJCALLSTACKUP64 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
202
203  bb.2.bb2:
204
205    ; Test that the copy-read of %100 below is preserved, and the DBG_VALUE
206    ; operand is too.
207    ; CHECK-LABEL: bb.2.bb2:
208    ; CHECK:       ADJCALLSTACKDOWN64
209    ; CHECK-NEXT:  $rdi = COPY %[[COPIEDVREG]]
210    ; CHECK-NEXT:  DBG_VALUE %[[COPIEDVREG]], $noreg, ![[METAVAR]],
211    ; CHECK-NEXT:  CALL64pcrel32
212
213    ADJCALLSTACKDOWN64 0, 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
214    $rdi = COPY %100
215    DBG_VALUE %100, $noreg, !4, !DIExpression(), debug-location !7
216    CALL64pcrel32 @baz, csr_64, implicit $rsp, implicit $ssp, implicit $rdi, implicit-def $rsp, implicit-def $ssp
217    ADJCALLSTACKUP64 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
218
219...
220