xref: /aosp_15_r20/art/test/550-checker-multiply-accumulate/src/Main.java (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
1*795d594fSAndroid Build Coastguard Worker /*
2*795d594fSAndroid Build Coastguard Worker  * Copyright (C) 2015 The Android Open Source Project
3*795d594fSAndroid Build Coastguard Worker  *
4*795d594fSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*795d594fSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*795d594fSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*795d594fSAndroid Build Coastguard Worker  *
8*795d594fSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*795d594fSAndroid Build Coastguard Worker  *
10*795d594fSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*795d594fSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*795d594fSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*795d594fSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*795d594fSAndroid Build Coastguard Worker  * limitations under the License.
15*795d594fSAndroid Build Coastguard Worker  */
16*795d594fSAndroid Build Coastguard Worker 
17*795d594fSAndroid Build Coastguard Worker public class Main {
18*795d594fSAndroid Build Coastguard Worker 
assertIntEquals(int expected, int result)19*795d594fSAndroid Build Coastguard Worker   public static void assertIntEquals(int expected, int result) {
20*795d594fSAndroid Build Coastguard Worker     if (expected != result) {
21*795d594fSAndroid Build Coastguard Worker       throw new Error("Expected: " + expected + ", found: " + result);
22*795d594fSAndroid Build Coastguard Worker     }
23*795d594fSAndroid Build Coastguard Worker   }
24*795d594fSAndroid Build Coastguard Worker 
assertLongEquals(long expected, long result)25*795d594fSAndroid Build Coastguard Worker   public static void assertLongEquals(long expected, long result) {
26*795d594fSAndroid Build Coastguard Worker     if (expected != result) {
27*795d594fSAndroid Build Coastguard Worker       throw new Error("Expected: " + expected + ", found: " + result);
28*795d594fSAndroid Build Coastguard Worker     }
29*795d594fSAndroid Build Coastguard Worker   }
30*795d594fSAndroid Build Coastguard Worker 
31*795d594fSAndroid Build Coastguard Worker   /**
32*795d594fSAndroid Build Coastguard Worker    * Test basic merging of `MUL+ADD` into `MULADD`.
33*795d594fSAndroid Build Coastguard Worker    */
34*795d594fSAndroid Build Coastguard Worker 
35*795d594fSAndroid Build Coastguard Worker   /// CHECK-START-ARM64: int Main.$opt$noinline$mulAdd(int, int, int) instruction_simplifier_arm64 (before)
36*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Acc:i\d+>>         ParameterValue
37*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Left:i\d+>>        ParameterValue
38*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Right:i\d+>>       ParameterValue
39*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Mul:i\d+>>         Mul [<<Left>>,<<Right>>]
40*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Add:i\d+>>         Add [<<Acc>>,<<Mul>>]
41*795d594fSAndroid Build Coastguard Worker   /// CHECK:                            Return [<<Add>>]
42*795d594fSAndroid Build Coastguard Worker 
43*795d594fSAndroid Build Coastguard Worker   /// CHECK-START-ARM64: int Main.$opt$noinline$mulAdd(int, int, int) instruction_simplifier_arm64 (after)
44*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Acc:i\d+>>         ParameterValue
45*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Left:i\d+>>        ParameterValue
46*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Right:i\d+>>       ParameterValue
47*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<MulAdd:i\d+>>      MultiplyAccumulate [<<Acc>>,<<Left>>,<<Right>>] kind:Add
48*795d594fSAndroid Build Coastguard Worker   /// CHECK:                            Return [<<MulAdd>>]
49*795d594fSAndroid Build Coastguard Worker 
50*795d594fSAndroid Build Coastguard Worker   /// CHECK-START-ARM64: int Main.$opt$noinline$mulAdd(int, int, int) instruction_simplifier_arm64 (after)
51*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT:                        Mul
52*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT:                        Add
53*795d594fSAndroid Build Coastguard Worker 
54*795d594fSAndroid Build Coastguard Worker   /// CHECK-START-ARM64: int Main.$opt$noinline$mulAdd(int, int, int) disassembly (after)
55*795d594fSAndroid Build Coastguard Worker   /// CHECK:                            madd w{{\d+}}, w{{\d+}}, w{{\d+}}, w{{\d+}}
56*795d594fSAndroid Build Coastguard Worker 
57*795d594fSAndroid Build Coastguard Worker   /// CHECK-START-ARM: int Main.$opt$noinline$mulAdd(int, int, int) instruction_simplifier_arm (before)
58*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Acc:i\d+>>         ParameterValue
59*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Left:i\d+>>        ParameterValue
60*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Right:i\d+>>       ParameterValue
61*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Mul:i\d+>>         Mul [<<Left>>,<<Right>>]
62*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Add:i\d+>>         Add [<<Acc>>,<<Mul>>]
63*795d594fSAndroid Build Coastguard Worker   /// CHECK:                            Return [<<Add>>]
64*795d594fSAndroid Build Coastguard Worker 
65*795d594fSAndroid Build Coastguard Worker   /// CHECK-START-ARM: int Main.$opt$noinline$mulAdd(int, int, int) instruction_simplifier_arm (after)
66*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Acc:i\d+>>         ParameterValue
67*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Left:i\d+>>        ParameterValue
68*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Right:i\d+>>       ParameterValue
69*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<MulAdd:i\d+>>      MultiplyAccumulate [<<Acc>>,<<Left>>,<<Right>>] kind:Add
70*795d594fSAndroid Build Coastguard Worker   /// CHECK:                            Return [<<MulAdd>>]
71*795d594fSAndroid Build Coastguard Worker 
72*795d594fSAndroid Build Coastguard Worker   /// CHECK-START-ARM: int Main.$opt$noinline$mulAdd(int, int, int) instruction_simplifier_arm (after)
73*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT:                        Mul
74*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT:                        Add
75*795d594fSAndroid Build Coastguard Worker 
76*795d594fSAndroid Build Coastguard Worker   /// CHECK-START-ARM: int Main.$opt$noinline$mulAdd(int, int, int) disassembly (after)
77*795d594fSAndroid Build Coastguard Worker   /// CHECK:                            mla r{{\d+}}, r{{\d+}}, r{{\d+}}, r{{\d+}}
78*795d594fSAndroid Build Coastguard Worker 
$opt$noinline$mulAdd(int acc, int left, int right)79*795d594fSAndroid Build Coastguard Worker   public static int $opt$noinline$mulAdd(int acc, int left, int right) {
80*795d594fSAndroid Build Coastguard Worker     return acc + left * right;
81*795d594fSAndroid Build Coastguard Worker   }
82*795d594fSAndroid Build Coastguard Worker 
83*795d594fSAndroid Build Coastguard Worker   /**
84*795d594fSAndroid Build Coastguard Worker    * Test basic merging of `MUL+SUB` into `MULSUB`.
85*795d594fSAndroid Build Coastguard Worker    */
86*795d594fSAndroid Build Coastguard Worker 
87*795d594fSAndroid Build Coastguard Worker   /// CHECK-START-ARM64: long Main.$opt$noinline$mulSub(long, long, long) instruction_simplifier_arm64 (before)
88*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Acc:j\d+>>         ParameterValue
89*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Left:j\d+>>        ParameterValue
90*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Right:j\d+>>       ParameterValue
91*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Mul:j\d+>>         Mul [<<Left>>,<<Right>>]
92*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Sub:j\d+>>         Sub [<<Acc>>,<<Mul>>]
93*795d594fSAndroid Build Coastguard Worker   /// CHECK:                            Return [<<Sub>>]
94*795d594fSAndroid Build Coastguard Worker 
95*795d594fSAndroid Build Coastguard Worker   /// CHECK-START-ARM64: long Main.$opt$noinline$mulSub(long, long, long) instruction_simplifier_arm64 (after)
96*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Acc:j\d+>>         ParameterValue
97*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Left:j\d+>>        ParameterValue
98*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Right:j\d+>>       ParameterValue
99*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<MulSub:j\d+>>      MultiplyAccumulate [<<Acc>>,<<Left>>,<<Right>>] kind:Sub
100*795d594fSAndroid Build Coastguard Worker   /// CHECK:                            Return [<<MulSub>>]
101*795d594fSAndroid Build Coastguard Worker 
102*795d594fSAndroid Build Coastguard Worker   /// CHECK-START-ARM64: long Main.$opt$noinline$mulSub(long, long, long) instruction_simplifier_arm64 (after)
103*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT:                        Mul
104*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT:                        Sub
105*795d594fSAndroid Build Coastguard Worker 
106*795d594fSAndroid Build Coastguard Worker   /// CHECK-START-ARM64: long Main.$opt$noinline$mulSub(long, long, long) disassembly (after)
107*795d594fSAndroid Build Coastguard Worker   /// CHECK:                            msub x{{\d+}}, x{{\d+}}, x{{\d+}}, x{{\d+}}
108*795d594fSAndroid Build Coastguard Worker 
109*795d594fSAndroid Build Coastguard Worker   /// CHECK-START-ARM: long Main.$opt$noinline$mulSub(long, long, long) instruction_simplifier_arm (before)
110*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Acc:j\d+>>         ParameterValue
111*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Left:j\d+>>        ParameterValue
112*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Right:j\d+>>       ParameterValue
113*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Mul:j\d+>>         Mul [<<Left>>,<<Right>>]
114*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Sub:j\d+>>         Sub [<<Acc>>,<<Mul>>]
115*795d594fSAndroid Build Coastguard Worker   /// CHECK:                            Return [<<Sub>>]
116*795d594fSAndroid Build Coastguard Worker 
117*795d594fSAndroid Build Coastguard Worker   /// CHECK-START-ARM: long Main.$opt$noinline$mulSub(long, long, long) instruction_simplifier_arm (after)
118*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT:                        MultiplyAccumulate
119*795d594fSAndroid Build Coastguard Worker 
$opt$noinline$mulSub(long acc, long left, long right)120*795d594fSAndroid Build Coastguard Worker   public static long $opt$noinline$mulSub(long acc, long left, long right) {
121*795d594fSAndroid Build Coastguard Worker     return acc - left * right;
122*795d594fSAndroid Build Coastguard Worker   }
123*795d594fSAndroid Build Coastguard Worker 
124*795d594fSAndroid Build Coastguard Worker   /**
125*795d594fSAndroid Build Coastguard Worker    * Test that we do not create a multiply-accumulate instruction when there
126*795d594fSAndroid Build Coastguard Worker    * are other uses of the multiplication that cannot merge it.
127*795d594fSAndroid Build Coastguard Worker    */
128*795d594fSAndroid Build Coastguard Worker 
129*795d594fSAndroid Build Coastguard Worker   /// CHECK-START-ARM64: int Main.$opt$noinline$multipleUses1(int, int, int) instruction_simplifier_arm64 (before)
130*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Acc:i\d+>>         ParameterValue
131*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Left:i\d+>>        ParameterValue
132*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Right:i\d+>>       ParameterValue
133*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Mul:i\d+>>         Mul [<<Left>>,<<Right>>]
134*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Add:i\d+>>         Add [<<Acc>>,<<Mul>>]
135*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Or:i\d+>>          Or [<<Mul>>,<<Add>>]
136*795d594fSAndroid Build Coastguard Worker   /// CHECK:                            Return [<<Or>>]
137*795d594fSAndroid Build Coastguard Worker 
138*795d594fSAndroid Build Coastguard Worker   /// CHECK-START-ARM64: int Main.$opt$noinline$multipleUses1(int, int, int) instruction_simplifier_arm64 (after)
139*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Acc:i\d+>>         ParameterValue
140*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Left:i\d+>>        ParameterValue
141*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Right:i\d+>>       ParameterValue
142*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Mul:i\d+>>         Mul [<<Left>>,<<Right>>]
143*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Add:i\d+>>         Add [<<Acc>>,<<Mul>>]
144*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Or:i\d+>>          Or [<<Mul>>,<<Add>>]
145*795d594fSAndroid Build Coastguard Worker   /// CHECK:                            Return [<<Or>>]
146*795d594fSAndroid Build Coastguard Worker 
147*795d594fSAndroid Build Coastguard Worker   /// CHECK-START-ARM64: int Main.$opt$noinline$multipleUses1(int, int, int) instruction_simplifier_arm64 (after)
148*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT:                        MultiplyAccumulate
149*795d594fSAndroid Build Coastguard Worker 
150*795d594fSAndroid Build Coastguard Worker   /// CHECK-START-ARM: int Main.$opt$noinline$multipleUses1(int, int, int) instruction_simplifier_arm (before)
151*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Acc:i\d+>>         ParameterValue
152*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Left:i\d+>>        ParameterValue
153*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Right:i\d+>>       ParameterValue
154*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Mul:i\d+>>         Mul [<<Left>>,<<Right>>]
155*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Add:i\d+>>         Add [<<Acc>>,<<Mul>>]
156*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Or:i\d+>>          Or [<<Mul>>,<<Add>>]
157*795d594fSAndroid Build Coastguard Worker   /// CHECK:                            Return [<<Or>>]
158*795d594fSAndroid Build Coastguard Worker 
159*795d594fSAndroid Build Coastguard Worker   /// CHECK-START-ARM: int Main.$opt$noinline$multipleUses1(int, int, int) instruction_simplifier_arm (after)
160*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Acc:i\d+>>         ParameterValue
161*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Left:i\d+>>        ParameterValue
162*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Right:i\d+>>       ParameterValue
163*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Mul:i\d+>>         Mul [<<Left>>,<<Right>>]
164*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Add:i\d+>>         Add [<<Acc>>,<<Mul>>]
165*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Or:i\d+>>          Or [<<Mul>>,<<Add>>]
166*795d594fSAndroid Build Coastguard Worker   /// CHECK:                            Return [<<Or>>]
167*795d594fSAndroid Build Coastguard Worker 
168*795d594fSAndroid Build Coastguard Worker   /// CHECK-START-ARM: int Main.$opt$noinline$multipleUses1(int, int, int) instruction_simplifier_arm (after)
169*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT:                        MultiplyAccumulate
170*795d594fSAndroid Build Coastguard Worker 
$opt$noinline$multipleUses1(int acc, int left, int right)171*795d594fSAndroid Build Coastguard Worker   public static int $opt$noinline$multipleUses1(int acc, int left, int right) {
172*795d594fSAndroid Build Coastguard Worker     int temp = left * right;
173*795d594fSAndroid Build Coastguard Worker     return temp | (acc + temp);
174*795d594fSAndroid Build Coastguard Worker   }
175*795d594fSAndroid Build Coastguard Worker 
176*795d594fSAndroid Build Coastguard Worker   /**
177*795d594fSAndroid Build Coastguard Worker    * Test that we do not create a multiply-accumulate instruction even when all
178*795d594fSAndroid Build Coastguard Worker    * uses of the multiplication can merge it.
179*795d594fSAndroid Build Coastguard Worker    */
180*795d594fSAndroid Build Coastguard Worker 
181*795d594fSAndroid Build Coastguard Worker   /// CHECK-START-ARM64: long Main.$opt$noinline$multipleUses2(long, long, long) instruction_simplifier_arm64 (before)
182*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Acc:j\d+>>         ParameterValue
183*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Left:j\d+>>        ParameterValue
184*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Right:j\d+>>       ParameterValue
185*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Mul:j\d+>>         Mul [<<Left>>,<<Right>>]
186*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Add:j\d+>>         Add [<<Acc>>,<<Mul>>]
187*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Sub:j\d+>>         Sub [<<Acc>>,<<Mul>>]
188*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Res:j\d+>>         Add [<<Add>>,<<Sub>>]
189*795d594fSAndroid Build Coastguard Worker   /// CHECK:                            Return [<<Res>>]
190*795d594fSAndroid Build Coastguard Worker 
191*795d594fSAndroid Build Coastguard Worker   /// CHECK-START-ARM64: long Main.$opt$noinline$multipleUses2(long, long, long) instruction_simplifier_arm64 (after)
192*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Acc:j\d+>>         ParameterValue
193*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Left:j\d+>>        ParameterValue
194*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Right:j\d+>>       ParameterValue
195*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Mul:j\d+>>         Mul [<<Left>>,<<Right>>]
196*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Add:j\d+>>         Add [<<Acc>>,<<Mul>>]
197*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Sub:j\d+>>         Sub [<<Acc>>,<<Mul>>]
198*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Res:j\d+>>         Add [<<Add>>,<<Sub>>]
199*795d594fSAndroid Build Coastguard Worker   /// CHECK:                            Return [<<Res>>]
200*795d594fSAndroid Build Coastguard Worker 
201*795d594fSAndroid Build Coastguard Worker   /// CHECK-START-ARM64: long Main.$opt$noinline$multipleUses2(long, long, long) instruction_simplifier_arm64 (after)
202*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT:                        MultiplyAccumulate
203*795d594fSAndroid Build Coastguard Worker 
204*795d594fSAndroid Build Coastguard Worker   /// CHECK-START-ARM: long Main.$opt$noinline$multipleUses2(long, long, long) instruction_simplifier_arm (before)
205*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Acc:j\d+>>         ParameterValue
206*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Left:j\d+>>        ParameterValue
207*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Right:j\d+>>       ParameterValue
208*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Mul:j\d+>>         Mul [<<Left>>,<<Right>>]
209*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Add:j\d+>>         Add [<<Acc>>,<<Mul>>]
210*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Sub:j\d+>>         Sub [<<Acc>>,<<Mul>>]
211*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Res:j\d+>>         Add [<<Add>>,<<Sub>>]
212*795d594fSAndroid Build Coastguard Worker   /// CHECK:                            Return [<<Res>>]
213*795d594fSAndroid Build Coastguard Worker 
214*795d594fSAndroid Build Coastguard Worker   /// CHECK-START-ARM: long Main.$opt$noinline$multipleUses2(long, long, long) instruction_simplifier_arm (after)
215*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Acc:j\d+>>         ParameterValue
216*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Left:j\d+>>        ParameterValue
217*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Right:j\d+>>       ParameterValue
218*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Mul:j\d+>>         Mul [<<Left>>,<<Right>>]
219*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Add:j\d+>>         Add [<<Acc>>,<<Mul>>]
220*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Sub:j\d+>>         Sub [<<Acc>>,<<Mul>>]
221*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Res:j\d+>>         Add [<<Add>>,<<Sub>>]
222*795d594fSAndroid Build Coastguard Worker   /// CHECK:                            Return [<<Res>>]
223*795d594fSAndroid Build Coastguard Worker 
224*795d594fSAndroid Build Coastguard Worker   /// CHECK-START-ARM: long Main.$opt$noinline$multipleUses2(long, long, long) instruction_simplifier_arm (after)
225*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT:                        MultiplyAccumulate
226*795d594fSAndroid Build Coastguard Worker 
227*795d594fSAndroid Build Coastguard Worker 
$opt$noinline$multipleUses2(long acc, long left, long right)228*795d594fSAndroid Build Coastguard Worker   public static long $opt$noinline$multipleUses2(long acc, long left, long right) {
229*795d594fSAndroid Build Coastguard Worker     long temp = left * right;
230*795d594fSAndroid Build Coastguard Worker     return (acc + temp) + (acc - temp);
231*795d594fSAndroid Build Coastguard Worker   }
232*795d594fSAndroid Build Coastguard Worker 
233*795d594fSAndroid Build Coastguard Worker 
234*795d594fSAndroid Build Coastguard Worker   /**
235*795d594fSAndroid Build Coastguard Worker    * Test the interpretation of `a * (b + 1)` as `a + (a * b)`.
236*795d594fSAndroid Build Coastguard Worker    */
237*795d594fSAndroid Build Coastguard Worker 
238*795d594fSAndroid Build Coastguard Worker   /// CHECK-START-ARM64: int Main.$opt$noinline$mulPlusOne(int, int) instruction_simplifier_arm64 (before)
239*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Acc:i\d+>>         ParameterValue
240*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Var:i\d+>>         ParameterValue
241*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Const1:i\d+>>      IntConstant 1
242*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Add:i\d+>>         Add [<<Var>>,<<Const1>>]
243*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Mul:i\d+>>         Mul [<<Acc>>,<<Add>>]
244*795d594fSAndroid Build Coastguard Worker   /// CHECK:                            Return [<<Mul>>]
245*795d594fSAndroid Build Coastguard Worker 
246*795d594fSAndroid Build Coastguard Worker   /// CHECK-START-ARM64: int Main.$opt$noinline$mulPlusOne(int, int) instruction_simplifier_arm64 (after)
247*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Acc:i\d+>>         ParameterValue
248*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Var:i\d+>>         ParameterValue
249*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<MulAdd:i\d+>>      MultiplyAccumulate [<<Acc>>,<<Acc>>,<<Var>>] kind:Add
250*795d594fSAndroid Build Coastguard Worker   /// CHECK:                            Return [<<MulAdd>>]
251*795d594fSAndroid Build Coastguard Worker 
252*795d594fSAndroid Build Coastguard Worker   /// CHECK-START-ARM64: int Main.$opt$noinline$mulPlusOne(int, int) instruction_simplifier_arm64 (after)
253*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT:                        Mul
254*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT:                        Add
255*795d594fSAndroid Build Coastguard Worker 
256*795d594fSAndroid Build Coastguard Worker   /// CHECK-START-ARM64: int Main.$opt$noinline$mulPlusOne(int, int) disassembly (after)
257*795d594fSAndroid Build Coastguard Worker   /// CHECK:                            madd w{{\d+}}, w{{\d+}}, w{{\d+}}, w{{\d+}}
258*795d594fSAndroid Build Coastguard Worker 
259*795d594fSAndroid Build Coastguard Worker   /// CHECK-START-ARM: int Main.$opt$noinline$mulPlusOne(int, int) instruction_simplifier_arm (before)
260*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Acc:i\d+>>         ParameterValue
261*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Var:i\d+>>         ParameterValue
262*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Const1:i\d+>>      IntConstant 1
263*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Add:i\d+>>         Add [<<Var>>,<<Const1>>]
264*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Mul:i\d+>>         Mul [<<Acc>>,<<Add>>]
265*795d594fSAndroid Build Coastguard Worker   /// CHECK:                            Return [<<Mul>>]
266*795d594fSAndroid Build Coastguard Worker 
267*795d594fSAndroid Build Coastguard Worker   /// CHECK-START-ARM: int Main.$opt$noinline$mulPlusOne(int, int) instruction_simplifier_arm (after)
268*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Acc:i\d+>>         ParameterValue
269*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Var:i\d+>>         ParameterValue
270*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<MulAdd:i\d+>>      MultiplyAccumulate [<<Acc>>,<<Acc>>,<<Var>>] kind:Add
271*795d594fSAndroid Build Coastguard Worker   /// CHECK:                            Return [<<MulAdd>>]
272*795d594fSAndroid Build Coastguard Worker 
273*795d594fSAndroid Build Coastguard Worker   /// CHECK-START-ARM: int Main.$opt$noinline$mulPlusOne(int, int) instruction_simplifier_arm (after)
274*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT:                        Mul
275*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT:                        Add
276*795d594fSAndroid Build Coastguard Worker 
277*795d594fSAndroid Build Coastguard Worker   /// CHECK-START-ARM: int Main.$opt$noinline$mulPlusOne(int, int) disassembly (after)
278*795d594fSAndroid Build Coastguard Worker   /// CHECK:                            mla r{{\d+}}, r{{\d+}}, r{{\d+}}, r{{\d+}}
279*795d594fSAndroid Build Coastguard Worker 
$opt$noinline$mulPlusOne(int acc, int var)280*795d594fSAndroid Build Coastguard Worker   public static int $opt$noinline$mulPlusOne(int acc, int var) {
281*795d594fSAndroid Build Coastguard Worker     return acc * (var + 1);
282*795d594fSAndroid Build Coastguard Worker   }
283*795d594fSAndroid Build Coastguard Worker 
284*795d594fSAndroid Build Coastguard Worker 
285*795d594fSAndroid Build Coastguard Worker   /**
286*795d594fSAndroid Build Coastguard Worker    * Test the interpretation of `a * (1 - b)` as `a - (a * b)`.
287*795d594fSAndroid Build Coastguard Worker    */
288*795d594fSAndroid Build Coastguard Worker 
289*795d594fSAndroid Build Coastguard Worker   /// CHECK-START-ARM64: long Main.$opt$noinline$mulMinusOne(long, long) instruction_simplifier_arm64 (before)
290*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Acc:j\d+>>         ParameterValue
291*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Var:j\d+>>         ParameterValue
292*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Const1:j\d+>>      LongConstant 1
293*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Sub:j\d+>>         Sub [<<Const1>>,<<Var>>]
294*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Mul:j\d+>>         Mul [<<Acc>>,<<Sub>>]
295*795d594fSAndroid Build Coastguard Worker   /// CHECK:                            Return [<<Mul>>]
296*795d594fSAndroid Build Coastguard Worker 
297*795d594fSAndroid Build Coastguard Worker   /// CHECK-START-ARM64: long Main.$opt$noinline$mulMinusOne(long, long) instruction_simplifier_arm64 (after)
298*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Acc:j\d+>>         ParameterValue
299*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Var:j\d+>>         ParameterValue
300*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<MulSub:j\d+>>      MultiplyAccumulate [<<Acc>>,<<Acc>>,<<Var>>] kind:Sub
301*795d594fSAndroid Build Coastguard Worker   /// CHECK:                            Return [<<MulSub>>]
302*795d594fSAndroid Build Coastguard Worker 
303*795d594fSAndroid Build Coastguard Worker   /// CHECK-START-ARM64: long Main.$opt$noinline$mulMinusOne(long, long) instruction_simplifier_arm64 (after)
304*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT:                        Mul
305*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT:                        Sub
306*795d594fSAndroid Build Coastguard Worker 
307*795d594fSAndroid Build Coastguard Worker   /// CHECK-START-ARM64: long Main.$opt$noinline$mulMinusOne(long, long) disassembly (after)
308*795d594fSAndroid Build Coastguard Worker   /// CHECK:                            msub x{{\d+}}, x{{\d+}}, x{{\d+}}, x{{\d+}}
309*795d594fSAndroid Build Coastguard Worker 
310*795d594fSAndroid Build Coastguard Worker   /// CHECK-START-ARM: long Main.$opt$noinline$mulMinusOne(long, long) instruction_simplifier_arm (before)
311*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Acc:j\d+>>         ParameterValue
312*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Var:j\d+>>         ParameterValue
313*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Const1:j\d+>>      LongConstant 1
314*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Sub:j\d+>>         Sub [<<Const1>>,<<Var>>]
315*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Mul:j\d+>>         Mul [<<Acc>>,<<Sub>>]
316*795d594fSAndroid Build Coastguard Worker   /// CHECK:                            Return [<<Mul>>]
317*795d594fSAndroid Build Coastguard Worker 
318*795d594fSAndroid Build Coastguard Worker   /// CHECK-START-ARM: long Main.$opt$noinline$mulMinusOne(long, long) instruction_simplifier_arm (after)
319*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT:                        MultiplyAccumulate
$opt$noinline$mulMinusOne(long acc, long var)320*795d594fSAndroid Build Coastguard Worker   public static long $opt$noinline$mulMinusOne(long acc, long var) {
321*795d594fSAndroid Build Coastguard Worker     return acc * (1 - var);
322*795d594fSAndroid Build Coastguard Worker   }
323*795d594fSAndroid Build Coastguard Worker 
324*795d594fSAndroid Build Coastguard Worker   /**
325*795d594fSAndroid Build Coastguard Worker    * Test basic merging of `MUL+NEG` into `MULNEG`.
326*795d594fSAndroid Build Coastguard Worker    */
327*795d594fSAndroid Build Coastguard Worker 
328*795d594fSAndroid Build Coastguard Worker   /// CHECK-START-ARM64: int Main.$opt$noinline$mulNeg(int, int) instruction_simplifier_arm64 (before)
329*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Left:i\d+>>        ParameterValue
330*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Right:i\d+>>       ParameterValue
331*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Mul:i\d+>>         Mul [<<Left>>,<<Right>>]
332*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Neg:i\d+>>         Neg [<<Mul>>]
333*795d594fSAndroid Build Coastguard Worker   /// CHECK:                            Return [<<Neg>>]
334*795d594fSAndroid Build Coastguard Worker 
335*795d594fSAndroid Build Coastguard Worker   /// CHECK-START-ARM64: int Main.$opt$noinline$mulNeg(int, int) instruction_simplifier_arm64 (after)
336*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Left:i\d+>>        ParameterValue
337*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Right:i\d+>>       ParameterValue
338*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Const0:i\d+>>      IntConstant 0
339*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<MulNeg:i\d+>>      MultiplyAccumulate [<<Const0>>,<<Left>>,<<Right>>] kind:Sub
340*795d594fSAndroid Build Coastguard Worker   /// CHECK:                            Return [<<MulNeg>>]
341*795d594fSAndroid Build Coastguard Worker 
342*795d594fSAndroid Build Coastguard Worker   /// CHECK-START-ARM64: int Main.$opt$noinline$mulNeg(int, int) instruction_simplifier_arm64 (after)
343*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT:                        Mul
344*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT:                        Neg
345*795d594fSAndroid Build Coastguard Worker 
346*795d594fSAndroid Build Coastguard Worker   /// CHECK-START-ARM64: int Main.$opt$noinline$mulNeg(int, int) disassembly (after)
347*795d594fSAndroid Build Coastguard Worker   /// CHECK:                            mneg w{{\d+}}, w{{\d+}}, w{{\d+}}
348*795d594fSAndroid Build Coastguard Worker 
349*795d594fSAndroid Build Coastguard Worker   /// CHECK-START-ARM: int Main.$opt$noinline$mulNeg(int, int) instruction_simplifier_arm (before)
350*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Left:i\d+>>        ParameterValue
351*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Right:i\d+>>       ParameterValue
352*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Mul:i\d+>>         Mul [<<Left>>,<<Right>>]
353*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Neg:i\d+>>         Neg [<<Mul>>]
354*795d594fSAndroid Build Coastguard Worker   /// CHECK:                            Return [<<Neg>>]
355*795d594fSAndroid Build Coastguard Worker 
356*795d594fSAndroid Build Coastguard Worker   /// CHECK-START-ARM: int Main.$opt$noinline$mulNeg(int, int) instruction_simplifier_arm (after)
357*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Left:i\d+>>        ParameterValue
358*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Right:i\d+>>       ParameterValue
359*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Mul:i\d+>>         Mul [<<Left>>,<<Right>>]
360*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Neg:i\d+>>         Neg [<<Mul>>]
361*795d594fSAndroid Build Coastguard Worker   /// CHECK:                            Return [<<Neg>>]
362*795d594fSAndroid Build Coastguard Worker 
363*795d594fSAndroid Build Coastguard Worker   /// CHECK-START-ARM: int Main.$opt$noinline$mulNeg(int, int) instruction_simplifier_arm (after)
364*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT:                        MultiplyAccumulate
365*795d594fSAndroid Build Coastguard Worker 
$opt$noinline$mulNeg(int left, int right)366*795d594fSAndroid Build Coastguard Worker   public static int $opt$noinline$mulNeg(int left, int right) {
367*795d594fSAndroid Build Coastguard Worker     return - (left * right);
368*795d594fSAndroid Build Coastguard Worker   }
369*795d594fSAndroid Build Coastguard Worker 
370*795d594fSAndroid Build Coastguard Worker   /**
371*795d594fSAndroid Build Coastguard Worker    * Test basic merging of `MUL+NEG` into `MULNEG`.
372*795d594fSAndroid Build Coastguard Worker    */
373*795d594fSAndroid Build Coastguard Worker 
374*795d594fSAndroid Build Coastguard Worker   /// CHECK-START-ARM64: long Main.$opt$noinline$mulNeg(long, long) instruction_simplifier_arm64 (before)
375*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Left:j\d+>>        ParameterValue
376*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Right:j\d+>>       ParameterValue
377*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Mul:j\d+>>         Mul [<<Left>>,<<Right>>]
378*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Neg:j\d+>>         Neg [<<Mul>>]
379*795d594fSAndroid Build Coastguard Worker   /// CHECK:                            Return [<<Neg>>]
380*795d594fSAndroid Build Coastguard Worker 
381*795d594fSAndroid Build Coastguard Worker   /// CHECK-START-ARM64: long Main.$opt$noinline$mulNeg(long, long) instruction_simplifier_arm64 (after)
382*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Left:j\d+>>        ParameterValue
383*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Right:j\d+>>       ParameterValue
384*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Const0:j\d+>>      LongConstant 0
385*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<MulNeg:j\d+>>      MultiplyAccumulate [<<Const0>>,<<Left>>,<<Right>>] kind:Sub
386*795d594fSAndroid Build Coastguard Worker   /// CHECK:                            Return [<<MulNeg>>]
387*795d594fSAndroid Build Coastguard Worker 
388*795d594fSAndroid Build Coastguard Worker   /// CHECK-START-ARM64: long Main.$opt$noinline$mulNeg(long, long) instruction_simplifier_arm64 (after)
389*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT:                        Mul
390*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT:                        Neg
391*795d594fSAndroid Build Coastguard Worker 
392*795d594fSAndroid Build Coastguard Worker   /// CHECK-START-ARM64: long Main.$opt$noinline$mulNeg(long, long) disassembly (after)
393*795d594fSAndroid Build Coastguard Worker   /// CHECK:                            mneg x{{\d+}}, x{{\d+}}, x{{\d+}}
394*795d594fSAndroid Build Coastguard Worker 
395*795d594fSAndroid Build Coastguard Worker   /// CHECK-START-ARM: long Main.$opt$noinline$mulNeg(long, long) instruction_simplifier_arm (before)
396*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Left:j\d+>>        ParameterValue
397*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Right:j\d+>>       ParameterValue
398*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Mul:j\d+>>         Mul [<<Left>>,<<Right>>]
399*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Neg:j\d+>>         Neg [<<Mul>>]
400*795d594fSAndroid Build Coastguard Worker   /// CHECK:                            Return [<<Neg>>]
401*795d594fSAndroid Build Coastguard Worker 
402*795d594fSAndroid Build Coastguard Worker   /// CHECK-START-ARM: long Main.$opt$noinline$mulNeg(long, long) instruction_simplifier_arm (after)
403*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Left:j\d+>>        ParameterValue
404*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Right:j\d+>>       ParameterValue
405*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Mul:j\d+>>         Mul [<<Left>>,<<Right>>]
406*795d594fSAndroid Build Coastguard Worker   /// CHECK:       <<Neg:j\d+>>         Neg [<<Mul>>]
407*795d594fSAndroid Build Coastguard Worker   /// CHECK:                            Return [<<Neg>>]
408*795d594fSAndroid Build Coastguard Worker 
409*795d594fSAndroid Build Coastguard Worker   /// CHECK-START-ARM: long Main.$opt$noinline$mulNeg(long, long) instruction_simplifier_arm (after)
410*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT:                        MultiplyAccumulate
411*795d594fSAndroid Build Coastguard Worker 
$opt$noinline$mulNeg(long left, long right)412*795d594fSAndroid Build Coastguard Worker   public static long $opt$noinline$mulNeg(long left, long right) {
413*795d594fSAndroid Build Coastguard Worker     return - (left * right);
414*795d594fSAndroid Build Coastguard Worker   }
415*795d594fSAndroid Build Coastguard Worker 
416*795d594fSAndroid Build Coastguard Worker   /// CHECK-START-ARM64: void Main.SimdMulAdd(int[], int[]) instruction_simplifier$after_loop_opt (before)
417*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:     Phi                            loop:<<Loop:B\d+>> outer_loop:none
418*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:     VecMul                         loop:<<Loop>>      outer_loop:none
419*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:     VecAdd                         loop:<<Loop>>      outer_loop:none
420*795d594fSAndroid Build Coastguard Worker 
421*795d594fSAndroid Build Coastguard Worker   /// CHECK-START-ARM64: void Main.SimdMulAdd(int[], int[]) instruction_simplifier$after_loop_opt (after)
422*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:     Phi                            loop:<<Loop:B\d+>> outer_loop:none
423*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:     VecMultiplyAccumulate kind:Add loop:<<Loop>>      outer_loop:none
424*795d594fSAndroid Build Coastguard Worker 
425*795d594fSAndroid Build Coastguard Worker   /// CHECK-START-ARM64: void Main.SimdMulAdd(int[], int[]) instruction_simplifier$after_loop_opt (after)
426*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT:     VecMul
427*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT:     VecAdd
428*795d594fSAndroid Build Coastguard Worker 
SimdMulAdd(int[] array1, int[] array2)429*795d594fSAndroid Build Coastguard Worker   public static void SimdMulAdd(int[] array1, int[] array2) {
430*795d594fSAndroid Build Coastguard Worker     for (int j = 0; j < 100; j++) {
431*795d594fSAndroid Build Coastguard Worker       array2[j] += 12345 * array1[j];
432*795d594fSAndroid Build Coastguard Worker     }
433*795d594fSAndroid Build Coastguard Worker   }
434*795d594fSAndroid Build Coastguard Worker 
SimdMulAddLong(long[] array1, long[] array2)435*795d594fSAndroid Build Coastguard Worker   public static void SimdMulAddLong(long[] array1, long[] array2) {
436*795d594fSAndroid Build Coastguard Worker     for (int j = 0; j < 100; j++) {
437*795d594fSAndroid Build Coastguard Worker       array2[j] += 12345 * array1[j];
438*795d594fSAndroid Build Coastguard Worker     }
439*795d594fSAndroid Build Coastguard Worker   }
440*795d594fSAndroid Build Coastguard Worker 
441*795d594fSAndroid Build Coastguard Worker   /// CHECK-START-ARM64: void Main.SimdMulSub(int[], int[]) instruction_simplifier$after_loop_opt (before)
442*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:     Phi                            loop:<<Loop:B\d+>> outer_loop:none
443*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:     VecMul                         loop:<<Loop>>      outer_loop:none
444*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:     VecSub                         loop:<<Loop>>      outer_loop:none
445*795d594fSAndroid Build Coastguard Worker 
446*795d594fSAndroid Build Coastguard Worker   /// CHECK-START-ARM64: void Main.SimdMulSub(int[], int[]) instruction_simplifier$after_loop_opt (after)
447*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:     Phi                            loop:<<Loop:B\d+>> outer_loop:none
448*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:     VecMultiplyAccumulate kind:Sub loop:<<Loop>>      outer_loop:none
449*795d594fSAndroid Build Coastguard Worker 
450*795d594fSAndroid Build Coastguard Worker   /// CHECK-START-ARM64: void Main.SimdMulSub(int[], int[]) instruction_simplifier$after_loop_opt (after)
451*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT:     VecMul
452*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT:     VecSub
453*795d594fSAndroid Build Coastguard Worker 
SimdMulSub(int[] array1, int[] array2)454*795d594fSAndroid Build Coastguard Worker   public static void SimdMulSub(int[] array1, int[] array2) {
455*795d594fSAndroid Build Coastguard Worker     for (int j = 0; j < 100; j++) {
456*795d594fSAndroid Build Coastguard Worker       array2[j] -= 12345 * array1[j];
457*795d594fSAndroid Build Coastguard Worker     }
458*795d594fSAndroid Build Coastguard Worker   }
459*795d594fSAndroid Build Coastguard Worker 
SimdMulSubLong(long[] array1, long[] array2)460*795d594fSAndroid Build Coastguard Worker   public static void SimdMulSubLong(long[] array1, long[] array2) {
461*795d594fSAndroid Build Coastguard Worker     for (int j = 0; j < 100; j++) {
462*795d594fSAndroid Build Coastguard Worker       array2[j] -= 12345 * array1[j];
463*795d594fSAndroid Build Coastguard Worker     }
464*795d594fSAndroid Build Coastguard Worker   }
465*795d594fSAndroid Build Coastguard Worker 
466*795d594fSAndroid Build Coastguard Worker   /// CHECK-START-ARM64: void Main.SimdMulMultipleUses(int[], int[]) instruction_simplifier$after_loop_opt (before)
467*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:     Phi                            loop:<<Loop:B\d+>> outer_loop:none
468*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:     VecMul                         loop:<<Loop>>      outer_loop:none
469*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:     VecSub                         loop:<<Loop>>      outer_loop:none
470*795d594fSAndroid Build Coastguard Worker 
471*795d594fSAndroid Build Coastguard Worker   /// CHECK-START-ARM64: void Main.SimdMulMultipleUses(int[], int[]) instruction_simplifier$after_loop_opt (after)
472*795d594fSAndroid Build Coastguard Worker   /// CHECK-NOT: VecMultiplyAccumulate
473*795d594fSAndroid Build Coastguard Worker 
SimdMulMultipleUses(int[] array1, int[] array2)474*795d594fSAndroid Build Coastguard Worker   public static void SimdMulMultipleUses(int[] array1, int[] array2) {
475*795d594fSAndroid Build Coastguard Worker     for (int j = 0; j < 100; j++) {
476*795d594fSAndroid Build Coastguard Worker        int temp = 12345 * array1[j];
477*795d594fSAndroid Build Coastguard Worker        array2[j] -= temp;
478*795d594fSAndroid Build Coastguard Worker        array1[j] = temp;
479*795d594fSAndroid Build Coastguard Worker     }
480*795d594fSAndroid Build Coastguard Worker   }
481*795d594fSAndroid Build Coastguard Worker 
SimdMulMultipleUsesLong(long[] array1, long[] array2)482*795d594fSAndroid Build Coastguard Worker   public static void SimdMulMultipleUsesLong(long[] array1, long[] array2) {
483*795d594fSAndroid Build Coastguard Worker     for (int j = 0; j < 100; j++) {
484*795d594fSAndroid Build Coastguard Worker        long temp = 12345 * array1[j];
485*795d594fSAndroid Build Coastguard Worker        array2[j] -= temp;
486*795d594fSAndroid Build Coastguard Worker        array1[j] = temp;
487*795d594fSAndroid Build Coastguard Worker     }
488*795d594fSAndroid Build Coastguard Worker   }
489*795d594fSAndroid Build Coastguard Worker 
490*795d594fSAndroid Build Coastguard Worker   public static final int ARRAY_SIZE = 1000;
491*795d594fSAndroid Build Coastguard Worker 
initArray(int[] array)492*795d594fSAndroid Build Coastguard Worker   public static void initArray(int[] array) {
493*795d594fSAndroid Build Coastguard Worker     for (int i = 0; i < ARRAY_SIZE; i++) {
494*795d594fSAndroid Build Coastguard Worker       array[i] = i;
495*795d594fSAndroid Build Coastguard Worker     }
496*795d594fSAndroid Build Coastguard Worker   }
497*795d594fSAndroid Build Coastguard Worker 
initArrayLong(long[] array)498*795d594fSAndroid Build Coastguard Worker   public static void initArrayLong(long[] array) {
499*795d594fSAndroid Build Coastguard Worker     for (int i = 0; i < ARRAY_SIZE; i++) {
500*795d594fSAndroid Build Coastguard Worker       array[i] = i;
501*795d594fSAndroid Build Coastguard Worker     }
502*795d594fSAndroid Build Coastguard Worker   }
503*795d594fSAndroid Build Coastguard Worker 
calcArraySum(int[] array)504*795d594fSAndroid Build Coastguard Worker   public static int calcArraySum(int[] array) {
505*795d594fSAndroid Build Coastguard Worker     int sum = 0;
506*795d594fSAndroid Build Coastguard Worker     for (int i = 0; i < ARRAY_SIZE; i++) {
507*795d594fSAndroid Build Coastguard Worker       sum += array[i];
508*795d594fSAndroid Build Coastguard Worker     }
509*795d594fSAndroid Build Coastguard Worker     return sum;
510*795d594fSAndroid Build Coastguard Worker   }
511*795d594fSAndroid Build Coastguard Worker 
calcArraySumLong(long[] array)512*795d594fSAndroid Build Coastguard Worker   public static long calcArraySumLong(long[] array) {
513*795d594fSAndroid Build Coastguard Worker     long sum = 0;
514*795d594fSAndroid Build Coastguard Worker     for (int i = 0; i < ARRAY_SIZE; i++) {
515*795d594fSAndroid Build Coastguard Worker       sum += array[i];
516*795d594fSAndroid Build Coastguard Worker     }
517*795d594fSAndroid Build Coastguard Worker     return sum;
518*795d594fSAndroid Build Coastguard Worker   }
519*795d594fSAndroid Build Coastguard Worker 
testSimdMultiplyAccumulate()520*795d594fSAndroid Build Coastguard Worker   public static void testSimdMultiplyAccumulate() {
521*795d594fSAndroid Build Coastguard Worker     int[] array1 = new int[ARRAY_SIZE];
522*795d594fSAndroid Build Coastguard Worker     int[] array2 = new int[ARRAY_SIZE];
523*795d594fSAndroid Build Coastguard Worker     long[] array3 = new long[ARRAY_SIZE];
524*795d594fSAndroid Build Coastguard Worker     long[] array4 = new long[ARRAY_SIZE];
525*795d594fSAndroid Build Coastguard Worker 
526*795d594fSAndroid Build Coastguard Worker     initArray(array1);
527*795d594fSAndroid Build Coastguard Worker     initArray(array2);
528*795d594fSAndroid Build Coastguard Worker     SimdMulSub(array1, array2);
529*795d594fSAndroid Build Coastguard Worker     assertIntEquals(-60608250, calcArraySum(array2));
530*795d594fSAndroid Build Coastguard Worker 
531*795d594fSAndroid Build Coastguard Worker     initArrayLong(array3);
532*795d594fSAndroid Build Coastguard Worker     initArrayLong(array4);
533*795d594fSAndroid Build Coastguard Worker     SimdMulSubLong(array3, array4);
534*795d594fSAndroid Build Coastguard Worker     assertLongEquals(-60608250, calcArraySumLong(array4));
535*795d594fSAndroid Build Coastguard Worker 
536*795d594fSAndroid Build Coastguard Worker     initArray(array1);
537*795d594fSAndroid Build Coastguard Worker     initArray(array2);
538*795d594fSAndroid Build Coastguard Worker     SimdMulAdd(array1, array2);
539*795d594fSAndroid Build Coastguard Worker     assertIntEquals(61607250, calcArraySum(array2));
540*795d594fSAndroid Build Coastguard Worker 
541*795d594fSAndroid Build Coastguard Worker     initArrayLong(array3);
542*795d594fSAndroid Build Coastguard Worker     initArrayLong(array4);
543*795d594fSAndroid Build Coastguard Worker     SimdMulAddLong(array3, array4);
544*795d594fSAndroid Build Coastguard Worker     assertLongEquals(61607250, calcArraySumLong(array4));
545*795d594fSAndroid Build Coastguard Worker   }
546*795d594fSAndroid Build Coastguard Worker 
main(String[] args)547*795d594fSAndroid Build Coastguard Worker   public static void main(String[] args) {
548*795d594fSAndroid Build Coastguard Worker     assertIntEquals(7, $opt$noinline$mulAdd(1, 2, 3));
549*795d594fSAndroid Build Coastguard Worker     assertLongEquals(-26, $opt$noinline$mulSub(4, 5, 6));
550*795d594fSAndroid Build Coastguard Worker     assertIntEquals(79, $opt$noinline$multipleUses1(7, 8, 9));
551*795d594fSAndroid Build Coastguard Worker     assertLongEquals(20, $opt$noinline$multipleUses2(10, 11, 12));
552*795d594fSAndroid Build Coastguard Worker     assertIntEquals(195, $opt$noinline$mulPlusOne(13, 14));
553*795d594fSAndroid Build Coastguard Worker     assertLongEquals(-225, $opt$noinline$mulMinusOne(15, 16));
554*795d594fSAndroid Build Coastguard Worker     assertIntEquals(-306, $opt$noinline$mulNeg(17, 18));
555*795d594fSAndroid Build Coastguard Worker     assertLongEquals(-380, $opt$noinline$mulNeg(19, 20));
556*795d594fSAndroid Build Coastguard Worker 
557*795d594fSAndroid Build Coastguard Worker     testSimdMultiplyAccumulate();
558*795d594fSAndroid Build Coastguard Worker   }
559*795d594fSAndroid Build Coastguard Worker }
560