blob: 54b54d08bcad0407954ddc43eb4eee5a465c7a82 [file] [log] [blame]
Aart Bikdf7822e2016-12-06 10:05:30 -08001/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17//
18// Test on loop optimizations, in particular around polynomial induction.
19//
20public class Main {
21
22 /// CHECK-START: int Main.poly1() loop_optimization (before)
23 /// CHECK-DAG: Phi loop:<<Loop:B\d+>>
24 /// CHECK-DAG: Add loop:<<Loop>>
25 /// CHECK-DAG: Add loop:<<Loop>>
26 //
27 /// CHECK-START: int Main.poly1() loop_optimization (after)
28 /// CHECK-DAG: <<Zer:i\d+>> IntConstant 0 loop:none
29 /// CHECK-DAG: <<Int:i\d+>> IntConstant 55 loop:none
30 /// CHECK-DAG: <<Add:i\d+>> Add [<<Int>>,<<Zer>>] loop:none
31 /// CHECK-DAG: Return [<<Add>>] loop:none
32 //
33 /// CHECK-START: int Main.poly1() instruction_simplifier$after_bce (after)
34 /// CHECK-DAG: <<Int:i\d+>> IntConstant 55 loop:none
35 /// CHECK-DAG: Return [<<Int>>] loop:none
36 //
37 /// CHECK-START: int Main.poly1() loop_optimization (after)
38 /// CHECK-NOT: Phi
39 public static int poly1() {
40 int a = 0;
41 for (int i = 0; i <= 10; i++) {
42 a += i;
43 }
44 return a;
45 }
46
47 // Multiplication in linear induction has been optimized earlier,
48 // but that does not stop the induction variable recognition
49 // and loop optimizer.
50 //
51 /// CHECK-START: int Main.poly2(int) loop_optimization (before)
52 /// CHECK-DAG: Phi loop:<<Loop:B\d+>>
53 /// CHECK-DAG: Shl loop:<<Loop>>
54 /// CHECK-DAG: Add loop:<<Loop>>
55 /// CHECK-DAG: Add loop:<<Loop>>
56 /// CHECK-DAG: Add loop:<<Loop>>
57 /// CHECK-DAG: Add loop:<<Loop>>
58 //
59 /// CHECK-START: int Main.poly2(int) loop_optimization (after)
60 /// CHECK-DAG: <<Par:i\d+>> ParameterValue loop:none
61 /// CHECK-DAG: <<Int:i\d+>> IntConstant 185 loop:none
62 /// CHECK-DAG: <<Add:i\d+>> Add [<<Int>>,<<Par>>] loop:none
63 /// CHECK-DAG: Return [<<Add>>] loop:none
64 //
65 /// CHECK-START: int Main.poly2(int) loop_optimization (after)
66 /// CHECK-NOT: Phi
67 public static int poly2(int a) {
68 for (int i = 0; i < 10; i++) {
69 int k = 3 * i + 5;
70 a += k;
71 }
72 return a;
73 }
74
75 /// CHECK-START: int Main.poly3() loop_optimization (before)
76 /// CHECK-DAG: Phi loop:<<Loop:B\d+>>
77 /// CHECK-DAG: Add loop:<<Loop>>
78 /// CHECK-DAG: Add loop:<<Loop>>
79 //
80 /// CHECK-START: int Main.poly3() loop_optimization (after)
81 /// CHECK-DAG: <<Ini:i\d+>> IntConstant 12345 loop:none
82 /// CHECK-DAG: <<Int:i\d+>> IntConstant -2146736968 loop:none
83 /// CHECK-DAG: <<Add:i\d+>> Add [<<Int>>,<<Ini>>] loop:none
84 /// CHECK-DAG: Return [<<Add>>] loop:none
85 //
86 /// CHECK-START: int Main.poly3() instruction_simplifier$after_bce (after)
87 /// CHECK-DAG: <<Int:i\d+>> IntConstant -2146724623 loop:none
88 /// CHECK-DAG: Return [<<Int>>] loop:none
89 //
90 /// CHECK-START: int Main.poly3() loop_optimization (after)
91 /// CHECK-NOT: Phi
92 public static int poly3() {
93 int a = 12345;
94 for (int i = 0; i <= 10; i++) {
95 a += (2147483646 * i + 67890);
96 }
97 return a;
98 }
99
100 /// CHECK-START: int Main.polyBCE1() BCE (before)
101 /// CHECK-DAG: BoundsCheck loop:none
102 /// CHECK-DAG: BoundsCheck loop:{{B\d+}}
103 //
104 /// CHECK-START: int Main.polyBCE1() BCE (after)
105 /// CHECK-NOT: BoundsCheck
106 /// CHECK-NOT: Deoptimize
107 public static int polyBCE1() {
108 int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
109 11, 12, 13, 14, 15, 16, 17, 19, 19, 20,
110 21, 22 };
111 int a = 0;
112 int r = 0;
113 for (int i = 0; i < 8; i++) {
114 r += x[a];
115 a += i;
116 }
117 return r;
118 }
119
120 /// CHECK-START: int Main.polyBCE2() BCE (before)
121 /// CHECK-DAG: BoundsCheck loop:none
122 /// CHECK-DAG: BoundsCheck loop:{{B\d+}}
123 //
124 /// CHECK-START: int Main.polyBCE2() BCE (after)
125 /// CHECK-NOT: BoundsCheck
126 /// CHECK-NOT: Deoptimize
127 public static int polyBCE2() {
128 int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
129 11, 12, 13, 14, 15, 16, 17, 19, 19, 20,
130 21, 22, 23, 24, 25, 26, 27 };
131 int a = 1;
132 int r = 0;
133 for (int i = 0; i < 6; i++) {
134 int k = 2 * i + 1;
135 r -= x[a];
136 a += k;
137 }
138 return r;
139 }
140
141 /// CHECK-START: int Main.polyBCE3() BCE (before)
142 /// CHECK-DAG: BoundsCheck loop:none
143 /// CHECK-DAG: BoundsCheck loop:{{B\d+}}
144 //
145 /// CHECK-START: int Main.polyBCE3() BCE (after)
146 /// CHECK-NOT: BoundsCheck
147 /// CHECK-NOT: Deoptimize
148 public static int polyBCE3() {
149 int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
150 11, 12, 13, 14, 15, 16, 17, 19, 19, 20,
151 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
152 31, 32, 33, 34, 35, 36, 37, 38 };
153 int r = 0;
154 int a1 = 1;
155 int a2 = 2;
156 for (int i = 0; i < 5; i++) {
157 int t = a1 + a2; // two polynomials combined into new polynomial
158 r -= x[t];
159 a1 += (3 * i + 1);
160 a2 += (2 * i);
161 }
162 return r;
163 }
164
165 //
166 // Verifier.
167 //
168
169 public static void main(String[] args) {
170 expectEquals(55, poly1());
171 expectEquals(185, poly2(0));
172 expectEquals(192, poly2(7));
173 expectEquals(-2146724623, poly3());
174 expectEquals(64, polyBCE1());
175 expectEquals(-68, polyBCE2());
176 expectEquals(-80, polyBCE3());
177
178 System.out.println("passed");
179 }
180
181 private static void expectEquals(int expected, int result) {
182 if (expected != result) {
183 throw new Error("Expected: " + expected + ", found: " + result);
184 }
185 }
186}