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
| // Copyright 2017 The Go Authors. All rights reserved.
| // Use of this source code is governed by a BSD-style
| // license that can be found in the LICENSE file.
|
| package ssa
|
| import (
| "cmd/compile/internal/types"
| "cmd/internal/src"
| "testing"
| )
|
| func TestLoopConditionS390X(t *testing.T) {
| // Test that a simple loop condition does not generate a conditional
| // move (issue #19227).
| //
| // MOVDLT is generated when Less64 is lowered but should be
| // optimized into an LT branch.
| //
| // For example, compiling the following loop:
| //
| // for i := 0; i < N; i++ {
| // sum += 3
| // }
| //
| // should generate assembly similar to:
| // loop:
| // CMP R0, R1
| // BGE done
| // ADD $3, R4
| // ADD $1, R1
| // BR loop
| // done:
| //
| // rather than:
| // loop:
| // MOVD $0, R2
| // MOVD $1, R3
| // CMP R0, R1
| // MOVDLT R2, R3
| // CMPW R2, $0
| // BNE done
| // ADD $3, R4
| // ADD $1, R1
| // BR loop
| // done:
| //
| c := testConfigS390X(t)
| fun := c.Fun("entry",
| Bloc("entry",
| Valu("mem", OpInitMem, types.TypeMem, 0, nil),
| Valu("SP", OpSP, c.config.Types.Uintptr, 0, nil),
| Valu("ret", OpLocalAddr, c.config.Types.Int64.PtrTo(), 0, nil, "SP", "mem"),
| Valu("N", OpArg, c.config.Types.Int64, 0, c.Frontend().Auto(src.NoXPos, c.config.Types.Int64)),
| Valu("starti", OpConst64, c.config.Types.Int64, 0, nil),
| Valu("startsum", OpConst64, c.config.Types.Int64, 0, nil),
| Goto("b1")),
| Bloc("b1",
| Valu("phii", OpPhi, c.config.Types.Int64, 0, nil, "starti", "i"),
| Valu("phisum", OpPhi, c.config.Types.Int64, 0, nil, "startsum", "sum"),
| Valu("cmp1", OpLess64, c.config.Types.Bool, 0, nil, "phii", "N"),
| If("cmp1", "b2", "b3")),
| Bloc("b2",
| Valu("c1", OpConst64, c.config.Types.Int64, 1, nil),
| Valu("i", OpAdd64, c.config.Types.Int64, 0, nil, "phii", "c1"),
| Valu("c3", OpConst64, c.config.Types.Int64, 3, nil),
| Valu("sum", OpAdd64, c.config.Types.Int64, 0, nil, "phisum", "c3"),
| Goto("b1")),
| Bloc("b3",
| Valu("retdef", OpVarDef, types.TypeMem, 0, nil, "mem"),
| Valu("store", OpStore, types.TypeMem, 0, c.config.Types.Int64, "ret", "phisum", "retdef"),
| Exit("store")))
| CheckFunc(fun.f)
| Compile(fun.f)
| CheckFunc(fun.f)
|
| checkOpcodeCounts(t, fun.f, map[Op]int{
| OpS390XMOVDLT: 0,
| OpS390XMOVDGT: 0,
| OpS390XMOVDLE: 0,
| OpS390XMOVDGE: 0,
| OpS390XMOVDEQ: 0,
| OpS390XMOVDNE: 0,
| OpS390XCMP: 1,
| OpS390XCMPWconst: 0,
| })
| }
|
|