1
2
3
4
5 package ssa
6
7 import (
8 "cmd/compile/internal/types"
9 "cmd/internal/obj/x86"
10 "fmt"
11 "testing"
12 )
13
14 func TestLiveControlOps(t *testing.T) {
15 c := testConfig(t)
16 f := c.Fun("entry",
17 Bloc("entry",
18 Valu("mem", OpInitMem, types.TypeMem, 0, nil),
19 Valu("x", OpAMD64MOVLconst, c.config.Types.Int8, 1, nil),
20 Valu("y", OpAMD64MOVLconst, c.config.Types.Int8, 2, nil),
21 Valu("a", OpAMD64TESTB, types.TypeFlags, 0, nil, "x", "y"),
22 Valu("b", OpAMD64TESTB, types.TypeFlags, 0, nil, "y", "x"),
23 Eq("a", "if", "exit"),
24 ),
25 Bloc("if",
26 Eq("b", "plain", "exit"),
27 ),
28 Bloc("plain",
29 Goto("exit"),
30 ),
31 Bloc("exit",
32 Exit("mem"),
33 ),
34 )
35 flagalloc(f.f)
36 regalloc(f.f)
37 checkFunc(f.f)
38 }
39
40
41
42 func TestNoGetgLoadReg(t *testing.T) {
43
53 c := testConfigARM64(t)
54 f := c.Fun("b1",
55 Bloc("b1",
56 Valu("v1", OpInitMem, types.TypeMem, 0, nil),
57 Valu("v6", OpArg, c.config.Types.Int64, 0, c.Temp(c.config.Types.Int64)),
58 Valu("v8", OpGetG, c.config.Types.Int64.PtrTo(), 0, nil, "v1"),
59 Valu("v11", OpARM64CMPconst, types.TypeFlags, 0, nil, "v6"),
60 Eq("v11", "b2", "b4"),
61 ),
62 Bloc("b4",
63 Goto("b3"),
64 ),
65 Bloc("b3",
66 Valu("v14", OpPhi, types.TypeMem, 0, nil, "v1", "v12"),
67 Valu("sb", OpSB, c.config.Types.Uintptr, 0, nil),
68 Valu("v16", OpARM64MOVDstore, types.TypeMem, 0, nil, "v8", "sb", "v14"),
69 Exit("v16"),
70 ),
71 Bloc("b2",
72 Valu("v12", OpARM64CALLstatic, types.TypeMem, 0, AuxCallLSym("_"), "v1"),
73 Goto("b3"),
74 ),
75 )
76 regalloc(f.f)
77 checkFunc(f.f)
78
79 r := f.f.RegAlloc
80 for _, b := range f.blocks {
81 for _, v := range b.Values {
82 if v.Op == OpLoadReg && r[v.ID].String() == "g" {
83 t.Errorf("Saw OpLoadReg targeting g register: %s", v.LongString())
84 }
85 }
86 }
87 }
88
89
90
91 func TestSpillWithLoop(t *testing.T) {
92 c := testConfig(t)
93 f := c.Fun("entry",
94 Bloc("entry",
95 Valu("mem", OpInitMem, types.TypeMem, 0, nil),
96 Valu("ptr", OpArg, c.config.Types.Int64.PtrTo(), 0, c.Temp(c.config.Types.Int64)),
97 Valu("cond", OpArg, c.config.Types.Bool, 0, c.Temp(c.config.Types.Bool)),
98 Valu("ld", OpAMD64MOVQload, c.config.Types.Int64, 0, nil, "ptr", "mem"),
99 Goto("loop"),
100 ),
101 Bloc("loop",
102 Valu("memphi", OpPhi, types.TypeMem, 0, nil, "mem", "call"),
103 Valu("call", OpAMD64CALLstatic, types.TypeMem, 0, AuxCallLSym("_"), "memphi"),
104 Valu("test", OpAMD64CMPBconst, types.TypeFlags, 0, nil, "cond"),
105 Eq("test", "next", "exit"),
106 ),
107 Bloc("next",
108 Goto("loop"),
109 ),
110 Bloc("exit",
111 Valu("store", OpAMD64MOVQstore, types.TypeMem, 0, nil, "ptr", "ld", "call"),
112 Exit("store"),
113 ),
114 )
115 regalloc(f.f)
116 checkFunc(f.f)
117 for _, v := range f.blocks["loop"].Values {
118 if v.Op == OpStoreReg {
119 t.Errorf("spill inside loop %s", v.LongString())
120 }
121 }
122 }
123
124 func TestSpillMove1(t *testing.T) {
125 c := testConfig(t)
126 f := c.Fun("entry",
127 Bloc("entry",
128 Valu("mem", OpInitMem, types.TypeMem, 0, nil),
129 Valu("x", OpArg, c.config.Types.Int64, 0, c.Temp(c.config.Types.Int64)),
130 Valu("p", OpArg, c.config.Types.Int64.PtrTo(), 0, c.Temp(c.config.Types.Int64.PtrTo())),
131 Valu("a", OpAMD64TESTQ, types.TypeFlags, 0, nil, "x", "x"),
132 Goto("loop1"),
133 ),
134 Bloc("loop1",
135 Valu("y", OpAMD64MULQ, c.config.Types.Int64, 0, nil, "x", "x"),
136 Eq("a", "loop2", "exit1"),
137 ),
138 Bloc("loop2",
139 Eq("a", "loop1", "exit2"),
140 ),
141 Bloc("exit1",
142
143 Valu("mem2", OpAMD64MOVQstore, types.TypeMem, 0, nil, "p", "y", "mem"),
144 Valu("mem3", OpAMD64CALLstatic, types.TypeMem, 0, AuxCallLSym("_"), "mem2"),
145 Exit("mem3"),
146 ),
147 Bloc("exit2",
148
149 Valu("mem4", OpAMD64CALLstatic, types.TypeMem, 0, AuxCallLSym("_"), "mem"),
150 Valu("mem5", OpAMD64MOVQstore, types.TypeMem, 0, nil, "p", "y", "mem4"),
151 Exit("mem5"),
152 ),
153 )
154 flagalloc(f.f)
155 regalloc(f.f)
156 checkFunc(f.f)
157
158 if numSpills(f.blocks["loop1"]) != 0 {
159 t.Errorf("spill present from loop1")
160 }
161 if numSpills(f.blocks["loop2"]) != 0 {
162 t.Errorf("spill present in loop2")
163 }
164 if numSpills(f.blocks["exit1"]) != 0 {
165 t.Errorf("spill present in exit1")
166 }
167 if numSpills(f.blocks["exit2"]) != 1 {
168 t.Errorf("spill missing in exit2")
169 }
170
171 }
172
173 func TestSpillMove2(t *testing.T) {
174 c := testConfig(t)
175 f := c.Fun("entry",
176 Bloc("entry",
177 Valu("mem", OpInitMem, types.TypeMem, 0, nil),
178 Valu("x", OpArg, c.config.Types.Int64, 0, c.Temp(c.config.Types.Int64)),
179 Valu("p", OpArg, c.config.Types.Int64.PtrTo(), 0, c.Temp(c.config.Types.Int64.PtrTo())),
180 Valu("a", OpAMD64TESTQ, types.TypeFlags, 0, nil, "x", "x"),
181 Goto("loop1"),
182 ),
183 Bloc("loop1",
184 Valu("y", OpAMD64MULQ, c.config.Types.Int64, 0, nil, "x", "x"),
185 Eq("a", "loop2", "exit1"),
186 ),
187 Bloc("loop2",
188 Eq("a", "loop1", "exit2"),
189 ),
190 Bloc("exit1",
191
192 Valu("mem2", OpAMD64CALLstatic, types.TypeMem, 0, AuxCallLSym("_"), "mem"),
193 Valu("mem3", OpAMD64MOVQstore, types.TypeMem, 0, nil, "p", "y", "mem2"),
194 Exit("mem3"),
195 ),
196 Bloc("exit2",
197
198 Valu("mem4", OpAMD64CALLstatic, types.TypeMem, 0, AuxCallLSym("_"), "mem"),
199 Valu("mem5", OpAMD64MOVQstore, types.TypeMem, 0, nil, "p", "y", "mem4"),
200 Exit("mem5"),
201 ),
202 )
203 flagalloc(f.f)
204 regalloc(f.f)
205 checkFunc(f.f)
206
207
208 if numSpills(f.blocks["loop1"]) != 1 {
209 t.Errorf("spill missing from loop1")
210 }
211 if numSpills(f.blocks["loop2"]) != 0 {
212 t.Errorf("spill present in loop2")
213 }
214 if numSpills(f.blocks["exit1"]) != 0 {
215 t.Errorf("spill present in exit1")
216 }
217 if numSpills(f.blocks["exit2"]) != 0 {
218 t.Errorf("spill present in exit2")
219 }
220
221 }
222
223 func TestClobbersArg0(t *testing.T) {
224 c := testConfig(t)
225 f := c.Fun("entry",
226 Bloc("entry",
227 Valu("mem", OpInitMem, types.TypeMem, 0, nil),
228 Valu("ptr", OpArg, c.config.Types.Int64.PtrTo(), 0, c.Temp(c.config.Types.Int64.PtrTo())),
229 Valu("dst", OpArg, c.config.Types.Int64.PtrTo().PtrTo(), 0, c.Temp(c.config.Types.Int64.PtrTo().PtrTo())),
230 Valu("zero", OpAMD64LoweredZeroLoop, types.TypeMem, 256, nil, "ptr", "mem"),
231 Valu("store", OpAMD64MOVQstore, types.TypeMem, 0, nil, "dst", "ptr", "zero"),
232 Exit("store")))
233 flagalloc(f.f)
234 regalloc(f.f)
235 checkFunc(f.f)
236
237
238 if n := numCopies(f.blocks["entry"]); n != 1 {
239 fmt.Printf("%s\n", f.f.String())
240 t.Errorf("got %d copies, want 1", n)
241 }
242 }
243
244 func TestClobbersArg1(t *testing.T) {
245 c := testConfig(t)
246 f := c.Fun("entry",
247 Bloc("entry",
248 Valu("mem", OpInitMem, types.TypeMem, 0, nil),
249 Valu("src", OpArg, c.config.Types.Int64.PtrTo(), 0, c.Temp(c.config.Types.Int64.PtrTo())),
250 Valu("dst", OpArg, c.config.Types.Int64.PtrTo(), 0, c.Temp(c.config.Types.Int64.PtrTo())),
251 Valu("use1", OpArg, c.config.Types.Int64.PtrTo().PtrTo(), 0, c.Temp(c.config.Types.Int64.PtrTo().PtrTo())),
252 Valu("use2", OpArg, c.config.Types.Int64.PtrTo().PtrTo(), 0, c.Temp(c.config.Types.Int64.PtrTo().PtrTo())),
253 Valu("move", OpAMD64LoweredMoveLoop, types.TypeMem, 256, nil, "dst", "src", "mem"),
254 Valu("store1", OpAMD64MOVQstore, types.TypeMem, 0, nil, "use1", "src", "move"),
255 Valu("store2", OpAMD64MOVQstore, types.TypeMem, 0, nil, "use2", "dst", "store1"),
256 Exit("store2")))
257 flagalloc(f.f)
258 regalloc(f.f)
259 checkFunc(f.f)
260
261
262 if n := numCopies(f.blocks["entry"]); n != 2 {
263 fmt.Printf("%s\n", f.f.String())
264 t.Errorf("got %d copies, want 2", n)
265 }
266 }
267
268 func TestNoRematerializeDeadConstant(t *testing.T) {
269 c := testConfigARM64(t)
270 f := c.Fun("b1",
271 Bloc("b1",
272 Valu("mem", OpInitMem, types.TypeMem, 0, nil),
273 Valu("addr", OpArg, c.config.Types.Int32.PtrTo(), 0, c.Temp(c.config.Types.Int32.PtrTo())),
274 Valu("const", OpARM64MOVDconst, c.config.Types.Int32, -1, nil),
275 Valu("cmp", OpARM64CMPconst, types.TypeFlags, 0, nil, "const"),
276 Goto("b2"),
277 ),
278 Bloc("b2",
279 Valu("phi_mem", OpPhi, types.TypeMem, 0, nil, "mem", "callmem"),
280 Eq("cmp", "b6", "b3"),
281 ),
282 Bloc("b3",
283 Valu("call", OpARM64CALLstatic, types.TypeMem, 0, AuxCallLSym("_"), "phi_mem"),
284 Valu("callmem", OpSelectN, types.TypeMem, 0, nil, "call"),
285 Eq("cmp", "b5", "b4"),
286 ),
287 Bloc("b4",
288 Goto("b2"),
289 ),
290 Bloc("b5",
291 Valu("user", OpAMD64MOVQstore, types.TypeMem, 0, nil, "addr", "const", "callmem"),
292 Exit("user"),
293 ),
294 Bloc("b6",
295 Exit("phi_mem"),
296 ),
297 )
298
299 regalloc(f.f)
300 checkFunc(f.f)
301
302
303 for _, v := range f.blocks["b4"].Values {
304 if v.Op == OpARM64MOVDconst && v.AuxInt == -1 {
305 t.Errorf("constant -1 rematerialized in loop block b4: %s", v.LongString())
306 }
307 }
308 }
309
310 func numSpills(b *Block) int {
311 return numOps(b, OpStoreReg)
312 }
313 func numCopies(b *Block) int {
314 return numOps(b, OpCopy)
315 }
316 func numOps(b *Block, op Op) int {
317 n := 0
318 for _, v := range b.Values {
319 if v.Op == op {
320 n++
321 }
322 }
323 return n
324 }
325
326 func TestRematerializeableRegCompatible(t *testing.T) {
327 c := testConfig(t)
328 f := c.Fun("entry",
329 Bloc("entry",
330 Valu("mem", OpInitMem, types.TypeMem, 0, nil),
331 Valu("x", OpAMD64MOVLconst, c.config.Types.Int32, 1, nil),
332 Valu("a", OpAMD64POR, c.config.Types.Float32, 0, nil, "x", "x"),
333 Valu("res", OpMakeResult, types.NewResults([]*types.Type{c.config.Types.Float32, types.TypeMem}), 0, nil, "a", "mem"),
334 Ret("res"),
335 ),
336 )
337 regalloc(f.f)
338 checkFunc(f.f)
339 moveFound := false
340 for _, v := range f.f.Blocks[0].Values {
341 if v.Op == OpCopy && x86.REG_X0 <= v.Reg() && v.Reg() <= x86.REG_X31 {
342 moveFound = true
343 }
344 }
345 if !moveFound {
346 t.Errorf("Expects an Copy to be issued, but got: %+v", f.f)
347 }
348 }
349
350 func TestPreload(t *testing.T) {
351 c := testConfig(t)
352
353
354 f := c.Fun("entry",
355 Bloc("entry",
356 Valu("ptr", OpArgIntReg, c.config.Types.Int8.PtrTo(), 0, &AuxNameOffset{Name: c.Temp(c.config.Types.Int8.PtrTo()), Offset: 0}),
357 Valu("mem", OpInitMem, types.TypeMem, 0, nil),
358 Valu("x0", OpAMD64MOVBload, c.config.Types.Int8, 0, nil, "ptr", "mem"),
359 Valu("x1", OpAMD64MOVBload, c.config.Types.Int8, 1, nil, "ptr", "mem"),
360 Valu("x2", OpAMD64MOVBload, c.config.Types.Int8, 2, nil, "ptr", "mem"),
361 Valu("x3", OpAMD64MOVBload, c.config.Types.Int8, 3, nil, "ptr", "mem"),
362 Valu("x4", OpAMD64MOVBload, c.config.Types.Int8, 4, nil, "ptr", "mem"),
363 Valu("x5", OpAMD64MOVBload, c.config.Types.Int8, 5, nil, "ptr", "mem"),
364 Valu("x6", OpAMD64MOVBload, c.config.Types.Int8, 6, nil, "ptr", "mem"),
365 Valu("x7", OpAMD64MOVBload, c.config.Types.Int8, 7, nil, "ptr", "mem"),
366 Valu("x8", OpAMD64MOVBload, c.config.Types.Int8, 8, nil, "ptr", "mem"),
367 Valu("x9", OpAMD64MOVBload, c.config.Types.Int8, 9, nil, "ptr", "mem"),
368 Valu("x10", OpAMD64MOVBload, c.config.Types.Int8, 10, nil, "ptr", "mem"),
369 Valu("x11", OpAMD64MOVBload, c.config.Types.Int8, 11, nil, "ptr", "mem"),
370 Valu("init", OpAMD64MOVQconst, c.config.Types.Int64, 0, nil),
371 Goto("loopHead"),
372 ),
373 Bloc("loopHead",
374 Valu("phi", OpPhi, c.config.Types.Int64, 0, nil, "init", "next"),
375 Valu("test", OpAMD64CMPQconst, types.TypeFlags, 10, nil, "phi"),
376 Lt("test", "loopBody", "exit"),
377 ),
378 Bloc("loopBody",
379 Valu("next", OpAMD64ADDQconst, c.config.Types.Int64, 1, nil, "phi"),
380 Goto("loopHead"),
381 ),
382 Bloc("exit",
383 Valu("m0", OpAMD64MOVBstore, types.TypeMem, 0, nil, "ptr", "x0", "mem"),
384 Valu("m1", OpAMD64MOVBstore, types.TypeMem, 1, nil, "ptr", "x1", "m0"),
385 Valu("m2", OpAMD64MOVBstore, types.TypeMem, 2, nil, "ptr", "x2", "m1"),
386 Valu("m3", OpAMD64MOVBstore, types.TypeMem, 3, nil, "ptr", "x3", "m2"),
387 Valu("m4", OpAMD64MOVBstore, types.TypeMem, 4, nil, "ptr", "x4", "m3"),
388 Valu("m5", OpAMD64MOVBstore, types.TypeMem, 5, nil, "ptr", "x5", "m4"),
389 Valu("m6", OpAMD64MOVBstore, types.TypeMem, 6, nil, "ptr", "x6", "m5"),
390 Valu("m7", OpAMD64MOVBstore, types.TypeMem, 7, nil, "ptr", "x7", "m6"),
391 Valu("m8", OpAMD64MOVBstore, types.TypeMem, 8, nil, "ptr", "x8", "m7"),
392 Valu("m9", OpAMD64MOVBstore, types.TypeMem, 9, nil, "ptr", "x9", "m8"),
393 Valu("m10", OpAMD64MOVBstore, types.TypeMem, 10, nil, "ptr", "x10", "m9"),
394 Valu("m11", OpAMD64MOVBstore, types.TypeMem, 11, nil, "ptr", "x11", "m10"),
395 Ret("m11"),
396 ),
397 )
398 f.f.Blocks[1].Likely = BranchLikely
399 regalloc(f.f)
400 checkFunc(f.f)
401
402 v := f.values["phi"]
403 loc := f.f.RegAlloc[v.ID]
404 if _, ok := loc.(*Register); !ok {
405 t.Errorf("Expects to use a register for phi, but got: %s\n%v", loc, f.f)
406 }
407 }
408
409
410
411
412
413
414 func TestStartRegsDrop(t *testing.T) {
415 c := testConfig(t)
416
417 f := c.Fun("entry",
418 Bloc("entry",
419 Valu("mem", OpInitMem, types.TypeMem, 0, nil),
420 Valu("ptr", OpArg, c.config.Types.Int64.PtrTo(), 0, c.Temp(c.config.Types.Int64)),
421
422 Valu("u0", OpAMD64MOVQload, c.config.Types.Int64, 100, nil, "ptr", "mem"),
423 Valu("u1", OpAMD64MOVQload, c.config.Types.Int64, 108, nil, "ptr", "mem"),
424 Valu("u2", OpAMD64MOVQload, c.config.Types.Int64, 116, nil, "ptr", "mem"),
425 Valu("u3", OpAMD64MOVQload, c.config.Types.Int64, 124, nil, "ptr", "mem"),
426 Valu("u4", OpAMD64MOVQload, c.config.Types.Int64, 132, nil, "ptr", "mem"),
427 Valu("u5", OpAMD64MOVQload, c.config.Types.Int64, 140, nil, "ptr", "mem"),
428 Valu("u6", OpAMD64MOVQload, c.config.Types.Int64, 148, nil, "ptr", "mem"),
429 Valu("u7", OpAMD64MOVQload, c.config.Types.Int64, 156, nil, "ptr", "mem"),
430
431 Valu("v0", OpAMD64MOVQload, c.config.Types.Int64, 0, nil, "ptr", "mem"),
432
433 Valu("cond", OpAMD64MOVLconst, c.config.Types.Int32, 1, nil),
434 Valu("test", OpAMD64TESTL, types.TypeFlags, 0, nil, "cond", "cond"),
435 Eq("test", "left", "right"),
436 ),
437 Bloc("left",
438
439
440 Goto("merge"),
441 ),
442 Bloc("right",
443
444
445 Valu("r0", OpAMD64MOVQload, c.config.Types.Int64, 200, nil, "ptr", "mem"),
446 Valu("r1", OpAMD64MOVQload, c.config.Types.Int64, 208, nil, "ptr", "mem"),
447 Valu("r2", OpAMD64MOVQload, c.config.Types.Int64, 216, nil, "ptr", "mem"),
448 Valu("r3", OpAMD64MOVQload, c.config.Types.Int64, 224, nil, "ptr", "mem"),
449 Valu("r4", OpAMD64MOVQload, c.config.Types.Int64, 232, nil, "ptr", "mem"),
450 Valu("r5", OpAMD64MOVQload, c.config.Types.Int64, 240, nil, "ptr", "mem"),
451 Valu("r6", OpAMD64MOVQload, c.config.Types.Int64, 248, nil, "ptr", "mem"),
452 Valu("r7", OpAMD64MOVQload, c.config.Types.Int64, 256, nil, "ptr", "mem"),
453 Valu("r8", OpAMD64MOVQload, c.config.Types.Int64, 264, nil, "ptr", "mem"),
454 Valu("r9", OpAMD64MOVQload, c.config.Types.Int64, 272, nil, "ptr", "mem"),
455 Valu("r10", OpAMD64MOVQload, c.config.Types.Int64, 280, nil, "ptr", "mem"),
456 Valu("r11", OpAMD64MOVQload, c.config.Types.Int64, 288, nil, "ptr", "mem"),
457 Valu("r12", OpAMD64MOVQload, c.config.Types.Int64, 296, nil, "ptr", "mem"),
458 Valu("r13", OpAMD64MOVQload, c.config.Types.Int64, 304, nil, "ptr", "mem"),
459 Valu("r14", OpAMD64MOVQload, c.config.Types.Int64, 312, nil, "ptr", "mem"),
460 Valu("r15", OpAMD64MOVQload, c.config.Types.Int64, 320, nil, "ptr", "mem"),
461 Valu("sum0", OpAMD64ADDQ, c.config.Types.Int64, 0, nil, "r0", "r1"),
462 Valu("sum1", OpAMD64ADDQ, c.config.Types.Int64, 0, nil, "r2", "r3"),
463 Valu("sum2", OpAMD64ADDQ, c.config.Types.Int64, 0, nil, "r4", "r5"),
464 Valu("sum3", OpAMD64ADDQ, c.config.Types.Int64, 0, nil, "r6", "r7"),
465 Valu("sum4", OpAMD64ADDQ, c.config.Types.Int64, 0, nil, "r8", "r9"),
466 Valu("sum5", OpAMD64ADDQ, c.config.Types.Int64, 0, nil, "r10", "r11"),
467 Valu("sum6", OpAMD64ADDQ, c.config.Types.Int64, 0, nil, "r12", "r13"),
468 Valu("sum7", OpAMD64ADDQ, c.config.Types.Int64, 0, nil, "r14", "r15"),
469 Valu("store0", OpAMD64MOVQstore, types.TypeMem, 400, nil, "ptr", "sum0", "mem"),
470 Valu("store1", OpAMD64MOVQstore, types.TypeMem, 408, nil, "ptr", "sum1", "store0"),
471 Valu("store2", OpAMD64MOVQstore, types.TypeMem, 416, nil, "ptr", "sum2", "store1"),
472 Valu("store3", OpAMD64MOVQstore, types.TypeMem, 424, nil, "ptr", "sum3", "store2"),
473 Valu("store4", OpAMD64MOVQstore, types.TypeMem, 432, nil, "ptr", "sum4", "store3"),
474 Valu("store5", OpAMD64MOVQstore, types.TypeMem, 440, nil, "ptr", "sum5", "store4"),
475 Valu("store6", OpAMD64MOVQstore, types.TypeMem, 448, nil, "ptr", "sum6", "store5"),
476 Valu("store7", OpAMD64MOVQstore, types.TypeMem, 456, nil, "ptr", "sum7", "store6"),
477 Goto("merge"),
478 ),
479 Bloc("merge",
480
481 Valu("p0", OpPhi, c.config.Types.Int64, 0, nil, "v0", "v0"),
482
483 Valu("n0", OpAMD64MOVQload, c.config.Types.Int64, 500, nil, "ptr", "mem"),
484 Valu("n1", OpAMD64MOVQload, c.config.Types.Int64, 508, nil, "ptr", "mem"),
485 Valu("n2", OpAMD64MOVQload, c.config.Types.Int64, 516, nil, "ptr", "mem"),
486 Valu("n3", OpAMD64MOVQload, c.config.Types.Int64, 524, nil, "ptr", "mem"),
487 Valu("n4", OpAMD64MOVQload, c.config.Types.Int64, 532, nil, "ptr", "mem"),
488 Valu("n5", OpAMD64MOVQload, c.config.Types.Int64, 540, nil, "ptr", "mem"),
489 Valu("n6", OpAMD64MOVQload, c.config.Types.Int64, 548, nil, "ptr", "mem"),
490 Valu("n7", OpAMD64MOVQload, c.config.Types.Int64, 556, nil, "ptr", "mem"),
491 Valu("n8", OpAMD64MOVQload, c.config.Types.Int64, 564, nil, "ptr", "mem"),
492 Valu("n9", OpAMD64MOVQload, c.config.Types.Int64, 572, nil, "ptr", "mem"),
493 Valu("n10", OpAMD64MOVQload, c.config.Types.Int64, 580, nil, "ptr", "mem"),
494 Valu("n11", OpAMD64MOVQload, c.config.Types.Int64, 588, nil, "ptr", "mem"),
495 Valu("n12", OpAMD64MOVQload, c.config.Types.Int64, 596, nil, "ptr", "mem"),
496 Valu("n13", OpAMD64MOVQload, c.config.Types.Int64, 604, nil, "ptr", "mem"),
497
498 Valu("a0", OpAMD64ADDQ, c.config.Types.Int64, 0, nil, "n0", "n1"),
499 Valu("a1", OpAMD64ADDQ, c.config.Types.Int64, 0, nil, "n2", "n3"),
500 Valu("a2", OpAMD64ADDQ, c.config.Types.Int64, 0, nil, "n4", "n5"),
501 Valu("a3", OpAMD64ADDQ, c.config.Types.Int64, 0, nil, "n6", "n7"),
502 Valu("a4", OpAMD64ADDQ, c.config.Types.Int64, 0, nil, "n8", "n9"),
503 Valu("a5", OpAMD64ADDQ, c.config.Types.Int64, 0, nil, "n10", "n11"),
504 Valu("a6", OpAMD64ADDQ, c.config.Types.Int64, 0, nil, "n12", "n13"),
505 Valu("s0", OpAMD64MOVQstore, types.TypeMem, 0, nil, "ptr", "a0", "mem"),
506 Valu("s1", OpAMD64MOVQstore, types.TypeMem, 8, nil, "ptr", "a1", "s0"),
507 Valu("s2", OpAMD64MOVQstore, types.TypeMem, 16, nil, "ptr", "a2", "s1"),
508 Valu("s3", OpAMD64MOVQstore, types.TypeMem, 24, nil, "ptr", "a3", "s2"),
509 Valu("s4", OpAMD64MOVQstore, types.TypeMem, 32, nil, "ptr", "a4", "s3"),
510 Valu("s5", OpAMD64MOVQstore, types.TypeMem, 40, nil, "ptr", "a5", "s4"),
511 Valu("s6", OpAMD64MOVQstore, types.TypeMem, 48, nil, "ptr", "a6", "s5"),
512
513 Valu("t0", OpAMD64MOVQstore, types.TypeMem, 100, nil, "ptr", "u0", "s6"),
514 Valu("t1", OpAMD64MOVQstore, types.TypeMem, 108, nil, "ptr", "u1", "t0"),
515 Valu("t2", OpAMD64MOVQstore, types.TypeMem, 116, nil, "ptr", "u2", "t1"),
516 Valu("t3", OpAMD64MOVQstore, types.TypeMem, 124, nil, "ptr", "u3", "t2"),
517 Valu("t4", OpAMD64MOVQstore, types.TypeMem, 132, nil, "ptr", "u4", "t3"),
518 Valu("t5", OpAMD64MOVQstore, types.TypeMem, 140, nil, "ptr", "u5", "t4"),
519 Valu("t6", OpAMD64MOVQstore, types.TypeMem, 148, nil, "ptr", "u6", "t5"),
520 Valu("t7", OpAMD64MOVQstore, types.TypeMem, 156, nil, "ptr", "u7", "t6"),
521 Exit("t7"),
522 ),
523 )
524
525 regalloc(f.f)
526 checkFunc(f.f)
527
528 leftLoadCount := numOps(f.blocks["left"], OpLoadReg)
529 rightLoadCount := numOps(f.blocks["right"], OpLoadReg)
530 t.Logf("OpLoadReg count in left: %d, right: %d", leftLoadCount, rightLoadCount)
531
532
533 if rightLoadCount > 8 {
534 t.Errorf("expected <= 8 OpLoadReg in right block (got %d)", rightLoadCount)
535 }
536 }
537
View as plain text