1418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames/*
2fb7fc7b1e11523b6e4f444f0f54de0b49cd0c4e1Roland Levillain * Copyright (C) 2015 The Android Open Source Project
3fb7fc7b1e11523b6e4f444f0f54de0b49cd0c4e1Roland Levillain *
4fb7fc7b1e11523b6e4f444f0f54de0b49cd0c4e1Roland Levillain * Licensed under the Apache License, Version 2.0 (the "License");
5fb7fc7b1e11523b6e4f444f0f54de0b49cd0c4e1Roland Levillain * you may not use this file except in compliance with the License.
6fb7fc7b1e11523b6e4f444f0f54de0b49cd0c4e1Roland Levillain * You may obtain a copy of the License at
7fb7fc7b1e11523b6e4f444f0f54de0b49cd0c4e1Roland Levillain *
8fb7fc7b1e11523b6e4f444f0f54de0b49cd0c4e1Roland Levillain *      http://www.apache.org/licenses/LICENSE-2.0
9fb7fc7b1e11523b6e4f444f0f54de0b49cd0c4e1Roland Levillain *
10fb7fc7b1e11523b6e4f444f0f54de0b49cd0c4e1Roland Levillain * Unless required by applicable law or agreed to in writing, software
11fb7fc7b1e11523b6e4f444f0f54de0b49cd0c4e1Roland Levillain * distributed under the License is distributed on an "AS IS" BASIS,
12fb7fc7b1e11523b6e4f444f0f54de0b49cd0c4e1Roland Levillain * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13fb7fc7b1e11523b6e4f444f0f54de0b49cd0c4e1Roland Levillain * See the License for the specific language governing permissions and
14fb7fc7b1e11523b6e4f444f0f54de0b49cd0c4e1Roland Levillain * limitations under the License.
15fb7fc7b1e11523b6e4f444f0f54de0b49cd0c4e1Roland Levillain */
16418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames
17418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Ramespublic class Main {
18418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames
19418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  // A dummy value to defeat inlining of these routines.
20418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  static boolean doThrow = false;
21418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames
22418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  public static void assertIntEquals(int expected, int result) {
23418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames    if (expected != result) {
24418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames      throw new Error("Expected: " + expected + ", found: " + result);
25418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames    }
26418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  }
27418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames
28418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  public static void assertLongEquals(long expected, long result) {
29418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames    if (expected != result) {
30418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames      throw new Error("Expected: " + expected + ", found: " + result);
31418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames    }
32418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  }
33418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames
34418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  /**
35418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames   * Test basic merging of `MUL+ADD` into `MULADD`.
36418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames   */
37418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames
38418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  /// CHECK-START-ARM64: int Main.$opt$noinline$mulAdd(int, int, int) instruction_simplifier_arm64 (before)
39418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  /// CHECK:       <<Acc:i\d+>>         ParameterValue
40418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  /// CHECK:       <<Left:i\d+>>        ParameterValue
41418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  /// CHECK:       <<Right:i\d+>>       ParameterValue
42418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  /// CHECK:       <<Mul:i\d+>>         Mul [<<Left>>,<<Right>>]
43418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  /// CHECK:       <<Add:i\d+>>         Add [<<Acc>>,<<Mul>>]
44418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  /// CHECK:                            Return [<<Add>>]
45418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames
46418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  /// CHECK-START-ARM64: int Main.$opt$noinline$mulAdd(int, int, int) instruction_simplifier_arm64 (after)
47418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  /// CHECK:       <<Acc:i\d+>>         ParameterValue
48418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  /// CHECK:       <<Left:i\d+>>        ParameterValue
49418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  /// CHECK:       <<Right:i\d+>>       ParameterValue
504a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK:       <<MulAdd:i\d+>>      MultiplyAccumulate [<<Acc>>,<<Left>>,<<Right>>] kind:Add
51418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  /// CHECK:                            Return [<<MulAdd>>]
52418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames
53418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  /// CHECK-START-ARM64: int Main.$opt$noinline$mulAdd(int, int, int) instruction_simplifier_arm64 (after)
54418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  /// CHECK-NOT:                        Mul
55418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  /// CHECK-NOT:                        Add
56418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames
57418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  /// CHECK-START-ARM64: int Main.$opt$noinline$mulAdd(int, int, int) disassembly (after)
58418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  /// CHECK:                            madd w{{\d+}}, w{{\d+}}, w{{\d+}}, w{{\d+}}
59418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames
604a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK-START-ARM: int Main.$opt$noinline$mulAdd(int, int, int) instruction_simplifier_arm (before)
614a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK:       <<Acc:i\d+>>         ParameterValue
624a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK:       <<Left:i\d+>>        ParameterValue
634a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK:       <<Right:i\d+>>       ParameterValue
644a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK:       <<Mul:i\d+>>         Mul [<<Left>>,<<Right>>]
654a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK:       <<Add:i\d+>>         Add [<<Acc>>,<<Mul>>]
664a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK:                            Return [<<Add>>]
674a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko
684a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK-START-ARM: int Main.$opt$noinline$mulAdd(int, int, int) instruction_simplifier_arm (after)
694a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK:       <<Acc:i\d+>>         ParameterValue
704a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK:       <<Left:i\d+>>        ParameterValue
714a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK:       <<Right:i\d+>>       ParameterValue
724a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK:       <<MulAdd:i\d+>>      MultiplyAccumulate [<<Acc>>,<<Left>>,<<Right>>] kind:Add
734a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK:                            Return [<<MulAdd>>]
744a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko
754a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK-START-ARM: int Main.$opt$noinline$mulAdd(int, int, int) instruction_simplifier_arm (after)
764a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK-NOT:                        Mul
774a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK-NOT:                        Add
784a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko
794a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK-START-ARM: int Main.$opt$noinline$mulAdd(int, int, int) disassembly (after)
804a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK:                            mla r{{\d+}}, r{{\d+}}, r{{\d+}}, r{{\d+}}
814a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko
82418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  public static int $opt$noinline$mulAdd(int acc, int left, int right) {
83418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames    if (doThrow) throw new Error();
84418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames    return acc + left * right;
85418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  }
86418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames
87418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  /**
88418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames   * Test basic merging of `MUL+SUB` into `MULSUB`.
89418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames   */
90418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames
91418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  /// CHECK-START-ARM64: long Main.$opt$noinline$mulSub(long, long, long) instruction_simplifier_arm64 (before)
92418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  /// CHECK:       <<Acc:j\d+>>         ParameterValue
93418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  /// CHECK:       <<Left:j\d+>>        ParameterValue
94418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  /// CHECK:       <<Right:j\d+>>       ParameterValue
95418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  /// CHECK:       <<Mul:j\d+>>         Mul [<<Left>>,<<Right>>]
96418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  /// CHECK:       <<Sub:j\d+>>         Sub [<<Acc>>,<<Mul>>]
97418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  /// CHECK:                            Return [<<Sub>>]
98418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames
99418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  /// CHECK-START-ARM64: long Main.$opt$noinline$mulSub(long, long, long) instruction_simplifier_arm64 (after)
100418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  /// CHECK:       <<Acc:j\d+>>         ParameterValue
101418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  /// CHECK:       <<Left:j\d+>>        ParameterValue
102418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  /// CHECK:       <<Right:j\d+>>       ParameterValue
1034a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK:       <<MulSub:j\d+>>      MultiplyAccumulate [<<Acc>>,<<Left>>,<<Right>>] kind:Sub
104418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  /// CHECK:                            Return [<<MulSub>>]
105418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames
106418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  /// CHECK-START-ARM64: long Main.$opt$noinline$mulSub(long, long, long) instruction_simplifier_arm64 (after)
107418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  /// CHECK-NOT:                        Mul
108418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  /// CHECK-NOT:                        Sub
109418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames
110418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  /// CHECK-START-ARM64: long Main.$opt$noinline$mulSub(long, long, long) disassembly (after)
111418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  /// CHECK:                            msub x{{\d+}}, x{{\d+}}, x{{\d+}}, x{{\d+}}
112418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames
1134a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK-START-ARM: long Main.$opt$noinline$mulSub(long, long, long) instruction_simplifier_arm (before)
1144a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK:       <<Acc:j\d+>>         ParameterValue
1154a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK:       <<Left:j\d+>>        ParameterValue
1164a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK:       <<Right:j\d+>>       ParameterValue
1174a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK:       <<Mul:j\d+>>         Mul [<<Left>>,<<Right>>]
1184a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK:       <<Sub:j\d+>>         Sub [<<Acc>>,<<Mul>>]
1194a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK:                            Return [<<Sub>>]
1204a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko
1214a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK-START-ARM: long Main.$opt$noinline$mulSub(long, long, long) instruction_simplifier_arm (after)
1224a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK-NOT:                        MultiplyAccumulate
1234a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko
124418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  public static long $opt$noinline$mulSub(long acc, long left, long right) {
125418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames    if (doThrow) throw new Error();
126418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames    return acc - left * right;
127418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  }
128418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames
129418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  /**
130418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames   * Test that we do not create a multiply-accumulate instruction when there
131418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames   * are other uses of the multiplication that cannot merge it.
132418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames   */
133418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames
134418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  /// CHECK-START-ARM64: int Main.$opt$noinline$multipleUses1(int, int, int) instruction_simplifier_arm64 (before)
135418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  /// CHECK:       <<Acc:i\d+>>         ParameterValue
136418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  /// CHECK:       <<Left:i\d+>>        ParameterValue
137418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  /// CHECK:       <<Right:i\d+>>       ParameterValue
138418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  /// CHECK:       <<Mul:i\d+>>         Mul [<<Left>>,<<Right>>]
139418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  /// CHECK:       <<Add:i\d+>>         Add [<<Acc>>,<<Mul>>]
140418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  /// CHECK:       <<Or:i\d+>>          Or [<<Mul>>,<<Add>>]
141418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  /// CHECK:                            Return [<<Or>>]
142418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames
143418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  /// CHECK-START-ARM64: int Main.$opt$noinline$multipleUses1(int, int, int) instruction_simplifier_arm64 (after)
144418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  /// CHECK:       <<Acc:i\d+>>         ParameterValue
145418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  /// CHECK:       <<Left:i\d+>>        ParameterValue
146418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  /// CHECK:       <<Right:i\d+>>       ParameterValue
147418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  /// CHECK:       <<Mul:i\d+>>         Mul [<<Left>>,<<Right>>]
148418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  /// CHECK:       <<Add:i\d+>>         Add [<<Acc>>,<<Mul>>]
149418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  /// CHECK:       <<Or:i\d+>>          Or [<<Mul>>,<<Add>>]
150418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  /// CHECK:                            Return [<<Or>>]
151418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames
152418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  /// CHECK-START-ARM64: int Main.$opt$noinline$multipleUses1(int, int, int) instruction_simplifier_arm64 (after)
1534a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK-NOT:                        MultiplyAccumulate
1544a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko
1554a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK-START-ARM: int Main.$opt$noinline$multipleUses1(int, int, int) instruction_simplifier_arm (before)
1564a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK:       <<Acc:i\d+>>         ParameterValue
1574a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK:       <<Left:i\d+>>        ParameterValue
1584a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK:       <<Right:i\d+>>       ParameterValue
1594a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK:       <<Mul:i\d+>>         Mul [<<Left>>,<<Right>>]
1604a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK:       <<Add:i\d+>>         Add [<<Acc>>,<<Mul>>]
1614a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK:       <<Or:i\d+>>          Or [<<Mul>>,<<Add>>]
1624a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK:                            Return [<<Or>>]
1634a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko
1644a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK-START-ARM: int Main.$opt$noinline$multipleUses1(int, int, int) instruction_simplifier_arm (after)
1654a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK:       <<Acc:i\d+>>         ParameterValue
1664a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK:       <<Left:i\d+>>        ParameterValue
1674a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK:       <<Right:i\d+>>       ParameterValue
1684a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK:       <<Mul:i\d+>>         Mul [<<Left>>,<<Right>>]
1694a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK:       <<Add:i\d+>>         Add [<<Acc>>,<<Mul>>]
1704a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK:       <<Or:i\d+>>          Or [<<Mul>>,<<Add>>]
1714a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK:                            Return [<<Or>>]
1724a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko
1734a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK-START-ARM: int Main.$opt$noinline$multipleUses1(int, int, int) instruction_simplifier_arm (after)
1744a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK-NOT:                        MultiplyAccumulate
175418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames
176418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  public static int $opt$noinline$multipleUses1(int acc, int left, int right) {
177418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames    if (doThrow) throw new Error();
178418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames    int temp = left * right;
179418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames    return temp | (acc + temp);
180418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  }
181418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames
182418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  /**
183418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames   * Test that we do not create a multiply-accumulate instruction even when all
184418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames   * uses of the multiplication can merge it.
185418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames   */
186418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames
187418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  /// CHECK-START-ARM64: long Main.$opt$noinline$multipleUses2(long, long, long) instruction_simplifier_arm64 (before)
188418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  /// CHECK:       <<Acc:j\d+>>         ParameterValue
189418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  /// CHECK:       <<Left:j\d+>>        ParameterValue
190418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  /// CHECK:       <<Right:j\d+>>       ParameterValue
191418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  /// CHECK:       <<Mul:j\d+>>         Mul [<<Left>>,<<Right>>]
192418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  /// CHECK:       <<Add:j\d+>>         Add [<<Acc>>,<<Mul>>]
193418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  /// CHECK:       <<Sub:j\d+>>         Sub [<<Acc>>,<<Mul>>]
194418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  /// CHECK:       <<Res:j\d+>>         Add [<<Add>>,<<Sub>>]
195418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  /// CHECK:                            Return [<<Res>>]
196418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames
197418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  /// CHECK-START-ARM64: long Main.$opt$noinline$multipleUses2(long, long, long) instruction_simplifier_arm64 (after)
198418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  /// CHECK:       <<Acc:j\d+>>         ParameterValue
199418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  /// CHECK:       <<Left:j\d+>>        ParameterValue
200418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  /// CHECK:       <<Right:j\d+>>       ParameterValue
201418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  /// CHECK:       <<Mul:j\d+>>         Mul [<<Left>>,<<Right>>]
202418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  /// CHECK:       <<Add:j\d+>>         Add [<<Acc>>,<<Mul>>]
203418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  /// CHECK:       <<Sub:j\d+>>         Sub [<<Acc>>,<<Mul>>]
204418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  /// CHECK:       <<Res:j\d+>>         Add [<<Add>>,<<Sub>>]
205418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  /// CHECK:                            Return [<<Res>>]
206418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames
207418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  /// CHECK-START-ARM64: long Main.$opt$noinline$multipleUses2(long, long, long) instruction_simplifier_arm64 (after)
2084a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK-NOT:                        MultiplyAccumulate
2094a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko
2104a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK-START-ARM: long Main.$opt$noinline$multipleUses2(long, long, long) instruction_simplifier_arm (before)
2114a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK:       <<Acc:j\d+>>         ParameterValue
2124a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK:       <<Left:j\d+>>        ParameterValue
2134a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK:       <<Right:j\d+>>       ParameterValue
2144a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK:       <<Mul:j\d+>>         Mul [<<Left>>,<<Right>>]
2154a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK:       <<Add:j\d+>>         Add [<<Acc>>,<<Mul>>]
2164a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK:       <<Sub:j\d+>>         Sub [<<Acc>>,<<Mul>>]
2174a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK:       <<Res:j\d+>>         Add [<<Add>>,<<Sub>>]
2184a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK:                            Return [<<Res>>]
2194a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko
2204a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK-START-ARM: long Main.$opt$noinline$multipleUses2(long, long, long) instruction_simplifier_arm (after)
2214a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK:       <<Acc:j\d+>>         ParameterValue
2224a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK:       <<Left:j\d+>>        ParameterValue
2234a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK:       <<Right:j\d+>>       ParameterValue
2244a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK:       <<Mul:j\d+>>         Mul [<<Left>>,<<Right>>]
2254a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK:       <<Add:j\d+>>         Add [<<Acc>>,<<Mul>>]
2264a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK:       <<Sub:j\d+>>         Sub [<<Acc>>,<<Mul>>]
2274a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK:       <<Res:j\d+>>         Add [<<Add>>,<<Sub>>]
2284a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK:                            Return [<<Res>>]
2294a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko
2304a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK-START-ARM: long Main.$opt$noinline$multipleUses2(long, long, long) instruction_simplifier_arm (after)
2314a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK-NOT:                        MultiplyAccumulate
232418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames
233418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames
234418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  public static long $opt$noinline$multipleUses2(long acc, long left, long right) {
235418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames    if (doThrow) throw new Error();
236418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames    long temp = left * right;
237418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames    return (acc + temp) + (acc - temp);
238418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  }
239418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames
240418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames
241418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  /**
242418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames   * Test the interpretation of `a * (b + 1)` as `a + (a * b)`.
243418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames   */
244418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames
245418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  /// CHECK-START-ARM64: int Main.$opt$noinline$mulPlusOne(int, int) instruction_simplifier_arm64 (before)
246418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  /// CHECK:       <<Acc:i\d+>>         ParameterValue
247418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  /// CHECK:       <<Var:i\d+>>         ParameterValue
248418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  /// CHECK:       <<Const1:i\d+>>      IntConstant 1
249418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  /// CHECK:       <<Add:i\d+>>         Add [<<Var>>,<<Const1>>]
250418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  /// CHECK:       <<Mul:i\d+>>         Mul [<<Acc>>,<<Add>>]
251418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  /// CHECK:                            Return [<<Mul>>]
252418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames
253418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  /// CHECK-START-ARM64: int Main.$opt$noinline$mulPlusOne(int, int) instruction_simplifier_arm64 (after)
254418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  /// CHECK:       <<Acc:i\d+>>         ParameterValue
255418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  /// CHECK:       <<Var:i\d+>>         ParameterValue
2564a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK:       <<MulAdd:i\d+>>      MultiplyAccumulate [<<Acc>>,<<Acc>>,<<Var>>] kind:Add
257418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  /// CHECK:                            Return [<<MulAdd>>]
258418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames
259418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  /// CHECK-START-ARM64: int Main.$opt$noinline$mulPlusOne(int, int) instruction_simplifier_arm64 (after)
260418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  /// CHECK-NOT:                        Mul
261418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  /// CHECK-NOT:                        Add
262418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames
263418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  /// CHECK-START-ARM64: int Main.$opt$noinline$mulPlusOne(int, int) disassembly (after)
264418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  /// CHECK:                            madd w{{\d+}}, w{{\d+}}, w{{\d+}}, w{{\d+}}
265418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames
2664a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK-START-ARM: int Main.$opt$noinline$mulPlusOne(int, int) instruction_simplifier_arm (before)
2674a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK:       <<Acc:i\d+>>         ParameterValue
2684a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK:       <<Var:i\d+>>         ParameterValue
2694a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK:       <<Const1:i\d+>>      IntConstant 1
2704a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK:       <<Add:i\d+>>         Add [<<Var>>,<<Const1>>]
2714a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK:       <<Mul:i\d+>>         Mul [<<Acc>>,<<Add>>]
2724a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK:                            Return [<<Mul>>]
2734a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko
2744a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK-START-ARM: int Main.$opt$noinline$mulPlusOne(int, int) instruction_simplifier_arm (after)
2754a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK:       <<Acc:i\d+>>         ParameterValue
2764a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK:       <<Var:i\d+>>         ParameterValue
2774a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK:       <<MulAdd:i\d+>>      MultiplyAccumulate [<<Acc>>,<<Acc>>,<<Var>>] kind:Add
2784a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK:                            Return [<<MulAdd>>]
2794a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko
2804a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK-START-ARM: int Main.$opt$noinline$mulPlusOne(int, int) instruction_simplifier_arm (after)
2814a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK-NOT:                        Mul
2824a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK-NOT:                        Add
2834a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko
2844a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK-START-ARM: int Main.$opt$noinline$mulPlusOne(int, int) disassembly (after)
2854a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK:                            mla r{{\d+}}, r{{\d+}}, r{{\d+}}, r{{\d+}}
2864a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko
287418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  public static int $opt$noinline$mulPlusOne(int acc, int var) {
288418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames    if (doThrow) throw new Error();
289418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames    return acc * (var + 1);
290418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  }
291418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames
292418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames
293418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  /**
294418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames   * Test the interpretation of `a * (1 - b)` as `a - (a * b)`.
295418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames   */
296418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames
297418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  /// CHECK-START-ARM64: long Main.$opt$noinline$mulMinusOne(long, long) instruction_simplifier_arm64 (before)
298418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  /// CHECK:       <<Acc:j\d+>>         ParameterValue
299418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  /// CHECK:       <<Var:j\d+>>         ParameterValue
300418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  /// CHECK:       <<Const1:j\d+>>      LongConstant 1
301418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  /// CHECK:       <<Sub:j\d+>>         Sub [<<Const1>>,<<Var>>]
302418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  /// CHECK:       <<Mul:j\d+>>         Mul [<<Acc>>,<<Sub>>]
303418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  /// CHECK:                            Return [<<Mul>>]
304418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames
305418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  /// CHECK-START-ARM64: long Main.$opt$noinline$mulMinusOne(long, long) instruction_simplifier_arm64 (after)
306418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  /// CHECK:       <<Acc:j\d+>>         ParameterValue
307418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  /// CHECK:       <<Var:j\d+>>         ParameterValue
3084a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK:       <<MulSub:j\d+>>      MultiplyAccumulate [<<Acc>>,<<Acc>>,<<Var>>] kind:Sub
309418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  /// CHECK:                            Return [<<MulSub>>]
310418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames
311418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  /// CHECK-START-ARM64: long Main.$opt$noinline$mulMinusOne(long, long) instruction_simplifier_arm64 (after)
312418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  /// CHECK-NOT:                        Mul
313418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  /// CHECK-NOT:                        Sub
314418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames
315418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  /// CHECK-START-ARM64: long Main.$opt$noinline$mulMinusOne(long, long) disassembly (after)
316418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  /// CHECK:                            msub x{{\d+}}, x{{\d+}}, x{{\d+}}, x{{\d+}}
317418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames
3184a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK-START-ARM: long Main.$opt$noinline$mulMinusOne(long, long) instruction_simplifier_arm (before)
3194a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK:       <<Acc:j\d+>>         ParameterValue
3204a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK:       <<Var:j\d+>>         ParameterValue
3214a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK:       <<Const1:j\d+>>      LongConstant 1
3224a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK:       <<Sub:j\d+>>         Sub [<<Const1>>,<<Var>>]
3234a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK:       <<Mul:j\d+>>         Mul [<<Acc>>,<<Sub>>]
3244a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK:                            Return [<<Mul>>]
3254a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko
3264a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK-START-ARM: long Main.$opt$noinline$mulMinusOne(long, long) instruction_simplifier_arm (after)
3274a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK-NOT:                        MultiplyAccumulate
328418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  public static long $opt$noinline$mulMinusOne(long acc, long var) {
329418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames    if (doThrow) throw new Error();
330418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames    return acc * (1 - var);
331418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  }
332418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames
3334a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /**
3344a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko   * Test basic merging of `MUL+NEG` into `MULNEG`.
3354a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko   */
3364a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko
3374a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK-START-ARM64: int Main.$opt$noinline$mulNeg(int, int) instruction_simplifier_arm64 (before)
3384a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK:       <<Left:i\d+>>        ParameterValue
3394a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK:       <<Right:i\d+>>       ParameterValue
3404a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK:       <<Mul:i\d+>>         Mul [<<Left>>,<<Right>>]
3414a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK:       <<Neg:i\d+>>         Neg [<<Mul>>]
3424a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK:                            Return [<<Neg>>]
3434a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko
3444a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK-START-ARM64: int Main.$opt$noinline$mulNeg(int, int) instruction_simplifier_arm64 (after)
3454a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK:       <<Left:i\d+>>        ParameterValue
3464a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK:       <<Right:i\d+>>       ParameterValue
3474a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK:       <<Const0:i\d+>>      IntConstant 0
3484a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK:       <<MulNeg:i\d+>>      MultiplyAccumulate [<<Const0>>,<<Left>>,<<Right>>] kind:Sub
3494a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK:                            Return [<<MulNeg>>]
3504a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko
3514a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK-START-ARM64: int Main.$opt$noinline$mulNeg(int, int) instruction_simplifier_arm64 (after)
3524a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK-NOT:                        Mul
3534a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK-NOT:                        Neg
3544a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko
3554a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK-START-ARM64: int Main.$opt$noinline$mulNeg(int, int) disassembly (after)
3564a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK:                            mneg w{{\d+}}, w{{\d+}}, w{{\d+}}
3574a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko
3584a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK-START-ARM: int Main.$opt$noinline$mulNeg(int, int) instruction_simplifier_arm (before)
3594a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK:       <<Left:i\d+>>        ParameterValue
3604a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK:       <<Right:i\d+>>       ParameterValue
3614a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK:       <<Mul:i\d+>>         Mul [<<Left>>,<<Right>>]
3624a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK:       <<Neg:i\d+>>         Neg [<<Mul>>]
3634a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK:                            Return [<<Neg>>]
3644a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko
3654a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK-START-ARM: int Main.$opt$noinline$mulNeg(int, int) instruction_simplifier_arm (after)
3664a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK:       <<Left:i\d+>>        ParameterValue
3674a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK:       <<Right:i\d+>>       ParameterValue
3684a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK:       <<Mul:i\d+>>         Mul [<<Left>>,<<Right>>]
3694a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK:       <<Neg:i\d+>>         Neg [<<Mul>>]
3704a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK:                            Return [<<Neg>>]
3714a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko
3724a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK-START-ARM: int Main.$opt$noinline$mulNeg(int, int) instruction_simplifier_arm (after)
3734a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK-NOT:                        MultiplyAccumulate
3744a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko
3754a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  public static int $opt$noinline$mulNeg(int left, int right) {
3764a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko    if (doThrow) throw new Error();
3774a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko    return - (left * right);
3784a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  }
3794a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko
3804a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /**
3814a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko   * Test basic merging of `MUL+NEG` into `MULNEG`.
3824a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko   */
3834a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko
3844a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK-START-ARM64: long Main.$opt$noinline$mulNeg(long, long) instruction_simplifier_arm64 (before)
3854a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK:       <<Left:j\d+>>        ParameterValue
3864a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK:       <<Right:j\d+>>       ParameterValue
3874a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK:       <<Mul:j\d+>>         Mul [<<Left>>,<<Right>>]
3884a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK:       <<Neg:j\d+>>         Neg [<<Mul>>]
3894a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK:                            Return [<<Neg>>]
3904a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko
3914a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK-START-ARM64: long Main.$opt$noinline$mulNeg(long, long) instruction_simplifier_arm64 (after)
3924a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK:       <<Left:j\d+>>        ParameterValue
3934a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK:       <<Right:j\d+>>       ParameterValue
3944a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK:       <<Const0:j\d+>>      LongConstant 0
3954a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK:       <<MulNeg:j\d+>>      MultiplyAccumulate [<<Const0>>,<<Left>>,<<Right>>] kind:Sub
3964a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK:                            Return [<<MulNeg>>]
3974a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko
3984a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK-START-ARM64: long Main.$opt$noinline$mulNeg(long, long) instruction_simplifier_arm64 (after)
3994a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK-NOT:                        Mul
4004a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK-NOT:                        Neg
4014a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko
4024a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK-START-ARM64: long Main.$opt$noinline$mulNeg(long, long) disassembly (after)
4034a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK:                            mneg x{{\d+}}, x{{\d+}}, x{{\d+}}
4044a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko
4054a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK-START-ARM: long Main.$opt$noinline$mulNeg(long, long) instruction_simplifier_arm (before)
4064a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK:       <<Left:j\d+>>        ParameterValue
4074a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK:       <<Right:j\d+>>       ParameterValue
4084a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK:       <<Mul:j\d+>>         Mul [<<Left>>,<<Right>>]
4094a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK:       <<Neg:j\d+>>         Neg [<<Mul>>]
4104a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK:                            Return [<<Neg>>]
4114a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko
4124a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK-START-ARM: long Main.$opt$noinline$mulNeg(long, long) instruction_simplifier_arm (after)
4134a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK:       <<Left:j\d+>>        ParameterValue
4144a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK:       <<Right:j\d+>>       ParameterValue
4154a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK:       <<Mul:j\d+>>         Mul [<<Left>>,<<Right>>]
4164a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK:       <<Neg:j\d+>>         Neg [<<Mul>>]
4174a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK:                            Return [<<Neg>>]
4184a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko
4194a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK-START-ARM: long Main.$opt$noinline$mulNeg(long, long) instruction_simplifier_arm (after)
4204a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  /// CHECK-NOT:                        MultiplyAccumulate
4214a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko
4224a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  public static long $opt$noinline$mulNeg(long left, long right) {
4234a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko    if (doThrow) throw new Error();
4244a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko    return - (left * right);
4254a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko  }
426418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames
4279cb7fe4daf872fd0cb312489af263ebc622033a8Aart Bik  /// CHECK-START-{ARM64,MIPS64}: void Main.SimdMulAdd(int[], int[]) instruction_simplifier$after_bce (before)
428f34dd206d0073fb3949be872224420a8488f551fArtem Serov  /// CHECK-DAG:     Phi                            loop:<<Loop:B\d+>> outer_loop:none
429f34dd206d0073fb3949be872224420a8488f551fArtem Serov  /// CHECK-DAG:     VecMul                         loop:<<Loop>>      outer_loop:none
430f34dd206d0073fb3949be872224420a8488f551fArtem Serov  /// CHECK-DAG:     VecAdd                         loop:<<Loop>>      outer_loop:none
431f34dd206d0073fb3949be872224420a8488f551fArtem Serov
4329cb7fe4daf872fd0cb312489af263ebc622033a8Aart Bik  /// CHECK-START-{ARM64,MIPS64}: void Main.SimdMulAdd(int[], int[]) instruction_simplifier$after_bce (after)
433f34dd206d0073fb3949be872224420a8488f551fArtem Serov  /// CHECK-DAG:     Phi                            loop:<<Loop:B\d+>> outer_loop:none
434f34dd206d0073fb3949be872224420a8488f551fArtem Serov  /// CHECK-DAG:     VecMultiplyAccumulate kind:Add loop:<<Loop>>      outer_loop:none
435f34dd206d0073fb3949be872224420a8488f551fArtem Serov
4369cb7fe4daf872fd0cb312489af263ebc622033a8Aart Bik  /// CHECK-START-{ARM64,MIPS64}: void Main.SimdMulAdd(int[], int[]) instruction_simplifier$after_bce (after)
437bc5460b850a0fa2d8dcf6c8d36b0eb86f8fe46a8Lena Djokic  /// CHECK-NOT:     VecMul
438bc5460b850a0fa2d8dcf6c8d36b0eb86f8fe46a8Lena Djokic  /// CHECK-NOT:     VecAdd
439bc5460b850a0fa2d8dcf6c8d36b0eb86f8fe46a8Lena Djokic
440f34dd206d0073fb3949be872224420a8488f551fArtem Serov  public static void SimdMulAdd(int[] array1, int[] array2) {
441f34dd206d0073fb3949be872224420a8488f551fArtem Serov    for (int j = 0; j < 100; j++) {
442f34dd206d0073fb3949be872224420a8488f551fArtem Serov      array2[j] += 12345 * array1[j];
443f34dd206d0073fb3949be872224420a8488f551fArtem Serov    }
444f34dd206d0073fb3949be872224420a8488f551fArtem Serov  }
445f34dd206d0073fb3949be872224420a8488f551fArtem Serov
446bc5460b850a0fa2d8dcf6c8d36b0eb86f8fe46a8Lena Djokic  /// CHECK-START-MIPS64: void Main.SimdMulAddLong(long[], long[]) instruction_simplifier$after_bce (before)
447bc5460b850a0fa2d8dcf6c8d36b0eb86f8fe46a8Lena Djokic  /// CHECK-DAG:     Phi                            loop:<<Loop:B\d+>> outer_loop:none
448bc5460b850a0fa2d8dcf6c8d36b0eb86f8fe46a8Lena Djokic  /// CHECK-DAG:     VecMul                         loop:<<Loop>>      outer_loop:none
449bc5460b850a0fa2d8dcf6c8d36b0eb86f8fe46a8Lena Djokic  /// CHECK-DAG:     VecAdd                         loop:<<Loop>>      outer_loop:none
450bc5460b850a0fa2d8dcf6c8d36b0eb86f8fe46a8Lena Djokic
451bc5460b850a0fa2d8dcf6c8d36b0eb86f8fe46a8Lena Djokic  /// CHECK-START-MIPS64: void Main.SimdMulAddLong(long[], long[]) instruction_simplifier$after_bce (after)
452bc5460b850a0fa2d8dcf6c8d36b0eb86f8fe46a8Lena Djokic  /// CHECK-DAG:     Phi                            loop:<<Loop:B\d+>> outer_loop:none
453bc5460b850a0fa2d8dcf6c8d36b0eb86f8fe46a8Lena Djokic  /// CHECK-DAG:     VecMultiplyAccumulate kind:Add loop:<<Loop>>      outer_loop:none
454bc5460b850a0fa2d8dcf6c8d36b0eb86f8fe46a8Lena Djokic
455bc5460b850a0fa2d8dcf6c8d36b0eb86f8fe46a8Lena Djokic  /// CHECK-START-MIPS64: void Main.SimdMulAddLong(long[], long[]) instruction_simplifier$after_bce (after)
456bc5460b850a0fa2d8dcf6c8d36b0eb86f8fe46a8Lena Djokic  /// CHECK-NOT:     VecMul
457bc5460b850a0fa2d8dcf6c8d36b0eb86f8fe46a8Lena Djokic  /// CHECK-NOT:     VecAdd
458bc5460b850a0fa2d8dcf6c8d36b0eb86f8fe46a8Lena Djokic  public static void SimdMulAddLong(long[] array1, long[] array2) {
459bc5460b850a0fa2d8dcf6c8d36b0eb86f8fe46a8Lena Djokic    for (int j = 0; j < 100; j++) {
460bc5460b850a0fa2d8dcf6c8d36b0eb86f8fe46a8Lena Djokic      array2[j] += 12345 * array1[j];
461bc5460b850a0fa2d8dcf6c8d36b0eb86f8fe46a8Lena Djokic    }
462bc5460b850a0fa2d8dcf6c8d36b0eb86f8fe46a8Lena Djokic  }
463bc5460b850a0fa2d8dcf6c8d36b0eb86f8fe46a8Lena Djokic
4649cb7fe4daf872fd0cb312489af263ebc622033a8Aart Bik  /// CHECK-START-{ARM64,MIPS64}: void Main.SimdMulSub(int[], int[]) instruction_simplifier$after_bce (before)
465f34dd206d0073fb3949be872224420a8488f551fArtem Serov  /// CHECK-DAG:     Phi                            loop:<<Loop:B\d+>> outer_loop:none
466f34dd206d0073fb3949be872224420a8488f551fArtem Serov  /// CHECK-DAG:     VecMul                         loop:<<Loop>>      outer_loop:none
467f34dd206d0073fb3949be872224420a8488f551fArtem Serov  /// CHECK-DAG:     VecSub                         loop:<<Loop>>      outer_loop:none
468f34dd206d0073fb3949be872224420a8488f551fArtem Serov
4699cb7fe4daf872fd0cb312489af263ebc622033a8Aart Bik  /// CHECK-START-{ARM64,MIPS64}: void Main.SimdMulSub(int[], int[]) instruction_simplifier$after_bce (after)
470f34dd206d0073fb3949be872224420a8488f551fArtem Serov  /// CHECK-DAG:     Phi                            loop:<<Loop:B\d+>> outer_loop:none
471f34dd206d0073fb3949be872224420a8488f551fArtem Serov  /// CHECK-DAG:     VecMultiplyAccumulate kind:Sub loop:<<Loop>>      outer_loop:none
472f34dd206d0073fb3949be872224420a8488f551fArtem Serov
4739cb7fe4daf872fd0cb312489af263ebc622033a8Aart Bik  /// CHECK-START-{ARM64,MIPS64}: void Main.SimdMulSub(int[], int[]) instruction_simplifier$after_bce (after)
474bc5460b850a0fa2d8dcf6c8d36b0eb86f8fe46a8Lena Djokic  /// CHECK-NOT:     VecMul
475bc5460b850a0fa2d8dcf6c8d36b0eb86f8fe46a8Lena Djokic  /// CHECK-NOT:     VecSub
476bc5460b850a0fa2d8dcf6c8d36b0eb86f8fe46a8Lena Djokic
477f34dd206d0073fb3949be872224420a8488f551fArtem Serov  public static void SimdMulSub(int[] array1, int[] array2) {
478f34dd206d0073fb3949be872224420a8488f551fArtem Serov    for (int j = 0; j < 100; j++) {
479f34dd206d0073fb3949be872224420a8488f551fArtem Serov      array2[j] -= 12345 * array1[j];
480f34dd206d0073fb3949be872224420a8488f551fArtem Serov    }
481f34dd206d0073fb3949be872224420a8488f551fArtem Serov  }
482f34dd206d0073fb3949be872224420a8488f551fArtem Serov
483bc5460b850a0fa2d8dcf6c8d36b0eb86f8fe46a8Lena Djokic  /// CHECK-START-MIPS64: void Main.SimdMulSubLong(long[], long[]) instruction_simplifier$after_bce (before)
484bc5460b850a0fa2d8dcf6c8d36b0eb86f8fe46a8Lena Djokic  /// CHECK-DAG:     Phi                            loop:<<Loop:B\d+>> outer_loop:none
485bc5460b850a0fa2d8dcf6c8d36b0eb86f8fe46a8Lena Djokic  /// CHECK-DAG:     VecMul                         loop:<<Loop>>      outer_loop:none
486bc5460b850a0fa2d8dcf6c8d36b0eb86f8fe46a8Lena Djokic  /// CHECK-DAG:     VecSub                         loop:<<Loop>>      outer_loop:none
487bc5460b850a0fa2d8dcf6c8d36b0eb86f8fe46a8Lena Djokic
488bc5460b850a0fa2d8dcf6c8d36b0eb86f8fe46a8Lena Djokic  /// CHECK-START-MIPS64: void Main.SimdMulSubLong(long[], long[]) instruction_simplifier$after_bce (after)
489bc5460b850a0fa2d8dcf6c8d36b0eb86f8fe46a8Lena Djokic  /// CHECK-DAG:     Phi                            loop:<<Loop:B\d+>> outer_loop:none
490bc5460b850a0fa2d8dcf6c8d36b0eb86f8fe46a8Lena Djokic  /// CHECK-DAG:     VecMultiplyAccumulate kind:Sub loop:<<Loop>>      outer_loop:none
491bc5460b850a0fa2d8dcf6c8d36b0eb86f8fe46a8Lena Djokic
492bc5460b850a0fa2d8dcf6c8d36b0eb86f8fe46a8Lena Djokic  /// CHECK-START-MIPS64: void Main.SimdMulSubLong(long[], long[]) instruction_simplifier$after_bce (after)
493bc5460b850a0fa2d8dcf6c8d36b0eb86f8fe46a8Lena Djokic  /// CHECK-NOT:     VecMul
494bc5460b850a0fa2d8dcf6c8d36b0eb86f8fe46a8Lena Djokic  /// CHECK-NOT:     VecSub
495bc5460b850a0fa2d8dcf6c8d36b0eb86f8fe46a8Lena Djokic  public static void SimdMulSubLong(long[] array1, long[] array2) {
496bc5460b850a0fa2d8dcf6c8d36b0eb86f8fe46a8Lena Djokic    for (int j = 0; j < 100; j++) {
497bc5460b850a0fa2d8dcf6c8d36b0eb86f8fe46a8Lena Djokic      array2[j] -= 12345 * array1[j];
498bc5460b850a0fa2d8dcf6c8d36b0eb86f8fe46a8Lena Djokic    }
499bc5460b850a0fa2d8dcf6c8d36b0eb86f8fe46a8Lena Djokic  }
500bc5460b850a0fa2d8dcf6c8d36b0eb86f8fe46a8Lena Djokic
5019cb7fe4daf872fd0cb312489af263ebc622033a8Aart Bik  /// CHECK-START-{ARM64,MIPS64}: void Main.SimdMulMultipleUses(int[], int[]) instruction_simplifier$after_bce (before)
502bc5460b850a0fa2d8dcf6c8d36b0eb86f8fe46a8Lena Djokic  /// CHECK-DAG:     Phi                            loop:<<Loop:B\d+>> outer_loop:none
503bc5460b850a0fa2d8dcf6c8d36b0eb86f8fe46a8Lena Djokic  /// CHECK-DAG:     VecMul                         loop:<<Loop>>      outer_loop:none
504bc5460b850a0fa2d8dcf6c8d36b0eb86f8fe46a8Lena Djokic  /// CHECK-DAG:     VecSub                         loop:<<Loop>>      outer_loop:none
505bc5460b850a0fa2d8dcf6c8d36b0eb86f8fe46a8Lena Djokic
5069cb7fe4daf872fd0cb312489af263ebc622033a8Aart Bik  /// CHECK-START-{ARM64,MIPS64}: void Main.SimdMulMultipleUses(int[], int[]) instruction_simplifier$after_bce (after)
507bc5460b850a0fa2d8dcf6c8d36b0eb86f8fe46a8Lena Djokic  /// CHECK-NOT: VecMultiplyAccumulate
508bc5460b850a0fa2d8dcf6c8d36b0eb86f8fe46a8Lena Djokic
509f34dd206d0073fb3949be872224420a8488f551fArtem Serov  public static void SimdMulMultipleUses(int[] array1, int[] array2) {
510f34dd206d0073fb3949be872224420a8488f551fArtem Serov    for (int j = 0; j < 100; j++) {
511f34dd206d0073fb3949be872224420a8488f551fArtem Serov       int temp = 12345 * array1[j];
512f34dd206d0073fb3949be872224420a8488f551fArtem Serov       array2[j] -= temp;
513f34dd206d0073fb3949be872224420a8488f551fArtem Serov       array1[j] = temp;
514f34dd206d0073fb3949be872224420a8488f551fArtem Serov    }
515f34dd206d0073fb3949be872224420a8488f551fArtem Serov  }
516f34dd206d0073fb3949be872224420a8488f551fArtem Serov
517bc5460b850a0fa2d8dcf6c8d36b0eb86f8fe46a8Lena Djokic  /// CHECK-START-MIPS64: void Main.SimdMulMultipleUsesLong(long[], long[]) instruction_simplifier$after_bce (before)
518bc5460b850a0fa2d8dcf6c8d36b0eb86f8fe46a8Lena Djokic  /// CHECK-DAG:     Phi                            loop:<<Loop:B\d+>> outer_loop:none
519bc5460b850a0fa2d8dcf6c8d36b0eb86f8fe46a8Lena Djokic  /// CHECK-DAG:     VecMul                         loop:<<Loop>>      outer_loop:none
520bc5460b850a0fa2d8dcf6c8d36b0eb86f8fe46a8Lena Djokic  /// CHECK-DAG:     VecSub                         loop:<<Loop>>      outer_loop:none
521bc5460b850a0fa2d8dcf6c8d36b0eb86f8fe46a8Lena Djokic
522bc5460b850a0fa2d8dcf6c8d36b0eb86f8fe46a8Lena Djokic  /// CHECK-START-MIPS64: void Main.SimdMulMultipleUsesLong(long[], long[]) instruction_simplifier$after_bce (after)
523bc5460b850a0fa2d8dcf6c8d36b0eb86f8fe46a8Lena Djokic  /// CHECK-NOT: VecMultiplyAccumulate
524bc5460b850a0fa2d8dcf6c8d36b0eb86f8fe46a8Lena Djokic  public static void SimdMulMultipleUsesLong(long[] array1, long[] array2) {
525bc5460b850a0fa2d8dcf6c8d36b0eb86f8fe46a8Lena Djokic    for (int j = 0; j < 100; j++) {
526bc5460b850a0fa2d8dcf6c8d36b0eb86f8fe46a8Lena Djokic       long temp = 12345 * array1[j];
527bc5460b850a0fa2d8dcf6c8d36b0eb86f8fe46a8Lena Djokic       array2[j] -= temp;
528bc5460b850a0fa2d8dcf6c8d36b0eb86f8fe46a8Lena Djokic       array1[j] = temp;
529bc5460b850a0fa2d8dcf6c8d36b0eb86f8fe46a8Lena Djokic    }
530bc5460b850a0fa2d8dcf6c8d36b0eb86f8fe46a8Lena Djokic  }
531bc5460b850a0fa2d8dcf6c8d36b0eb86f8fe46a8Lena Djokic
532f34dd206d0073fb3949be872224420a8488f551fArtem Serov  public static final int ARRAY_SIZE = 1000;
533f34dd206d0073fb3949be872224420a8488f551fArtem Serov
534f34dd206d0073fb3949be872224420a8488f551fArtem Serov  public static void initArray(int[] array) {
535f34dd206d0073fb3949be872224420a8488f551fArtem Serov    for (int i = 0; i < ARRAY_SIZE; i++) {
536f34dd206d0073fb3949be872224420a8488f551fArtem Serov      array[i] = i;
537f34dd206d0073fb3949be872224420a8488f551fArtem Serov    }
538f34dd206d0073fb3949be872224420a8488f551fArtem Serov  }
539f34dd206d0073fb3949be872224420a8488f551fArtem Serov
540bc5460b850a0fa2d8dcf6c8d36b0eb86f8fe46a8Lena Djokic  public static void initArrayLong(long[] array) {
541bc5460b850a0fa2d8dcf6c8d36b0eb86f8fe46a8Lena Djokic    for (int i = 0; i < ARRAY_SIZE; i++) {
542bc5460b850a0fa2d8dcf6c8d36b0eb86f8fe46a8Lena Djokic      array[i] = i;
543bc5460b850a0fa2d8dcf6c8d36b0eb86f8fe46a8Lena Djokic    }
544bc5460b850a0fa2d8dcf6c8d36b0eb86f8fe46a8Lena Djokic  }
545bc5460b850a0fa2d8dcf6c8d36b0eb86f8fe46a8Lena Djokic
546f34dd206d0073fb3949be872224420a8488f551fArtem Serov  public static int calcArraySum(int[] array) {
547f34dd206d0073fb3949be872224420a8488f551fArtem Serov    int sum = 0;
548f34dd206d0073fb3949be872224420a8488f551fArtem Serov    for (int i = 0; i < ARRAY_SIZE; i++) {
549f34dd206d0073fb3949be872224420a8488f551fArtem Serov      sum += array[i];
550f34dd206d0073fb3949be872224420a8488f551fArtem Serov    }
551f34dd206d0073fb3949be872224420a8488f551fArtem Serov    return sum;
552f34dd206d0073fb3949be872224420a8488f551fArtem Serov  }
553f34dd206d0073fb3949be872224420a8488f551fArtem Serov
554bc5460b850a0fa2d8dcf6c8d36b0eb86f8fe46a8Lena Djokic  public static long calcArraySumLong(long[] array) {
555bc5460b850a0fa2d8dcf6c8d36b0eb86f8fe46a8Lena Djokic    long sum = 0;
556bc5460b850a0fa2d8dcf6c8d36b0eb86f8fe46a8Lena Djokic    for (int i = 0; i < ARRAY_SIZE; i++) {
557bc5460b850a0fa2d8dcf6c8d36b0eb86f8fe46a8Lena Djokic      sum += array[i];
558bc5460b850a0fa2d8dcf6c8d36b0eb86f8fe46a8Lena Djokic    }
559bc5460b850a0fa2d8dcf6c8d36b0eb86f8fe46a8Lena Djokic    return sum;
560bc5460b850a0fa2d8dcf6c8d36b0eb86f8fe46a8Lena Djokic  }
561bc5460b850a0fa2d8dcf6c8d36b0eb86f8fe46a8Lena Djokic
562f34dd206d0073fb3949be872224420a8488f551fArtem Serov  public static void testSimdMultiplyAccumulate() {
563f34dd206d0073fb3949be872224420a8488f551fArtem Serov    int[] array1 = new int[ARRAY_SIZE];
564f34dd206d0073fb3949be872224420a8488f551fArtem Serov    int[] array2 = new int[ARRAY_SIZE];
565bc5460b850a0fa2d8dcf6c8d36b0eb86f8fe46a8Lena Djokic    long[] array3 = new long[ARRAY_SIZE];
566bc5460b850a0fa2d8dcf6c8d36b0eb86f8fe46a8Lena Djokic    long[] array4 = new long[ARRAY_SIZE];
567f34dd206d0073fb3949be872224420a8488f551fArtem Serov
568f34dd206d0073fb3949be872224420a8488f551fArtem Serov    initArray(array1);
569f34dd206d0073fb3949be872224420a8488f551fArtem Serov    initArray(array2);
570f34dd206d0073fb3949be872224420a8488f551fArtem Serov    SimdMulSub(array1, array2);
571f34dd206d0073fb3949be872224420a8488f551fArtem Serov    assertIntEquals(-60608250, calcArraySum(array2));
572f34dd206d0073fb3949be872224420a8488f551fArtem Serov
573bc5460b850a0fa2d8dcf6c8d36b0eb86f8fe46a8Lena Djokic    initArrayLong(array3);
574bc5460b850a0fa2d8dcf6c8d36b0eb86f8fe46a8Lena Djokic    initArrayLong(array4);
575bc5460b850a0fa2d8dcf6c8d36b0eb86f8fe46a8Lena Djokic    SimdMulSubLong(array3, array4);
576bc5460b850a0fa2d8dcf6c8d36b0eb86f8fe46a8Lena Djokic    assertLongEquals(-60608250, calcArraySumLong(array4));
577bc5460b850a0fa2d8dcf6c8d36b0eb86f8fe46a8Lena Djokic
578f34dd206d0073fb3949be872224420a8488f551fArtem Serov    initArray(array1);
579f34dd206d0073fb3949be872224420a8488f551fArtem Serov    initArray(array2);
580f34dd206d0073fb3949be872224420a8488f551fArtem Serov    SimdMulAdd(array1, array2);
581f34dd206d0073fb3949be872224420a8488f551fArtem Serov    assertIntEquals(61607250, calcArraySum(array2));
582bc5460b850a0fa2d8dcf6c8d36b0eb86f8fe46a8Lena Djokic
583bc5460b850a0fa2d8dcf6c8d36b0eb86f8fe46a8Lena Djokic    initArrayLong(array3);
584bc5460b850a0fa2d8dcf6c8d36b0eb86f8fe46a8Lena Djokic    initArrayLong(array4);
585bc5460b850a0fa2d8dcf6c8d36b0eb86f8fe46a8Lena Djokic    SimdMulAddLong(array3, array4);
586bc5460b850a0fa2d8dcf6c8d36b0eb86f8fe46a8Lena Djokic    assertLongEquals(61607250, calcArraySumLong(array4));
587f34dd206d0073fb3949be872224420a8488f551fArtem Serov  }
588f34dd206d0073fb3949be872224420a8488f551fArtem Serov
589418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  public static void main(String[] args) {
590418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames    assertIntEquals(7, $opt$noinline$mulAdd(1, 2, 3));
591418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames    assertLongEquals(-26, $opt$noinline$mulSub(4, 5, 6));
592418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames    assertIntEquals(79, $opt$noinline$multipleUses1(7, 8, 9));
593418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames    assertLongEquals(20, $opt$noinline$multipleUses2(10, 11, 12));
594418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames    assertIntEquals(195, $opt$noinline$mulPlusOne(13, 14));
595418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames    assertLongEquals(-225, $opt$noinline$mulMinusOne(15, 16));
5964a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko    assertIntEquals(-306, $opt$noinline$mulNeg(17, 18));
5974a0dad67867f389e01a5a6c0fe381d210f687c0dArtem Udovichenko    assertLongEquals(-380, $opt$noinline$mulNeg(19, 20));
598f34dd206d0073fb3949be872224420a8488f551fArtem Serov
599f34dd206d0073fb3949be872224420a8488f551fArtem Serov    testSimdMultiplyAccumulate();
600418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames  }
601418318f4d50e0cfc2d54330d7623ee030d4d727dAlexandre Rames}
602