1 /* 2 * Copyright (C) 2024 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 public class Main { 18 // Numbers have to be inlined for the bug to trigger: we cannot define this as a generic method 19 // that takes e.g. 12 as a parameter. We can define some methods to test different cases. Each 20 // method is the same as doing: 21 // result = initial_value; 22 // for (int i = start; i < end; ++i) { result += i * 10; } 23 // return result; 24 // As long as `end` is 5 or less 25 $noinline$nestedLoopCalculation_0_2_12()26 private static int $noinline$nestedLoopCalculation_0_2_12() { 27 int result = 12; 28 for (int outer = 0; outer < 2; ++outer) { 29 int first_inner; 30 for (first_inner = 5; first_inner > outer; first_inner--) {} 31 for (int second_inner = 0; second_inner < 10; second_inner++) { 32 result += first_inner; 33 } 34 } 35 return result; 36 } 37 $noinline$nestedLoopCalculation_1_3_12()38 private static int $noinline$nestedLoopCalculation_1_3_12() { 39 int result = 12; 40 for (int outer = 1; outer < 3; ++outer) { 41 int first_inner; 42 for (first_inner = 5; first_inner > outer; first_inner--) {} 43 for (int second_inner = 0; second_inner < 10; second_inner++) { 44 result += first_inner; 45 } 46 } 47 return result; 48 } 49 $noinline$nestedLoopCalculation_minus2_2_12()50 private static int $noinline$nestedLoopCalculation_minus2_2_12() { 51 int result = 12; 52 for (int outer = -2; outer < 2; ++outer) { 53 int first_inner; 54 for (first_inner = 5; first_inner > outer; first_inner--) {} 55 for (int second_inner = 0; second_inner < 10; second_inner++) { 56 result += first_inner; 57 } 58 } 59 return result; 60 } 61 $noinline$nestedLoopCalculation_0_5_12()62 private static int $noinline$nestedLoopCalculation_0_5_12() { 63 int result = 12; 64 for (int outer = 0; outer < 5; ++outer) { 65 int first_inner; 66 for (first_inner = 5; first_inner > outer; first_inner--) {} 67 for (int second_inner = 0; second_inner < 10; second_inner++) { 68 result += first_inner; 69 } 70 } 71 return result; 72 } 73 main(String[] f)74 public static void main(String[] f) { 75 // 12 + 0 + 10 = 22 76 assertIntEquals(22, $noinline$nestedLoopCalculation_0_2_12()); 77 // 12 + 10 + 20 = 42 78 assertIntEquals(42, $noinline$nestedLoopCalculation_1_3_12()); 79 // 12 + (-20) + (-10) + 0 + 10 = -8 80 assertIntEquals(-8, $noinline$nestedLoopCalculation_minus2_2_12()); 81 // 12 + 0 + 10 + 20 + 30 + 40 = 112 82 assertIntEquals(112, $noinline$nestedLoopCalculation_0_5_12()); 83 } 84 assertIntEquals(int expected, int result)85 public static void assertIntEquals(int expected, int result) { 86 if (expected != result) { 87 throw new Error("Expected: " + expected + ", found: " + result); 88 } 89 } 90 } 91