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