1f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko/*
2f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko * Copyright (C) 2015 The Android Open Source Project
3f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko *
4f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko * Licensed under the Apache License, Version 2.0 (the "License");
5f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko * you may not use this file except in compliance with the License.
6f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko * You may obtain a copy of the License at
7f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko *
8f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko *      http://www.apache.org/licenses/LICENSE-2.0
9f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko *
10f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko * Unless required by applicable law or agreed to in writing, software
11f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko * distributed under the License is distributed on an "AS IS" BASIS,
12f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko * See the License for the specific language governing permissions and
14f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko * limitations under the License.
15f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko */
16f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko
17f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Markopublic class Main {
18f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko
19f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko  public static void assertIntEquals(int expected, int result) {
20f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko    if (expected != result) {
21f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko      throw new Error("Expected: " + expected + ", found: " + result);
22f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko    }
23f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko  }
24f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko
25cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko  public static void assertStringEquals(String expected, String result) {
26cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko    if (expected != null ? !expected.equals(result) : result != null) {
27cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko      throw new Error("Expected: " + expected + ", found: " + result);
28cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko    }
29cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko  }
30cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko
31f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko  public static boolean doThrow = false;
32f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko
33f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko  private static int $noinline$foo(int x) {
34f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko    if (doThrow) { throw new Error(); }
35f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko    return x;
36f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko  }
37f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko
38f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko  /// CHECK-START: int Main.testSimple(int) sharpening (before)
39f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko  /// CHECK:                InvokeStaticOrDirect method_load_kind:dex_cache_via_method
40f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko
41f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko  /// CHECK-START-ARM: int Main.testSimple(int) sharpening (after)
42f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko  /// CHECK-NOT:            ArmDexCacheArraysBase
43f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko  /// CHECK:                InvokeStaticOrDirect method_load_kind:dex_cache_pc_relative
44f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko
45f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko  /// CHECK-START-ARM64: int Main.testSimple(int) sharpening (after)
46f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko  /// CHECK:                InvokeStaticOrDirect method_load_kind:dex_cache_pc_relative
47f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko
48f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko  /// CHECK-START-X86: int Main.testSimple(int) sharpening (after)
49f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko  /// CHECK-NOT:            X86ComputeBaseMethodAddress
50f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko  /// CHECK:                InvokeStaticOrDirect method_load_kind:dex_cache_pc_relative
51f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko
52f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko  /// CHECK-START-X86_64: int Main.testSimple(int) sharpening (after)
53f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko  /// CHECK:                InvokeStaticOrDirect method_load_kind:dex_cache_pc_relative
54f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko
55f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko  /// CHECK-START-ARM: int Main.testSimple(int) dex_cache_array_fixups_arm (after)
56f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko  /// CHECK:                ArmDexCacheArraysBase
57f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko  /// CHECK-NOT:            ArmDexCacheArraysBase
58f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko
59f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko  /// CHECK-START-X86: int Main.testSimple(int) pc_relative_fixups_x86 (after)
60f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko  /// CHECK:                X86ComputeBaseMethodAddress
61f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko  /// CHECK-NOT:            X86ComputeBaseMethodAddress
62f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko
63f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko  public static int testSimple(int x) {
64f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko    // This call should use PC-relative dex cache array load to retrieve the target method.
65f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko    return $noinline$foo(x);
66f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko  }
67f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko
68f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko  /// CHECK-START: int Main.testDiamond(boolean, int) sharpening (before)
69f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko  /// CHECK:                InvokeStaticOrDirect method_load_kind:dex_cache_via_method
70f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko
71f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko  /// CHECK-START-ARM: int Main.testDiamond(boolean, int) sharpening (after)
72f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko  /// CHECK-NOT:            ArmDexCacheArraysBase
73f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko  /// CHECK:                InvokeStaticOrDirect method_load_kind:dex_cache_pc_relative
74f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko  /// CHECK:                InvokeStaticOrDirect method_load_kind:dex_cache_pc_relative
75f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko
76f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko  /// CHECK-START-ARM64: int Main.testDiamond(boolean, int) sharpening (after)
77f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko  /// CHECK:                InvokeStaticOrDirect method_load_kind:dex_cache_pc_relative
78f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko  /// CHECK:                InvokeStaticOrDirect method_load_kind:dex_cache_pc_relative
79f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko
80f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko  /// CHECK-START-X86: int Main.testDiamond(boolean, int) sharpening (after)
81f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko  /// CHECK-NOT:            X86ComputeBaseMethodAddress
82f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko  /// CHECK:                InvokeStaticOrDirect method_load_kind:dex_cache_pc_relative
83f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko  /// CHECK:                InvokeStaticOrDirect method_load_kind:dex_cache_pc_relative
84f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko
85f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko  /// CHECK-START-X86_64: int Main.testDiamond(boolean, int) sharpening (after)
86f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko  /// CHECK:                InvokeStaticOrDirect method_load_kind:dex_cache_pc_relative
87f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko  /// CHECK:                InvokeStaticOrDirect method_load_kind:dex_cache_pc_relative
88f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko
89f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko  /// CHECK-START-ARM: int Main.testDiamond(boolean, int) dex_cache_array_fixups_arm (after)
90f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko  /// CHECK:                ArmDexCacheArraysBase
91f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko  /// CHECK-NOT:            ArmDexCacheArraysBase
92f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko
93f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko  /// CHECK-START-ARM: int Main.testDiamond(boolean, int) dex_cache_array_fixups_arm (after)
94f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko  /// CHECK:                ArmDexCacheArraysBase
95f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko  /// CHECK-NEXT:           If
96f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko
97f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko  /// CHECK-START-X86: int Main.testDiamond(boolean, int) pc_relative_fixups_x86 (after)
98f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko  /// CHECK:                X86ComputeBaseMethodAddress
99f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko  /// CHECK-NOT:            X86ComputeBaseMethodAddress
100f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko
101f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko  /// CHECK-START-X86: int Main.testDiamond(boolean, int) pc_relative_fixups_x86 (after)
102f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko  /// CHECK:                X86ComputeBaseMethodAddress
103f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko  /// CHECK-NEXT:           If
104f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko
105f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko  public static int testDiamond(boolean negate, int x) {
106f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko    // These calls should use PC-relative dex cache array loads to retrieve the target method.
107f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko    // PC-relative bases used by X86 and ARM should be pulled before the If.
108f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko    if (negate) {
109f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko      return $noinline$foo(-x);
110f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko    } else {
111f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko      return $noinline$foo(x);
112f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko    }
113f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko  }
114f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko
115f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko  /// CHECK-START-X86: int Main.testLoop(int[], int) pc_relative_fixups_x86 (before)
116f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko  /// CHECK-NOT:            X86ComputeBaseMethodAddress
117f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko
118f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko  /// CHECK-START-X86: int Main.testLoop(int[], int) pc_relative_fixups_x86 (after)
119f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko  /// CHECK:                X86ComputeBaseMethodAddress
120f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko  /// CHECK-NOT:            X86ComputeBaseMethodAddress
121f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko
122f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko  /// CHECK-START-X86: int Main.testLoop(int[], int) pc_relative_fixups_x86 (after)
123f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko  /// CHECK:                InvokeStaticOrDirect
124f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko  /// CHECK-NOT:            InvokeStaticOrDirect
125f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko
126f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko  /// CHECK-START-X86: int Main.testLoop(int[], int) pc_relative_fixups_x86 (after)
127f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko  /// CHECK:                ArrayLength
128f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko  /// CHECK-NEXT:           X86ComputeBaseMethodAddress
129f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko  /// CHECK-NEXT:           Goto
130f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko  /// CHECK:                begin_block
131f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko  /// CHECK:                InvokeStaticOrDirect method_load_kind:dex_cache_pc_relative
132f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko
133f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko  /// CHECK-START-ARM: int Main.testLoop(int[], int) dex_cache_array_fixups_arm (before)
134f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko  /// CHECK-NOT:            ArmDexCacheArraysBase
135f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko
136f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko  /// CHECK-START-ARM: int Main.testLoop(int[], int) dex_cache_array_fixups_arm (after)
137f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko  /// CHECK:                ArmDexCacheArraysBase
138f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko  /// CHECK-NOT:            ArmDexCacheArraysBase
139f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko
140f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko  /// CHECK-START-ARM: int Main.testLoop(int[], int) dex_cache_array_fixups_arm (after)
141f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko  /// CHECK:                InvokeStaticOrDirect
142f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko  /// CHECK-NOT:            InvokeStaticOrDirect
143f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko
144f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko  /// CHECK-START-ARM: int Main.testLoop(int[], int) dex_cache_array_fixups_arm (after)
145f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko  /// CHECK:                ArrayLength
146f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko  /// CHECK-NEXT:           ArmDexCacheArraysBase
147f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko  /// CHECK-NEXT:           Goto
148f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko  /// CHECK:                begin_block
149f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko  /// CHECK:                InvokeStaticOrDirect method_load_kind:dex_cache_pc_relative
150f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko
151f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko  public static int testLoop(int[] array, int x) {
152f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko    // PC-relative bases used by X86 and ARM should be pulled before the loop.
153f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko    for (int i : array) {
154f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko      x += $noinline$foo(i);
155f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko    }
156f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko    return x;
157f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko  }
158f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko
159f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko  /// CHECK-START-X86: int Main.testLoopWithDiamond(int[], boolean, int) pc_relative_fixups_x86 (before)
160f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko  /// CHECK-NOT:            X86ComputeBaseMethodAddress
161f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko
162f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko  /// CHECK-START-X86: int Main.testLoopWithDiamond(int[], boolean, int) pc_relative_fixups_x86 (after)
163f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko  /// CHECK:                If
164f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko  /// CHECK:                begin_block
165f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko  /// CHECK:                ArrayLength
166f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko  /// CHECK-NEXT:           X86ComputeBaseMethodAddress
167f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko  /// CHECK-NEXT:           Goto
168f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko
169f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko  /// CHECK-START-ARM: int Main.testLoopWithDiamond(int[], boolean, int) dex_cache_array_fixups_arm (before)
170f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko  /// CHECK-NOT:            ArmDexCacheArraysBase
171f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko
172f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko  /// CHECK-START-ARM: int Main.testLoopWithDiamond(int[], boolean, int) dex_cache_array_fixups_arm (after)
173f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko  /// CHECK:                If
174f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko  /// CHECK:                begin_block
175f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko  /// CHECK:                ArrayLength
176f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko  /// CHECK-NEXT:           ArmDexCacheArraysBase
177f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko  /// CHECK-NEXT:           Goto
178f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko
179f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko  public static int testLoopWithDiamond(int[] array, boolean negate, int x) {
180f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko    // PC-relative bases used by X86 and ARM should be pulled before the loop
181f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko    // but not outside the if.
182f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko    if (array != null) {
183f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko      for (int i : array) {
184f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko        if (negate) {
185f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko          x += $noinline$foo(-i);
186f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko        } else {
187f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko          x += $noinline$foo(i);
188f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko        }
189f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko      }
190f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko    }
191f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko    return x;
192f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko  }
193f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko
194cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko  /// CHECK-START: java.lang.String Main.$noinline$getBootImageString() sharpening (before)
195cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko  /// CHECK:                LoadString load_kind:DexCacheViaMethod
196cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko
197cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko  /// CHECK-START-X86: java.lang.String Main.$noinline$getBootImageString() sharpening (after)
198cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko  // Note: load kind depends on PIC/non-PIC
199cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko  // TODO: Remove DexCacheViaMethod when read barrier config supports BootImageAddress.
200cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko  /// CHECK:                LoadString load_kind:{{BootImageAddress|DexCachePcRelative|DexCacheViaMethod}}
201cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko
202cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko  /// CHECK-START-X86_64: java.lang.String Main.$noinline$getBootImageString() sharpening (after)
203cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko  // Note: load kind depends on PIC/non-PIC
204cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko  // TODO: Remove DexCacheViaMethod when read barrier config supports BootImageAddress.
205cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko  /// CHECK:                LoadString load_kind:{{BootImageAddress|DexCachePcRelative|DexCacheViaMethod}}
206cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko
207cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko  /// CHECK-START-ARM: java.lang.String Main.$noinline$getBootImageString() sharpening (after)
208cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko  // Note: load kind depends on PIC/non-PIC
209cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko  // TODO: Remove DexCacheViaMethod when read barrier config supports BootImageAddress.
210cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko  /// CHECK:                LoadString load_kind:{{BootImageAddress|DexCachePcRelative|DexCacheViaMethod}}
211cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko
212cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko  /// CHECK-START-ARM64: java.lang.String Main.$noinline$getBootImageString() sharpening (after)
213cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko  // Note: load kind depends on PIC/non-PIC
214cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko  // TODO: Remove DexCacheViaMethod when read barrier config supports BootImageAddress.
215cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko  /// CHECK:                LoadString load_kind:{{BootImageAddress|DexCachePcRelative|DexCacheViaMethod}}
216cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko
217cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko  public static String $noinline$getBootImageString() {
218cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko    // Prevent inlining to avoid the string comparison being optimized away.
219cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko    if (doThrow) { throw new Error(); }
220cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko    // Empty string is known to be in the boot image.
221cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko    return "";
222cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko  }
223cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko
224cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko  /// CHECK-START: java.lang.String Main.$noinline$getNonBootImageString() sharpening (before)
225cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko  /// CHECK:                LoadString load_kind:DexCacheViaMethod
226cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko
227cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko  /// CHECK-START-X86: java.lang.String Main.$noinline$getNonBootImageString() sharpening (after)
228cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko  /// CHECK:                LoadString load_kind:DexCachePcRelative
229cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko
230cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko  /// CHECK-START-X86: java.lang.String Main.$noinline$getNonBootImageString() pc_relative_fixups_x86 (after)
231cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko  /// CHECK-DAG:            X86ComputeBaseMethodAddress
232cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko  /// CHECK-DAG:            LoadString load_kind:DexCachePcRelative
233cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko
234cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko  /// CHECK-START-X86_64: java.lang.String Main.$noinline$getNonBootImageString() sharpening (after)
235cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko  /// CHECK:                LoadString load_kind:DexCachePcRelative
236cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko
237cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko  /// CHECK-START-ARM: java.lang.String Main.$noinline$getNonBootImageString() sharpening (after)
238cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko  /// CHECK:                LoadString load_kind:DexCachePcRelative
239cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko
240cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko  /// CHECK-START-ARM: java.lang.String Main.$noinline$getNonBootImageString() dex_cache_array_fixups_arm (after)
241cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko  /// CHECK-DAG:            ArmDexCacheArraysBase
242cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko  /// CHECK-DAG:            LoadString load_kind:DexCachePcRelative
243cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko
244cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko  /// CHECK-START-ARM64: java.lang.String Main.$noinline$getNonBootImageString() sharpening (after)
245cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko  /// CHECK:                LoadString load_kind:DexCachePcRelative
246cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko
247cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko  public static String $noinline$getNonBootImageString() {
248cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko    // Prevent inlining to avoid the string comparison being optimized away.
249cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko    if (doThrow) { throw new Error(); }
250cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko    // This string is not in the boot image.
251cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko    return "non-boot-image-string";
252cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko  }
253cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko
254f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko  public static void main(String[] args) {
255f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko    assertIntEquals(1, testSimple(1));
256f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko    assertIntEquals(1, testDiamond(false, 1));
257f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko    assertIntEquals(-1, testDiamond(true, 1));
258f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko    assertIntEquals(3, testLoop(new int[]{ 2 }, 1));
259f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko    assertIntEquals(8, testLoop(new int[]{ 3, 4 }, 1));
260f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko    assertIntEquals(1, testLoopWithDiamond(null, false, 1));
261f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko    assertIntEquals(3, testLoopWithDiamond(new int[]{ 2 }, false, 1));
262f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko    assertIntEquals(-6, testLoopWithDiamond(new int[]{ 3, 4 }, true, 1));
263cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko    assertStringEquals("", $noinline$getBootImageString());
264cac5a7e871f1f346b317894359ad06fa7bd67fbaVladimir Marko    assertStringEquals("non-boot-image-string", $noinline$getNonBootImageString());
265f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko  }
266f64242a30c6e05a8e4302a64eab4bcc28297dc9eVladimir Marko}
267