• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2015 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 public class Main {
19   public static boolean doThrow = false;
20 
assertIntEquals(int expected, int result)21   public static void assertIntEquals(int expected, int result) {
22     if (expected != result) {
23       throw new Error("Expected: " + expected + ", found: " + result);
24     }
25   }
26 
assertBooleanEquals(boolean expected, boolean result)27   public static void assertBooleanEquals(boolean expected, boolean result) {
28     if (expected != result) {
29       throw new Error("Expected: " + expected + ", found: " + result);
30     }
31   }
32 
assertCharEquals(char expected, char result)33   public static void assertCharEquals(char expected, char result) {
34     if (expected != result) {
35       throw new Error("Expected: " + expected + ", found: " + result);
36     }
37   }
38 
assertStringContains(String searchTerm, String result)39   public static void assertStringContains(String searchTerm, String result) {
40     if (result == null || !result.contains(searchTerm)) {
41       throw new Error("Search term: " + searchTerm + ", not found in: " + result);
42     }
43   }
44 
main(String[] args)45   public static void main(String[] args) {
46     stringEqualsSame();
47     stringArgumentNotNull("Foo");
48 
49     assertIntEquals(0, $opt$noinline$getStringLength(""));
50     assertIntEquals(3, $opt$noinline$getStringLength("abc"));
51     assertIntEquals(10, $opt$noinline$getStringLength("0123456789"));
52 
53     assertBooleanEquals(true, $opt$noinline$isStringEmpty(""));
54     assertBooleanEquals(false, $opt$noinline$isStringEmpty("abc"));
55     assertBooleanEquals(false, $opt$noinline$isStringEmpty("0123456789"));
56 
57     assertCharEquals('a', $opt$noinline$stringCharAt("a", 0));
58     assertCharEquals('a', $opt$noinline$stringCharAt("abc", 0));
59     assertCharEquals('b', $opt$noinline$stringCharAt("abc", 1));
60     assertCharEquals('c', $opt$noinline$stringCharAt("abc", 2));
61     assertCharEquals('7', $opt$noinline$stringCharAt("0123456789", 7));
62 
63     try {
64       $opt$noinline$stringCharAt("abc", -1);
65       throw new Error("Should throw SIOOB.");
66     } catch (StringIndexOutOfBoundsException sioob) {
67       assertStringContains("java.lang.String.charAt", sioob.getStackTrace()[0].toString());
68       assertStringContains("Main.$opt$noinline$stringCharAt", sioob.getStackTrace()[1].toString());
69     }
70     try {
71       $opt$noinline$stringCharAt("abc", 3);
72       throw new Error("Should throw SIOOB.");
73     } catch (StringIndexOutOfBoundsException sioob) {
74       assertStringContains("java.lang.String.charAt", sioob.getStackTrace()[0].toString());
75       assertStringContains("Main.$opt$noinline$stringCharAt", sioob.getStackTrace()[1].toString());
76     }
77     try {
78       $opt$noinline$stringCharAt("abc", Integer.MAX_VALUE);
79       throw new Error("Should throw SIOOB.");
80     } catch (StringIndexOutOfBoundsException sioob) {
81       assertStringContains("java.lang.String.charAt", sioob.getStackTrace()[0].toString());
82       assertStringContains("Main.$opt$noinline$stringCharAt", sioob.getStackTrace()[1].toString());
83     }
84 
85     assertCharEquals('7', $opt$noinline$stringCharAtCatch("0123456789", 7));
86     assertCharEquals('\0', $opt$noinline$stringCharAtCatch("0123456789", 10));
87 
88     assertIntEquals('a' + 'b' + 'c', $opt$noinline$stringSumChars("abc"));
89     assertIntEquals('a' + 'b' + 'c', $opt$noinline$stringSumLeadingChars("abcdef", 3));
90     try {
91       $opt$noinline$stringSumLeadingChars("abcdef", 7);
92       throw new Error("Should throw SIOOB.");
93     } catch (StringIndexOutOfBoundsException sioob) {
94       assertStringContains("java.lang.String.charAt", sioob.getStackTrace()[0].toString());
95       assertStringContains("Main.$opt$noinline$stringSumLeadingChars",
96                            sioob.getStackTrace()[1].toString());
97     }
98     assertIntEquals('a' + 'b' + 'c' + 'd', $opt$noinline$stringSum4LeadingChars("abcdef"));
99     try {
100       $opt$noinline$stringSum4LeadingChars("abc");
101       throw new Error("Should throw SIOOB.");
102     } catch (StringIndexOutOfBoundsException sioob) {
103       assertStringContains("java.lang.String.charAt", sioob.getStackTrace()[0].toString());
104       assertStringContains("Main.$opt$noinline$stringSum4LeadingChars",
105                            sioob.getStackTrace()[1].toString());
106     }
107   }
108 
109   /// CHECK-START: int Main.$opt$noinline$getStringLength(java.lang.String) instruction_simplifier (before)
110   /// CHECK-DAG:  <<Length:i\d+>>   InvokeVirtual intrinsic:StringLength
111   /// CHECK-DAG:                    Return [<<Length>>]
112 
113   /// CHECK-START: int Main.$opt$noinline$getStringLength(java.lang.String) instruction_simplifier (after)
114   /// CHECK-DAG:  <<String:l\d+>>   ParameterValue
115   /// CHECK-DAG:  <<NullCk:l\d+>>   NullCheck [<<String>>]
116   /// CHECK-DAG:  <<Length:i\d+>>   ArrayLength [<<NullCk>>] is_string_length:true
117   /// CHECK-DAG:                    Return [<<Length>>]
118 
119   /// CHECK-START: int Main.$opt$noinline$getStringLength(java.lang.String) instruction_simplifier (after)
120   /// CHECK-NOT:                    InvokeVirtual intrinsic:StringLength
121 
$opt$noinline$getStringLength(String s)122   static public int $opt$noinline$getStringLength(String s) {
123     if (doThrow) { throw new Error(); }
124     return s.length();
125   }
126 
127   /// CHECK-START: boolean Main.$opt$noinline$isStringEmpty(java.lang.String) instruction_simplifier (before)
128   /// CHECK-DAG:  <<IsEmpty:z\d+>>  InvokeVirtual intrinsic:StringIsEmpty
129   /// CHECK-DAG:                    Return [<<IsEmpty>>]
130 
131   /// CHECK-START: boolean Main.$opt$noinline$isStringEmpty(java.lang.String) instruction_simplifier (after)
132   /// CHECK-DAG:  <<String:l\d+>>   ParameterValue
133   /// CHECK-DAG:  <<Const0:i\d+>>   IntConstant 0
134   /// CHECK-DAG:  <<NullCk:l\d+>>   NullCheck [<<String>>]
135   /// CHECK-DAG:  <<Length:i\d+>>   ArrayLength [<<NullCk>>] is_string_length:true
136   /// CHECK-DAG:  <<IsEmpty:z\d+>>  Equal [<<Length>>,<<Const0>>]
137   /// CHECK-DAG:                    Return [<<IsEmpty>>]
138 
139   /// CHECK-START: boolean Main.$opt$noinline$isStringEmpty(java.lang.String) instruction_simplifier (after)
140   /// CHECK-NOT:                    InvokeVirtual intrinsic:StringIsEmpty
141 
$opt$noinline$isStringEmpty(String s)142   static public boolean $opt$noinline$isStringEmpty(String s) {
143     if (doThrow) { throw new Error(); }
144     return s.isEmpty();
145   }
146 
147   /// CHECK-START: char Main.$opt$noinline$stringCharAt(java.lang.String, int) instruction_simplifier (before)
148   /// CHECK-DAG:  <<Char:c\d+>>     InvokeVirtual intrinsic:StringCharAt
149   /// CHECK-DAG:                    Return [<<Char>>]
150 
151   /// CHECK-START: char Main.$opt$noinline$stringCharAt(java.lang.String, int) instruction_simplifier (after)
152   /// CHECK-DAG:  <<String:l\d+>>   ParameterValue
153   /// CHECK-DAG:  <<Pos:i\d+>>      ParameterValue
154   /// CHECK-DAG:  <<NullCk:l\d+>>   NullCheck [<<String>>]
155   /// CHECK-DAG:  <<Length:i\d+>>   ArrayLength [<<NullCk>>] is_string_length:true
156   /// CHECK-DAG:  <<Bounds:i\d+>>   BoundsCheck [<<Pos>>,<<Length>>] is_string_char_at:true
157   /// CHECK-DAG:  <<Char:c\d+>>     ArrayGet [<<NullCk>>,<<Bounds>>] is_string_char_at:true
158   /// CHECK-DAG:                    Return [<<Char>>]
159 
160   /// CHECK-START: char Main.$opt$noinline$stringCharAt(java.lang.String, int) instruction_simplifier (after)
161   /// CHECK-NOT:                    InvokeVirtual intrinsic:StringCharAt
162 
$opt$noinline$stringCharAt(String s, int pos)163   static public char $opt$noinline$stringCharAt(String s, int pos) {
164     if (doThrow) { throw new Error(); }
165     return s.charAt(pos);
166   }
167 
168   /// CHECK-START: char Main.$opt$noinline$stringCharAtCatch(java.lang.String, int) instruction_simplifier (before)
169   /// CHECK-DAG:  <<Char:c\d+>>     InvokeVirtual intrinsic:StringCharAt
170   /// CHECK-DAG:                    Return [<<Char>>]
171 
172   /// CHECK-START: char Main.$opt$noinline$stringCharAtCatch(java.lang.String, int) instruction_simplifier (after)
173   /// CHECK-DAG:  <<String:l\d+>>   ParameterValue
174   /// CHECK-DAG:  <<Pos:i\d+>>      ParameterValue
175   /// CHECK-DAG:  <<NullCk:l\d+>>   NullCheck [<<String>>]
176   /// CHECK-DAG:  <<Length:i\d+>>   ArrayLength [<<NullCk>>] is_string_length:true
177   /// CHECK-DAG:  <<Bounds:i\d+>>   BoundsCheck [<<Pos>>,<<Length>>] is_string_char_at:true
178   /// CHECK-DAG:  <<Char:c\d+>>     ArrayGet [<<NullCk>>,<<Bounds>>] is_string_char_at:true
179   /// CHECK-DAG:                    Return [<<Char>>]
180 
181   /// CHECK-START: char Main.$opt$noinline$stringCharAtCatch(java.lang.String, int) instruction_simplifier (after)
182   /// CHECK-NOT:                    InvokeVirtual intrinsic:StringCharAt
183 
$opt$noinline$stringCharAtCatch(String s, int pos)184   static public char $opt$noinline$stringCharAtCatch(String s, int pos) {
185     if (doThrow) { throw new Error(); }
186     try {
187       return s.charAt(pos);
188     } catch (StringIndexOutOfBoundsException ignored) {
189       return '\0';
190     }
191   }
192 
193   /// CHECK-START: int Main.$opt$noinline$stringSumChars(java.lang.String) instruction_simplifier (before)
194   /// CHECK-DAG:                    InvokeVirtual intrinsic:StringLength
195   /// CHECK-DAG:                    InvokeVirtual intrinsic:StringCharAt
196 
197   /// CHECK-START: int Main.$opt$noinline$stringSumChars(java.lang.String) instruction_simplifier (after)
198   /// CHECK-DAG:                    ArrayLength is_string_length:true
199   /// CHECK-DAG:                    ArrayLength is_string_length:true
200   /// CHECK-DAG:                    BoundsCheck is_string_char_at:true
201   /// CHECK-DAG:                    ArrayGet is_string_char_at:true
202 
203   /// CHECK-START: int Main.$opt$noinline$stringSumChars(java.lang.String) instruction_simplifier (after)
204   /// CHECK-NOT:                    InvokeVirtual intrinsic:StringLength
205   /// CHECK-NOT:                    InvokeVirtual intrinsic:StringCharAt
206 
207   /// CHECK-START: int Main.$opt$noinline$stringSumChars(java.lang.String) GVN (after)
208   /// CHECK-DAG:                    ArrayLength is_string_length:true
209   /// CHECK-NOT:                    ArrayLength is_string_length:true
210 
211   /// CHECK-START: int Main.$opt$noinline$stringSumChars(java.lang.String) BCE (after)
212   /// CHECK-NOT:                    BoundsCheck
213 
$opt$noinline$stringSumChars(String s)214   static public int $opt$noinline$stringSumChars(String s) {
215     if (doThrow) { throw new Error(); }
216     int sum = 0;
217     int len = s.length();
218     for (int i = 0; i < len; ++i) {
219       sum += s.charAt(i);
220     }
221     return sum;
222   }
223 
224   /// CHECK-START: int Main.$opt$noinline$stringSumLeadingChars(java.lang.String, int) instruction_simplifier (before)
225   /// CHECK-DAG:                    InvokeVirtual intrinsic:StringCharAt
226 
227   /// CHECK-START: int Main.$opt$noinline$stringSumLeadingChars(java.lang.String, int) instruction_simplifier (after)
228   /// CHECK-DAG:                    ArrayLength is_string_length:true
229   /// CHECK-DAG:                    BoundsCheck is_string_char_at:true
230   /// CHECK-DAG:                    ArrayGet is_string_char_at:true
231 
232   /// CHECK-START: int Main.$opt$noinline$stringSumLeadingChars(java.lang.String, int) instruction_simplifier (after)
233   /// CHECK-NOT:                    InvokeVirtual intrinsic:StringCharAt
234 
235   /// CHECK-START: int Main.$opt$noinline$stringSumLeadingChars(java.lang.String, int) BCE (after)
236   /// CHECK-DAG:                    Deoptimize env:[[{{[^\]]*}}]]
237 
238   /// CHECK-START: int Main.$opt$noinline$stringSumLeadingChars(java.lang.String, int) BCE (after)
239   /// CHECK-NOT:                    BoundsCheck is_string_char_at:true
240 
$opt$noinline$stringSumLeadingChars(String s, int n)241   static public int $opt$noinline$stringSumLeadingChars(String s, int n) {
242     if (doThrow) { throw new Error(); }
243     int sum = 0;
244     for (int i = 0; i < n; ++i) {
245       sum += s.charAt(i);
246     }
247     return sum;
248   }
249 
250   /// CHECK-START: int Main.$opt$noinline$stringSum4LeadingChars(java.lang.String) instruction_simplifier (before)
251   /// CHECK-DAG:                    InvokeVirtual intrinsic:StringCharAt
252   /// CHECK-DAG:                    InvokeVirtual intrinsic:StringCharAt
253   /// CHECK-DAG:                    InvokeVirtual intrinsic:StringCharAt
254   /// CHECK-DAG:                    InvokeVirtual intrinsic:StringCharAt
255 
256   /// CHECK-START: int Main.$opt$noinline$stringSum4LeadingChars(java.lang.String) instruction_simplifier (after)
257   /// CHECK-DAG:                    ArrayLength is_string_length:true
258   /// CHECK-DAG:                    BoundsCheck is_string_char_at:true
259   /// CHECK-DAG:                    ArrayGet is_string_char_at:true
260   /// CHECK-DAG:                    ArrayLength is_string_length:true
261   /// CHECK-DAG:                    BoundsCheck is_string_char_at:true
262   /// CHECK-DAG:                    ArrayGet is_string_char_at:true
263   /// CHECK-DAG:                    ArrayLength is_string_length:true
264   /// CHECK-DAG:                    BoundsCheck is_string_char_at:true
265   /// CHECK-DAG:                    ArrayGet is_string_char_at:true
266   /// CHECK-DAG:                    ArrayLength is_string_length:true
267   /// CHECK-DAG:                    BoundsCheck is_string_char_at:true
268   /// CHECK-DAG:                    ArrayGet is_string_char_at:true
269 
270   /// CHECK-START: int Main.$opt$noinline$stringSum4LeadingChars(java.lang.String) instruction_simplifier (after)
271   /// CHECK-NOT:                    InvokeVirtual intrinsic:StringCharAt
272 
273   /// CHECK-START: int Main.$opt$noinline$stringSum4LeadingChars(java.lang.String) BCE (after)
274   /// CHECK-DAG:                    Deoptimize env:[[{{[^\]]*}}]]
275 
276   /// CHECK-START: int Main.$opt$noinline$stringSum4LeadingChars(java.lang.String) BCE (after)
277   /// CHECK-NOT:                    BoundsCheck is_string_char_at:true
278 
$opt$noinline$stringSum4LeadingChars(String s)279   static public int $opt$noinline$stringSum4LeadingChars(String s) {
280     if (doThrow) { throw new Error(); }
281     int sum = s.charAt(0) + s.charAt(1) + s.charAt(2) + s.charAt(3);
282     return sum;
283   }
284 
285   /// CHECK-START: boolean Main.stringEqualsSame() instruction_simplifier (before)
286   /// CHECK:      InvokeStaticOrDirect
287 
288   /// CHECK-START: boolean Main.stringEqualsSame() register (before)
289   /// CHECK:      <<Const1:i\d+>> IntConstant 1
290   /// CHECK:      Return [<<Const1>>]
291 
292   /// CHECK-START: boolean Main.stringEqualsSame() register (before)
293   /// CHECK-NOT:  InvokeStaticOrDirect
stringEqualsSame()294   public static boolean stringEqualsSame() {
295     return $inline$callStringEquals("obj", "obj");
296   }
297 
298   /// CHECK-START: boolean Main.stringEqualsNull() register (after)
299   /// CHECK:      <<Invoke:z\d+>> InvokeVirtual
300   /// CHECK:      Return [<<Invoke>>]
stringEqualsNull()301   public static boolean stringEqualsNull() {
302     String o = (String)myObject;
303     return $inline$callStringEquals(o, o);
304   }
305 
$inline$callStringEquals(String a, String b)306   public static boolean $inline$callStringEquals(String a, String b) {
307     return a.equals(b);
308   }
309 
310   /// CHECK-START-X86: boolean Main.stringArgumentNotNull(java.lang.Object) disassembly (after)
311   /// CHECK:          InvokeVirtual {{.*\.equals.*}} intrinsic:StringEquals
312   /// CHECK-NOT:      test
313 
314   /// CHECK-START-X86_64: boolean Main.stringArgumentNotNull(java.lang.Object) disassembly (after)
315   /// CHECK:          InvokeVirtual {{.*\.equals.*}} intrinsic:StringEquals
316   /// CHECK-NOT:      test
317 
318   /// CHECK-START-ARM: boolean Main.stringArgumentNotNull(java.lang.Object) disassembly (after)
319   /// CHECK:          InvokeVirtual {{.*\.equals.*}} intrinsic:StringEquals
320   // CompareAndBranchIfZero() may emit either CBZ or CMP+BEQ.
321   /// CHECK-NOT:      cbz
322   /// CHECK-NOT:      cmp {{r\d+}}, #0
323   // Terminate the scope for the CHECK-NOT search at the reference or length comparison,
324   // whichever comes first.
325   /// CHECK:          cmp {{r\d+}}, {{r\d+}}
326 
327   /// CHECK-START-ARM64: boolean Main.stringArgumentNotNull(java.lang.Object) disassembly (after)
328   /// CHECK:          InvokeVirtual {{.*\.equals.*}} intrinsic:StringEquals
329   /// CHECK-NOT:      cbz
330   // Terminate the scope for the CHECK-NOT search at the reference or length comparison,
331   // whichever comes first.
332   /// CHECK:          cmp {{w.*,}} {{w.*|#.*}}
333 
334   /// CHECK-START-MIPS: boolean Main.stringArgumentNotNull(java.lang.Object) disassembly (after)
335   /// CHECK:          InvokeVirtual {{.*\.equals.*}} intrinsic:StringEquals
336   /// CHECK-NOT:      beq r0,
337   /// CHECK-NOT:      beqz
338   /// CHECK-NOT:      beqzc
339   // Terminate the scope for the CHECK-NOT search at the class field or length comparison,
340   // whichever comes first.
341   /// CHECK:          lw
342 
343   /// CHECK-START-MIPS64: boolean Main.stringArgumentNotNull(java.lang.Object) disassembly (after)
344   /// CHECK:          InvokeVirtual {{.*\.equals.*}} intrinsic:StringEquals
345   /// CHECK-NOT:      beqzc
346   // Terminate the scope for the CHECK-NOT search at the reference comparison.
347   /// CHECK:          beqc
stringArgumentNotNull(Object obj)348   public static boolean stringArgumentNotNull(Object obj) {
349     obj.getClass();
350     return "foo".equals(obj);
351   }
352 
353   // Test is very brittle as it depends on the order we emit instructions.
354   /// CHECK-START-X86: boolean Main.stringArgumentIsString() disassembly (after)
355   /// CHECK:          InvokeVirtual intrinsic:StringEquals
356   /// CHECK:          test
357   /// CHECK:          jz/eq
358   // Check that we don't try to compare the classes.
359   /// CHECK-NOT:      mov
360   /// CHECK:          cmp
361 
362   // Test is very brittle as it depends on the order we emit instructions.
363   /// CHECK-START-X86_64: boolean Main.stringArgumentIsString() disassembly (after)
364   /// CHECK:          InvokeVirtual intrinsic:StringEquals
365   /// CHECK:          test
366   /// CHECK:          jz/eq
367   // Check that we don't try to compare the classes.
368   /// CHECK-NOT:      mov
369   /// CHECK:          cmp
370 
371   // Test is brittle as it depends on the class offset being 0.
372   /// CHECK-START-ARM: boolean Main.stringArgumentIsString() disassembly (after)
373   /// CHECK:          InvokeVirtual intrinsic:StringEquals
374   /// CHECK:          {{cbz|cmp}}
375   // Check that we don't try to compare the classes.
376   // The dissassembler currently explicitly emits the offset 0 but don't rely on it.
377   // We want to terminate the CHECK-NOT search after two CMPs, one for reference
378   // equality and one for length comparison but these may be emitted in different order,
379   // so repeat the check twice.
380   /// CHECK-NOT:      ldr{{(|.w)}} {{r\d+}}, [{{r\d+}}]
381   /// CHECK-NOT:      ldr{{(|.w)}} {{r\d+}}, [{{r\d+}}, #0]
382   /// CHECK:          cmp {{r\d+}}, {{r\d+}}
383   /// CHECK-NOT:      ldr{{(|.w)}} {{r\d+}}, [{{r\d+}}]
384   /// CHECK-NOT:      ldr{{(|.w)}} {{r\d+}}, [{{r\d+}}, #0]
385   /// CHECK:          cmp {{r\d+}}, {{r\d+}}
386 
387   // Test is brittle as it depends on the class offset being 0.
388   /// CHECK-START-ARM64: boolean Main.stringArgumentIsString() disassembly (after)
389   /// CHECK:          InvokeVirtual intrinsic:StringEquals
390   /// CHECK:          cbz
391   // Check that we don't try to compare the classes.
392   // The dissassembler currently does not explicitly emits the offset 0 but don't rely on it.
393   // We want to terminate the CHECK-NOT search after two CMPs, one for reference
394   // equality and one for length comparison but these may be emitted in different order,
395   // so repeat the check twice.
396   /// CHECK-NOT:      ldr {{w\d+}}, [{{x\d+}}]
397   /// CHECK-NOT:      ldr {{w\d+}}, [{{x\d+}}, #0]
398   /// CHECK:          cmp {{w\d+}}, {{w\d+|#.*}}
399   /// CHECK-NOT:      ldr {{w\d+}}, [{{x\d+}}]
400   /// CHECK-NOT:      ldr {{w\d+}}, [{{x\d+}}, #0]
401   /// CHECK:          cmp {{w\d+}}, {{w\d+|#.*}}
402 
403   // Test is brittle as it depends on the class offset being 0.
404   /// CHECK-START-MIPS: boolean Main.stringArgumentIsString() disassembly (after)
405   /// CHECK:          InvokeVirtual intrinsic:StringEquals
406   /// CHECK:          beq{{(zc)?}}
407   // Check that we don't try to compare the classes.
408   /// CHECK-NOT:      lw {{r\d+}}, +0({{r\d+}})
409   /// CHECK:          bne{{c?}}
410 
411   // Test is brittle as it depends on the class offset being 0.
412   /// CHECK-START-MIPS64: boolean Main.stringArgumentIsString() disassembly (after)
413   /// CHECK:          InvokeVirtual intrinsic:StringEquals
414   /// CHECK:          beqzc
415   // Check that we don't try to compare the classes.
416   /// CHECK-NOT:      lw {{r\d+}}, +0({{r\d+}})
417   /// CHECK:          bnec
stringArgumentIsString()418   public static boolean stringArgumentIsString() {
419     return "foo".equals(myString);
420   }
421 
422   static String myString;
423   static Object myObject;
424 }
425