• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# RUN: llc -mtriple=x86_64-- -run-pass=peephole-opt -o - %s | FileCheck %s
2
3--- |
4  define i32 @foo(i32 %a) {
5  bb0:
6    br label %bb1
7
8  bb1:                                              ; preds = %bb7, %bb0
9    %vreg0 = phi i32 [ 0, %bb0 ], [ %vreg3, %bb7 ]
10    %cond0 = icmp eq i32 %a, 0
11    br i1 %cond0, label %bb4, label %bb3
12
13  bb3:                                              ; preds = %bb1
14    br label %bb4
15
16  bb4:                                              ; preds = %bb1, %bb3
17    %vreg5 = phi i32 [ 2, %bb3 ], [ 1, %bb1 ]
18    %cond1 = icmp eq i32 %vreg5, 0
19    br i1 %cond1, label %bb7, label %bb6
20
21  bb6:                                              ; preds = %bb4
22    br label %bb7
23
24  bb7:                                              ; preds = %bb4, %bb6
25    %vreg1 = phi i32 [ 2, %bb6 ], [ 1, %bb4 ]
26    %vreg2 = add i32 %vreg5, %vreg0
27    %vreg3 = add i32 %vreg1, %vreg2
28    %cond2 = icmp slt i32 %vreg3, 10
29    br i1 %cond2, label %bb1, label %bb8
30
31  bb8:                                              ; preds = %bb7
32    ret i32 0
33  }
34
35  define i32 @bar(i32 %a, i32* %p) {
36  bb0:
37    br label %bb1
38
39  bb1:                                              ; preds = %bb7, %bb0
40    %vreg0 = phi i32 [ 0, %bb0 ], [ %vreg3, %bb7 ]
41    %cond0 = icmp eq i32 %a, 0
42    br i1 %cond0, label %bb4, label %bb3
43
44  bb3:                                              ; preds = %bb1
45    br label %bb4
46
47  bb4:                                              ; preds = %bb1, %bb3
48    %vreg5 = phi i32 [ 2, %bb3 ], [ 1, %bb1 ]
49    %cond1 = icmp eq i32 %vreg5, 0
50    br i1 %cond1, label %bb7, label %bb6
51
52  bb6:                                              ; preds = %bb4
53    br label %bb7
54
55  bb7:                                              ; preds = %bb4, %bb6
56    %vreg1 = phi i32 [ 2, %bb6 ], [ 1, %bb4 ]
57    %vreg2 = add i32 %vreg5, %vreg0
58    store i32 %vreg0, i32* %p
59    %vreg3 = add i32 %vreg1, %vreg2
60    %cond2 = icmp slt i32 %vreg3, 10
61    br i1 %cond2, label %bb1, label %bb8
62
63  bb8:                                              ; preds = %bb7
64    ret i32 0
65  }
66
67...
68---
69# There is a recurrence formulated around %0, %10, and %3. Check that operands
70# are commuted for ADD instructions in bb.5.bb7 so that the values involved in
71# the recurrence are tied. This will remove redundant copy instruction.
72name:            foo
73tracksRegLiveness: true
74registers:
75  - { id: 0, class: gr32, preferred-register: '' }
76  - { id: 1, class: gr32, preferred-register: '' }
77  - { id: 2, class: gr32, preferred-register: '' }
78  - { id: 3, class: gr32, preferred-register: '' }
79  - { id: 4, class: gr32, preferred-register: '' }
80  - { id: 5, class: gr32, preferred-register: '' }
81  - { id: 6, class: gr32, preferred-register: '' }
82  - { id: 7, class: gr32, preferred-register: '' }
83  - { id: 8, class: gr32, preferred-register: '' }
84  - { id: 9, class: gr32, preferred-register: '' }
85  - { id: 10, class: gr32, preferred-register: '' }
86  - { id: 11, class: gr32, preferred-register: '' }
87  - { id: 12, class: gr32, preferred-register: '' }
88liveins:
89  - { reg: '$edi', virtual-reg: '%4' }
90body:             |
91  bb.0.bb0:
92    successors: %bb.1(0x80000000)
93    liveins: $edi
94
95    %4 = COPY $edi
96    %5 = MOV32r0 implicit-def dead $eflags
97
98  bb.1.bb1:
99    successors: %bb.3(0x30000000), %bb.2(0x50000000)
100
101    ; CHECK: %0:gr32 = PHI %5, %bb.0, %3, %bb.5
102    %0 = PHI %5, %bb.0, %3, %bb.5
103    %6 = MOV32ri 1
104    TEST32rr %4, %4, implicit-def $eflags
105    JCC_1 %bb.3, 4, implicit $eflags
106    JMP_1 %bb.2
107
108  bb.2.bb3:
109    successors: %bb.3(0x80000000)
110
111    %7 = MOV32ri 2
112
113  bb.3.bb4:
114    successors: %bb.5(0x30000000), %bb.4(0x50000000)
115
116    %1 = PHI %6, %bb.1, %7, %bb.2
117    TEST32rr %1, %1, implicit-def $eflags
118    JCC_1 %bb.5, 4, implicit $eflags
119    JMP_1 %bb.4
120
121  bb.4.bb6:
122    successors: %bb.5(0x80000000)
123
124    %9 = MOV32ri 2
125
126  bb.5.bb7:
127    successors: %bb.1(0x7c000000), %bb.6(0x04000000)
128
129    %2 = PHI %6, %bb.3, %9, %bb.4
130    %10 = ADD32rr %1, %0, implicit-def dead $eflags
131    ; CHECK: %10:gr32 = ADD32rr
132    ; CHECK-SAME: %0,
133    ; CHECK-SAME: %1,
134    %3 = ADD32rr %2, killed %10, implicit-def dead $eflags
135    ; CHECK: %3:gr32 = ADD32rr
136    ; CHECK-SAME: %10,
137    ; CHECK-SAME: %2,
138    %11 = SUB32ri8 %3, 10, implicit-def $eflags
139    JCC_1 %bb.1, 12, implicit $eflags
140    JMP_1 %bb.6
141
142  bb.6.bb8:
143    %12 = MOV32r0 implicit-def dead $eflags
144    $eax = COPY %12
145    RET 0, $eax
146
147...
148---
149# Here a recurrence is formulated around %0, %11, and %3, but operands should
150# not be commuted because %0 has a use outside of recurrence. This is to
151# prevent the case of commuting operands ties the values with overlapping live
152# ranges.
153name:            bar
154tracksRegLiveness: true
155registers:
156  - { id: 0, class: gr32, preferred-register: '' }
157  - { id: 1, class: gr32, preferred-register: '' }
158  - { id: 2, class: gr32, preferred-register: '' }
159  - { id: 3, class: gr32, preferred-register: '' }
160  - { id: 4, class: gr32, preferred-register: '' }
161  - { id: 5, class: gr64, preferred-register: '' }
162  - { id: 6, class: gr32, preferred-register: '' }
163  - { id: 7, class: gr32, preferred-register: '' }
164  - { id: 8, class: gr32, preferred-register: '' }
165  - { id: 9, class: gr32, preferred-register: '' }
166  - { id: 10, class: gr32, preferred-register: '' }
167  - { id: 11, class: gr32, preferred-register: '' }
168  - { id: 12, class: gr32, preferred-register: '' }
169  - { id: 13, class: gr32, preferred-register: '' }
170liveins:
171  - { reg: '$edi', virtual-reg: '%4' }
172  - { reg: '$rsi', virtual-reg: '%5' }
173body:             |
174  bb.0.bb0:
175    successors: %bb.1(0x80000000)
176    liveins: $edi, $rsi
177
178    %5 = COPY $rsi
179    %4 = COPY $edi
180    %6 = MOV32r0 implicit-def dead $eflags
181
182  bb.1.bb1:
183    successors: %bb.3(0x30000000), %bb.2(0x50000000)
184
185    %0 = PHI %6, %bb.0, %3, %bb.5
186    ; CHECK: %0:gr32 = PHI %6, %bb.0, %3, %bb.5
187    %7 = MOV32ri 1
188    TEST32rr %4, %4, implicit-def $eflags
189    JCC_1 %bb.3, 4, implicit $eflags
190    JMP_1 %bb.2
191
192  bb.2.bb3:
193    successors: %bb.3(0x80000000)
194
195    %8 = MOV32ri 2
196
197  bb.3.bb4:
198    successors: %bb.5(0x30000000), %bb.4(0x50000000)
199
200    %1 = PHI %7, %bb.1, %8, %bb.2
201    TEST32rr %1, %1, implicit-def $eflags
202    JCC_1 %bb.5, 4, implicit $eflags
203    JMP_1 %bb.4
204
205  bb.4.bb6:
206    successors: %bb.5(0x80000000)
207
208    %10 = MOV32ri 2
209
210  bb.5.bb7:
211    successors: %bb.1(0x7c000000), %bb.6(0x04000000)
212
213    %2 = PHI %7, %bb.3, %10, %bb.4
214    %11 = ADD32rr %1, %0, implicit-def dead $eflags
215    ; CHECK: %11:gr32 = ADD32rr
216    ; CHECK-SAME: %1,
217    ; CHECK-SAME: %0,
218    MOV32mr %5, 1, $noreg, 0, $noreg, %0 :: (store 4 into %ir.p)
219    %3 = ADD32rr %2, killed %11, implicit-def dead $eflags
220    ; CHECK: %3:gr32 = ADD32rr
221    ; CHECK-SAME: %2,
222    ; CHECK-SAME: %11,
223    %12 = SUB32ri8 %3, 10, implicit-def $eflags
224    JCC_1 %bb.1, 12, implicit $eflags
225    JMP_1 %bb.6
226
227  bb.6.bb8:
228    %13 = MOV32r0 implicit-def dead $eflags
229    $eax = COPY %13
230    RET 0, $eax
231
232...
233