/// CHECK-START: int Main.earlyExitFirst(int) loop_optimization (before) /// CHECK-DAG: Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: Phi loop:<<Loop>> outer_loop:none // /// CHECK-START: int Main.earlyExitFirst(int) loop_optimization (after) /// CHECK-DAG: Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: Phi loop:<<Loop>> outer_loop:none staticint earlyExitFirst(int m) { int k = 0; for (int i = 0; i < 10; i++) { if (i == m) { return k;
}
k++;
} return k;
}
/// CHECK-START: int Main.earlyExitLast(int) loop_optimization (before) /// CHECK-DAG: Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: Phi loop:<<Loop>> outer_loop:none // /// CHECK-START: int Main.earlyExitLast(int) loop_optimization (after) /// CHECK-DAG: Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: Phi loop:<<Loop>> outer_loop:none staticint earlyExitLast(int m) { int k = 0; for (int i = 0; i < 10; i++) {
k++; if (i == m) { return k;
}
} return k;
}
/// CHECK-START: int Main.earlyExitNested() loop_optimization (before) /// CHECK-DAG: Phi loop:<<Loop1:B\d+>> outer_loop:none /// CHECK-DAG: Phi loop:<<Loop1>> outer_loop:none /// CHECK-DAG: Phi loop:<<Loop2:B\d+>> outer_loop:<<Loop1>> /// CHECK-DAG: Phi loop:<<Loop2>> outer_loop:<<Loop1>> // /// CHECK-START: int Main.earlyExitNested() loop_optimization (after) /// CHECK-DAG: Phi loop:<<Loop1:B\d+>> outer_loop:none /// CHECK-DAG: Phi loop:<<Loop1>> outer_loop:none // /// CHECK-START: int Main.earlyExitNested() loop_optimization (after) /// CHECK-NOT: Phi loop:{{B\d+}} outer_loop:{{B\d+}} staticint earlyExitNested() { int offset = 0; for (int i = 0; i < 2; i++) { int start = offset; // This loop can be removed. for (int j = 0; j < 2; j++) {
offset++;
} if (i == 1) { return start;
}
} return0;
}
// Regression test for b/33774618: transfer operations involving // narrowing linear induction should be done correctly. // /// CHECK-START: int Main.transferNarrowWrap() loop_optimization (before) /// CHECK-DAG: Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: Phi loop:<<Loop>> outer_loop:none /// CHECK-DAG: Phi loop:<<Loop>> outer_loop:none /// CHECK-DAG: Phi loop:<<Loop>> outer_loop:none // /// CHECK-START: int Main.transferNarrowWrap() loop_optimization (after) /// CHECK-DAG: Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: Phi loop:<<Loop>> outer_loop:none /// CHECK-DAG: Phi loop:<<Loop>> outer_loop:none /// CHECK-DAG: Phi loop:<<Loop>> outer_loop:none staticint transferNarrowWrap() { short x = 0; int w = 10; int v = 3; for (int i = 0; i < 10; i++) {
v = w + 1; // transfer on wrap-around
w = x; // wrap-around
x += 2; // narrowing linear
} return v;
}
// Regression test for b/33774618: transfer operations involving // narrowing linear induction should be done correctly // (currently rejected, could be improved). // /// CHECK-START: int Main.polynomialShort() loop_optimization (before) /// CHECK-DAG: Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: Phi loop:<<Loop>> outer_loop:none // /// CHECK-START: int Main.polynomialShort() loop_optimization (after) /// CHECK-DAG: Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: Phi loop:<<Loop>> outer_loop:none staticint polynomialShort() { int x = 0; for (short i = 0; i < 10; i++) {
x = x - i; // polynomial on narrowing linear
} return x;
}
// Regression test for b/33774618: transfer operations involving // narrowing linear induction should be done correctly // (currently rejected, could be improved). // /// CHECK-START: int Main.polynomialIntFromLong() loop_optimization (before) /// CHECK-DAG: Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: Phi loop:<<Loop>> outer_loop:none // /// CHECK-START: int Main.polynomialIntFromLong() loop_optimization (after) /// CHECK-DAG: Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: Phi loop:<<Loop>> outer_loop:none staticint polynomialIntFromLong() { int x = 0; for (long i = 0; i < 10; i++) {
x = x - (int) i; // polynomial on narrowing linear
} return x;
}
/// CHECK-START: int Main.polynomialInt() loop_optimization (before) /// CHECK-DAG: Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: Phi loop:<<Loop>> outer_loop:none // /// CHECK-START: int Main.polynomialInt() loop_optimization (after) /// CHECK-NOT: Phi // /// CHECK-START: int Main.polynomialInt() instruction_simplifier$before_codegen (after) /// CHECK-DAG: <<Int:i\d+>> IntConstant -45 loop:none /// CHECK-DAG: Return [<<Int>>] loop:none staticint polynomialInt() { int x = 0; for (int i = 0; i < 10; i++) {
x = x - i;
} return x;
}
// Regression test for b/34779592 (found with fuzz testing): overflow for last value // of division truncates to zero, for multiplication it simply truncates. // /// CHECK-START: int Main.geoIntDivLastValue(int) loop_optimization (before) /// CHECK-DAG: Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: Phi loop:<<Loop>> outer_loop:none // /// CHECK-START: int Main.geoIntDivLastValue(int) loop_optimization (after) /// CHECK-NOT: Phi // /// CHECK-START: int Main.geoIntDivLastValue(int) instruction_simplifier$before_codegen (after) /// CHECK-DAG: <<Int:i\d+>> IntConstant 0 loop:none /// CHECK-DAG: Return [<<Int>>] loop:none staticint geoIntDivLastValue(int x) { for (int i = 0; i < 2; i++) {
x /= 1081788608;
} return x;
}
/// CHECK-START: int Main.geoIntMulLastValue(int) loop_optimization (before) /// CHECK-DAG: Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: Phi loop:<<Loop>> outer_loop:none // /// CHECK-START: int Main.geoIntMulLastValue(int) loop_optimization (after) /// CHECK-NOT: Phi // /// CHECK-START: int Main.geoIntMulLastValue(int) instruction_simplifier$before_codegen (after) /// CHECK-DAG: <<Par:i\d+>> ParameterValue loop:none /// CHECK-DAG: <<Int:i\d+>> IntConstant -194211840 loop:none /// CHECK-DAG: <<Mul:i\d+>> Mul [<<Par>>,<<Int>>] loop:none /// CHECK-DAG: Return [<<Mul>>] loop:none staticint geoIntMulLastValue(int x) { for (int i = 0; i < 2; i++) {
x *= 1081788608;
} return x;
}
/// CHECK-START: long Main.geoLongDivLastValue(long) loop_optimization (before) /// CHECK-DAG: Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: Phi loop:<<Loop>> outer_loop:none // /// CHECK-START: long Main.geoLongDivLastValue(long) loop_optimization (after) /// CHECK-NOT: Phi // /// CHECK-START: long Main.geoLongDivLastValue(long) instruction_simplifier$before_codegen (after) /// CHECK-DAG: <<Long:j\d+>> LongConstant 0 loop:none /// CHECK-DAG: Return [<<Long>>] loop:none // // Tests overflow in the divisor (while updating intermediate result). staticlong geoLongDivLastValue(long x) { for (int i = 0; i < 10; i++) {
x /= 1081788608;
} return x;
}
/// CHECK-START: long Main.geoLongDivLastValue() loop_optimization (before) /// CHECK-DAG: Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: Phi loop:<<Loop>> outer_loop:none // /// CHECK-START: long Main.geoLongDivLastValue() loop_optimization (after) /// CHECK-NOT: Phi // /// CHECK-START: long Main.geoLongDivLastValue() instruction_simplifier$before_codegen (after) /// CHECK-DAG: <<Long:j\d+>> LongConstant 0 loop:none /// CHECK-DAG: Return [<<Long>>] loop:none // // Tests overflow in the divisor (while updating base). staticlong geoLongDivLastValue() { long x = -1; for (int i2 = 0; i2 < 2; i2++) {
x /= (Long.MAX_VALUE);
} return x;
}
/// CHECK-START: long Main.geoLongMulLastValue(long) loop_optimization (before) /// CHECK-DAG: Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: Phi loop:<<Loop>> outer_loop:none // /// CHECK-START: long Main.geoLongMulLastValue(long) loop_optimization (after) /// CHECK-NOT: Phi // /// CHECK-START: long Main.geoLongMulLastValue(long) instruction_simplifier$before_codegen (after) /// CHECK-DAG: <<Par:j\d+>> ParameterValue loop:none /// CHECK-DAG: <<Long:j\d+>> LongConstant -8070450532247928832 loop:none /// CHECK-DAG: <<Mul:j\d+>> Mul [<<Par>>,<<Long>>] loop:none /// CHECK-DAG: Return [<<Mul>>] loop:none staticlong geoLongMulLastValue(long x) { for (int i = 0; i < 10; i++) {
x *= 1081788608;
} return x;
}
// If vectorized, the narrowing subscript should not cause // type inconsistencies in the synthesized code. staticvoid narrowingSubscript(float[] a) { float val = 2.0f; for (long i = 0; i < a.length; i++) {
a[(int) i] += val;
}
}
// If vectorized, invariant stride should be recognized // as a reduction, not a unit stride in outer loop. staticvoid reduc(int[] xx, int[] yy) { for (int i0 = 0; i0 < 2; i0++) { for (int i1 = 0; i1 < 469; i1++) {
xx[i0] -= (++yy[i1]);
}
}
}
/// CHECK-START: void Main.string2Bytes(char[], java.lang.String) loop_optimization (before) /// CHECK-DAG: ArrayGet loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: ArraySet loop:<<Loop>> outer_loop:none // /// CHECK-START-ARM: void Main.string2Bytes(char[], java.lang.String) loop_optimization (after) /// CHECK-NOT: VecLoad // /// CHECK-START-ARM64: void Main.string2Bytes(char[], java.lang.String) loop_optimization (after) /// CHECK-IF: hasIsaFeature("sve") and os.environ.get('ART_FORCE_TRY_PREDICATED_SIMD') == 'true' // // TODO: Support CharAt for SVE. /// CHECK-NOT: VecLoad // /// CHECK-ELSE: // /// CHECK-DAG: VecLoad loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: VecStore loop:<<Loop>> outer_loop:none // /// CHECK-FI: // // NOTE: should correctly deal with compressed and uncompressed cases. privatestaticvoid string2Bytes(char[] a, String b) { int min = Math.min(a.length, b.length()); for (int i = 0; i < min; i++) {
a[i] = b.charAt(i);
}
}
/// CHECK-START-ARM64: void Main.$noinline$stringToShorts(short[], java.lang.String) loop_optimization (after) /// CHECK-IF: hasIsaFeature("sve") and os.environ.get('ART_FORCE_TRY_PREDICATED_SIMD') == 'true' // // TODO: Support CharAt for SVE. /// CHECK-NOT: VecLoad // /// CHECK-ELSE: // /// CHECK-DAG: VecLoad loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: VecStore loop:<<Loop>> outer_loop:none // /// CHECK-FI: privatestaticvoid $noinline$stringToShorts(short[] dest, String src) { int min = Math.min(dest.length, src.length()); for (int i = 0; i < min; ++i) {
dest[i] = (short) src.charAt(i);
}
}
// A strange function that does not inline. privatestaticvoid $noinline$foo(boolean x, int n) { if (n < 0) thrownew Error("oh no"); if (n > 100) {
$noinline$foo(!x, n - 1);
$noinline$foo(!x, n - 2);
$noinline$foo(!x, n - 3);
$noinline$foo(!x, n - 4);
}
}
// A loop with environment uses of x (the terminating condition). As exposed by bug // b/37247891, the loop can be unrolled, but should handle the (unlikely, but clearly // not impossible) environment uses of the terminating condition in a correct manner. privatestaticvoid envUsesInCond() { boolean x = false; for (int i = 0; !(x = i >= 1); i++) {
$noinline$foo(true, i);
}
}
// Bug b/37768917: potential dynamic BCE vs. loop optimizations // case should be deal with correctly (used to DCHECK fail). privatestaticvoid arrayInTripCount(int[] a, byte[] b, int n) { for (int k = 0; k < n; k++) { for (int i = 0, u = a[0]; i < u; i++) {
b[i] += 2;
}
}
}
// Environment of an instruction, removed during SimplifyInduction, should be adjusted. // /// CHECK-START: void Main.inductionMax(int[]) loop_optimization (before) /// CHECK-DAG: Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: Phi loop:<<Loop>> outer_loop:none // /// CHECK-START: void Main.inductionMax(int[]) loop_optimization (after) /// CHECK-NOT: Phi privatestaticvoid inductionMax(int[] a) { int s = 0; for (int i = 0; i < 10; i++) {
s = Math.max(s, 5);
}
}
/// CHECK-START: int Main.feedsIntoDeopt(int[]) loop_optimization (before) /// CHECK-DAG: Phi loop:<<Loop1:B\d+>> outer_loop:none /// CHECK-DAG: Phi loop:<<Loop1>> outer_loop:none /// CHECK-DAG: Phi loop:<<Loop2:B\d+>> outer_loop:none // /// CHECK-EVAL: "<<Loop1>>" != "<<Loop2>>" // /// CHECK-START: int Main.feedsIntoDeopt(int[]) loop_optimization (after) /// CHECK-DAG: Phi loop:{{B\d+}} outer_loop:none /// CHECK-NOT: Phi staticint feedsIntoDeopt(int[] a) { // Reduction should be removed. int r = 0; for (int i = 0; i < 100; i++) {
r += 10;
} // Even though uses feed into deopts of BCE. for (int i = 1; i < 100; i++) {
a[i] = a[i - 1];
} return r;
}
staticint absCanBeNegative(int x) { int a[] = { 1, 2, 3 }; int y = 0; for (int i = Math.abs(x); i < a.length; i++) {
y += a[i];
} return y;
}
// b/65478356: sum up 2-dim array. staticint sum(int[][] a) { int sum = 0; for (int y = 0; y < a.length; y++) { int[] aa = a[y]; for (int x = 0; x < aa.length; x++) {
sum += aa[x];
}
} return sum;
}
// Mixed of 16-bit and 8-bit array references. staticvoid castAndNarrow(byte[] x, char[] y) { for (int i = 0; i < x.length; i++) {
x[i] = (byte) ((short) y[i] + 1);
}
}
// Avoid bad scheduler-SIMD interaction. staticint doNotMoveSIMD() { int sum = 0; for (int j = 0; j <= 8; j++) { int[] a = newint[17]; // a[i] = 0; // ConstructorFence ? for (int i = 0; i < a.length; i++) {
a[i] += 1; // a[i] = 1;
} for (int i = 0; i < a.length; i++) {
sum += a[i]; // expect a[i] = 1;
}
} return sum;
}
// Ensure spilling saves full SIMD values. privatestaticfinalint reduction32Values(int[] a, int[] b, int[] c, int[] d) { int s0 = 0; int s1 = 0; int s2 = 0; int s3 = 0; int s4 = 0; int s5 = 0; int s6 = 0; int s7 = 0; int s8 = 0; int s9 = 0; int s10 = 0; int s11 = 0; int s12 = 0; int s13 = 0; int s14 = 0; int s15 = 0; int s16 = 0; int s17 = 0; int s18 = 0; int s19 = 0; int s20 = 0; int s21 = 0; int s22 = 0; int s23 = 0; int s24 = 0; int s25 = 0; int s26 = 0; int s27 = 0; int s28 = 0; int s29 = 0; int s30 = 0; int s31 = 0; for (int i = 1; i < 100; i++) {
s0 += a[i];
s1 += b[i];
s2 += c[i];
s3 += d[i];
s4 += a[i];
s5 += b[i];
s6 += c[i];
s7 += d[i];
s8 += a[i];
s9 += b[i];
s10 += c[i];
s11 += d[i];
s12 += a[i];
s13 += b[i];
s14 += c[i];
s15 += d[i];
s16 += a[i];
s17 += b[i];
s18 += c[i];
s19 += d[i];
s20 += a[i];
s21 += b[i];
s22 += c[i];
s23 += d[i];
s24 += a[i];
s25 += b[i];
s26 += c[i];
s27 += d[i];
s28 += a[i];
s29 += b[i];
s30 += c[i];
s31 += d[i];
} return s0 + s1 + s2 + s3 + s4 + s5 + s6 + s7 + s8 + s9 + s10 + s11 + s12 + s13 + s14 + s15 +
s16 + s17 + s18 + s19 + s20 + s21 + s22 + s23 +
s24 + s25 + s26 + s27 + s28 + s29 + s30 + s31;
}
// Ensure spilling saves regular FP values correctly when the graph HasSIMD() // is true. /// CHECK-START-ARM64: float Main.$noinline$ensureSlowPathFPSpillFill(float[], float[], float[], float[], int[]) loop_optimization (after) // // Both regular and SIMD accesses are present. /// CHECK-DAG: VecLoad /// CHECK-DAG: ArrayGet privatestaticfinalfloat $noinline$ensureSlowPathFPSpillFill(float[] a, float[] b, float[] c, float[] d, int[] e) { // This loop should be vectorized so the graph->HasSIMD() will be true. // A power-of-2 number of iterations is chosen to avoid peeling/unrolling interference. for (int i = 0; i < 64; i++) { // The actual values of the array elements don't matter, just the // presence of a SIMD loop.
e[i]++;
}
publicstaticint reductionIntoReplication() { int[] a = { 1, 2, 3, 4 }; int x = 0; for (int i = 0; i < 4; i++) {
x += a[i];
} for (int i = 0; i < 4; i++) {
a[i] = x;
} return a[3];
}
// Dot product and SAD vectorization idioms used to have a bug when some // instruction in the loop was visited twice causing a compiler crash. // It happened when two vectorization idioms' matched patterns had a common // sub-expression.
// Idioms common sub-expression bug: DotProduct and ArraySet. // /// CHECK-START-ARM64: int Main.testDotProdAndSet(byte[], byte[], byte[]) loop_optimization (after) /// CHECK-DAG: VecDotProd /// CHECK-DAG: VecStore publicstaticfinalint testDotProdAndSet(byte[] a, byte[] b, byte[] c) { int s = 1; for (int i = 0; i < b.length; i++) { int temp = a[i] * b[i];
c[i]= (byte)temp;
s += temp;
} return s - 1;
}
// Idioms common sub-expression bug: DotProduct and DotProduct. // /// CHECK-START-ARM64: int Main.testDotProdAndDotProd(byte[], byte[]) loop_optimization (after) /// CHECK-DAG: VecDotProd /// CHECK-DAG: VecDotProd publicstaticfinalint testDotProdAndDotProd(byte[] a, byte[] b) { int s0 = 1; int s1 = 1; for (int i = 0; i < b.length; i++) { int temp = a[i] * b[i];
s0 += temp;
s1 += temp;
} return s0 + s1;
}
// Idioms common sub-expression bug: SAD and ArraySet. // /// CHECK-START-ARM: int Main.testSADAndSet(int[], int[], int[]) loop_optimization (after) /// CHECK-DAG: VecSADAccumulate /// CHECK-DAG: VecStore // /// CHECK-START-ARM64: int Main.testSADAndSet(int[], int[], int[]) loop_optimization (after) /// CHECK-IF: hasIsaFeature("sve") and os.environ.get('ART_FORCE_TRY_PREDICATED_SIMD') == 'true' // // VecSADAccumulate is not supported for SVE. /// CHECK-NOT: VecSADAccumulate // /// CHECK-ELSE: // /// CHECK-DAG: VecSADAccumulate /// CHECK-DAG: VecStore // /// CHECK-FI: publicstaticint testSADAndSet(int[] x, int[] y, int[] z) { int min_length = Math.min(x.length, y.length); int sad = 0; for (int i = 0; i < min_length; i++) { int temp = Math.abs(x[i] - y[i]);
z[i] = temp;
sad += temp;
} return sad;
}
// Idioms common sub-expression bug: SAD and SAD. /// CHECK-START-ARM: int Main.testSADAndSAD(int[], int[]) loop_optimization (after) /// CHECK-DAG: VecSADAccumulate /// CHECK-DAG: VecSADAccumulate // /// CHECK-START-ARM64: int Main.testSADAndSAD(int[], int[]) loop_optimization (after) /// CHECK-IF: hasIsaFeature("sve") and os.environ.get('ART_FORCE_TRY_PREDICATED_SIMD') == 'true' // // VecSADAccumulate is not supported for SVE. /// CHECK-NOT: VecSADAccumulate // /// CHECK-ELSE: // /// CHECK-DAG: VecSADAccumulate /// CHECK-DAG: VecSADAccumulate // /// CHECK-FI: publicstaticfinalint testSADAndSAD(int[] x, int[] y) { int s0 = 1; int s1 = 1; for (int i = 0; i < x.length; i++) { int temp = Math.abs(x[i] - y[i]);
s0 += temp;
s1 += temp;
} return s0 + s1;
}
// Idioms common sub-expression bug: DotProd and DotProd with extra mul. // /// CHECK-START-ARM64: int Main.testDotProdAndDotProdExtraMul0(byte[], byte[]) loop_optimization (after) /// CHECK-DAG: VecMul /// CHECK-DAG: VecDotProd /// CHECK-DAG: VecDotProd publicstaticfinalint testDotProdAndDotProdExtraMul0(byte[] a, byte[] b) { int s0 = 1; int s1 = 1; for (int i = 0; i < b.length; i++) { int temp0 = a[i] * b[i]; int temp1 = (byte)(temp0) * a[i];
s0 += temp1;
s1 += temp0;
} return s0 + s1;
}
// Idioms common sub-expression bug: DotProd and DotProd with extra mul (reversed order). // /// CHECK-START-ARM64: int Main.testDotProdAndDotProdExtraMul1(byte[], byte[]) loop_optimization (after) /// CHECK-DAG: VecMul /// CHECK-DAG: VecDotProd /// CHECK-DAG: VecDotProd publicstaticfinalint testDotProdAndDotProdExtraMul1(byte[] a, byte[] b) { int s0 = 1; int s1 = 1; for (int i = 0; i < b.length; i++) { int temp0 = a[i] * b[i]; int temp1 = (byte)(temp0) * a[i];
s0 += temp0;
s1 += temp1;
} return s0 + s1;
}
// Idioms common sub-expression bug: SAD and SAD with extra abs. // /// CHECK-START-ARM: int Main.testSADAndSADExtraAbs0(int[], int[]) loop_optimization (after) /// CHECK-DAG: VecSub /// CHECK-DAG: VecAbs /// CHECK-DAG: VecSADAccumulate /// CHECK-DAG: VecSADAccumulate // /// CHECK-START-ARM64: int Main.testSADAndSADExtraAbs0(int[], int[]) loop_optimization (after) /// CHECK-IF: hasIsaFeature("sve") and os.environ.get('ART_FORCE_TRY_PREDICATED_SIMD') == 'true' // // VecSADAccumulate is not supported for SVE. /// CHECK-NOT: VecSADAccumulate // /// CHECK-ELSE: // /// CHECK-DAG: VecSub /// CHECK-DAG: VecAbs /// CHECK-DAG: VecSADAccumulate /// CHECK-DAG: VecSADAccumulate // /// CHECK-FI: publicstaticfinalint testSADAndSADExtraAbs0(int[] x, int[] y) { int s0 = 1; int s1 = 1; for (int i = 0; i < x.length; i++) { int temp0 = Math.abs(x[i] - y[i]); int temp1 = Math.abs(temp0 - y[i]);
s0 += temp1;
s1 += temp0;
} return s0 + s1;
}
// Idioms common sub-expression bug: SAD and SAD with extra abs (reversed order). // /// CHECK-START-ARM: int Main.testSADAndSADExtraAbs1(int[], int[]) loop_optimization (after) /// CHECK-DAG: VecSub /// CHECK-DAG: VecAbs /// CHECK-DAG: VecSADAccumulate /// CHECK-DAG: VecSADAccumulate // /// CHECK-START-ARM64: int Main.testSADAndSADExtraAbs1(int[], int[]) loop_optimization (after) /// CHECK-IF: hasIsaFeature("sve") and os.environ.get('ART_FORCE_TRY_PREDICATED_SIMD') == 'true' // // VecSADAccumulate is not supported for SVE. /// CHECK-NOT: VecSADAccumulate // /// CHECK-ELSE: // /// CHECK-DAG: VecSub /// CHECK-DAG: VecAbs /// CHECK-DAG: VecSADAccumulate /// CHECK-DAG: VecSADAccumulate // /// CHECK-FI: publicstaticfinalint testSADAndSADExtraAbs1(int[] x, int[] y) { int s0 = 1; int s1 = 1; for (int i = 0; i < x.length; i++) { int temp0 = Math.abs(x[i] - y[i]); int temp1 = Math.abs(temp0 - y[i]);
s0 += temp0;
s1 += temp1;
} return s0 + s1;
}
// Idioms common sub-expression bug: SAD and DotProd combined. // /// CHECK-START-ARM64: int Main.testSADAndDotProdCombined0(byte[], byte[]) loop_optimization (after) /// CHECK-IF: hasIsaFeature("sve") and os.environ.get('ART_FORCE_TRY_PREDICATED_SIMD') == 'true' // // VecSADAccumulate is not supported for SVE. /// CHECK-NOT: VecSADAccumulate // /// CHECK-ELSE: // /// CHECK-DAG: VecSub /// CHECK-DAG: VecSADAccumulate /// CHECK-DAG: VecDotProd // /// CHECK-FI: publicstaticfinalint testSADAndDotProdCombined0(byte[] x, byte[] y) { int s0 = 1; int s1 = 1; for (int i = 0; i < x.length; i++) { int temp0 = x[i] - y[i]; int temp1 = Math.abs(temp0); int temp2 = x[i] * (byte)(temp0);
s0 += temp1;
s1 += temp2;
} return s0 + s1;
}
// Idioms common sub-expression bug: SAD and DotProd combined (reversed order). /// CHECK-START-ARM64: int Main.testSADAndDotProdCombined1(byte[], byte[]) loop_optimization (after) /// CHECK-IF: hasIsaFeature("sve") and os.environ.get('ART_FORCE_TRY_PREDICATED_SIMD') == 'true' // // VecSADAccumulate is not supported for SVE. /// CHECK-NOT: VecSADAccumulate // /// CHECK-ELSE: // /// CHECK-DAG: VecSub /// CHECK-DAG: VecSADAccumulate /// CHECK-DAG: VecDotProd // /// CHECK-FI: publicstaticfinalint testSADAndDotProdCombined1(byte[] x, byte[] y) { int s0 = 1; int s1 = 1; for (int i = 0; i < x.length; i++) { int temp0 = x[i] - y[i]; int temp1 = Math.abs(temp0); int temp2 = x[i] * (byte)(temp0);
s0 += temp2;
s1 += temp1;
} return s0 + s1;
}
// Regression test for the case, where a loop is vectorized in predicated mode, and there is // a disambiguation scalar loop added. Make sure that the set, which records instructions // inserted outside of new loops, is not reset until the full vectorization process has // happened. // // Based on void android.util.Spline$MonotoneCubicSpline.<init>(float[], float[]). // /// CHECK-START-ARM64: void Main.$noinline$testExternalSetForLoopWithDisambiguation(int[], int[]) loop_optimization (after) /// CHECK-IF: hasIsaFeature("sve") and os.environ.get('ART_FORCE_TRY_PREDICATED_SIMD') == 'true' // /// CHECK-DAG: <<Pred:j\d+>> VecPredSetAll loop:none /// CHECK-DAG: VecReplicateScalar [{{i\d+}},<<Pred>>] loop:none // /// CHECK-ELSE: // /// CHECK-DAG: VecReplicateScalar loop:none // /// CHECK-FI: // // Vector loop. /// CHECK-DAG: Phi loop:<<VectorLoop:B\d+>> outer_loop:none /// CHECK-DAG: VecLoad loop:<<VectorLoop>> outer_loop:none // // Backup scalar loop. /// CHECK-DAG: Phi loop:<<ScalarLoop:B\d+>> outer_loop:none /// CHECK-DAG: ArrayGet loop:<<ScalarLoop>> outer_loop:none publicstaticvoid $noinline$testExternalSetForLoopWithDisambiguation(int[] d, int[] m) {
m[0] = d[0]; for (int i = 1; i < m.length; i++) {
m[i] = (d[i - 1] + d[i]) * 53;
}
}
publicstaticfinalint ARRAY_SIZE = 512;
privatestaticbyte[] createAndInitByteArray(int x) { byte[] a = newbyte[ARRAY_SIZE]; for (int i = 0; i < a.length; i++) {
a[i] = (byte)((~i) + x);
} return a;
}
privatestaticint[] createAndInitIntArray(int x) { int[] a = newint[ARRAY_SIZE]; for (int i = 0; i < a.length; i++) {
a[i] = (~i) + x;
} return a;
}
float[] a = newfloat[16];
narrowingSubscript(a); for (int i = 0; i < 16; i++) {
expectEquals(2.0f, a[i]);
}
int[] xx = newint[2]; int[] yy = newint[469];
reduc(xx, yy);
expectEquals(-469, xx[0]);
expectEquals(-938, xx[1]); for (int i = 0; i < 469; i++) {
expectEquals(2, yy[i]);
}
char[] aa = newchar[23];
String bb = "hello world how are you";
string2Bytes(aa, bb); for (int i = 0; i < aa.length; i++) {
expectEquals(aa[i], bb.charAt(i));
}
String cc = "\u1010\u2020llo world how are y\u3030\u4040";
string2Bytes(aa, cc); for (int i = 0; i < aa.length; i++) {
expectEquals(aa[i], cc.charAt(i));
}
short[] s2s = newshort[12];
$noinline$stringToShorts(s2s, "abcdefghijkl"); for (int i = 0; i < s2s.length; ++i) {
expectEquals((short) "abcdefghijkl".charAt(i), s2s[i]);
}
envUsesInCond();
short[] dd = newshort[23];
oneBoth(dd, aa); for (int i = 0; i < aa.length; i++) {
expectEquals(aa[i], 1);
expectEquals(dd[i], 1);
}
xx[0] = 10; byte[] bt = newbyte[10];
arrayInTripCount(xx, bt, 20); for (int i = 0; i < bt.length; i++) {
expectEquals(40, bt[i]);
}
byte[] b1 = newbyte[259]; // few extra iterations byte[] b2 = newbyte[259]; for (int i = 0; i < 259; i++) {
b1[i] = 0;
b2[i] = (byte) i;
}
typeConv(b1, b2); for (int i = 0; i < 259; i++) {
expectEquals((byte)(i + 1), b1[i]);
}
inductionMax(yy);
int[] f = newint[100];
f[0] = 11;
expectEquals(1000, feedsIntoDeopt(f)); for (int i = 0; i < 100; i++) {
expectEquals(11, f[i]);
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.