blob: dfa150406d84d660cbb798e2b7ff3ea37e8f7141 [file] [log] [blame]
Mingyao Yangf384f882014-10-22 16:08:18 -07001/*
2 * Copyright (C) 2014 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
Mathieu Chartierb666f482015-02-18 14:33:14 -080017#include "base/arena_allocator.h"
Mingyao Yangf384f882014-10-22 16:08:18 -070018#include "bounds_check_elimination.h"
19#include "builder.h"
20#include "gvn.h"
Aart Bik22af3be2015-09-10 12:50:58 -070021#include "induction_var_analysis.h"
Mingyao Yang0304e182015-01-30 16:41:29 -080022#include "instruction_simplifier.h"
Mingyao Yangf384f882014-10-22 16:08:18 -070023#include "nodes.h"
24#include "optimizing_unit_test.h"
Nicolas Geoffray827eedb2015-01-26 15:18:36 +000025#include "side_effects_analysis.h"
Mingyao Yangf384f882014-10-22 16:08:18 -070026
27#include "gtest/gtest.h"
28
29namespace art {
30
Aart Bik22af3be2015-09-10 12:50:58 -070031/**
32 * Fixture class for the BoundsCheckElimination tests.
33 */
34class BoundsCheckEliminationTest : public testing::Test {
35 public:
36 BoundsCheckEliminationTest() : pool_(), allocator_(&pool_) {
37 graph_ = CreateGraph(&allocator_);
38 graph_->SetHasBoundsChecks(true);
39 }
40
41 ~BoundsCheckEliminationTest() { }
42
43 void RunBCE() {
44 graph_->BuildDominatorTree();
Aart Bik22af3be2015-09-10 12:50:58 -070045
46 InstructionSimplifier(graph_).Run();
47
48 SideEffectsAnalysis side_effects(graph_);
49 side_effects.Run();
50
51 GVNOptimization(graph_, side_effects).Run();
52
53 HInductionVarAnalysis induction(graph_);
54 induction.Run();
55
Aart Bik4a342772015-11-30 10:17:46 -080056 BoundsCheckElimination(graph_, side_effects, &induction).Run();
Aart Bik22af3be2015-09-10 12:50:58 -070057 }
58
59 ArenaPool pool_;
60 ArenaAllocator allocator_;
61 HGraph* graph_;
62};
63
Nicolas Geoffraye6f17152015-01-26 15:13:47 +000064
Mingyao Yangf384f882014-10-22 16:08:18 -070065// if (i < 0) { array[i] = 1; // Can't eliminate. }
66// else if (i >= array.length) { array[i] = 1; // Can't eliminate. }
67// else { array[i] = 1; // Can eliminate. }
Aart Bik22af3be2015-09-10 12:50:58 -070068TEST_F(BoundsCheckEliminationTest, NarrowingRangeArrayBoundsElimination) {
69 HBasicBlock* entry = new (&allocator_) HBasicBlock(graph_);
70 graph_->AddBlock(entry);
71 graph_->SetEntryBlock(entry);
72 HInstruction* parameter1 = new (&allocator_)
Andreas Gampea5b09a62016-11-17 15:21:22 -080073 HParameterValue(graph_->GetDexFile(), dex::TypeIndex(0), 0, Primitive::kPrimNot); // array
Aart Bik22af3be2015-09-10 12:50:58 -070074 HInstruction* parameter2 = new (&allocator_)
Andreas Gampea5b09a62016-11-17 15:21:22 -080075 HParameterValue(graph_->GetDexFile(), dex::TypeIndex(0), 0, Primitive::kPrimInt); // i
Mingyao Yangf384f882014-10-22 16:08:18 -070076 entry->AddInstruction(parameter1);
77 entry->AddInstruction(parameter2);
David Brazdil8d5b8b22015-03-24 10:51:52 +000078
Aart Bik22af3be2015-09-10 12:50:58 -070079 HInstruction* constant_1 = graph_->GetIntConstant(1);
80 HInstruction* constant_0 = graph_->GetIntConstant(0);
Mingyao Yangf384f882014-10-22 16:08:18 -070081
Aart Bik22af3be2015-09-10 12:50:58 -070082 HBasicBlock* block1 = new (&allocator_) HBasicBlock(graph_);
83 graph_->AddBlock(block1);
84 HInstruction* cmp = new (&allocator_) HGreaterThanOrEqual(parameter2, constant_0);
85 HIf* if_inst = new (&allocator_) HIf(cmp);
Mingyao Yangf384f882014-10-22 16:08:18 -070086 block1->AddInstruction(cmp);
87 block1->AddInstruction(if_inst);
88 entry->AddSuccessor(block1);
89
Aart Bik22af3be2015-09-10 12:50:58 -070090 HBasicBlock* block2 = new (&allocator_) HBasicBlock(graph_);
91 graph_->AddBlock(block2);
92 HNullCheck* null_check = new (&allocator_) HNullCheck(parameter1, 0);
Calin Juravle154746b2015-10-06 15:46:54 +010093 HArrayLength* array_length = new (&allocator_) HArrayLength(null_check, 0);
Aart Bik22af3be2015-09-10 12:50:58 -070094 HBoundsCheck* bounds_check2 = new (&allocator_)
Mingyao Yangf384f882014-10-22 16:08:18 -070095 HBoundsCheck(parameter2, array_length, 0);
Aart Bik22af3be2015-09-10 12:50:58 -070096 HArraySet* array_set = new (&allocator_) HArraySet(
Mingyao Yangf384f882014-10-22 16:08:18 -070097 null_check, bounds_check2, constant_1, Primitive::kPrimInt, 0);
98 block2->AddInstruction(null_check);
99 block2->AddInstruction(array_length);
100 block2->AddInstruction(bounds_check2);
101 block2->AddInstruction(array_set);
102
Aart Bik22af3be2015-09-10 12:50:58 -0700103 HBasicBlock* block3 = new (&allocator_) HBasicBlock(graph_);
104 graph_->AddBlock(block3);
105 null_check = new (&allocator_) HNullCheck(parameter1, 0);
Calin Juravle154746b2015-10-06 15:46:54 +0100106 array_length = new (&allocator_) HArrayLength(null_check, 0);
Aart Bik22af3be2015-09-10 12:50:58 -0700107 cmp = new (&allocator_) HLessThan(parameter2, array_length);
108 if_inst = new (&allocator_) HIf(cmp);
Mingyao Yangf384f882014-10-22 16:08:18 -0700109 block3->AddInstruction(null_check);
110 block3->AddInstruction(array_length);
111 block3->AddInstruction(cmp);
112 block3->AddInstruction(if_inst);
113
Aart Bik22af3be2015-09-10 12:50:58 -0700114 HBasicBlock* block4 = new (&allocator_) HBasicBlock(graph_);
115 graph_->AddBlock(block4);
116 null_check = new (&allocator_) HNullCheck(parameter1, 0);
Calin Juravle154746b2015-10-06 15:46:54 +0100117 array_length = new (&allocator_) HArrayLength(null_check, 0);
Aart Bik22af3be2015-09-10 12:50:58 -0700118 HBoundsCheck* bounds_check4 = new (&allocator_)
Mingyao Yangf384f882014-10-22 16:08:18 -0700119 HBoundsCheck(parameter2, array_length, 0);
Aart Bik22af3be2015-09-10 12:50:58 -0700120 array_set = new (&allocator_) HArraySet(
Mingyao Yangf384f882014-10-22 16:08:18 -0700121 null_check, bounds_check4, constant_1, Primitive::kPrimInt, 0);
122 block4->AddInstruction(null_check);
123 block4->AddInstruction(array_length);
124 block4->AddInstruction(bounds_check4);
125 block4->AddInstruction(array_set);
126
Aart Bik22af3be2015-09-10 12:50:58 -0700127 HBasicBlock* block5 = new (&allocator_) HBasicBlock(graph_);
128 graph_->AddBlock(block5);
129 null_check = new (&allocator_) HNullCheck(parameter1, 0);
Calin Juravle154746b2015-10-06 15:46:54 +0100130 array_length = new (&allocator_) HArrayLength(null_check, 0);
Aart Bik22af3be2015-09-10 12:50:58 -0700131 HBoundsCheck* bounds_check5 = new (&allocator_)
Mingyao Yangf384f882014-10-22 16:08:18 -0700132 HBoundsCheck(parameter2, array_length, 0);
Aart Bik22af3be2015-09-10 12:50:58 -0700133 array_set = new (&allocator_) HArraySet(
Mingyao Yangf384f882014-10-22 16:08:18 -0700134 null_check, bounds_check5, constant_1, Primitive::kPrimInt, 0);
135 block5->AddInstruction(null_check);
136 block5->AddInstruction(array_length);
137 block5->AddInstruction(bounds_check5);
138 block5->AddInstruction(array_set);
139
Aart Bik22af3be2015-09-10 12:50:58 -0700140 HBasicBlock* exit = new (&allocator_) HBasicBlock(graph_);
141 graph_->AddBlock(exit);
Mingyao Yangf384f882014-10-22 16:08:18 -0700142 block2->AddSuccessor(exit);
143 block4->AddSuccessor(exit);
144 block5->AddSuccessor(exit);
Aart Bik22af3be2015-09-10 12:50:58 -0700145 exit->AddInstruction(new (&allocator_) HExit());
Mingyao Yangf384f882014-10-22 16:08:18 -0700146
147 block1->AddSuccessor(block3); // True successor
148 block1->AddSuccessor(block2); // False successor
149
150 block3->AddSuccessor(block5); // True successor
151 block3->AddSuccessor(block4); // False successor
152
Aart Bik22af3be2015-09-10 12:50:58 -0700153 RunBCE();
154
Mingyao Yangf384f882014-10-22 16:08:18 -0700155 ASSERT_FALSE(IsRemoved(bounds_check2));
156 ASSERT_FALSE(IsRemoved(bounds_check4));
157 ASSERT_TRUE(IsRemoved(bounds_check5));
158}
159
160// if (i > 0) {
161// // Positive number plus MAX_INT will overflow and be negative.
162// int j = i + Integer.MAX_VALUE;
163// if (j < array.length) array[j] = 1; // Can't eliminate.
164// }
Aart Bik22af3be2015-09-10 12:50:58 -0700165TEST_F(BoundsCheckEliminationTest, OverflowArrayBoundsElimination) {
166 HBasicBlock* entry = new (&allocator_) HBasicBlock(graph_);
167 graph_->AddBlock(entry);
168 graph_->SetEntryBlock(entry);
169 HInstruction* parameter1 = new (&allocator_)
Andreas Gampea5b09a62016-11-17 15:21:22 -0800170 HParameterValue(graph_->GetDexFile(), dex::TypeIndex(0), 0, Primitive::kPrimNot); // array
Aart Bik22af3be2015-09-10 12:50:58 -0700171 HInstruction* parameter2 = new (&allocator_)
Andreas Gampea5b09a62016-11-17 15:21:22 -0800172 HParameterValue(graph_->GetDexFile(), dex::TypeIndex(0), 0, Primitive::kPrimInt); // i
Mingyao Yangf384f882014-10-22 16:08:18 -0700173 entry->AddInstruction(parameter1);
174 entry->AddInstruction(parameter2);
David Brazdil8d5b8b22015-03-24 10:51:52 +0000175
Aart Bik22af3be2015-09-10 12:50:58 -0700176 HInstruction* constant_1 = graph_->GetIntConstant(1);
177 HInstruction* constant_0 = graph_->GetIntConstant(0);
178 HInstruction* constant_max_int = graph_->GetIntConstant(INT_MAX);
Mingyao Yangf384f882014-10-22 16:08:18 -0700179
Aart Bik22af3be2015-09-10 12:50:58 -0700180 HBasicBlock* block1 = new (&allocator_) HBasicBlock(graph_);
181 graph_->AddBlock(block1);
182 HInstruction* cmp = new (&allocator_) HLessThanOrEqual(parameter2, constant_0);
183 HIf* if_inst = new (&allocator_) HIf(cmp);
Mingyao Yangf384f882014-10-22 16:08:18 -0700184 block1->AddInstruction(cmp);
185 block1->AddInstruction(if_inst);
186 entry->AddSuccessor(block1);
187
Aart Bik22af3be2015-09-10 12:50:58 -0700188 HBasicBlock* block2 = new (&allocator_) HBasicBlock(graph_);
189 graph_->AddBlock(block2);
190 HInstruction* add = new (&allocator_) HAdd(Primitive::kPrimInt, parameter2, constant_max_int);
191 HNullCheck* null_check = new (&allocator_) HNullCheck(parameter1, 0);
Calin Juravle154746b2015-10-06 15:46:54 +0100192 HArrayLength* array_length = new (&allocator_) HArrayLength(null_check, 0);
Aart Bik22af3be2015-09-10 12:50:58 -0700193 HInstruction* cmp2 = new (&allocator_) HGreaterThanOrEqual(add, array_length);
194 if_inst = new (&allocator_) HIf(cmp2);
Mingyao Yangf384f882014-10-22 16:08:18 -0700195 block2->AddInstruction(add);
196 block2->AddInstruction(null_check);
197 block2->AddInstruction(array_length);
198 block2->AddInstruction(cmp2);
199 block2->AddInstruction(if_inst);
200
Aart Bik22af3be2015-09-10 12:50:58 -0700201 HBasicBlock* block3 = new (&allocator_) HBasicBlock(graph_);
202 graph_->AddBlock(block3);
203 HBoundsCheck* bounds_check = new (&allocator_)
Mingyao Yangf384f882014-10-22 16:08:18 -0700204 HBoundsCheck(add, array_length, 0);
Aart Bik22af3be2015-09-10 12:50:58 -0700205 HArraySet* array_set = new (&allocator_) HArraySet(
Mingyao Yangf384f882014-10-22 16:08:18 -0700206 null_check, bounds_check, constant_1, Primitive::kPrimInt, 0);
207 block3->AddInstruction(bounds_check);
208 block3->AddInstruction(array_set);
209
Aart Bik22af3be2015-09-10 12:50:58 -0700210 HBasicBlock* exit = new (&allocator_) HBasicBlock(graph_);
211 graph_->AddBlock(exit);
212 exit->AddInstruction(new (&allocator_) HExit());
Andreas Gampe0418b5b2014-12-04 17:24:50 -0800213 block1->AddSuccessor(exit); // true successor
214 block1->AddSuccessor(block2); // false successor
215 block2->AddSuccessor(exit); // true successor
216 block2->AddSuccessor(block3); // false successor
Mingyao Yangf384f882014-10-22 16:08:18 -0700217 block3->AddSuccessor(exit);
218
Aart Bik22af3be2015-09-10 12:50:58 -0700219 RunBCE();
220
Mingyao Yangf384f882014-10-22 16:08:18 -0700221 ASSERT_FALSE(IsRemoved(bounds_check));
222}
223
224// if (i < array.length) {
225// int j = i - Integer.MAX_VALUE;
Aart Bik22af3be2015-09-10 12:50:58 -0700226// j = j - Integer.MAX_VALUE; // j is (i+2) after subtracting MAX_INT twice
Mingyao Yangf384f882014-10-22 16:08:18 -0700227// if (j > 0) array[j] = 1; // Can't eliminate.
228// }
Aart Bik22af3be2015-09-10 12:50:58 -0700229TEST_F(BoundsCheckEliminationTest, UnderflowArrayBoundsElimination) {
230 HBasicBlock* entry = new (&allocator_) HBasicBlock(graph_);
231 graph_->AddBlock(entry);
232 graph_->SetEntryBlock(entry);
233 HInstruction* parameter1 = new (&allocator_)
Andreas Gampea5b09a62016-11-17 15:21:22 -0800234 HParameterValue(graph_->GetDexFile(), dex::TypeIndex(0), 0, Primitive::kPrimNot); // array
Aart Bik22af3be2015-09-10 12:50:58 -0700235 HInstruction* parameter2 = new (&allocator_)
Andreas Gampea5b09a62016-11-17 15:21:22 -0800236 HParameterValue(graph_->GetDexFile(), dex::TypeIndex(0), 0, Primitive::kPrimInt); // i
Mingyao Yangf384f882014-10-22 16:08:18 -0700237 entry->AddInstruction(parameter1);
238 entry->AddInstruction(parameter2);
David Brazdil8d5b8b22015-03-24 10:51:52 +0000239
Aart Bik22af3be2015-09-10 12:50:58 -0700240 HInstruction* constant_1 = graph_->GetIntConstant(1);
241 HInstruction* constant_0 = graph_->GetIntConstant(0);
242 HInstruction* constant_max_int = graph_->GetIntConstant(INT_MAX);
Mingyao Yangf384f882014-10-22 16:08:18 -0700243
Aart Bik22af3be2015-09-10 12:50:58 -0700244 HBasicBlock* block1 = new (&allocator_) HBasicBlock(graph_);
245 graph_->AddBlock(block1);
246 HNullCheck* null_check = new (&allocator_) HNullCheck(parameter1, 0);
Calin Juravle154746b2015-10-06 15:46:54 +0100247 HArrayLength* array_length = new (&allocator_) HArrayLength(null_check, 0);
Aart Bik22af3be2015-09-10 12:50:58 -0700248 HInstruction* cmp = new (&allocator_) HGreaterThanOrEqual(parameter2, array_length);
249 HIf* if_inst = new (&allocator_) HIf(cmp);
Mingyao Yangf384f882014-10-22 16:08:18 -0700250 block1->AddInstruction(null_check);
251 block1->AddInstruction(array_length);
252 block1->AddInstruction(cmp);
253 block1->AddInstruction(if_inst);
254 entry->AddSuccessor(block1);
255
Aart Bik22af3be2015-09-10 12:50:58 -0700256 HBasicBlock* block2 = new (&allocator_) HBasicBlock(graph_);
257 graph_->AddBlock(block2);
258 HInstruction* sub1 = new (&allocator_) HSub(Primitive::kPrimInt, parameter2, constant_max_int);
259 HInstruction* sub2 = new (&allocator_) HSub(Primitive::kPrimInt, sub1, constant_max_int);
260 HInstruction* cmp2 = new (&allocator_) HLessThanOrEqual(sub2, constant_0);
261 if_inst = new (&allocator_) HIf(cmp2);
Mingyao Yangf384f882014-10-22 16:08:18 -0700262 block2->AddInstruction(sub1);
263 block2->AddInstruction(sub2);
264 block2->AddInstruction(cmp2);
265 block2->AddInstruction(if_inst);
266
Aart Bik22af3be2015-09-10 12:50:58 -0700267 HBasicBlock* block3 = new (&allocator_) HBasicBlock(graph_);
268 graph_->AddBlock(block3);
269 HBoundsCheck* bounds_check = new (&allocator_)
Mingyao Yangf384f882014-10-22 16:08:18 -0700270 HBoundsCheck(sub2, array_length, 0);
Aart Bik22af3be2015-09-10 12:50:58 -0700271 HArraySet* array_set = new (&allocator_) HArraySet(
Mingyao Yangf384f882014-10-22 16:08:18 -0700272 null_check, bounds_check, constant_1, Primitive::kPrimInt, 0);
273 block3->AddInstruction(bounds_check);
274 block3->AddInstruction(array_set);
275
Aart Bik22af3be2015-09-10 12:50:58 -0700276 HBasicBlock* exit = new (&allocator_) HBasicBlock(graph_);
277 graph_->AddBlock(exit);
278 exit->AddInstruction(new (&allocator_) HExit());
Andreas Gampe0418b5b2014-12-04 17:24:50 -0800279 block1->AddSuccessor(exit); // true successor
280 block1->AddSuccessor(block2); // false successor
281 block2->AddSuccessor(exit); // true successor
282 block2->AddSuccessor(block3); // false successor
Mingyao Yangf384f882014-10-22 16:08:18 -0700283 block3->AddSuccessor(exit);
284
Aart Bik22af3be2015-09-10 12:50:58 -0700285 RunBCE();
286
Mingyao Yangf384f882014-10-22 16:08:18 -0700287 ASSERT_FALSE(IsRemoved(bounds_check));
288}
289
Andreas Gampe0ba62732015-03-24 02:39:46 +0000290// array[6] = 1; // Can't eliminate.
Mingyao Yangd43b3ac2015-04-01 14:03:04 -0700291// array[5] = 1; // Can eliminate.
292// array[4] = 1; // Can eliminate.
Aart Bik22af3be2015-09-10 12:50:58 -0700293TEST_F(BoundsCheckEliminationTest, ConstantArrayBoundsElimination) {
294 HBasicBlock* entry = new (&allocator_) HBasicBlock(graph_);
295 graph_->AddBlock(entry);
296 graph_->SetEntryBlock(entry);
Calin Juravlee6e3bea2015-10-14 13:53:10 +0000297 HInstruction* parameter = new (&allocator_) HParameterValue(
Andreas Gampea5b09a62016-11-17 15:21:22 -0800298 graph_->GetDexFile(), dex::TypeIndex(0), 0, Primitive::kPrimNot);
Mingyao Yangf384f882014-10-22 16:08:18 -0700299 entry->AddInstruction(parameter);
David Brazdil8d5b8b22015-03-24 10:51:52 +0000300
Aart Bik22af3be2015-09-10 12:50:58 -0700301 HInstruction* constant_5 = graph_->GetIntConstant(5);
302 HInstruction* constant_4 = graph_->GetIntConstant(4);
303 HInstruction* constant_6 = graph_->GetIntConstant(6);
304 HInstruction* constant_1 = graph_->GetIntConstant(1);
Mingyao Yangf384f882014-10-22 16:08:18 -0700305
Aart Bik22af3be2015-09-10 12:50:58 -0700306 HBasicBlock* block = new (&allocator_) HBasicBlock(graph_);
307 graph_->AddBlock(block);
Mingyao Yangf384f882014-10-22 16:08:18 -0700308 entry->AddSuccessor(block);
309
Aart Bik22af3be2015-09-10 12:50:58 -0700310 HNullCheck* null_check = new (&allocator_) HNullCheck(parameter, 0);
Calin Juravle154746b2015-10-06 15:46:54 +0100311 HArrayLength* array_length = new (&allocator_) HArrayLength(null_check, 0);
Aart Bik22af3be2015-09-10 12:50:58 -0700312 HBoundsCheck* bounds_check6 = new (&allocator_)
Mingyao Yangd43b3ac2015-04-01 14:03:04 -0700313 HBoundsCheck(constant_6, array_length, 0);
Aart Bik22af3be2015-09-10 12:50:58 -0700314 HInstruction* array_set = new (&allocator_) HArraySet(
Mingyao Yangd43b3ac2015-04-01 14:03:04 -0700315 null_check, bounds_check6, constant_1, Primitive::kPrimInt, 0);
316 block->AddInstruction(null_check);
317 block->AddInstruction(array_length);
318 block->AddInstruction(bounds_check6);
319 block->AddInstruction(array_set);
320
Aart Bik22af3be2015-09-10 12:50:58 -0700321 null_check = new (&allocator_) HNullCheck(parameter, 0);
Calin Juravle154746b2015-10-06 15:46:54 +0100322 array_length = new (&allocator_) HArrayLength(null_check, 0);
Aart Bik22af3be2015-09-10 12:50:58 -0700323 HBoundsCheck* bounds_check5 = new (&allocator_)
Mingyao Yangf384f882014-10-22 16:08:18 -0700324 HBoundsCheck(constant_5, array_length, 0);
Aart Bik22af3be2015-09-10 12:50:58 -0700325 array_set = new (&allocator_) HArraySet(
Mingyao Yangf384f882014-10-22 16:08:18 -0700326 null_check, bounds_check5, constant_1, Primitive::kPrimInt, 0);
327 block->AddInstruction(null_check);
328 block->AddInstruction(array_length);
329 block->AddInstruction(bounds_check5);
330 block->AddInstruction(array_set);
331
Aart Bik22af3be2015-09-10 12:50:58 -0700332 null_check = new (&allocator_) HNullCheck(parameter, 0);
Calin Juravle154746b2015-10-06 15:46:54 +0100333 array_length = new (&allocator_) HArrayLength(null_check, 0);
Aart Bik22af3be2015-09-10 12:50:58 -0700334 HBoundsCheck* bounds_check4 = new (&allocator_)
Mingyao Yangf384f882014-10-22 16:08:18 -0700335 HBoundsCheck(constant_4, array_length, 0);
Aart Bik22af3be2015-09-10 12:50:58 -0700336 array_set = new (&allocator_) HArraySet(
Mingyao Yangf384f882014-10-22 16:08:18 -0700337 null_check, bounds_check4, constant_1, Primitive::kPrimInt, 0);
338 block->AddInstruction(null_check);
339 block->AddInstruction(array_length);
340 block->AddInstruction(bounds_check4);
341 block->AddInstruction(array_set);
342
Aart Bik22af3be2015-09-10 12:50:58 -0700343 block->AddInstruction(new (&allocator_) HGoto());
Mingyao Yangf384f882014-10-22 16:08:18 -0700344
Aart Bik22af3be2015-09-10 12:50:58 -0700345 HBasicBlock* exit = new (&allocator_) HBasicBlock(graph_);
346 graph_->AddBlock(exit);
Mingyao Yangf384f882014-10-22 16:08:18 -0700347 block->AddSuccessor(exit);
Aart Bik22af3be2015-09-10 12:50:58 -0700348 exit->AddInstruction(new (&allocator_) HExit());
Mingyao Yangf384f882014-10-22 16:08:18 -0700349
Aart Bik22af3be2015-09-10 12:50:58 -0700350 RunBCE();
351
Andreas Gampe0ba62732015-03-24 02:39:46 +0000352 ASSERT_FALSE(IsRemoved(bounds_check6));
Mingyao Yangd43b3ac2015-04-01 14:03:04 -0700353 ASSERT_TRUE(IsRemoved(bounds_check5));
354 ASSERT_TRUE(IsRemoved(bounds_check4));
Mingyao Yangf384f882014-10-22 16:08:18 -0700355}
356
357// for (int i=initial; i<array.length; i+=increment) { array[i] = 10; }
Aart Bik22af3be2015-09-10 12:50:58 -0700358static HInstruction* BuildSSAGraph1(HGraph* graph,
359 ArenaAllocator* allocator,
360 int initial,
361 int increment,
362 IfCondition cond = kCondGE) {
Mingyao Yangf384f882014-10-22 16:08:18 -0700363 HBasicBlock* entry = new (allocator) HBasicBlock(graph);
364 graph->AddBlock(entry);
365 graph->SetEntryBlock(entry);
Calin Juravlee6e3bea2015-10-14 13:53:10 +0000366 HInstruction* parameter = new (allocator) HParameterValue(
Andreas Gampea5b09a62016-11-17 15:21:22 -0800367 graph->GetDexFile(), dex::TypeIndex(0), 0, Primitive::kPrimNot);
Mingyao Yangf384f882014-10-22 16:08:18 -0700368 entry->AddInstruction(parameter);
David Brazdil8d5b8b22015-03-24 10:51:52 +0000369
370 HInstruction* constant_initial = graph->GetIntConstant(initial);
371 HInstruction* constant_increment = graph->GetIntConstant(increment);
372 HInstruction* constant_10 = graph->GetIntConstant(10);
Mingyao Yangf384f882014-10-22 16:08:18 -0700373
374 HBasicBlock* block = new (allocator) HBasicBlock(graph);
375 graph->AddBlock(block);
376 entry->AddSuccessor(block);
377 block->AddInstruction(new (allocator) HGoto());
378
379 HBasicBlock* loop_header = new (allocator) HBasicBlock(graph);
380 HBasicBlock* loop_body = new (allocator) HBasicBlock(graph);
381 HBasicBlock* exit = new (allocator) HBasicBlock(graph);
382
383 graph->AddBlock(loop_header);
384 graph->AddBlock(loop_body);
385 graph->AddBlock(exit);
386 block->AddSuccessor(loop_header);
387 loop_header->AddSuccessor(exit); // true successor
388 loop_header->AddSuccessor(loop_body); // false successor
389 loop_body->AddSuccessor(loop_header);
390
391 HPhi* phi = new (allocator) HPhi(allocator, 0, 0, Primitive::kPrimInt);
Mingyao Yangf384f882014-10-22 16:08:18 -0700392 HInstruction* null_check = new (allocator) HNullCheck(parameter, 0);
Calin Juravle154746b2015-10-06 15:46:54 +0100393 HInstruction* array_length = new (allocator) HArrayLength(null_check, 0);
Mingyao Yangf384f882014-10-22 16:08:18 -0700394 HInstruction* cmp = nullptr;
395 if (cond == kCondGE) {
396 cmp = new (allocator) HGreaterThanOrEqual(phi, array_length);
397 } else {
398 DCHECK(cond == kCondGT);
399 cmp = new (allocator) HGreaterThan(phi, array_length);
400 }
401 HInstruction* if_inst = new (allocator) HIf(cmp);
402 loop_header->AddPhi(phi);
403 loop_header->AddInstruction(null_check);
404 loop_header->AddInstruction(array_length);
405 loop_header->AddInstruction(cmp);
406 loop_header->AddInstruction(if_inst);
David Brazdil1abb4192015-02-17 18:33:36 +0000407 phi->AddInput(constant_initial);
Mingyao Yangf384f882014-10-22 16:08:18 -0700408
409 null_check = new (allocator) HNullCheck(parameter, 0);
Calin Juravle154746b2015-10-06 15:46:54 +0100410 array_length = new (allocator) HArrayLength(null_check, 0);
Aart Bik22af3be2015-09-10 12:50:58 -0700411 HInstruction* bounds_check = new (allocator) HBoundsCheck(phi, array_length, 0);
Mingyao Yangf384f882014-10-22 16:08:18 -0700412 HInstruction* array_set = new (allocator) HArraySet(
Aart Bik22af3be2015-09-10 12:50:58 -0700413 null_check, bounds_check, constant_10, Primitive::kPrimInt, 0);
Mingyao Yangf384f882014-10-22 16:08:18 -0700414
415 HInstruction* add = new (allocator) HAdd(Primitive::kPrimInt, phi, constant_increment);
416 loop_body->AddInstruction(null_check);
417 loop_body->AddInstruction(array_length);
Aart Bik22af3be2015-09-10 12:50:58 -0700418 loop_body->AddInstruction(bounds_check);
Mingyao Yangf384f882014-10-22 16:08:18 -0700419 loop_body->AddInstruction(array_set);
420 loop_body->AddInstruction(add);
421 loop_body->AddInstruction(new (allocator) HGoto());
422 phi->AddInput(add);
423
424 exit->AddInstruction(new (allocator) HExit());
425
Aart Bik22af3be2015-09-10 12:50:58 -0700426 return bounds_check;
Mingyao Yangf384f882014-10-22 16:08:18 -0700427}
428
Aart Bik22af3be2015-09-10 12:50:58 -0700429TEST_F(BoundsCheckEliminationTest, LoopArrayBoundsElimination1a) {
Mingyao Yangf384f882014-10-22 16:08:18 -0700430 // for (int i=0; i<array.length; i++) { array[i] = 10; // Can eliminate with gvn. }
Aart Bik22af3be2015-09-10 12:50:58 -0700431 HInstruction* bounds_check = BuildSSAGraph1(graph_, &allocator_, 0, 1);
432 RunBCE();
Mingyao Yangf384f882014-10-22 16:08:18 -0700433 ASSERT_TRUE(IsRemoved(bounds_check));
Aart Bik22af3be2015-09-10 12:50:58 -0700434}
Mingyao Yangf384f882014-10-22 16:08:18 -0700435
Aart Bik22af3be2015-09-10 12:50:58 -0700436TEST_F(BoundsCheckEliminationTest, LoopArrayBoundsElimination1b) {
Mingyao Yangf384f882014-10-22 16:08:18 -0700437 // for (int i=1; i<array.length; i++) { array[i] = 10; // Can eliminate. }
Aart Bik22af3be2015-09-10 12:50:58 -0700438 HInstruction* bounds_check = BuildSSAGraph1(graph_, &allocator_, 1, 1);
439 RunBCE();
Mingyao Yangf384f882014-10-22 16:08:18 -0700440 ASSERT_TRUE(IsRemoved(bounds_check));
Aart Bik22af3be2015-09-10 12:50:58 -0700441}
Mingyao Yangf384f882014-10-22 16:08:18 -0700442
Aart Bik22af3be2015-09-10 12:50:58 -0700443TEST_F(BoundsCheckEliminationTest, LoopArrayBoundsElimination1c) {
Mingyao Yangf384f882014-10-22 16:08:18 -0700444 // for (int i=-1; i<array.length; i++) { array[i] = 10; // Can't eliminate. }
Aart Bik22af3be2015-09-10 12:50:58 -0700445 HInstruction* bounds_check = BuildSSAGraph1(graph_, &allocator_, -1, 1);
446 RunBCE();
Mingyao Yangf384f882014-10-22 16:08:18 -0700447 ASSERT_FALSE(IsRemoved(bounds_check));
Aart Bik22af3be2015-09-10 12:50:58 -0700448}
Mingyao Yangf384f882014-10-22 16:08:18 -0700449
Aart Bik22af3be2015-09-10 12:50:58 -0700450TEST_F(BoundsCheckEliminationTest, LoopArrayBoundsElimination1d) {
Mingyao Yangf384f882014-10-22 16:08:18 -0700451 // for (int i=0; i<=array.length; i++) { array[i] = 10; // Can't eliminate. }
Aart Bik22af3be2015-09-10 12:50:58 -0700452 HInstruction* bounds_check = BuildSSAGraph1(graph_, &allocator_, 0, 1, kCondGT);
453 RunBCE();
Mingyao Yangf384f882014-10-22 16:08:18 -0700454 ASSERT_FALSE(IsRemoved(bounds_check));
Aart Bik22af3be2015-09-10 12:50:58 -0700455}
Mingyao Yangf384f882014-10-22 16:08:18 -0700456
Aart Bik22af3be2015-09-10 12:50:58 -0700457TEST_F(BoundsCheckEliminationTest, LoopArrayBoundsElimination1e) {
Mingyao Yangf384f882014-10-22 16:08:18 -0700458 // for (int i=0; i<array.length; i += 2) {
459 // array[i] = 10; // Can't eliminate due to overflow concern. }
Aart Bik22af3be2015-09-10 12:50:58 -0700460 HInstruction* bounds_check = BuildSSAGraph1(graph_, &allocator_, 0, 2);
461 RunBCE();
Mingyao Yangf384f882014-10-22 16:08:18 -0700462 ASSERT_FALSE(IsRemoved(bounds_check));
Aart Bik22af3be2015-09-10 12:50:58 -0700463}
Mingyao Yangf384f882014-10-22 16:08:18 -0700464
Aart Bik22af3be2015-09-10 12:50:58 -0700465TEST_F(BoundsCheckEliminationTest, LoopArrayBoundsElimination1f) {
Mingyao Yangf384f882014-10-22 16:08:18 -0700466 // for (int i=1; i<array.length; i += 2) { array[i] = 10; // Can eliminate. }
Aart Bik22af3be2015-09-10 12:50:58 -0700467 HInstruction* bounds_check = BuildSSAGraph1(graph_, &allocator_, 1, 2);
468 RunBCE();
Mingyao Yangf384f882014-10-22 16:08:18 -0700469 ASSERT_TRUE(IsRemoved(bounds_check));
470}
471
472// for (int i=array.length; i>0; i+=increment) { array[i-1] = 10; }
Aart Bik22af3be2015-09-10 12:50:58 -0700473static HInstruction* BuildSSAGraph2(HGraph *graph,
474 ArenaAllocator* allocator,
475 int initial,
476 int increment = -1,
477 IfCondition cond = kCondLE) {
Mingyao Yangf384f882014-10-22 16:08:18 -0700478 HBasicBlock* entry = new (allocator) HBasicBlock(graph);
479 graph->AddBlock(entry);
480 graph->SetEntryBlock(entry);
Calin Juravlee6e3bea2015-10-14 13:53:10 +0000481 HInstruction* parameter = new (allocator) HParameterValue(
Andreas Gampea5b09a62016-11-17 15:21:22 -0800482 graph->GetDexFile(), dex::TypeIndex(0), 0, Primitive::kPrimNot);
Mingyao Yangf384f882014-10-22 16:08:18 -0700483 entry->AddInstruction(parameter);
David Brazdil8d5b8b22015-03-24 10:51:52 +0000484
485 HInstruction* constant_initial = graph->GetIntConstant(initial);
486 HInstruction* constant_increment = graph->GetIntConstant(increment);
487 HInstruction* constant_minus_1 = graph->GetIntConstant(-1);
488 HInstruction* constant_10 = graph->GetIntConstant(10);
Mingyao Yangf384f882014-10-22 16:08:18 -0700489
490 HBasicBlock* block = new (allocator) HBasicBlock(graph);
491 graph->AddBlock(block);
492 entry->AddSuccessor(block);
493 HInstruction* null_check = new (allocator) HNullCheck(parameter, 0);
Calin Juravle154746b2015-10-06 15:46:54 +0100494 HInstruction* array_length = new (allocator) HArrayLength(null_check, 0);
Mingyao Yangf384f882014-10-22 16:08:18 -0700495 block->AddInstruction(null_check);
496 block->AddInstruction(array_length);
497 block->AddInstruction(new (allocator) HGoto());
498
499 HBasicBlock* loop_header = new (allocator) HBasicBlock(graph);
500 HBasicBlock* loop_body = new (allocator) HBasicBlock(graph);
501 HBasicBlock* exit = new (allocator) HBasicBlock(graph);
502
503 graph->AddBlock(loop_header);
504 graph->AddBlock(loop_body);
505 graph->AddBlock(exit);
506 block->AddSuccessor(loop_header);
507 loop_header->AddSuccessor(exit); // true successor
508 loop_header->AddSuccessor(loop_body); // false successor
509 loop_body->AddSuccessor(loop_header);
510
511 HPhi* phi = new (allocator) HPhi(allocator, 0, 0, Primitive::kPrimInt);
Mingyao Yangf384f882014-10-22 16:08:18 -0700512 HInstruction* cmp = nullptr;
513 if (cond == kCondLE) {
514 cmp = new (allocator) HLessThanOrEqual(phi, constant_initial);
515 } else {
516 DCHECK(cond == kCondLT);
517 cmp = new (allocator) HLessThan(phi, constant_initial);
518 }
519 HInstruction* if_inst = new (allocator) HIf(cmp);
520 loop_header->AddPhi(phi);
521 loop_header->AddInstruction(cmp);
522 loop_header->AddInstruction(if_inst);
David Brazdil1abb4192015-02-17 18:33:36 +0000523 phi->AddInput(array_length);
Mingyao Yangf384f882014-10-22 16:08:18 -0700524
525 HInstruction* add = new (allocator) HAdd(Primitive::kPrimInt, phi, constant_minus_1);
526 null_check = new (allocator) HNullCheck(parameter, 0);
Calin Juravle154746b2015-10-06 15:46:54 +0100527 array_length = new (allocator) HArrayLength(null_check, 0);
Aart Bik22af3be2015-09-10 12:50:58 -0700528 HInstruction* bounds_check = new (allocator) HBoundsCheck(add, array_length, 0);
Mingyao Yangf384f882014-10-22 16:08:18 -0700529 HInstruction* array_set = new (allocator) HArraySet(
Aart Bik22af3be2015-09-10 12:50:58 -0700530 null_check, bounds_check, constant_10, Primitive::kPrimInt, 0);
Mingyao Yangf384f882014-10-22 16:08:18 -0700531 HInstruction* add_phi = new (allocator) HAdd(Primitive::kPrimInt, phi, constant_increment);
532 loop_body->AddInstruction(add);
533 loop_body->AddInstruction(null_check);
534 loop_body->AddInstruction(array_length);
Aart Bik22af3be2015-09-10 12:50:58 -0700535 loop_body->AddInstruction(bounds_check);
Mingyao Yangf384f882014-10-22 16:08:18 -0700536 loop_body->AddInstruction(array_set);
537 loop_body->AddInstruction(add_phi);
538 loop_body->AddInstruction(new (allocator) HGoto());
539 phi->AddInput(add);
540
541 exit->AddInstruction(new (allocator) HExit());
542
Aart Bik22af3be2015-09-10 12:50:58 -0700543 return bounds_check;
Mingyao Yangf384f882014-10-22 16:08:18 -0700544}
545
Aart Bik22af3be2015-09-10 12:50:58 -0700546TEST_F(BoundsCheckEliminationTest, LoopArrayBoundsElimination2a) {
Mingyao Yangf384f882014-10-22 16:08:18 -0700547 // for (int i=array.length; i>0; i--) { array[i-1] = 10; // Can eliminate with gvn. }
Aart Bik22af3be2015-09-10 12:50:58 -0700548 HInstruction* bounds_check = BuildSSAGraph2(graph_, &allocator_, 0);
549 RunBCE();
Mingyao Yangf384f882014-10-22 16:08:18 -0700550 ASSERT_TRUE(IsRemoved(bounds_check));
Aart Bik22af3be2015-09-10 12:50:58 -0700551}
Mingyao Yangf384f882014-10-22 16:08:18 -0700552
Aart Bik22af3be2015-09-10 12:50:58 -0700553TEST_F(BoundsCheckEliminationTest, LoopArrayBoundsElimination2b) {
Mingyao Yangf384f882014-10-22 16:08:18 -0700554 // for (int i=array.length; i>1; i--) { array[i-1] = 10; // Can eliminate. }
Aart Bik22af3be2015-09-10 12:50:58 -0700555 HInstruction* bounds_check = BuildSSAGraph2(graph_, &allocator_, 1);
556 RunBCE();
Mingyao Yangf384f882014-10-22 16:08:18 -0700557 ASSERT_TRUE(IsRemoved(bounds_check));
Aart Bik22af3be2015-09-10 12:50:58 -0700558}
Mingyao Yangf384f882014-10-22 16:08:18 -0700559
Aart Bik22af3be2015-09-10 12:50:58 -0700560TEST_F(BoundsCheckEliminationTest, LoopArrayBoundsElimination2c) {
Mingyao Yangf384f882014-10-22 16:08:18 -0700561 // for (int i=array.length; i>-1; i--) { array[i-1] = 10; // Can't eliminate. }
Aart Bik22af3be2015-09-10 12:50:58 -0700562 HInstruction* bounds_check = BuildSSAGraph2(graph_, &allocator_, -1);
563 RunBCE();
Mingyao Yangf384f882014-10-22 16:08:18 -0700564 ASSERT_FALSE(IsRemoved(bounds_check));
Aart Bik22af3be2015-09-10 12:50:58 -0700565}
Mingyao Yangf384f882014-10-22 16:08:18 -0700566
Aart Bik22af3be2015-09-10 12:50:58 -0700567TEST_F(BoundsCheckEliminationTest, LoopArrayBoundsElimination2d) {
Mingyao Yangf384f882014-10-22 16:08:18 -0700568 // for (int i=array.length; i>=0; i--) { array[i-1] = 10; // Can't eliminate. }
Aart Bik22af3be2015-09-10 12:50:58 -0700569 HInstruction* bounds_check = BuildSSAGraph2(graph_, &allocator_, 0, -1, kCondLT);
570 RunBCE();
Mingyao Yangf384f882014-10-22 16:08:18 -0700571 ASSERT_FALSE(IsRemoved(bounds_check));
Aart Bik22af3be2015-09-10 12:50:58 -0700572}
Mingyao Yangf384f882014-10-22 16:08:18 -0700573
Aart Bik22af3be2015-09-10 12:50:58 -0700574TEST_F(BoundsCheckEliminationTest, LoopArrayBoundsElimination2e) {
Mingyao Yangf384f882014-10-22 16:08:18 -0700575 // for (int i=array.length; i>0; i-=2) { array[i-1] = 10; // Can eliminate. }
Aart Bik22af3be2015-09-10 12:50:58 -0700576 HInstruction* bounds_check = BuildSSAGraph2(graph_, &allocator_, 0, -2);
577 RunBCE();
Mingyao Yangf384f882014-10-22 16:08:18 -0700578 ASSERT_TRUE(IsRemoved(bounds_check));
579}
580
Mingyao Yang8c8bad82015-02-09 18:13:26 -0800581// int[] array = new int[10];
Mingyao Yangf384f882014-10-22 16:08:18 -0700582// for (int i=0; i<10; i+=increment) { array[i] = 10; }
Aart Bik22af3be2015-09-10 12:50:58 -0700583static HInstruction* BuildSSAGraph3(HGraph* graph,
584 ArenaAllocator* allocator,
585 int initial,
586 int increment,
587 IfCondition cond) {
Mingyao Yangf384f882014-10-22 16:08:18 -0700588 HBasicBlock* entry = new (allocator) HBasicBlock(graph);
589 graph->AddBlock(entry);
590 graph->SetEntryBlock(entry);
David Brazdil8d5b8b22015-03-24 10:51:52 +0000591
592 HInstruction* constant_10 = graph->GetIntConstant(10);
593 HInstruction* constant_initial = graph->GetIntConstant(initial);
594 HInstruction* constant_increment = graph->GetIntConstant(increment);
Mingyao Yangf384f882014-10-22 16:08:18 -0700595
596 HBasicBlock* block = new (allocator) HBasicBlock(graph);
597 graph->AddBlock(block);
598 entry->AddSuccessor(block);
Nicolas Geoffray69aa6012015-06-09 10:34:25 +0100599 HInstruction* new_array = new (allocator) HNewArray(
600 constant_10,
601 graph->GetCurrentMethod(),
602 0,
Andreas Gampea5b09a62016-11-17 15:21:22 -0800603 dex::TypeIndex(static_cast<uint16_t>(Primitive::kPrimInt)),
Nicolas Geoffray69aa6012015-06-09 10:34:25 +0100604 graph->GetDexFile(),
605 kQuickAllocArray);
Mingyao Yangf384f882014-10-22 16:08:18 -0700606 block->AddInstruction(new_array);
607 block->AddInstruction(new (allocator) HGoto());
608
609 HBasicBlock* loop_header = new (allocator) HBasicBlock(graph);
610 HBasicBlock* loop_body = new (allocator) HBasicBlock(graph);
611 HBasicBlock* exit = new (allocator) HBasicBlock(graph);
612
613 graph->AddBlock(loop_header);
614 graph->AddBlock(loop_body);
615 graph->AddBlock(exit);
616 block->AddSuccessor(loop_header);
617 loop_header->AddSuccessor(exit); // true successor
618 loop_header->AddSuccessor(loop_body); // false successor
619 loop_body->AddSuccessor(loop_header);
620
621 HPhi* phi = new (allocator) HPhi(allocator, 0, 0, Primitive::kPrimInt);
Mingyao Yangf384f882014-10-22 16:08:18 -0700622 HInstruction* cmp = nullptr;
623 if (cond == kCondGE) {
624 cmp = new (allocator) HGreaterThanOrEqual(phi, constant_10);
625 } else {
626 DCHECK(cond == kCondGT);
627 cmp = new (allocator) HGreaterThan(phi, constant_10);
628 }
629 HInstruction* if_inst = new (allocator) HIf(cmp);
630 loop_header->AddPhi(phi);
631 loop_header->AddInstruction(cmp);
632 loop_header->AddInstruction(if_inst);
David Brazdil1abb4192015-02-17 18:33:36 +0000633 phi->AddInput(constant_initial);
Mingyao Yangf384f882014-10-22 16:08:18 -0700634
635 HNullCheck* null_check = new (allocator) HNullCheck(new_array, 0);
Calin Juravle154746b2015-10-06 15:46:54 +0100636 HArrayLength* array_length = new (allocator) HArrayLength(null_check, 0);
Aart Bik22af3be2015-09-10 12:50:58 -0700637 HInstruction* bounds_check = new (allocator) HBoundsCheck(phi, array_length, 0);
Mingyao Yangf384f882014-10-22 16:08:18 -0700638 HInstruction* array_set = new (allocator) HArraySet(
Aart Bik22af3be2015-09-10 12:50:58 -0700639 null_check, bounds_check, constant_10, Primitive::kPrimInt, 0);
Mingyao Yangf384f882014-10-22 16:08:18 -0700640 HInstruction* add = new (allocator) HAdd(Primitive::kPrimInt, phi, constant_increment);
641 loop_body->AddInstruction(null_check);
642 loop_body->AddInstruction(array_length);
Aart Bik22af3be2015-09-10 12:50:58 -0700643 loop_body->AddInstruction(bounds_check);
Mingyao Yangf384f882014-10-22 16:08:18 -0700644 loop_body->AddInstruction(array_set);
645 loop_body->AddInstruction(add);
646 loop_body->AddInstruction(new (allocator) HGoto());
647 phi->AddInput(add);
648
649 exit->AddInstruction(new (allocator) HExit());
650
Aart Bik22af3be2015-09-10 12:50:58 -0700651 return bounds_check;
Mingyao Yangf384f882014-10-22 16:08:18 -0700652}
653
Aart Bik22af3be2015-09-10 12:50:58 -0700654TEST_F(BoundsCheckEliminationTest, LoopArrayBoundsElimination3a) {
Mingyao Yang8c8bad82015-02-09 18:13:26 -0800655 // int[] array = new int[10];
Mingyao Yangf384f882014-10-22 16:08:18 -0700656 // for (int i=0; i<10; i++) { array[i] = 10; // Can eliminate. }
Aart Bik22af3be2015-09-10 12:50:58 -0700657 HInstruction* bounds_check = BuildSSAGraph3(graph_, &allocator_, 0, 1, kCondGE);
658 RunBCE();
Mingyao Yangf384f882014-10-22 16:08:18 -0700659 ASSERT_TRUE(IsRemoved(bounds_check));
Aart Bik22af3be2015-09-10 12:50:58 -0700660}
Mingyao Yangf384f882014-10-22 16:08:18 -0700661
Aart Bik22af3be2015-09-10 12:50:58 -0700662TEST_F(BoundsCheckEliminationTest, LoopArrayBoundsElimination3b) {
Mingyao Yang8c8bad82015-02-09 18:13:26 -0800663 // int[] array = new int[10];
Mingyao Yangf384f882014-10-22 16:08:18 -0700664 // for (int i=1; i<10; i++) { array[i] = 10; // Can eliminate. }
Aart Bik22af3be2015-09-10 12:50:58 -0700665 HInstruction* bounds_check = BuildSSAGraph3(graph_, &allocator_, 1, 1, kCondGE);
666 RunBCE();
Mingyao Yangf384f882014-10-22 16:08:18 -0700667 ASSERT_TRUE(IsRemoved(bounds_check));
Aart Bik22af3be2015-09-10 12:50:58 -0700668}
Mingyao Yangf384f882014-10-22 16:08:18 -0700669
Aart Bik22af3be2015-09-10 12:50:58 -0700670TEST_F(BoundsCheckEliminationTest, LoopArrayBoundsElimination3c) {
Mingyao Yang8c8bad82015-02-09 18:13:26 -0800671 // int[] array = new int[10];
Mingyao Yangf384f882014-10-22 16:08:18 -0700672 // for (int i=0; i<=10; i++) { array[i] = 10; // Can't eliminate. }
Aart Bik22af3be2015-09-10 12:50:58 -0700673 HInstruction* bounds_check = BuildSSAGraph3(graph_, &allocator_, 0, 1, kCondGT);
674 RunBCE();
Mingyao Yangf384f882014-10-22 16:08:18 -0700675 ASSERT_FALSE(IsRemoved(bounds_check));
Aart Bik22af3be2015-09-10 12:50:58 -0700676}
Mingyao Yangf384f882014-10-22 16:08:18 -0700677
Aart Bik22af3be2015-09-10 12:50:58 -0700678TEST_F(BoundsCheckEliminationTest, LoopArrayBoundsElimination3d) {
Mingyao Yang8c8bad82015-02-09 18:13:26 -0800679 // int[] array = new int[10];
Mingyao Yangf384f882014-10-22 16:08:18 -0700680 // for (int i=1; i<10; i+=8) { array[i] = 10; // Can eliminate. }
Aart Bik22af3be2015-09-10 12:50:58 -0700681 HInstruction* bounds_check = BuildSSAGraph3(graph_, &allocator_, 1, 8, kCondGE);
682 RunBCE();
Mingyao Yangf384f882014-10-22 16:08:18 -0700683 ASSERT_TRUE(IsRemoved(bounds_check));
684}
685
686// for (int i=initial; i<array.length; i++) { array[array.length-i-1] = 10; }
Aart Bik22af3be2015-09-10 12:50:58 -0700687static HInstruction* BuildSSAGraph4(HGraph* graph,
688 ArenaAllocator* allocator,
689 int initial,
690 IfCondition cond = kCondGE) {
Mingyao Yangf384f882014-10-22 16:08:18 -0700691 HBasicBlock* entry = new (allocator) HBasicBlock(graph);
692 graph->AddBlock(entry);
693 graph->SetEntryBlock(entry);
Calin Juravlee6e3bea2015-10-14 13:53:10 +0000694 HInstruction* parameter = new (allocator) HParameterValue(
Andreas Gampea5b09a62016-11-17 15:21:22 -0800695 graph->GetDexFile(), dex::TypeIndex(0), 0, Primitive::kPrimNot);
Mingyao Yangf384f882014-10-22 16:08:18 -0700696 entry->AddInstruction(parameter);
David Brazdil8d5b8b22015-03-24 10:51:52 +0000697
698 HInstruction* constant_initial = graph->GetIntConstant(initial);
699 HInstruction* constant_1 = graph->GetIntConstant(1);
700 HInstruction* constant_10 = graph->GetIntConstant(10);
701 HInstruction* constant_minus_1 = graph->GetIntConstant(-1);
Mingyao Yangf384f882014-10-22 16:08:18 -0700702
703 HBasicBlock* block = new (allocator) HBasicBlock(graph);
704 graph->AddBlock(block);
705 entry->AddSuccessor(block);
706 block->AddInstruction(new (allocator) HGoto());
707
708 HBasicBlock* loop_header = new (allocator) HBasicBlock(graph);
709 HBasicBlock* loop_body = new (allocator) HBasicBlock(graph);
710 HBasicBlock* exit = new (allocator) HBasicBlock(graph);
711
712 graph->AddBlock(loop_header);
713 graph->AddBlock(loop_body);
714 graph->AddBlock(exit);
715 block->AddSuccessor(loop_header);
716 loop_header->AddSuccessor(exit); // true successor
717 loop_header->AddSuccessor(loop_body); // false successor
718 loop_body->AddSuccessor(loop_header);
719
720 HPhi* phi = new (allocator) HPhi(allocator, 0, 0, Primitive::kPrimInt);
Mingyao Yangf384f882014-10-22 16:08:18 -0700721 HInstruction* null_check = new (allocator) HNullCheck(parameter, 0);
Calin Juravle154746b2015-10-06 15:46:54 +0100722 HInstruction* array_length = new (allocator) HArrayLength(null_check, 0);
Mingyao Yangf384f882014-10-22 16:08:18 -0700723 HInstruction* cmp = nullptr;
724 if (cond == kCondGE) {
725 cmp = new (allocator) HGreaterThanOrEqual(phi, array_length);
726 } else if (cond == kCondGT) {
727 cmp = new (allocator) HGreaterThan(phi, array_length);
728 }
729 HInstruction* if_inst = new (allocator) HIf(cmp);
730 loop_header->AddPhi(phi);
731 loop_header->AddInstruction(null_check);
732 loop_header->AddInstruction(array_length);
733 loop_header->AddInstruction(cmp);
734 loop_header->AddInstruction(if_inst);
David Brazdil1abb4192015-02-17 18:33:36 +0000735 phi->AddInput(constant_initial);
Mingyao Yangf384f882014-10-22 16:08:18 -0700736
737 null_check = new (allocator) HNullCheck(parameter, 0);
Calin Juravle154746b2015-10-06 15:46:54 +0100738 array_length = new (allocator) HArrayLength(null_check, 0);
Mingyao Yangf384f882014-10-22 16:08:18 -0700739 HInstruction* sub = new (allocator) HSub(Primitive::kPrimInt, array_length, phi);
740 HInstruction* add_minus_1 = new (allocator)
741 HAdd(Primitive::kPrimInt, sub, constant_minus_1);
Aart Bik22af3be2015-09-10 12:50:58 -0700742 HInstruction* bounds_check = new (allocator) HBoundsCheck(add_minus_1, array_length, 0);
Mingyao Yangf384f882014-10-22 16:08:18 -0700743 HInstruction* array_set = new (allocator) HArraySet(
Aart Bik22af3be2015-09-10 12:50:58 -0700744 null_check, bounds_check, constant_10, Primitive::kPrimInt, 0);
Mingyao Yangf384f882014-10-22 16:08:18 -0700745 HInstruction* add = new (allocator) HAdd(Primitive::kPrimInt, phi, constant_1);
746 loop_body->AddInstruction(null_check);
747 loop_body->AddInstruction(array_length);
748 loop_body->AddInstruction(sub);
749 loop_body->AddInstruction(add_minus_1);
Aart Bik22af3be2015-09-10 12:50:58 -0700750 loop_body->AddInstruction(bounds_check);
Mingyao Yangf384f882014-10-22 16:08:18 -0700751 loop_body->AddInstruction(array_set);
752 loop_body->AddInstruction(add);
753 loop_body->AddInstruction(new (allocator) HGoto());
754 phi->AddInput(add);
755
756 exit->AddInstruction(new (allocator) HExit());
757
Aart Bik22af3be2015-09-10 12:50:58 -0700758 return bounds_check;
Mingyao Yangf384f882014-10-22 16:08:18 -0700759}
760
Aart Bik22af3be2015-09-10 12:50:58 -0700761TEST_F(BoundsCheckEliminationTest, LoopArrayBoundsElimination4a) {
Mingyao Yangf384f882014-10-22 16:08:18 -0700762 // for (int i=0; i<array.length; i++) { array[array.length-i-1] = 10; // Can eliminate with gvn. }
Aart Bik22af3be2015-09-10 12:50:58 -0700763 HInstruction* bounds_check = BuildSSAGraph4(graph_, &allocator_, 0);
764 RunBCE();
Mingyao Yangf384f882014-10-22 16:08:18 -0700765 ASSERT_TRUE(IsRemoved(bounds_check));
Aart Bik22af3be2015-09-10 12:50:58 -0700766}
Mingyao Yangf384f882014-10-22 16:08:18 -0700767
Aart Bik22af3be2015-09-10 12:50:58 -0700768TEST_F(BoundsCheckEliminationTest, LoopArrayBoundsElimination4b) {
Mingyao Yangf384f882014-10-22 16:08:18 -0700769 // for (int i=1; i<array.length; i++) { array[array.length-i-1] = 10; // Can eliminate. }
Aart Bik22af3be2015-09-10 12:50:58 -0700770 HInstruction* bounds_check = BuildSSAGraph4(graph_, &allocator_, 1);
771 RunBCE();
Mingyao Yangf384f882014-10-22 16:08:18 -0700772 ASSERT_TRUE(IsRemoved(bounds_check));
Aart Bik22af3be2015-09-10 12:50:58 -0700773}
Mingyao Yangf384f882014-10-22 16:08:18 -0700774
Aart Bik22af3be2015-09-10 12:50:58 -0700775TEST_F(BoundsCheckEliminationTest, LoopArrayBoundsElimination4c) {
Mingyao Yangf384f882014-10-22 16:08:18 -0700776 // for (int i=0; i<=array.length; i++) { array[array.length-i] = 10; // Can't eliminate. }
Aart Bik22af3be2015-09-10 12:50:58 -0700777 HInstruction* bounds_check = BuildSSAGraph4(graph_, &allocator_, 0, kCondGT);
778 RunBCE();
Mingyao Yangf384f882014-10-22 16:08:18 -0700779 ASSERT_FALSE(IsRemoved(bounds_check));
780}
781
782// Bubble sort:
783// (Every array access bounds-check can be eliminated.)
784// for (int i=0; i<array.length-1; i++) {
785// for (int j=0; j<array.length-i-1; j++) {
786// if (array[j] > array[j+1]) {
787// int temp = array[j+1];
788// array[j+1] = array[j];
789// array[j] = temp;
790// }
791// }
792// }
Aart Bik22af3be2015-09-10 12:50:58 -0700793TEST_F(BoundsCheckEliminationTest, BubbleSortArrayBoundsElimination) {
794 HBasicBlock* entry = new (&allocator_) HBasicBlock(graph_);
795 graph_->AddBlock(entry);
796 graph_->SetEntryBlock(entry);
Calin Juravlee6e3bea2015-10-14 13:53:10 +0000797 HInstruction* parameter = new (&allocator_) HParameterValue(
Andreas Gampea5b09a62016-11-17 15:21:22 -0800798 graph_->GetDexFile(), dex::TypeIndex(0), 0, Primitive::kPrimNot);
Mingyao Yangf384f882014-10-22 16:08:18 -0700799 entry->AddInstruction(parameter);
David Brazdil8d5b8b22015-03-24 10:51:52 +0000800
Aart Bik22af3be2015-09-10 12:50:58 -0700801 HInstruction* constant_0 = graph_->GetIntConstant(0);
802 HInstruction* constant_minus_1 = graph_->GetIntConstant(-1);
803 HInstruction* constant_1 = graph_->GetIntConstant(1);
Mingyao Yangf384f882014-10-22 16:08:18 -0700804
Aart Bik22af3be2015-09-10 12:50:58 -0700805 HBasicBlock* block = new (&allocator_) HBasicBlock(graph_);
806 graph_->AddBlock(block);
Mingyao Yangf384f882014-10-22 16:08:18 -0700807 entry->AddSuccessor(block);
Aart Bik22af3be2015-09-10 12:50:58 -0700808 block->AddInstruction(new (&allocator_) HGoto());
Mingyao Yangf384f882014-10-22 16:08:18 -0700809
Aart Bik22af3be2015-09-10 12:50:58 -0700810 HBasicBlock* exit = new (&allocator_) HBasicBlock(graph_);
811 graph_->AddBlock(exit);
812 exit->AddInstruction(new (&allocator_) HExit());
Mingyao Yangf384f882014-10-22 16:08:18 -0700813
Aart Bik22af3be2015-09-10 12:50:58 -0700814 HBasicBlock* outer_header = new (&allocator_) HBasicBlock(graph_);
815 graph_->AddBlock(outer_header);
816 HPhi* phi_i = new (&allocator_) HPhi(&allocator_, 0, 0, Primitive::kPrimInt);
817 HNullCheck* null_check = new (&allocator_) HNullCheck(parameter, 0);
Calin Juravle154746b2015-10-06 15:46:54 +0100818 HArrayLength* array_length = new (&allocator_) HArrayLength(null_check, 0);
Aart Bik22af3be2015-09-10 12:50:58 -0700819 HAdd* add = new (&allocator_) HAdd(Primitive::kPrimInt, array_length, constant_minus_1);
820 HInstruction* cmp = new (&allocator_) HGreaterThanOrEqual(phi_i, add);
821 HIf* if_inst = new (&allocator_) HIf(cmp);
Mingyao Yangf384f882014-10-22 16:08:18 -0700822 outer_header->AddPhi(phi_i);
823 outer_header->AddInstruction(null_check);
824 outer_header->AddInstruction(array_length);
825 outer_header->AddInstruction(add);
826 outer_header->AddInstruction(cmp);
827 outer_header->AddInstruction(if_inst);
David Brazdil1abb4192015-02-17 18:33:36 +0000828 phi_i->AddInput(constant_0);
Mingyao Yangf384f882014-10-22 16:08:18 -0700829
Aart Bik22af3be2015-09-10 12:50:58 -0700830 HBasicBlock* inner_header = new (&allocator_) HBasicBlock(graph_);
831 graph_->AddBlock(inner_header);
832 HPhi* phi_j = new (&allocator_) HPhi(&allocator_, 0, 0, Primitive::kPrimInt);
833 null_check = new (&allocator_) HNullCheck(parameter, 0);
Calin Juravle154746b2015-10-06 15:46:54 +0100834 array_length = new (&allocator_) HArrayLength(null_check, 0);
Aart Bik22af3be2015-09-10 12:50:58 -0700835 HSub* sub = new (&allocator_) HSub(Primitive::kPrimInt, array_length, phi_i);
836 add = new (&allocator_) HAdd(Primitive::kPrimInt, sub, constant_minus_1);
837 cmp = new (&allocator_) HGreaterThanOrEqual(phi_j, add);
838 if_inst = new (&allocator_) HIf(cmp);
Mingyao Yangf384f882014-10-22 16:08:18 -0700839 inner_header->AddPhi(phi_j);
840 inner_header->AddInstruction(null_check);
841 inner_header->AddInstruction(array_length);
842 inner_header->AddInstruction(sub);
843 inner_header->AddInstruction(add);
844 inner_header->AddInstruction(cmp);
845 inner_header->AddInstruction(if_inst);
David Brazdil1abb4192015-02-17 18:33:36 +0000846 phi_j->AddInput(constant_0);
Mingyao Yangf384f882014-10-22 16:08:18 -0700847
Aart Bik22af3be2015-09-10 12:50:58 -0700848 HBasicBlock* inner_body_compare = new (&allocator_) HBasicBlock(graph_);
849 graph_->AddBlock(inner_body_compare);
850 null_check = new (&allocator_) HNullCheck(parameter, 0);
Calin Juravle154746b2015-10-06 15:46:54 +0100851 array_length = new (&allocator_) HArrayLength(null_check, 0);
Aart Bik22af3be2015-09-10 12:50:58 -0700852 HBoundsCheck* bounds_check1 = new (&allocator_) HBoundsCheck(phi_j, array_length, 0);
853 HArrayGet* array_get_j = new (&allocator_)
Calin Juravle154746b2015-10-06 15:46:54 +0100854 HArrayGet(null_check, bounds_check1, Primitive::kPrimInt, 0);
Mingyao Yangf384f882014-10-22 16:08:18 -0700855 inner_body_compare->AddInstruction(null_check);
856 inner_body_compare->AddInstruction(array_length);
857 inner_body_compare->AddInstruction(bounds_check1);
858 inner_body_compare->AddInstruction(array_get_j);
Aart Bik22af3be2015-09-10 12:50:58 -0700859 HInstruction* j_plus_1 = new (&allocator_) HAdd(Primitive::kPrimInt, phi_j, constant_1);
860 null_check = new (&allocator_) HNullCheck(parameter, 0);
Calin Juravle154746b2015-10-06 15:46:54 +0100861 array_length = new (&allocator_) HArrayLength(null_check, 0);
Aart Bik22af3be2015-09-10 12:50:58 -0700862 HBoundsCheck* bounds_check2 = new (&allocator_) HBoundsCheck(j_plus_1, array_length, 0);
863 HArrayGet* array_get_j_plus_1 = new (&allocator_)
Calin Juravle154746b2015-10-06 15:46:54 +0100864 HArrayGet(null_check, bounds_check2, Primitive::kPrimInt, 0);
Aart Bik22af3be2015-09-10 12:50:58 -0700865 cmp = new (&allocator_) HGreaterThanOrEqual(array_get_j, array_get_j_plus_1);
866 if_inst = new (&allocator_) HIf(cmp);
Mingyao Yangf384f882014-10-22 16:08:18 -0700867 inner_body_compare->AddInstruction(j_plus_1);
868 inner_body_compare->AddInstruction(null_check);
869 inner_body_compare->AddInstruction(array_length);
870 inner_body_compare->AddInstruction(bounds_check2);
871 inner_body_compare->AddInstruction(array_get_j_plus_1);
872 inner_body_compare->AddInstruction(cmp);
873 inner_body_compare->AddInstruction(if_inst);
874
Aart Bik22af3be2015-09-10 12:50:58 -0700875 HBasicBlock* inner_body_swap = new (&allocator_) HBasicBlock(graph_);
876 graph_->AddBlock(inner_body_swap);
877 j_plus_1 = new (&allocator_) HAdd(Primitive::kPrimInt, phi_j, constant_1);
Mingyao Yangf384f882014-10-22 16:08:18 -0700878 // temp = array[j+1]
Aart Bik22af3be2015-09-10 12:50:58 -0700879 null_check = new (&allocator_) HNullCheck(parameter, 0);
Calin Juravle154746b2015-10-06 15:46:54 +0100880 array_length = new (&allocator_) HArrayLength(null_check, 0);
Aart Bik22af3be2015-09-10 12:50:58 -0700881 HInstruction* bounds_check3 = new (&allocator_) HBoundsCheck(j_plus_1, array_length, 0);
882 array_get_j_plus_1 = new (&allocator_)
Calin Juravle154746b2015-10-06 15:46:54 +0100883 HArrayGet(null_check, bounds_check3, Primitive::kPrimInt, 0);
Mingyao Yangf384f882014-10-22 16:08:18 -0700884 inner_body_swap->AddInstruction(j_plus_1);
885 inner_body_swap->AddInstruction(null_check);
886 inner_body_swap->AddInstruction(array_length);
887 inner_body_swap->AddInstruction(bounds_check3);
888 inner_body_swap->AddInstruction(array_get_j_plus_1);
889 // array[j+1] = array[j]
Aart Bik22af3be2015-09-10 12:50:58 -0700890 null_check = new (&allocator_) HNullCheck(parameter, 0);
Calin Juravle154746b2015-10-06 15:46:54 +0100891 array_length = new (&allocator_) HArrayLength(null_check, 0);
Aart Bik22af3be2015-09-10 12:50:58 -0700892 HInstruction* bounds_check4 = new (&allocator_) HBoundsCheck(phi_j, array_length, 0);
893 array_get_j = new (&allocator_)
Calin Juravle154746b2015-10-06 15:46:54 +0100894 HArrayGet(null_check, bounds_check4, Primitive::kPrimInt, 0);
Mingyao Yangf384f882014-10-22 16:08:18 -0700895 inner_body_swap->AddInstruction(null_check);
896 inner_body_swap->AddInstruction(array_length);
897 inner_body_swap->AddInstruction(bounds_check4);
898 inner_body_swap->AddInstruction(array_get_j);
Aart Bik22af3be2015-09-10 12:50:58 -0700899 null_check = new (&allocator_) HNullCheck(parameter, 0);
Calin Juravle154746b2015-10-06 15:46:54 +0100900 array_length = new (&allocator_) HArrayLength(null_check, 0);
Aart Bik22af3be2015-09-10 12:50:58 -0700901 HInstruction* bounds_check5 = new (&allocator_) HBoundsCheck(j_plus_1, array_length, 0);
902 HArraySet* array_set_j_plus_1 = new (&allocator_)
Mingyao Yangf384f882014-10-22 16:08:18 -0700903 HArraySet(null_check, bounds_check5, array_get_j, Primitive::kPrimInt, 0);
904 inner_body_swap->AddInstruction(null_check);
905 inner_body_swap->AddInstruction(array_length);
906 inner_body_swap->AddInstruction(bounds_check5);
907 inner_body_swap->AddInstruction(array_set_j_plus_1);
908 // array[j] = temp
Aart Bik22af3be2015-09-10 12:50:58 -0700909 null_check = new (&allocator_) HNullCheck(parameter, 0);
Calin Juravle154746b2015-10-06 15:46:54 +0100910 array_length = new (&allocator_) HArrayLength(null_check, 0);
Aart Bik22af3be2015-09-10 12:50:58 -0700911 HInstruction* bounds_check6 = new (&allocator_) HBoundsCheck(phi_j, array_length, 0);
912 HArraySet* array_set_j = new (&allocator_)
Mingyao Yangf384f882014-10-22 16:08:18 -0700913 HArraySet(null_check, bounds_check6, array_get_j_plus_1, Primitive::kPrimInt, 0);
914 inner_body_swap->AddInstruction(null_check);
915 inner_body_swap->AddInstruction(array_length);
916 inner_body_swap->AddInstruction(bounds_check6);
917 inner_body_swap->AddInstruction(array_set_j);
Aart Bik22af3be2015-09-10 12:50:58 -0700918 inner_body_swap->AddInstruction(new (&allocator_) HGoto());
Mingyao Yangf384f882014-10-22 16:08:18 -0700919
Aart Bik22af3be2015-09-10 12:50:58 -0700920 HBasicBlock* inner_body_add = new (&allocator_) HBasicBlock(graph_);
921 graph_->AddBlock(inner_body_add);
922 add = new (&allocator_) HAdd(Primitive::kPrimInt, phi_j, constant_1);
Mingyao Yangf384f882014-10-22 16:08:18 -0700923 inner_body_add->AddInstruction(add);
Aart Bik22af3be2015-09-10 12:50:58 -0700924 inner_body_add->AddInstruction(new (&allocator_) HGoto());
Mingyao Yangf384f882014-10-22 16:08:18 -0700925 phi_j->AddInput(add);
926
Aart Bik22af3be2015-09-10 12:50:58 -0700927 HBasicBlock* outer_body_add = new (&allocator_) HBasicBlock(graph_);
928 graph_->AddBlock(outer_body_add);
929 add = new (&allocator_) HAdd(Primitive::kPrimInt, phi_i, constant_1);
Mingyao Yangf384f882014-10-22 16:08:18 -0700930 outer_body_add->AddInstruction(add);
Aart Bik22af3be2015-09-10 12:50:58 -0700931 outer_body_add->AddInstruction(new (&allocator_) HGoto());
Mingyao Yangf384f882014-10-22 16:08:18 -0700932 phi_i->AddInput(add);
933
934 block->AddSuccessor(outer_header);
935 outer_header->AddSuccessor(exit);
936 outer_header->AddSuccessor(inner_header);
937 inner_header->AddSuccessor(outer_body_add);
938 inner_header->AddSuccessor(inner_body_compare);
939 inner_body_compare->AddSuccessor(inner_body_add);
940 inner_body_compare->AddSuccessor(inner_body_swap);
941 inner_body_swap->AddSuccessor(inner_body_add);
942 inner_body_add->AddSuccessor(inner_header);
943 outer_body_add->AddSuccessor(outer_header);
944
Aart Bik22af3be2015-09-10 12:50:58 -0700945 RunBCE(); // gvn removes same bounds check already
Mingyao Yangf384f882014-10-22 16:08:18 -0700946
Mingyao Yangf384f882014-10-22 16:08:18 -0700947 ASSERT_TRUE(IsRemoved(bounds_check1));
948 ASSERT_TRUE(IsRemoved(bounds_check2));
949 ASSERT_TRUE(IsRemoved(bounds_check3));
950 ASSERT_TRUE(IsRemoved(bounds_check4));
951 ASSERT_TRUE(IsRemoved(bounds_check5));
952 ASSERT_TRUE(IsRemoved(bounds_check6));
953}
954
955} // namespace art