1 /* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 /** 18 * Tests for MIN/MAX vectorization. 19 */ 20 public class Main { 21 22 /// CHECK-START: void Main.doitMin(short[], short[], short[]) loop_optimization (before) 23 /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none 24 /// CHECK-DAG: <<Get1:s\d+>> ArrayGet loop:<<Loop>> outer_loop:none 25 /// CHECK-DAG: <<Get2:s\d+>> ArrayGet loop:<<Loop>> outer_loop:none 26 /// CHECK-DAG: <<Min:i\d+>> InvokeStaticOrDirect [<<Get1>>,<<Get2>>] intrinsic:MathMinIntInt loop:<<Loop>> outer_loop:none 27 /// CHECK-DAG: <<Cnv:s\d+>> TypeConversion [<<Min>>] loop:<<Loop>> outer_loop:none 28 /// CHECK-DAG: ArraySet [{{l\d+}},<<Phi>>,<<Cnv>>] loop:<<Loop>> outer_loop:none 29 // 30 /// CHECK-START-{ARM,ARM64,MIPS64}: void Main.doitMin(short[], short[], short[]) loop_optimization (after) 31 /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop:B\d+>> outer_loop:none 32 /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none 33 /// CHECK-DAG: <<Min:d\d+>> VecMin [<<Get1>>,<<Get2>>] packed_type:Int16 loop:<<Loop>> outer_loop:none 34 /// CHECK-DAG: VecStore [{{l\d+}},{{i\d+}},<<Min>>] loop:<<Loop>> outer_loop:none doitMin(short[] x, short[] y, short[] z)35 private static void doitMin(short[] x, short[] y, short[] z) { 36 int min = Math.min(x.length, Math.min(y.length, z.length)); 37 for (int i = 0; i < min; i++) { 38 x[i] = (short) Math.min(y[i], z[i]); 39 } 40 } 41 42 /// CHECK-START: void Main.doitMinUnsigned(short[], short[], short[]) instruction_simplifier (before) 43 /// CHECK-DAG: <<IMAX:i\d+>> IntConstant 65535 loop:none 44 /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none 45 /// CHECK-DAG: <<Get1:s\d+>> ArrayGet loop:<<Loop>> outer_loop:none 46 /// CHECK-DAG: <<Get2:s\d+>> ArrayGet loop:<<Loop>> outer_loop:none 47 /// CHECK-DAG: <<And1:i\d+>> And [<<Get1>>,<<IMAX>>] loop:<<Loop>> outer_loop:none 48 /// CHECK-DAG: <<And2:i\d+>> And [<<Get2>>,<<IMAX>>] loop:<<Loop>> outer_loop:none 49 /// CHECK-DAG: <<Min:i\d+>> InvokeStaticOrDirect [<<And1>>,<<And2>>] intrinsic:MathMinIntInt loop:<<Loop>> outer_loop:none 50 /// CHECK-DAG: <<Cnv:s\d+>> TypeConversion [<<Min>>] loop:<<Loop>> outer_loop:none 51 /// CHECK-DAG: ArraySet [{{l\d+}},{{i\d+}},<<Cnv>>] loop:<<Loop>> outer_loop:none 52 // 53 /// CHECK-START: void Main.doitMinUnsigned(short[], short[], short[]) loop_optimization (before) 54 /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none 55 /// CHECK-DAG: <<Get1:c\d+>> ArrayGet loop:<<Loop>> outer_loop:none 56 /// CHECK-DAG: <<Get2:c\d+>> ArrayGet loop:<<Loop>> outer_loop:none 57 /// CHECK-DAG: <<Min:i\d+>> InvokeStaticOrDirect [<<Get1>>,<<Get2>>] intrinsic:MathMinIntInt loop:<<Loop>> outer_loop:none 58 /// CHECK-DAG: <<Cnv:s\d+>> TypeConversion [<<Min>>] loop:<<Loop>> outer_loop:none 59 /// CHECK-DAG: ArraySet [{{l\d+}},<<Phi>>,<<Cnv>>] loop:<<Loop>> outer_loop:none 60 // 61 /// CHECK-START-{ARM,ARM64,MIPS64}: void Main.doitMinUnsigned(short[], short[], short[]) loop_optimization (after) 62 /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop:B\d+>> outer_loop:none 63 /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none 64 /// CHECK-DAG: <<Min:d\d+>> VecMin [<<Get1>>,<<Get2>>] packed_type:Uint16 loop:<<Loop>> outer_loop:none 65 /// CHECK-DAG: VecStore [{{l\d+}},{{i\d+}},<<Min>>] loop:<<Loop>> outer_loop:none doitMinUnsigned(short[] x, short[] y, short[] z)66 private static void doitMinUnsigned(short[] x, short[] y, short[] z) { 67 int min = Math.min(x.length, Math.min(y.length, z.length)); 68 for (int i = 0; i < min; i++) { 69 x[i] = (short) Math.min(y[i] & 0xffff, z[i] & 0xffff); 70 } 71 } 72 73 /// CHECK-START: void Main.doitMax(short[], short[], short[]) loop_optimization (before) 74 /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none 75 /// CHECK-DAG: <<Get1:s\d+>> ArrayGet loop:<<Loop>> outer_loop:none 76 /// CHECK-DAG: <<Get2:s\d+>> ArrayGet loop:<<Loop>> outer_loop:none 77 /// CHECK-DAG: <<Max:i\d+>> InvokeStaticOrDirect [<<Get1>>,<<Get2>>] intrinsic:MathMaxIntInt loop:<<Loop>> outer_loop:none 78 /// CHECK-DAG: <<Cnv:s\d+>> TypeConversion [<<Max>>] loop:<<Loop>> outer_loop:none 79 /// CHECK-DAG: ArraySet [{{l\d+}},<<Phi>>,<<Cnv>>] loop:<<Loop>> outer_loop:none 80 // 81 /// CHECK-START-{ARM,ARM64,MIPS64}: void Main.doitMax(short[], short[], short[]) loop_optimization (after) 82 /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop:B\d+>> outer_loop:none 83 /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none 84 /// CHECK-DAG: <<Max:d\d+>> VecMax [<<Get1>>,<<Get2>>] packed_type:Int16 loop:<<Loop>> outer_loop:none 85 /// CHECK-DAG: VecStore [{{l\d+}},{{i\d+}},<<Max>>] loop:<<Loop>> outer_loop:none doitMax(short[] x, short[] y, short[] z)86 private static void doitMax(short[] x, short[] y, short[] z) { 87 int min = Math.min(x.length, Math.min(y.length, z.length)); 88 for (int i = 0; i < min; i++) { 89 x[i] = (short) Math.max(y[i], z[i]); 90 } 91 } 92 93 /// CHECK-START: void Main.doitMaxUnsigned(short[], short[], short[]) instruction_simplifier (before) 94 /// CHECK-DAG: <<IMAX:i\d+>> IntConstant 65535 loop:none 95 /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none 96 /// CHECK-DAG: <<Get1:s\d+>> ArrayGet loop:<<Loop>> outer_loop:none 97 /// CHECK-DAG: <<Get2:s\d+>> ArrayGet loop:<<Loop>> outer_loop:none 98 /// CHECK-DAG: <<And1:i\d+>> And [<<Get1>>,<<IMAX>>] loop:<<Loop>> outer_loop:none 99 /// CHECK-DAG: <<And2:i\d+>> And [<<Get2>>,<<IMAX>>] loop:<<Loop>> outer_loop:none 100 /// CHECK-DAG: <<Max:i\d+>> InvokeStaticOrDirect [<<And1>>,<<And2>>] intrinsic:MathMaxIntInt loop:<<Loop>> outer_loop:none 101 /// CHECK-DAG: <<Cnv:s\d+>> TypeConversion [<<Max>>] loop:<<Loop>> outer_loop:none 102 /// CHECK-DAG: ArraySet [{{l\d+}},{{i\d+}},<<Cnv>>] loop:<<Loop>> outer_loop:none 103 // 104 /// CHECK-START: void Main.doitMaxUnsigned(short[], short[], short[]) loop_optimization (before) 105 /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none 106 /// CHECK-DAG: <<Get1:c\d+>> ArrayGet loop:<<Loop>> outer_loop:none 107 /// CHECK-DAG: <<Get2:c\d+>> ArrayGet loop:<<Loop>> outer_loop:none 108 /// CHECK-DAG: <<Max:i\d+>> InvokeStaticOrDirect [<<Get1>>,<<Get2>>] intrinsic:MathMaxIntInt loop:<<Loop>> outer_loop:none 109 /// CHECK-DAG: <<Cnv:s\d+>> TypeConversion [<<Max>>] loop:<<Loop>> outer_loop:none 110 /// CHECK-DAG: ArraySet [{{l\d+}},<<Phi>>,<<Cnv>>] loop:<<Loop>> outer_loop:none 111 // 112 /// CHECK-START-{ARM,ARM64,MIPS64}: void Main.doitMaxUnsigned(short[], short[], short[]) loop_optimization (after) 113 /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop:B\d+>> outer_loop:none 114 /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none 115 /// CHECK-DAG: <<Max:d\d+>> VecMax [<<Get1>>,<<Get2>>] packed_type:Uint16 loop:<<Loop>> outer_loop:none 116 /// CHECK-DAG: VecStore [{{l\d+}},{{i\d+}},<<Max>>] loop:<<Loop>> outer_loop:none doitMaxUnsigned(short[] x, short[] y, short[] z)117 private static void doitMaxUnsigned(short[] x, short[] y, short[] z) { 118 int min = Math.min(x.length, Math.min(y.length, z.length)); 119 for (int i = 0; i < min; i++) { 120 x[i] = (short) Math.max(y[i] & 0xffff, z[i] & 0xffff); 121 } 122 } 123 124 /// CHECK-START: void Main.doitMin100(short[], short[]) loop_optimization (before) 125 /// CHECK-DAG: <<I100:i\d+>> IntConstant 100 loop:none 126 /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none 127 /// CHECK-DAG: <<Get:s\d+>> ArrayGet loop:<<Loop>> outer_loop:none 128 /// CHECK-DAG: <<Min:i\d+>> InvokeStaticOrDirect [<<Get>>,<<I100>>] intrinsic:MathMinIntInt loop:<<Loop>> outer_loop:none 129 /// CHECK-DAG: <<Cnv:s\d+>> TypeConversion [<<Min>>] loop:<<Loop>> outer_loop:none 130 /// CHECK-DAG: ArraySet [{{l\d+}},<<Phi>>,<<Cnv>>] loop:<<Loop>> outer_loop:none 131 // 132 /// CHECK-START-{ARM64,MIPS64}: void Main.doitMin100(short[], short[]) loop_optimization (after) 133 /// CHECK-DAG: <<I100:i\d+>> IntConstant 100 loop:none 134 /// CHECK-DAG: <<Repl:d\d+>> VecReplicateScalar [<<I100>>] loop:none 135 /// CHECK-DAG: <<Get:d\d+>> VecLoad loop:<<Loop:B\d+>> outer_loop:none 136 /// CHECK-DAG: <<Min:d\d+>> VecMin [<<Get>>,<<Repl>>] packed_type:Int16 loop:<<Loop>> outer_loop:none 137 /// CHECK-DAG: VecStore [{{l\d+}},{{i\d+}},<<Min>>] loop:<<Loop>> outer_loop:none doitMin100(short[] x, short[] y)138 private static void doitMin100(short[] x, short[] y) { 139 int min = Math.min(x.length, y.length); 140 for (int i = 0; i < min; i++) { 141 x[i] = (short) Math.min(y[i], 100); 142 } 143 } 144 main(String[] args)145 public static void main(String[] args) { 146 short[] interesting = { 147 (short) 0x0000, (short) 0x0001, (short) 0x007f, 148 (short) 0x0080, (short) 0x0081, (short) 0x00ff, 149 (short) 0x0100, (short) 0x0101, (short) 0x017f, 150 (short) 0x0180, (short) 0x0181, (short) 0x01ff, 151 (short) 0x7f00, (short) 0x7f01, (short) 0x7f7f, 152 (short) 0x7f80, (short) 0x7f81, (short) 0x7fff, 153 (short) 0x8000, (short) 0x8001, (short) 0x807f, 154 (short) 0x8080, (short) 0x8081, (short) 0x80ff, 155 (short) 0x8100, (short) 0x8101, (short) 0x817f, 156 (short) 0x8180, (short) 0x8181, (short) 0x81ff, 157 (short) 0xff00, (short) 0xff01, (short) 0xff7f, 158 (short) 0xff80, (short) 0xff81, (short) 0xffff 159 }; 160 // Initialize cross-values for the interesting values. 161 int total = interesting.length * interesting.length; 162 short[] x = new short[total]; 163 short[] y = new short[total]; 164 short[] z = new short[total]; 165 int k = 0; 166 for (int i = 0; i < interesting.length; i++) { 167 for (int j = 0; j < interesting.length; j++) { 168 x[k] = 0; 169 y[k] = interesting[i]; 170 z[k] = interesting[j]; 171 k++; 172 } 173 } 174 175 // And test. 176 doitMin(x, y, z); 177 for (int i = 0; i < total; i++) { 178 short expected = (short) Math.min(y[i], z[i]); 179 expectEquals(expected, x[i]); 180 } 181 doitMinUnsigned(x, y, z); 182 for (int i = 0; i < total; i++) { 183 short expected = (short) Math.min(y[i] & 0xffff, z[i] & 0xffff); 184 expectEquals(expected, x[i]); 185 } 186 doitMax(x, y, z); 187 for (int i = 0; i < total; i++) { 188 short expected = (short) Math.max(y[i], z[i]); 189 expectEquals(expected, x[i]); 190 } 191 doitMaxUnsigned(x, y, z); 192 for (int i = 0; i < total; i++) { 193 short expected = (short) Math.max(y[i] & 0xffff, z[i] & 0xffff); 194 expectEquals(expected, x[i]); 195 } 196 doitMin100(x, y); 197 for (int i = 0; i < total; i++) { 198 short expected = (short) Math.min(y[i], 100); 199 expectEquals(expected, x[i]); 200 } 201 202 System.out.println("passed"); 203 } 204 expectEquals(short expected, short result)205 private static void expectEquals(short expected, short result) { 206 if (expected != result) { 207 throw new Error("Expected: " + expected + ", found: " + result); 208 } 209 } 210 } 211