1# Copyright (C) 2016 The Android Open Source Project
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7#      http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14
15.class public LIrreducibleLoop;
16
17.super Ljava/lang/Object;
18
19# Check that both the irreducible loop and the other loop entry
20# move the constant-folded value to where it's expected.
21
22## CHECK-START-X86: int IrreducibleLoop.test1(int, long) register (after)
23## CHECK-DAG:                     ParallelMove {{.*84->.*}} loop:none
24## CHECK-DAG:                     ParallelMove {{.*84->.*}} loop:{{B\d+}} irreducible:true
25.method public static test1(IJ)I
26   .registers 10
27   const/16 v6, 2
28   const/16 v4, 1
29   const-wide/16 v0, 42
30   add-long v2, v0, v0
31
32   if-eqz p0, :loop_entry
33   goto :other_loop_pre_entry
34
35   # The then part: beginning of the irreducible loop.
36   :loop_entry
37   if-eqz p0, :exit
38   cmp-long v6, v2, p1
39   :other_loop_entry
40   sub-int p0, p0, v4
41   goto :loop_entry
42
43   # The other block branching to the irreducible loop.
44   # In that block, v4 has no live range.
45   :other_loop_pre_entry
46   goto :other_loop_entry
47
48   :exit
49   return v6
50.end method
51
52# Check that the compiler does not crash when
53# a live interval is found while connecting siblings, but that
54# live interval is inactive at the desired position.
55
56## CHECK-START-X86: int IrreducibleLoop.test2(int, long) register (after)
57## CHECK-DAG:                     ParallelMove {{.*84->.*}} loop:none
58## CHECK-DAG:                     ParallelMove {{.*84->.*}} loop:{{B\d+}} irreducible:true
59.method public static test2(IJ)I
60   .registers 14
61   const/16 v6, 2
62   const/16 v4, 1
63   const-wide/16 v0, 42
64   const-wide/16 v8, 68
65   add-long v2, v0, v0
66
67   if-eqz p0, :loop_entry
68   goto :other_loop_pre_entry
69
70   # The then part: beginning of the irreducible loop.
71   :loop_entry
72   if-eqz p0, :exit
73   cmp-long v6, v2, p1
74   :other_loop_entry
75   sub-int p0, p0, v4
76   goto :loop_entry
77
78   # The other block branching to the irreducible loop.
79   :other_loop_pre_entry
80   # Make v2 have a register location.
81   sput-wide v2, LIrreducibleLoop;->myField:J
82   # Stress register allocator on x86 to split v2.
83   sput-wide v0, LIrreducibleLoop;->myField:J
84   sput-wide p1, LIrreducibleLoop;->myField:J
85   sput-wide v8, LIrreducibleLoop;->myField:J
86   if-eqz p0, :join
87   # Stress register allocator on x86 to split v2.
88   sput-wide p1, LIrreducibleLoop;->myField:J
89   sput-wide v8, LIrreducibleLoop;->myField:J
90   sput-wide v0, LIrreducibleLoop;->myField:J
91   # Last use of v2 before the irreducible loop, that
92   # will create an interval hole.
93   sput-wide v2, LIrreducibleLoop;->myField:J
94   :join
95   goto :other_loop_entry
96
97   :exit
98   return v6
99.end method
100
101.field public static volatile myField:J
102