liyujie
2025-08-28 d9927380ed7c8366f762049be9f3fee225860833
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,
   })
}