diff options
18 files changed, 19 insertions, 2493 deletions
diff --git a/compiler/optimizing/loop_optimization.cc b/compiler/optimizing/loop_optimization.cc index 7f1b319c12..0d85c2fbf5 100644 --- a/compiler/optimizing/loop_optimization.cc +++ b/compiler/optimizing/loop_optimization.cc @@ -153,18 +153,6 @@ static bool IsSignExtensionAndGet(HInstruction* instruction, return false; } } - // A MIN-MAX on narrower operands qualifies as well - // (returning the operator itself). - if (instruction->IsMin() || instruction->IsMax()) { - HBinaryOperation* min_max = instruction->AsBinaryOperation(); - DCHECK(min_max->GetType() == DataType::Type::kInt32 || - min_max->GetType() == DataType::Type::kInt64); - if (IsSignExtensionAndGet(min_max->InputAt(0), type, operand) && - IsSignExtensionAndGet(min_max->InputAt(1), type, operand)) { - *operand = min_max; - return true; - } - } return false; } @@ -228,18 +216,6 @@ static bool IsZeroExtensionAndGet(HInstruction* instruction, return false; } } - // A MIN-MAX on narrower operands qualifies as well - // (returning the operator itself). - if (instruction->IsMin() || instruction->IsMax()) { - HBinaryOperation* min_max = instruction->AsBinaryOperation(); - DCHECK(min_max->GetType() == DataType::Type::kInt32 || - min_max->GetType() == DataType::Type::kInt64); - if (IsZeroExtensionAndGet(min_max->InputAt(0), type, operand) && - IsZeroExtensionAndGet(min_max->InputAt(1), type, operand)) { - *operand = min_max; - return true; - } - } return false; } @@ -363,128 +339,11 @@ static bool IsSubConst2(HGraph* graph, return false; } -// Detect clipped [lo, hi] range for nested MIN-MAX operations on a clippee, -// such as MIN(hi, MAX(lo, clippee)) for an arbitrary clippee expression. -// Example: MIN(10, MIN(20, MAX(0, x))) yields [0, 10] with clippee x. -static HInstruction* FindClippee(HInstruction* instruction, - /*out*/ int64_t* lo, - /*out*/ int64_t* hi) { - // Iterate into MIN(.., c)-MAX(.., c) expressions and 'tighten' the range [lo, hi]. - while (instruction->IsMin() || instruction->IsMax()) { - HBinaryOperation* min_max = instruction->AsBinaryOperation(); - DCHECK(min_max->GetType() == DataType::Type::kInt32 || - min_max->GetType() == DataType::Type::kInt64); - // Process the constant. - HConstant* right = min_max->GetConstantRight(); - if (right == nullptr) { - break; - } else if (instruction->IsMin()) { - *hi = std::min(*hi, Int64FromConstant(right)); - } else { - *lo = std::max(*lo, Int64FromConstant(right)); - } - instruction = min_max->GetLeastConstantLeft(); - } - // Iteration ends in any other expression (possibly MIN/MAX without constant). - // This leaf expression is the clippee with range [lo, hi]. - return instruction; -} - -// Set value range for type (or fail). -static bool CanSetRange(DataType::Type type, - /*out*/ int64_t* uhi, - /*out*/ int64_t* slo, - /*out*/ int64_t* shi) { - if (DataType::Size(type) == 1) { - *uhi = std::numeric_limits<uint8_t>::max(); - *slo = std::numeric_limits<int8_t>::min(); - *shi = std::numeric_limits<int8_t>::max(); - return true; - } else if (DataType::Size(type) == 2) { - *uhi = std::numeric_limits<uint16_t>::max(); - *slo = std::numeric_limits<int16_t>::min(); - *shi = std::numeric_limits<int16_t>::max(); - return true; - } - return false; -} - -// Accept various saturated addition forms. -static bool IsSaturatedAdd(HInstruction* a, - HInstruction* b, - DataType::Type type, - int64_t lo, - int64_t hi, - bool is_unsigned) { - int64_t ulo = 0, uhi = 0, slo = 0, shi = 0; - if (!CanSetRange(type, &uhi, &slo, &shi)) { - return false; - } - // Tighten the range for signed single clipping on constant. - if (!is_unsigned) { - int64_t c = 0; - if (IsInt64AndGet(a, &c) || IsInt64AndGet(b, &c)) { - // For c in proper range and narrower operand r: - // MIN(r + c, 127) c > 0 - // or MAX(r + c, -128) c < 0 (and possibly redundant bound). - if (0 < c && c <= shi && hi == shi) { - if (lo <= (slo + c)) { - return true; - } - } else if (slo <= c && c < 0 && lo == slo) { - if (hi >= (shi + c)) { - return true; - } - } - } - } - // Detect for narrower operands r and s: - // MIN(r + s, 255) => SAT_ADD_unsigned - // MAX(MIN(r + s, 127), -128) => SAT_ADD_signed. - return is_unsigned ? (lo <= ulo && hi == uhi) : (lo == slo && hi == shi); -} - -// Accept various saturated subtraction forms. -static bool IsSaturatedSub(HInstruction* a, - DataType::Type type, - int64_t lo, - int64_t hi, - bool is_unsigned) { - int64_t ulo = 0, uhi = 0, slo = 0, shi = 0; - if (!CanSetRange(type, &uhi, &slo, &shi)) { - return false; - } - // Tighten the range for signed single clipping on constant. - if (!is_unsigned) { - int64_t c = 0; - if (IsInt64AndGet(a, /*out*/ &c)) { - // For c in proper range and narrower operand r: - // MIN(c - r, 127) c > 0 - // or MAX(c - r, -128) c < 0 (and possibly redundant bound). - if (0 < c && c <= shi && hi == shi) { - if (lo <= (c - shi)) { - return true; - } - } else if (slo <= c && c < 0 && lo == slo) { - if (hi >= (c - slo)) { - return true; - } - } - } - } - // Detect for narrower operands r and s: - // MAX(r - s, 0) => SAT_SUB_unsigned - // MIN(MAX(r - s, -128), 127) => SAT_ADD_signed. - return is_unsigned ? (lo == ulo && hi >= uhi) : (lo == slo && hi == shi); -} - // Detect reductions of the following forms, // x = x_phi + .. // x = x_phi - .. -// x = min(x_phi, ..) -// x = max(x_phi, ..) static bool HasReductionFormat(HInstruction* reduction, HInstruction* phi) { - if (reduction->IsAdd() || reduction->IsMin() || reduction->IsMax()) { + if (reduction->IsAdd()) { return (reduction->InputAt(0) == phi && reduction->InputAt(1) != phi) || (reduction->InputAt(0) != phi && reduction->InputAt(1) == phi); } else if (reduction->IsSub()) { @@ -497,10 +356,6 @@ static bool HasReductionFormat(HInstruction* reduction, HInstruction* phi) { static HVecReduce::ReductionKind GetReductionKind(HVecOperation* reduction) { if (reduction->IsVecAdd() || reduction->IsVecSub() || reduction->IsVecSADAccumulate()) { return HVecReduce::kSum; - } else if (reduction->IsVecMin()) { - return HVecReduce::kMin; - } else if (reduction->IsVecMax()) { - return HVecReduce::kMax; } LOG(FATAL) << "Unsupported SIMD reduction " << reduction->GetId(); UNREACHABLE(); @@ -1601,37 +1456,6 @@ bool HLoopOptimization::VectorizeUse(LoopNode* node, } return true; } - } else if (instruction->IsMin() || instruction->IsMax()) { - // Recognize saturation arithmetic. - if (VectorizeSaturationIdiom(node, instruction, generate_code, type, restrictions)) { - return true; - } - // Deal with vector restrictions. - HInstruction* opa = instruction->InputAt(0); - HInstruction* opb = instruction->InputAt(1); - HInstruction* r = opa; - HInstruction* s = opb; - bool is_unsigned = false; - if (HasVectorRestrictions(restrictions, kNoMinMax)) { - return false; - } else if (HasVectorRestrictions(restrictions, kNoHiBits) && - !IsNarrowerOperands(opa, opb, type, &r, &s, &is_unsigned)) { - return false; // reject, unless all operands are same-extension narrower - } - // Accept MIN/MAX(x, y) for vectorizable operands. - DCHECK(r != nullptr && s != nullptr); - if (generate_code && vector_mode_ != kVector) { // de-idiom - r = opa; - s = opb; - } - if (VectorizeUse(node, r, generate_code, type, restrictions) && - VectorizeUse(node, s, generate_code, type, restrictions)) { - if (generate_code) { - GenerateVecOp( - instruction, vector_map_->Get(r), vector_map_->Get(s), type, is_unsigned); - } - return true; - } } return false; } @@ -1687,7 +1511,7 @@ bool HLoopOptimization::TrySetVectorType(DataType::Type type, uint64_t* restrict *restrictions |= kNoDiv; return TrySetVectorLength(4); case DataType::Type::kInt64: - *restrictions |= kNoDiv | kNoMul | kNoMinMax; + *restrictions |= kNoDiv | kNoMul; return TrySetVectorLength(2); case DataType::Type::kFloat32: *restrictions |= kNoReduction; @@ -1717,13 +1541,13 @@ bool HLoopOptimization::TrySetVectorType(DataType::Type type, uint64_t* restrict *restrictions |= kNoDiv | kNoSAD; return TrySetVectorLength(4); case DataType::Type::kInt64: - *restrictions |= kNoMul | kNoDiv | kNoShr | kNoAbs | kNoMinMax | kNoSAD; + *restrictions |= kNoMul | kNoDiv | kNoShr | kNoAbs | kNoSAD; return TrySetVectorLength(2); case DataType::Type::kFloat32: - *restrictions |= kNoMinMax | kNoReduction; // minmax: -0.0 vs +0.0 + *restrictions |= kNoReduction; return TrySetVectorLength(4); case DataType::Type::kFloat64: - *restrictions |= kNoMinMax | kNoReduction; // minmax: -0.0 vs +0.0 + *restrictions |= kNoReduction; return TrySetVectorLength(2); default: break; @@ -1736,11 +1560,11 @@ bool HLoopOptimization::TrySetVectorType(DataType::Type type, uint64_t* restrict case DataType::Type::kBool: case DataType::Type::kUint8: case DataType::Type::kInt8: - *restrictions |= kNoDiv | kNoSaturation; + *restrictions |= kNoDiv; return TrySetVectorLength(16); case DataType::Type::kUint16: case DataType::Type::kInt16: - *restrictions |= kNoDiv | kNoSaturation | kNoStringCharAt; + *restrictions |= kNoDiv | kNoStringCharAt; return TrySetVectorLength(8); case DataType::Type::kInt32: *restrictions |= kNoDiv; @@ -1749,10 +1573,10 @@ bool HLoopOptimization::TrySetVectorType(DataType::Type type, uint64_t* restrict *restrictions |= kNoDiv; return TrySetVectorLength(2); case DataType::Type::kFloat32: - *restrictions |= kNoMinMax | kNoReduction; // min/max(x, NaN) + *restrictions |= kNoReduction; return TrySetVectorLength(4); case DataType::Type::kFloat64: - *restrictions |= kNoMinMax | kNoReduction; // min/max(x, NaN) + *restrictions |= kNoReduction; return TrySetVectorLength(2); default: break; @@ -1765,11 +1589,11 @@ bool HLoopOptimization::TrySetVectorType(DataType::Type type, uint64_t* restrict case DataType::Type::kBool: case DataType::Type::kUint8: case DataType::Type::kInt8: - *restrictions |= kNoDiv | kNoSaturation; + *restrictions |= kNoDiv; return TrySetVectorLength(16); case DataType::Type::kUint16: case DataType::Type::kInt16: - *restrictions |= kNoDiv | kNoSaturation | kNoStringCharAt; + *restrictions |= kNoDiv | kNoStringCharAt; return TrySetVectorLength(8); case DataType::Type::kInt32: *restrictions |= kNoDiv; @@ -1778,10 +1602,10 @@ bool HLoopOptimization::TrySetVectorType(DataType::Type type, uint64_t* restrict *restrictions |= kNoDiv; return TrySetVectorLength(2); case DataType::Type::kFloat32: - *restrictions |= kNoMinMax | kNoReduction; // min/max(x, NaN) + *restrictions |= kNoReduction; return TrySetVectorLength(4); case DataType::Type::kFloat64: - *restrictions |= kNoMinMax | kNoReduction; // min/max(x, NaN) + *restrictions |= kNoReduction; return TrySetVectorLength(2); default: break; @@ -2006,8 +1830,7 @@ HInstruction* HLoopOptimization::ReduceAndExtractIfNeeded(HInstruction* instruct void HLoopOptimization::GenerateVecOp(HInstruction* org, HInstruction* opa, HInstruction* opb, - DataType::Type type, - bool is_unsigned) { + DataType::Type type) { uint32_t dex_pc = org->GetDexPc(); HInstruction* vector = nullptr; DataType::Type org_type = org->GetType(); @@ -2072,24 +1895,6 @@ void HLoopOptimization::GenerateVecOp(HInstruction* org, GENERATE_VEC( new (global_allocator_) HVecUShr(global_allocator_, opa, opb, type, vector_length_, dex_pc), new (global_allocator_) HUShr(org_type, opa, opb, dex_pc)); - case HInstruction::kMin: - GENERATE_VEC( - new (global_allocator_) HVecMin(global_allocator_, - opa, - opb, - HVecOperation::ToProperType(type, is_unsigned), - vector_length_, - dex_pc), - new (global_allocator_) HMin(org_type, opa, opb, dex_pc)); - case HInstruction::kMax: - GENERATE_VEC( - new (global_allocator_) HVecMax(global_allocator_, - opa, - opb, - HVecOperation::ToProperType(type, is_unsigned), - vector_length_, - dex_pc), - new (global_allocator_) HMax(org_type, opa, opb, dex_pc)); case HInstruction::kAbs: DCHECK(opb == nullptr); GENERATE_VEC( @@ -2108,79 +1913,6 @@ void HLoopOptimization::GenerateVecOp(HInstruction* org, // Vectorization idioms. // -// Method recognizes single and double clipping saturation arithmetic. -bool HLoopOptimization::VectorizeSaturationIdiom(LoopNode* node, - HInstruction* instruction, - bool generate_code, - DataType::Type type, - uint64_t restrictions) { - // Deal with vector restrictions. - if (HasVectorRestrictions(restrictions, kNoSaturation)) { - return false; - } - // Restrict type (generalize if one day we generalize allowed MIN/MAX integral types). - if (instruction->GetType() != DataType::Type::kInt32 && - instruction->GetType() != DataType::Type::kInt64) { - return false; - } - // Clipped addition or subtraction on narrower operands? We will try both - // formats since, e.g., x+c can be interpreted as x+c and x-(-c), depending - // on what clipping values are used, to get most benefits. - int64_t lo = std::numeric_limits<int64_t>::min(); - int64_t hi = std::numeric_limits<int64_t>::max(); - HInstruction* clippee = FindClippee(instruction, &lo, &hi); - HInstruction* a = nullptr; - HInstruction* b = nullptr; - HInstruction* r = nullptr; - HInstruction* s = nullptr; - bool is_unsigned = false; - bool is_add = true; - int64_t c = 0; - // First try for saturated addition. - if (IsAddConst2(graph_, clippee, /*out*/ &a, /*out*/ &b, /*out*/ &c) && c == 0 && - IsNarrowerOperands(a, b, type, &r, &s, &is_unsigned) && - IsSaturatedAdd(r, s, type, lo, hi, is_unsigned)) { - is_add = true; - } else { - // Then try again for saturated subtraction. - a = b = r = s = nullptr; - if (IsSubConst2(graph_, clippee, /*out*/ &a, /*out*/ &b) && - IsNarrowerOperands(a, b, type, &r, &s, &is_unsigned) && - IsSaturatedSub(r, type, lo, hi, is_unsigned)) { - is_add = false; - } else { - return false; - } - } - // Accept saturation idiom for vectorizable operands. - DCHECK(r != nullptr && s != nullptr); - if (generate_code && vector_mode_ != kVector) { // de-idiom - r = instruction->InputAt(0); - s = instruction->InputAt(1); - restrictions &= ~(kNoHiBits | kNoMinMax); // allow narrow MIN/MAX in seq - } - if (VectorizeUse(node, r, generate_code, type, restrictions) && - VectorizeUse(node, s, generate_code, type, restrictions)) { - if (generate_code) { - if (vector_mode_ == kVector) { - DataType::Type vtype = HVecOperation::ToProperType(type, is_unsigned); - HInstruction* op1 = vector_map_->Get(r); - HInstruction* op2 = vector_map_->Get(s); - vector_map_->Put(instruction, is_add - ? reinterpret_cast<HInstruction*>(new (global_allocator_) HVecSaturationAdd( - global_allocator_, op1, op2, vtype, vector_length_, kNoDexPc)) - : reinterpret_cast<HInstruction*>(new (global_allocator_) HVecSaturationSub( - global_allocator_, op1, op2, vtype, vector_length_, kNoDexPc))); - MaybeRecordStat(stats_, MethodCompilationStat::kLoopVectorizedIdiom); - } else { - GenerateVecOp(instruction, vector_map_->Get(r), vector_map_->Get(s), type); - } - } - return true; - } - return false; -} - // Method recognizes the following idioms: // rounding halving add (a + b + 1) >> 1 for unsigned/signed operands a, b // truncated halving add (a + b) >> 1 for unsigned/signed operands a, b diff --git a/compiler/optimizing/loop_optimization.h b/compiler/optimizing/loop_optimization.h index 11e969875e..7807da15ed 100644 --- a/compiler/optimizing/loop_optimization.h +++ b/compiler/optimizing/loop_optimization.h @@ -78,12 +78,10 @@ class HLoopOptimization : public HOptimization { kNoSignedHAdd = 1 << 5, // no signed halving add kNoUnroundedHAdd = 1 << 6, // no unrounded halving add kNoAbs = 1 << 7, // no absolute value - kNoMinMax = 1 << 8, // no min/max - kNoStringCharAt = 1 << 9, // no StringCharAt - kNoReduction = 1 << 10, // no reduction - kNoSAD = 1 << 11, // no sum of absolute differences (SAD) - kNoWideSAD = 1 << 12, // no sum of absolute differences (SAD) with operand widening - kNoSaturation = 1 << 13, // no saturation arithmetic + kNoStringCharAt = 1 << 8, // no StringCharAt + kNoReduction = 1 << 9, // no reduction + kNoSAD = 1 << 10, // no sum of absolute differences (SAD) + kNoWideSAD = 1 << 11, // no sum of absolute differences (SAD) with operand widening }; /* @@ -188,8 +186,7 @@ class HLoopOptimization : public HOptimization { void GenerateVecOp(HInstruction* org, HInstruction* opa, HInstruction* opb, - DataType::Type type, - bool is_unsigned = false); + DataType::Type type); // Vectorization idioms. bool VectorizeSaturationIdiom(LoopNode* node, diff --git a/test/651-checker-simd-minmax/build b/test/651-checker-simd-minmax/build deleted file mode 100644 index d85147f17b..0000000000 --- a/test/651-checker-simd-minmax/build +++ /dev/null @@ -1,20 +0,0 @@ -#!/bin/bash -# -# Copyright 2018 The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# See b/65168732 -export USE_D8=false - -./default-build "$@" diff --git a/test/651-checker-simd-minmax/expected.txt b/test/651-checker-simd-minmax/expected.txt deleted file mode 100644 index f362c45b77..0000000000 --- a/test/651-checker-simd-minmax/expected.txt +++ /dev/null @@ -1,7 +0,0 @@ -ByteSimdMinMax passed -CharSimdMinMax passed -ShortSimdMinMax passed -IntSimdMinMax passed -LongSimdMinMax passed -DoubleSimdMinMax passed -FloatSimdMinMax passed diff --git a/test/651-checker-simd-minmax/info.txt b/test/651-checker-simd-minmax/info.txt deleted file mode 100644 index 73af1242c0..0000000000 --- a/test/651-checker-simd-minmax/info.txt +++ /dev/null @@ -1 +0,0 @@ -Functional tests on min/max SIMD vectorization. diff --git a/test/651-checker-simd-minmax/src/ByteSimdMinMax.java b/test/651-checker-simd-minmax/src/ByteSimdMinMax.java deleted file mode 100644 index fff15faeaa..0000000000 --- a/test/651-checker-simd-minmax/src/ByteSimdMinMax.java +++ /dev/null @@ -1,273 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Tests for MIN/MAX vectorization. - */ -public class ByteSimdMinMax { - - /// CHECK-START: void ByteSimdMinMax.doitMin(byte[], byte[], byte[]) loop_optimization (before) - /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none - /// CHECK-DAG: <<Get1:b\d+>> ArrayGet loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Get2:b\d+>> ArrayGet loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Min:i\d+>> Min [<<Get1>>,<<Get2>>] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Cnv:b\d+>> TypeConversion [<<Min>>] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: ArraySet [{{l\d+}},<<Phi>>,<<Cnv>>] loop:<<Loop>> outer_loop:none - // - /// CHECK-START-{ARM,ARM64,MIPS64}: void ByteSimdMinMax.doitMin(byte[], byte[], byte[]) loop_optimization (after) - /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop:B\d+>> outer_loop:none - /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Min:d\d+>> VecMin [<<Get1>>,<<Get2>>] packed_type:Int8 loop:<<Loop>> outer_loop:none - /// CHECK-DAG: VecStore [{{l\d+}},{{i\d+}},<<Min>>] loop:<<Loop>> outer_loop:none - private static void doitMin(byte[] x, byte[] y, byte[] z) { - int min = Math.min(x.length, Math.min(y.length, z.length)); - for (int i = 0; i < min; i++) { - x[i] = (byte) Math.min(y[i], z[i]); - } - } - - /// CHECK-START: void ByteSimdMinMax.doitMinUnsigned(byte[], byte[], byte[]) instruction_simplifier (before) - /// CHECK-DAG: <<I255:i\d+>> IntConstant 255 loop:none - /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none - /// CHECK-DAG: <<Get1:b\d+>> ArrayGet loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Get2:b\d+>> ArrayGet loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<And1:i\d+>> And [<<Get1>>,<<I255>>] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<And2:i\d+>> And [<<Get2>>,<<I255>>] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Min:i\d+>> InvokeStaticOrDirect [<<And1>>,<<And2>>] intrinsic:MathMinIntInt loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Cnv:b\d+>> TypeConversion [<<Min>>] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: ArraySet [{{l\d+}},{{i\d+}},<<Cnv>>] loop:<<Loop>> outer_loop:none - // - /// CHECK-START: void ByteSimdMinMax.doitMinUnsigned(byte[], byte[], byte[]) loop_optimization (before) - /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none - /// CHECK-DAG: <<Get1:a\d+>> ArrayGet loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Get2:a\d+>> ArrayGet loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Min:i\d+>> Min [<<Get1>>,<<Get2>>] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Cnv:b\d+>> TypeConversion [<<Min>>] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: ArraySet [{{l\d+}},<<Phi>>,<<Cnv>>] loop:<<Loop>> outer_loop:none - // - /// CHECK-START-{ARM,ARM64,MIPS64}: void ByteSimdMinMax.doitMinUnsigned(byte[], byte[], byte[]) loop_optimization (after) - /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop:B\d+>> outer_loop:none - /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Min:d\d+>> VecMin [<<Get1>>,<<Get2>>] packed_type:Uint8 loop:<<Loop>> outer_loop:none - /// CHECK-DAG: VecStore [{{l\d+}},{{i\d+}},<<Min>>] loop:<<Loop>> outer_loop:none - private static void doitMinUnsigned(byte[] x, byte[] y, byte[] z) { - int min = Math.min(x.length, Math.min(y.length, z.length)); - for (int i = 0; i < min; i++) { - x[i] = (byte) Math.min(y[i] & 0xff, z[i] & 0xff); - } - } - - /// CHECK-START: void ByteSimdMinMax.doitMax(byte[], byte[], byte[]) loop_optimization (before) - /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none - /// CHECK-DAG: <<Get1:b\d+>> ArrayGet loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Get2:b\d+>> ArrayGet loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Max:i\d+>> Max [<<Get1>>,<<Get2>>] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Cnv:b\d+>> TypeConversion [<<Max>>] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: ArraySet [{{l\d+}},<<Phi>>,<<Cnv>>] loop:<<Loop>> outer_loop:none - // - /// CHECK-START-{ARM,ARM64,MIPS64}: void ByteSimdMinMax.doitMax(byte[], byte[], byte[]) loop_optimization (after) - /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop:B\d+>> outer_loop:none - /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Max:d\d+>> VecMax [<<Get1>>,<<Get2>>] packed_type:Int8 loop:<<Loop>> outer_loop:none - /// CHECK-DAG: VecStore [{{l\d+}},{{i\d+}},<<Max>>] loop:<<Loop>> outer_loop:none - private static void doitMax(byte[] x, byte[] y, byte[] z) { - int min = Math.min(x.length, Math.min(y.length, z.length)); - for (int i = 0; i < min; i++) { - x[i] = (byte) Math.max(y[i], z[i]); - } - } - - /// CHECK-START: void ByteSimdMinMax.doitMaxUnsigned(byte[], byte[], byte[]) instruction_simplifier (before) - /// CHECK-DAG: <<I255:i\d+>> IntConstant 255 loop:none - /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none - /// CHECK-DAG: <<Get1:b\d+>> ArrayGet loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Get2:b\d+>> ArrayGet loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<And1:i\d+>> And [<<Get1>>,<<I255>>] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<And2:i\d+>> And [<<Get2>>,<<I255>>] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Max:i\d+>> InvokeStaticOrDirect [<<And1>>,<<And2>>] intrinsic:MathMaxIntInt loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Cnv:b\d+>> TypeConversion [<<Max>>] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: ArraySet [{{l\d+}},{{i\d+}},<<Cnv>>] loop:<<Loop>> outer_loop:none - // - /// CHECK-START: void ByteSimdMinMax.doitMaxUnsigned(byte[], byte[], byte[]) loop_optimization (before) - /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none - /// CHECK-DAG: <<Get1:a\d+>> ArrayGet loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Get2:a\d+>> ArrayGet loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Max:i\d+>> Max [<<Get1>>,<<Get2>>] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Cnv:b\d+>> TypeConversion [<<Max>>] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: ArraySet [{{l\d+}},<<Phi>>,<<Cnv>>] loop:<<Loop>> outer_loop:none - // - /// CHECK-START-{ARM,ARM64,MIPS64}: void ByteSimdMinMax.doitMaxUnsigned(byte[], byte[], byte[]) loop_optimization (after) - /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop:B\d+>> outer_loop:none - /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Max:d\d+>> VecMax [<<Get1>>,<<Get2>>] packed_type:Uint8 loop:<<Loop>> outer_loop:none - /// CHECK-DAG: VecStore [{{l\d+}},{{i\d+}},<<Max>>] loop:<<Loop>> outer_loop:none - private static void doitMaxUnsigned(byte[] x, byte[] y, byte[] z) { - int min = Math.min(x.length, Math.min(y.length, z.length)); - for (int i = 0; i < min; i++) { - x[i] = (byte) Math.max(y[i] & 0xff, z[i] & 0xff); - } - } - - /// CHECK-START: void ByteSimdMinMax.doitMin100(byte[], byte[]) loop_optimization (before) - /// CHECK-DAG: <<I100:i\d+>> IntConstant 100 loop:none - /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none - /// CHECK-DAG: <<Get:b\d+>> ArrayGet loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Min:i\d+>> Min [<<Get>>,<<I100>>] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Cnv:b\d+>> TypeConversion [<<Min>>] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: ArraySet [{{l\d+}},<<Phi>>,<<Cnv>>] loop:<<Loop>> outer_loop:none - // - /// CHECK-START-{ARM,ARM64,MIPS64}: void ByteSimdMinMax.doitMin100(byte[], byte[]) loop_optimization (after) - /// CHECK-DAG: <<I100:i\d+>> IntConstant 100 loop:none - /// CHECK-DAG: <<Repl:d\d+>> VecReplicateScalar [<<I100>>] loop:none - /// CHECK-DAG: <<Get:d\d+>> VecLoad loop:<<Loop:B\d+>> outer_loop:none - /// CHECK-DAG: <<Min:d\d+>> VecMin [<<Get>>,<<Repl>>] packed_type:Int8 loop:<<Loop>> outer_loop:none - /// CHECK-DAG: VecStore [{{l\d+}},{{i\d+}},<<Min>>] loop:<<Loop>> outer_loop:none - private static void doitMin100(byte[] x, byte[] y) { - int min = Math.min(x.length, y.length); - for (int i = 0; i < min; i++) { - x[i] = (byte) Math.min(y[i], 100); - } - } - - /// CHECK-START-{ARM,ARM64,MIPS64}: void ByteSimdMinMax.doitMinMax(byte[], byte[]) loop_optimization (after) - /// CHECK-DAG: <<I11:i\d+>> IntConstant -11 loop:none - /// CHECK-DAG: <<I23:i\d+>> IntConstant 23 loop:none - /// CHECK-DAG: <<Rpl1:d\d+>> VecReplicateScalar [<<I23>>] loop:none - /// CHECK-DAG: <<Rpl2:d\d+>> VecReplicateScalar [<<I11>>] loop:none - /// CHECK-DAG: <<Get:d\d+>> VecLoad loop:<<Loop:B\d+>> outer_loop:none - /// CHECK-DAG: <<Min:d\d+>> VecMin [<<Get>>,<<Rpl1>>] packed_type:Int8 loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Max:d\d+>> VecMax [<<Min>>,<<Rpl2>>] packed_type:Int8 loop:<<Loop>> outer_loop:none - /// CHECK-DAG: VecStore [{{l\d+}},{{i\d+}},<<Max>>] loop:<<Loop>> outer_loop:none - private static void doitMinMax(byte[] x, byte[] y) { - int n = Math.min(x.length, y.length); - for (int i = 0; i < n; i++) { - x[i] = (byte) Math.max(-11, Math.min(y[i], 23)); - } - } - - /// CHECK-START-{ARM,ARM64,MIPS64}: void ByteSimdMinMax.doitMinMaxUnsigned(byte[], byte[]) loop_optimization (after) - /// CHECK-DAG: <<I11:i\d+>> IntConstant 11 loop:none - /// CHECK-DAG: <<I23:i\d+>> IntConstant 23 loop:none - /// CHECK-DAG: <<Rpl1:d\d+>> VecReplicateScalar [<<I23>>] loop:none - /// CHECK-DAG: <<Rpl2:d\d+>> VecReplicateScalar [<<I11>>] loop:none - /// CHECK-DAG: <<Get:d\d+>> VecLoad loop:<<Loop:B\d+>> outer_loop:none - /// CHECK-DAG: <<Min:d\d+>> VecMin [<<Get>>,<<Rpl1>>] packed_type:Uint8 loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Max:d\d+>> VecMax [<<Min>>,<<Rpl2>>] packed_type:Uint8 loop:<<Loop>> outer_loop:none - /// CHECK-DAG: VecStore [{{l\d+}},{{i\d+}},<<Max>>] loop:<<Loop>> outer_loop:none - private static void doitMinMaxUnsigned(byte[] x, byte[] y) { - int n = Math.min(x.length, y.length); - for (int i = 0; i < n; i++) { - x[i] = (byte) Math.max(11, Math.min(y[i] & 0xff, 23)); - } - } - - /// CHECK-START-{ARM,ARM64}: void ByteSimdMinMax.doitMinAlt(byte[], byte[], byte[]) loop_optimization (after) - /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop:B\d+>> outer_loop:none - /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Min:d\d+>> VecMin [<<Get1>>,<<Get2>>] packed_type:Int8 loop:<<Loop>> outer_loop:none - /// CHECK-DAG: VecStore [{{l\d+}},{{i\d+}},<<Min>>] loop:<<Loop>> outer_loop:none - private static void doitMinAlt(byte[] x, byte[] y, byte[] z) { - int n = Math.min(x.length, Math.min(y.length, z.length)); - for (int i = 0; i < n; ++i) { - x[i] = y[i] < z[i] ? y[i] : z[i]; - } - } - - /// CHECK-START-{ARM,ARM64,MIPS64}: void ByteSimdMinMax.doitMaxAlt(byte[], byte[], byte[]) loop_optimization (after) - /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop:B\d+>> outer_loop:none - /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Max:d\d+>> VecMax [<<Get1>>,<<Get2>>] packed_type:Int8 loop:<<Loop>> outer_loop:none - /// CHECK-DAG: VecStore [{{l\d+}},{{i\d+}},<<Max>>] loop:<<Loop>> outer_loop:none - private static void doitMaxAlt(byte[] x, byte[] y, byte[] z) { - int n = Math.min(x.length, Math.min(y.length, z.length)); - for (int i = 0; i < n; ++i) { - x[i] = y[i] > z[i] ? y[i] : z[i]; - } - } - - public static void main() { - // Initialize cross-values for all possible values. - int total = 256 * 256; - byte[] x = new byte[total]; - byte[] y = new byte[total]; - byte[] z = new byte[total]; - int k = 0; - for (int i = 0; i < 256; i++) { - for (int j = 0; j < 256; j++) { - x[k] = 0; - y[k] = (byte) i; - z[k] = (byte) j; - k++; - } - } - - // And test. - doitMin(x, y, z); - for (int i = 0; i < total; i++) { - byte expected = (byte) Math.min(y[i], z[i]); - expectEquals(expected, x[i]); - } - doitMinUnsigned(x, y, z); - for (int i = 0; i < total; i++) { - byte expected = (byte) Math.min(y[i] & 0xff, z[i] & 0xff); - expectEquals(expected, x[i]); - } - doitMax(x, y, z); - for (int i = 0; i < total; i++) { - byte expected = (byte) Math.max(y[i], z[i]); - expectEquals(expected, x[i]); - } - doitMaxUnsigned(x, y, z); - for (int i = 0; i < total; i++) { - byte expected = (byte) Math.max(y[i] & 0xff, z[i] & 0xff); - expectEquals(expected, x[i]); - } - doitMin100(x, y); - for (int i = 0; i < total; i++) { - byte expected = (byte) Math.min(y[i], 100); - expectEquals(expected, x[i]); - } - doitMinMax(x, y); - for (int i = 0; i < total; i++) { - int s = y[i]; - byte expected = (byte) (s < -11 ? -11 : (s > 23 ? 23 : s)); - expectEquals(expected, x[i]); - } - doitMinMaxUnsigned(x, y); - for (int i = 0; i < total; i++) { - int u = y[i] & 0xff; - byte expected = (byte) (u < 11 ? 11 : (u > 23 ? 23 : u)); - expectEquals(expected, x[i]); - } - doitMinAlt(x, y, z); - for (int i = 0; i < total; i++) { - byte expected = (byte) Math.min(y[i], z[i]); - expectEquals(expected, x[i]); - } - doitMaxAlt(x, y, z); - for (int i = 0; i < total; i++) { - byte expected = (byte) Math.max(y[i], z[i]); - expectEquals(expected, x[i]); - } - System.out.println("ByteSimdMinMax passed"); - } - - private static void expectEquals(byte expected, byte result) { - if (expected != result) { - throw new Error("Expected: " + expected + ", found: " + result); - } - } -} diff --git a/test/651-checker-simd-minmax/src/CharSimdMinMax.java b/test/651-checker-simd-minmax/src/CharSimdMinMax.java deleted file mode 100644 index 30169c4591..0000000000 --- a/test/651-checker-simd-minmax/src/CharSimdMinMax.java +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Tests for MIN/MAX vectorization. - */ -public class CharSimdMinMax { - - /// CHECK-START: void CharSimdMinMax.doitMin(char[], char[], char[]) loop_optimization (before) - /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none - /// CHECK-DAG: <<Get1:c\d+>> ArrayGet loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Get2:c\d+>> ArrayGet loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Min:i\d+>> Min [<<Get1>>,<<Get2>>] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Cnv:c\d+>> TypeConversion [<<Min>>] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: ArraySet [{{l\d+}},<<Phi>>,<<Cnv>>] loop:<<Loop>> outer_loop:none - // - /// CHECK-START-{ARM,ARM64,MIPS64}: void CharSimdMinMax.doitMin(char[], char[], char[]) loop_optimization (after) - /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop:B\d+>> outer_loop:none - /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Min:d\d+>> VecMin [<<Get1>>,<<Get2>>] packed_type:Uint16 loop:<<Loop>> outer_loop:none - /// CHECK-DAG: VecStore [{{l\d+}},{{i\d+}},<<Min>>] loop:<<Loop>> outer_loop:none - private static void doitMin(char[] x, char[] y, char[] z) { - int min = Math.min(x.length, Math.min(y.length, z.length)); - for (int i = 0; i < min; i++) { - x[i] = (char) Math.min(y[i], z[i]); - } - } - - /// CHECK-START: void CharSimdMinMax.doitMax(char[], char[], char[]) loop_optimization (before) - /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none - /// CHECK-DAG: <<Get1:c\d+>> ArrayGet loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Get2:c\d+>> ArrayGet loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Max:i\d+>> Max [<<Get1>>,<<Get2>>] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Cnv:c\d+>> TypeConversion [<<Max>>] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: ArraySet [{{l\d+}},<<Phi>>,<<Cnv>>] loop:<<Loop>> outer_loop:none - // - /// CHECK-START-{ARM,ARM64,MIPS64}: void CharSimdMinMax.doitMax(char[], char[], char[]) loop_optimization (after) - /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop:B\d+>> outer_loop:none - /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Max:d\d+>> VecMax [<<Get1>>,<<Get2>>] packed_type:Uint16 loop:<<Loop>> outer_loop:none - /// CHECK-DAG: VecStore [{{l\d+}},{{i\d+}},<<Max>>] loop:<<Loop>> outer_loop:none - private static void doitMax(char[] x, char[] y, char[] z) { - int min = Math.min(x.length, Math.min(y.length, z.length)); - for (int i = 0; i < min; i++) { - x[i] = (char) Math.max(y[i], z[i]); - } - } - - /// CHECK-START: void CharSimdMinMax.doitMin100(char[], char[]) loop_optimization (before) - /// CHECK-DAG: <<I100:i\d+>> IntConstant 100 loop:none - /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none - /// CHECK-DAG: <<Get:c\d+>> ArrayGet loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Min:i\d+>> Min [<<Get>>,<<I100>>] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Cnv:c\d+>> TypeConversion [<<Min>>] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: ArraySet [{{l\d+}},<<Phi>>,<<Cnv>>] loop:<<Loop>> outer_loop:none - // - /// CHECK-START-{ARM64,MIPS64}: void CharSimdMinMax.doitMin100(char[], char[]) loop_optimization (after) - /// CHECK-DAG: <<I100:i\d+>> IntConstant 100 loop:none - /// CHECK-DAG: <<Repl:d\d+>> VecReplicateScalar [<<I100>>] loop:none - /// CHECK-DAG: <<Get:d\d+>> VecLoad loop:<<Loop:B\d+>> outer_loop:none - /// CHECK-DAG: <<Min:d\d+>> VecMin [<<Get>>,<<Repl>>] packed_type:Uint16 loop:<<Loop>> outer_loop:none - /// CHECK-DAG: VecStore [{{l\d+}},{{i\d+}},<<Min>>] loop:<<Loop>> outer_loop:none - private static void doitMin100(char[] x, char[] y) { - int min = Math.min(x.length, y.length); - for (int i = 0; i < min; i++) { - x[i] = (char) Math.min(y[i], 100); - } - } - - public static void main() { - char[] interesting = { - 0x0000, 0x0001, 0x007f, 0x0080, 0x0081, 0x00ff, - 0x0100, 0x0101, 0x017f, 0x0180, 0x0181, 0x01ff, - 0x7f00, 0x7f01, 0x7f7f, 0x7f80, 0x7f81, 0x7fff, - 0x8000, 0x8001, 0x807f, 0x8080, 0x8081, 0x80ff, - 0x8100, 0x8101, 0x817f, 0x8180, 0x8181, 0x81ff, - 0xff00, 0xff01, 0xff7f, 0xff80, 0xff81, 0xffff - }; - // Initialize cross-values for the interesting values. - int total = interesting.length * interesting.length; - char[] x = new char[total]; - char[] y = new char[total]; - char[] z = new char[total]; - int k = 0; - for (int i = 0; i < interesting.length; i++) { - for (int j = 0; j < interesting.length; j++) { - x[k] = 0; - y[k] = interesting[i]; - z[k] = interesting[j]; - k++; - } - } - - // And test. - doitMin(x, y, z); - for (int i = 0; i < total; i++) { - char expected = (char) Math.min(y[i], z[i]); - expectEquals(expected, x[i]); - } - doitMax(x, y, z); - for (int i = 0; i < total; i++) { - char expected = (char) Math.max(y[i], z[i]); - expectEquals(expected, x[i]); - } - doitMin100(x, y); - for (int i = 0; i < total; i++) { - char expected = (char) Math.min(y[i], 100); - expectEquals(expected, x[i]); - } - - System.out.println("CharSimdMinMax passed"); - } - - private static void expectEquals(char expected, char result) { - if (expected != result) { - throw new Error("Expected: " + expected + ", found: " + result); - } - } -} diff --git a/test/651-checker-simd-minmax/src/DoubleSimdMinMax.java b/test/651-checker-simd-minmax/src/DoubleSimdMinMax.java deleted file mode 100644 index da20594db8..0000000000 --- a/test/651-checker-simd-minmax/src/DoubleSimdMinMax.java +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Tests for MIN/MAX vectorization. - */ -public class DoubleSimdMinMax { - - /// CHECK-START: void DoubleSimdMinMax.doitMin(double[], double[], double[]) loop_optimization (before) - /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none - /// CHECK-DAG: <<Get1:d\d+>> ArrayGet loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Get2:d\d+>> ArrayGet loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Min:d\d+>> Min [<<Get1>>,<<Get2>>] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: ArraySet [{{l\d+}},<<Phi>>,<<Min>>] loop:<<Loop>> outer_loop:none - // - // TODO x86: 0.0 vs -0.0? - // TODO MIPS64: min(x, NaN)? - // - /// CHECK-START-ARM64: void DoubleSimdMinMax.doitMin(double[], double[], double[]) loop_optimization (after) - /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop:B\d+>> outer_loop:none - /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Min:d\d+>> VecMin [<<Get1>>,<<Get2>>] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: VecStore [{{l\d+}},{{i\d+}},<<Min>>] loop:<<Loop>> outer_loop:none - private static void doitMin(double[] x, double[] y, double[] z) { - int min = Math.min(x.length, Math.min(y.length, z.length)); - for (int i = 0; i < min; i++) { - x[i] = Math.min(y[i], z[i]); - } - } - - /// CHECK-START: void DoubleSimdMinMax.doitMax(double[], double[], double[]) loop_optimization (before) - /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none - /// CHECK-DAG: <<Get1:d\d+>> ArrayGet loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Get2:d\d+>> ArrayGet loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Max:d\d+>> Max [<<Get1>>,<<Get2>>] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: ArraySet [{{l\d+}},<<Phi>>,<<Max>>] loop:<<Loop>> outer_loop:none - // - // TODO x86: 0.0 vs -0.0? - // TODO MIPS64: max(x, NaN)? - // - /// CHECK-START-ARM64: void DoubleSimdMinMax.doitMax(double[], double[], double[]) loop_optimization (after) - /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop:B\d+>> outer_loop:none - /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Max:d\d+>> VecMax [<<Get1>>,<<Get2>>] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: VecStore [{{l\d+}},{{i\d+}},<<Max>>] loop:<<Loop>> outer_loop:none - private static void doitMax(double[] x, double[] y, double[] z) { - int min = Math.min(x.length, Math.min(y.length, z.length)); - for (int i = 0; i < min; i++) { - x[i] = Math.max(y[i], z[i]); - } - } - - public static void main() { - double[] interesting = { - -0.0f, - +0.0f, - -1.0f, - +1.0f, - -3.14f, - +3.14f, - -100.0f, - +100.0f, - -4444.44f, - +4444.44f, - Double.MIN_NORMAL, - Double.MIN_VALUE, - Double.MAX_VALUE, - Double.NEGATIVE_INFINITY, - Double.POSITIVE_INFINITY, - Double.NaN - }; - // Initialize cross-values for the interesting values. - int total = interesting.length * interesting.length; - double[] x = new double[total]; - double[] y = new double[total]; - double[] z = new double[total]; - int k = 0; - for (int i = 0; i < interesting.length; i++) { - for (int j = 0; j < interesting.length; j++) { - x[k] = 0; - y[k] = interesting[i]; - z[k] = interesting[j]; - k++; - } - } - - // And test. - doitMin(x, y, z); - for (int i = 0; i < total; i++) { - double expected = Math.min(y[i], z[i]); - expectEquals(expected, x[i]); - } - doitMax(x, y, z); - for (int i = 0; i < total; i++) { - double expected = Math.max(y[i], z[i]); - expectEquals(expected, x[i]); - } - - System.out.println("DoubleSimdMinMax passed"); - } - - private static void expectEquals(double expected, double result) { - // Tests the bits directly. This distinguishes correctly between +0.0 - // and -0.0 and returns a canonical representation for all NaN. - long expected_bits = Double.doubleToLongBits(expected); - long result_bits = Double.doubleToLongBits(result); - if (expected_bits != result_bits) { - throw new Error("Expected: " + expected + - "(0x" + Long.toHexString(expected_bits) + "), found: " + result + - "(0x" + Long.toHexString(result_bits) + ")"); - } - } -} diff --git a/test/651-checker-simd-minmax/src/FloatSimdMinMax.java b/test/651-checker-simd-minmax/src/FloatSimdMinMax.java deleted file mode 100644 index 645081248a..0000000000 --- a/test/651-checker-simd-minmax/src/FloatSimdMinMax.java +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Tests for MIN/MAX vectorization. - */ -public class FloatSimdMinMax { - - /// CHECK-START: void FloatSimdMinMax.doitMin(float[], float[], float[]) loop_optimization (before) - /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none - /// CHECK-DAG: <<Get1:f\d+>> ArrayGet loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Get2:f\d+>> ArrayGet loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Min:f\d+>> Min [<<Get1>>,<<Get2>>] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: ArraySet [{{l\d+}},<<Phi>>,<<Min>>] loop:<<Loop>> outer_loop:none - // - // TODO x86: 0.0 vs -0.0? - // TODO MIPS64: min(x, NaN)? - // - /// CHECK-START-ARM64: void FloatSimdMinMax.doitMin(float[], float[], float[]) loop_optimization (after) - /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop:B\d+>> outer_loop:none - /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Min:d\d+>> VecMin [<<Get1>>,<<Get2>>] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: VecStore [{{l\d+}},{{i\d+}},<<Min>>] loop:<<Loop>> outer_loop:none - private static void doitMin(float[] x, float[] y, float[] z) { - int min = Math.min(x.length, Math.min(y.length, z.length)); - for (int i = 0; i < min; i++) { - x[i] = Math.min(y[i], z[i]); - } - } - - /// CHECK-START: void FloatSimdMinMax.doitMax(float[], float[], float[]) loop_optimization (before) - /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none - /// CHECK-DAG: <<Get1:f\d+>> ArrayGet loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Get2:f\d+>> ArrayGet loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Max:f\d+>> Max [<<Get1>>,<<Get2>>] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: ArraySet [{{l\d+}},<<Phi>>,<<Max>>] loop:<<Loop>> outer_loop:none - // - // TODO x86: 0.0 vs -0.0? - // TODO MIPS64: max(x, NaN)? - // - /// CHECK-START-ARM64: void FloatSimdMinMax.doitMax(float[], float[], float[]) loop_optimization (after) - /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop:B\d+>> outer_loop:none - /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Max:d\d+>> VecMax [<<Get1>>,<<Get2>>] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: VecStore [{{l\d+}},{{i\d+}},<<Max>>] loop:<<Loop>> outer_loop:none - private static void doitMax(float[] x, float[] y, float[] z) { - int min = Math.min(x.length, Math.min(y.length, z.length)); - for (int i = 0; i < min; i++) { - x[i] = Math.max(y[i], z[i]); - } - } - - public static void main() { - float[] interesting = { - -0.0f, - +0.0f, - -1.0f, - +1.0f, - -3.14f, - +3.14f, - -100.0f, - +100.0f, - -4444.44f, - +4444.44f, - Float.MIN_NORMAL, - Float.MIN_VALUE, - Float.MAX_VALUE, - Float.NEGATIVE_INFINITY, - Float.POSITIVE_INFINITY, - Float.NaN - }; - // Initialize cross-values for the interesting values. - int total = interesting.length * interesting.length; - float[] x = new float[total]; - float[] y = new float[total]; - float[] z = new float[total]; - int k = 0; - for (int i = 0; i < interesting.length; i++) { - for (int j = 0; j < interesting.length; j++) { - x[k] = 0; - y[k] = interesting[i]; - z[k] = interesting[j]; - k++; - } - } - - // And test. - doitMin(x, y, z); - for (int i = 0; i < total; i++) { - float expected = Math.min(y[i], z[i]); - expectEquals(expected, x[i]); - } - doitMax(x, y, z); - for (int i = 0; i < total; i++) { - float expected = Math.max(y[i], z[i]); - expectEquals(expected, x[i]); - } - - System.out.println("FloatSimdMinMax passed"); - } - - private static void expectEquals(float expected, float result) { - // Tests the bits directly. This distinguishes correctly between +0.0 - // and -0.0 and returns a canonical representation for all NaN. - int expected_bits = Float.floatToIntBits(expected); - int result_bits = Float.floatToIntBits(result); - if (expected_bits != result_bits) { - throw new Error("Expected: " + expected + - "(0x" + Integer.toHexString(expected_bits) + "), found: " + result + - "(0x" + Integer.toHexString(result_bits) + ")"); - } - } -} diff --git a/test/651-checker-simd-minmax/src/IntSimdMinMax.java b/test/651-checker-simd-minmax/src/IntSimdMinMax.java deleted file mode 100644 index ad88843175..0000000000 --- a/test/651-checker-simd-minmax/src/IntSimdMinMax.java +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Tests for MIN/MAX vectorization. - */ -public class IntSimdMinMax { - - /// CHECK-START: void IntSimdMinMax.doitMin(int[], int[], int[]) loop_optimization (before) - /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none - /// CHECK-DAG: <<Get1:i\d+>> ArrayGet loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Get2:i\d+>> ArrayGet loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Min:i\d+>> Min [<<Get1>>,<<Get2>>] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: ArraySet [{{l\d+}},<<Phi>>,<<Min>>] loop:<<Loop>> outer_loop:none - // - /// CHECK-START-{ARM,ARM64,MIPS64}: void IntSimdMinMax.doitMin(int[], int[], int[]) loop_optimization (after) - /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop:B\d+>> outer_loop:none - /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Min:d\d+>> VecMin [<<Get1>>,<<Get2>>] packed_type:Int32 loop:<<Loop>> outer_loop:none - /// CHECK-DAG: VecStore [{{l\d+}},{{i\d+}},<<Min>>] loop:<<Loop>> outer_loop:none - private static void doitMin(int[] x, int[] y, int[] z) { - int min = Math.min(x.length, Math.min(y.length, z.length)); - for (int i = 0; i < min; i++) { - x[i] = Math.min(y[i], z[i]); - } - } - - /// CHECK-START: void IntSimdMinMax.doitMax(int[], int[], int[]) loop_optimization (before) - /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none - /// CHECK-DAG: <<Get1:i\d+>> ArrayGet loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Get2:i\d+>> ArrayGet loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Max:i\d+>> Max [<<Get1>>,<<Get2>>] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: ArraySet [{{l\d+}},<<Phi>>,<<Max>>] loop:<<Loop>> outer_loop:none - // - /// CHECK-START-{ARM,ARM64,MIPS64}: void IntSimdMinMax.doitMax(int[], int[], int[]) loop_optimization (after) - /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop:B\d+>> outer_loop:none - /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Max:d\d+>> VecMax [<<Get1>>,<<Get2>>] packed_type:Int32 loop:<<Loop>> outer_loop:none - /// CHECK-DAG: VecStore [{{l\d+}},{{i\d+}},<<Max>>] loop:<<Loop>> outer_loop:none - private static void doitMax(int[] x, int[] y, int[] z) { - int min = Math.min(x.length, Math.min(y.length, z.length)); - for (int i = 0; i < min; i++) { - x[i] = Math.max(y[i], z[i]); - } - } - - /// CHECK-START-{ARM,ARM64}: int IntSimdMinMax.findMin(int[]) loop_optimization (after) - /// CHECK-DAG: <<Rep:d\d+>> VecReplicateScalar loop:none - /// CHECK-DAG: <<VPhi:d\d+>> Phi [<<Rep>>,<<Max:d\d+>>] loop:<<Loop:B\d+>> outer_loop:none - /// CHECK-DAG: <<Get:d\d+>> VecLoad [{{l\d+}},{{i\d+}}] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Max>> VecMin [<<Get>>,<<VPhi>>] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Red:d\d+>> VecReduce [<<VPhi>>] loop:none - /// CHECK-DAG: VecExtractScalar [<<Red>>] loop:none - private static int findMin(int[] a) { - int x = Integer.MAX_VALUE; - for (int i = 0; i < a.length; i++) { - if (a[i] < x) - x = a[i]; - } - return x; - } - - /// CHECK-START-{ARM,ARM64}: int IntSimdMinMax.findMax(int[]) loop_optimization (after) - /// CHECK-DAG: <<Rep:d\d+>> VecReplicateScalar loop:none - /// CHECK-DAG: <<VPhi:d\d+>> Phi [<<Rep>>,<<Max:d\d+>>] loop:<<Loop:B\d+>> outer_loop:none - /// CHECK-DAG: <<Get:d\d+>> VecLoad [{{l\d+}},{{i\d+}}] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Max>> VecMax [<<Get>>,<<VPhi>>] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Red:d\d+>> VecReduce [<<VPhi>>] loop:none - /// CHECK-DAG: VecExtractScalar [<<Red>>] loop:none - private static int findMax(int[] a) { - int x = Integer.MIN_VALUE; - for (int i = 0; i < a.length; i++) { - if (a[i] > x) - x = a[i]; - } - return x; - } - - public static void main() { - int[] interesting = { - 0x00000000, 0x00000001, 0x00007fff, 0x00008000, 0x00008001, 0x0000ffff, - 0x00010000, 0x00010001, 0x00017fff, 0x00018000, 0x00018001, 0x0001ffff, - 0x7fff0000, 0x7fff0001, 0x7fff7fff, 0x7fff8000, 0x7fff8001, 0x7fffffff, - 0x80000000, 0x80000001, 0x80007fff, 0x80008000, 0x80008001, 0x8000ffff, - 0x80010000, 0x80010001, 0x80017fff, 0x80018000, 0x80018001, 0x8001ffff, - 0xffff0000, 0xffff0001, 0xffff7fff, 0xffff8000, 0xffff8001, 0xffffffff - }; - // Initialize cross-values for the interesting values. - int total = interesting.length * interesting.length; - int[] x = new int[total]; - int[] y = new int[total]; - int[] z = new int[total]; - int k = 0; - for (int i = 0; i < interesting.length; i++) { - for (int j = 0; j < interesting.length; j++) { - x[k] = 0; - y[k] = interesting[i]; - z[k] = interesting[j]; - k++; - } - } - - // And test. - doitMin(x, y, z); - for (int i = 0; i < total; i++) { - int expected = Math.min(y[i], z[i]); - expectEquals(expected, x[i]); - } - doitMax(x, y, z); - for (int i = 0; i < total; i++) { - int expected = Math.max(y[i], z[i]); - expectEquals(expected, x[i]); - } - expectEquals(Integer.MIN_VALUE, findMin(x)); - expectEquals(Integer.MAX_VALUE, findMax(x)); - expectEquals(Integer.MIN_VALUE, findMin(y)); - expectEquals(Integer.MAX_VALUE, findMax(y)); - expectEquals(Integer.MIN_VALUE, findMin(z)); - expectEquals(Integer.MAX_VALUE, findMax(z)); - - System.out.println("IntSimdMinMax passed"); - } - - private static void expectEquals(int expected, int result) { - if (expected != result) { - throw new Error("Expected: " + expected + ", found: " + result); - } - } -} diff --git a/test/651-checker-simd-minmax/src/LongSimdMinMax.java b/test/651-checker-simd-minmax/src/LongSimdMinMax.java deleted file mode 100644 index bb0c6047ed..0000000000 --- a/test/651-checker-simd-minmax/src/LongSimdMinMax.java +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Tests for MIN/MAX vectorization. - */ -public class LongSimdMinMax { - - /// CHECK-START: void LongSimdMinMax.doitMin(long[], long[], long[]) loop_optimization (before) - /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none - /// CHECK-DAG: <<Get1:j\d+>> ArrayGet loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Get2:j\d+>> ArrayGet loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Min:j\d+>> Min [<<Get1>>,<<Get2>>] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: ArraySet [{{l\d+}},<<Phi>>,<<Min>>] loop:<<Loop>> outer_loop:none - // - // Not directly supported for longs. - // - /// CHECK-START-ARM64: void LongSimdMinMax.doitMin(long[], long[], long[]) loop_optimization (after) - /// CHECK-NOT: VecMin - // - /// CHECK-START-MIPS64: void LongSimdMinMax.doitMin(long[], long[], long[]) loop_optimization (after) - /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop:B\d+>> outer_loop:none - /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Min:d\d+>> VecMin [<<Get1>>,<<Get2>>] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: VecStore [{{l\d+}},{{i\d+}},<<Min>>] loop:<<Loop>> outer_loop:none - - private static void doitMin(long[] x, long[] y, long[] z) { - int min = Math.min(x.length, Math.min(y.length, z.length)); - for (int i = 0; i < min; i++) { - x[i] = Math.min(y[i], z[i]); - } - } - - /// CHECK-START: void LongSimdMinMax.doitMax(long[], long[], long[]) loop_optimization (before) - /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none - /// CHECK-DAG: <<Get1:j\d+>> ArrayGet loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Get2:j\d+>> ArrayGet loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Max:j\d+>> Max [<<Get1>>,<<Get2>>] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: ArraySet [{{l\d+}},<<Phi>>,<<Max>>] loop:<<Loop>> outer_loop:none - // - // Not directly supported for longs. - // - /// CHECK-START-ARM64: void LongSimdMinMax.doitMax(long[], long[], long[]) loop_optimization (after) - /// CHECK-NOT: VecMax - // - /// CHECK-START-MIPS64: void LongSimdMinMax.doitMax(long[], long[], long[]) loop_optimization (after) - /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop:B\d+>> outer_loop:none - /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Max:d\d+>> VecMax [<<Get1>>,<<Get2>>] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: VecStore [{{l\d+}},{{i\d+}},<<Max>>] loop:<<Loop>> outer_loop:none - private static void doitMax(long[] x, long[] y, long[] z) { - int min = Math.min(x.length, Math.min(y.length, z.length)); - for (int i = 0; i < min; i++) { - x[i] = Math.max(y[i], z[i]); - } - } - - public static void main() { - long[] interesting = { - 0x0000000000000000L, 0x0000000000000001L, 0x000000007fffffffL, - 0x0000000080000000L, 0x0000000080000001L, 0x00000000ffffffffL, - 0x0000000100000000L, 0x0000000100000001L, 0x000000017fffffffL, - 0x0000000180000000L, 0x0000000180000001L, 0x00000001ffffffffL, - 0x7fffffff00000000L, 0x7fffffff00000001L, 0x7fffffff7fffffffL, - 0x7fffffff80000000L, 0x7fffffff80000001L, 0x7fffffffffffffffL, - 0x8000000000000000L, 0x8000000000000001L, 0x800000007fffffffL, - 0x8000000080000000L, 0x8000000080000001L, 0x80000000ffffffffL, - 0x8000000100000000L, 0x8000000100000001L, 0x800000017fffffffL, - 0x8000000180000000L, 0x8000000180000001L, 0x80000001ffffffffL, - 0xffffffff00000000L, 0xffffffff00000001L, 0xffffffff7fffffffL, - 0xffffffff80000000L, 0xffffffff80000001L, 0xffffffffffffffffL - }; - // Initialize cross-values for the interesting values. - int total = interesting.length * interesting.length; - long[] x = new long[total]; - long[] y = new long[total]; - long[] z = new long[total]; - int k = 0; - for (int i = 0; i < interesting.length; i++) { - for (int j = 0; j < interesting.length; j++) { - x[k] = 0; - y[k] = interesting[i]; - z[k] = interesting[j]; - k++; - } - } - - // And test. - doitMin(x, y, z); - for (int i = 0; i < total; i++) { - long expected = Math.min(y[i], z[i]); - expectEquals(expected, x[i]); - } - doitMax(x, y, z); - for (int i = 0; i < total; i++) { - long expected = Math.max(y[i], z[i]); - expectEquals(expected, x[i]); - } - - System.out.println("LongSimdMinMax passed"); - } - - private static void expectEquals(long expected, long result) { - if (expected != result) { - throw new Error("Expected: " + expected + ", found: " + result); - } - } -} diff --git a/test/651-checker-simd-minmax/src/Main.java b/test/651-checker-simd-minmax/src/Main.java deleted file mode 100644 index 9134dd1edd..0000000000 --- a/test/651-checker-simd-minmax/src/Main.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -public class Main { - public static void main(String[] args) { - ByteSimdMinMax.main(); - CharSimdMinMax.main(); - ShortSimdMinMax.main(); - IntSimdMinMax.main(); - LongSimdMinMax.main(); - DoubleSimdMinMax.main(); - FloatSimdMinMax.main(); - } -} diff --git a/test/651-checker-simd-minmax/src/ShortSimdMinMax.java b/test/651-checker-simd-minmax/src/ShortSimdMinMax.java deleted file mode 100644 index 9075d8007c..0000000000 --- a/test/651-checker-simd-minmax/src/ShortSimdMinMax.java +++ /dev/null @@ -1,254 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Tests for MIN/MAX vectorization. - */ -public class ShortSimdMinMax { - - /// CHECK-START: void ShortSimdMinMax.doitMin(short[], short[], short[]) loop_optimization (before) - /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none - /// CHECK-DAG: <<Get1:s\d+>> ArrayGet loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Get2:s\d+>> ArrayGet loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Min:i\d+>> Min [<<Get1>>,<<Get2>>] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Cnv:s\d+>> TypeConversion [<<Min>>] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: ArraySet [{{l\d+}},<<Phi>>,<<Cnv>>] loop:<<Loop>> outer_loop:none - // - /// CHECK-START-{ARM,ARM64,MIPS64}: void ShortSimdMinMax.doitMin(short[], short[], short[]) loop_optimization (after) - /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop:B\d+>> outer_loop:none - /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Min:d\d+>> VecMin [<<Get1>>,<<Get2>>] packed_type:Int16 loop:<<Loop>> outer_loop:none - /// CHECK-DAG: VecStore [{{l\d+}},{{i\d+}},<<Min>>] loop:<<Loop>> outer_loop:none - private static void doitMin(short[] x, short[] y, short[] z) { - int min = Math.min(x.length, Math.min(y.length, z.length)); - for (int i = 0; i < min; i++) { - x[i] = (short) Math.min(y[i], z[i]); - } - } - - /// CHECK-START: void ShortSimdMinMax.doitMinUnsigned(short[], short[], short[]) instruction_simplifier (before) - /// CHECK-DAG: <<IMAX:i\d+>> IntConstant 65535 loop:none - /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none - /// CHECK-DAG: <<Get1:s\d+>> ArrayGet loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Get2:s\d+>> ArrayGet loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<And1:i\d+>> And [<<Get1>>,<<IMAX>>] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<And2:i\d+>> And [<<Get2>>,<<IMAX>>] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Min:i\d+>> InvokeStaticOrDirect [<<And1>>,<<And2>>] intrinsic:MathMinIntInt loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Cnv:s\d+>> TypeConversion [<<Min>>] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: ArraySet [{{l\d+}},{{i\d+}},<<Cnv>>] loop:<<Loop>> outer_loop:none - // - /// CHECK-START: void ShortSimdMinMax.doitMinUnsigned(short[], short[], short[]) loop_optimization (before) - /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none - /// CHECK-DAG: <<Get1:c\d+>> ArrayGet loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Get2:c\d+>> ArrayGet loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Min:i\d+>> Min [<<Get1>>,<<Get2>>] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Cnv:s\d+>> TypeConversion [<<Min>>] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: ArraySet [{{l\d+}},<<Phi>>,<<Cnv>>] loop:<<Loop>> outer_loop:none - // - /// CHECK-START-{ARM,ARM64,MIPS64}: void ShortSimdMinMax.doitMinUnsigned(short[], short[], short[]) loop_optimization (after) - /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop:B\d+>> outer_loop:none - /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Min:d\d+>> VecMin [<<Get1>>,<<Get2>>] packed_type:Uint16 loop:<<Loop>> outer_loop:none - /// CHECK-DAG: VecStore [{{l\d+}},{{i\d+}},<<Min>>] loop:<<Loop>> outer_loop:none - private static void doitMinUnsigned(short[] x, short[] y, short[] z) { - int min = Math.min(x.length, Math.min(y.length, z.length)); - for (int i = 0; i < min; i++) { - x[i] = (short) Math.min(y[i] & 0xffff, z[i] & 0xffff); - } - } - - /// CHECK-START: void ShortSimdMinMax.doitMax(short[], short[], short[]) loop_optimization (before) - /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none - /// CHECK-DAG: <<Get1:s\d+>> ArrayGet loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Get2:s\d+>> ArrayGet loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Max:i\d+>> Max [<<Get1>>,<<Get2>>] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Cnv:s\d+>> TypeConversion [<<Max>>] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: ArraySet [{{l\d+}},<<Phi>>,<<Cnv>>] loop:<<Loop>> outer_loop:none - // - /// CHECK-START-{ARM,ARM64,MIPS64}: void ShortSimdMinMax.doitMax(short[], short[], short[]) loop_optimization (after) - /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop:B\d+>> outer_loop:none - /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Max:d\d+>> VecMax [<<Get1>>,<<Get2>>] packed_type:Int16 loop:<<Loop>> outer_loop:none - /// CHECK-DAG: VecStore [{{l\d+}},{{i\d+}},<<Max>>] loop:<<Loop>> outer_loop:none - private static void doitMax(short[] x, short[] y, short[] z) { - int min = Math.min(x.length, Math.min(y.length, z.length)); - for (int i = 0; i < min; i++) { - x[i] = (short) Math.max(y[i], z[i]); - } - } - - /// CHECK-START: void ShortSimdMinMax.doitMaxUnsigned(short[], short[], short[]) instruction_simplifier (before) - /// CHECK-DAG: <<IMAX:i\d+>> IntConstant 65535 loop:none - /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none - /// CHECK-DAG: <<Get1:s\d+>> ArrayGet loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Get2:s\d+>> ArrayGet loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<And1:i\d+>> And [<<Get1>>,<<IMAX>>] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<And2:i\d+>> And [<<Get2>>,<<IMAX>>] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Max:i\d+>> InvokeStaticOrDirect [<<And1>>,<<And2>>] intrinsic:MathMaxIntInt loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Cnv:s\d+>> TypeConversion [<<Max>>] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: ArraySet [{{l\d+}},{{i\d+}},<<Cnv>>] loop:<<Loop>> outer_loop:none - // - /// CHECK-START: void ShortSimdMinMax.doitMaxUnsigned(short[], short[], short[]) loop_optimization (before) - /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none - /// CHECK-DAG: <<Get1:c\d+>> ArrayGet loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Get2:c\d+>> ArrayGet loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Max:i\d+>> Max [<<Get1>>,<<Get2>>] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Cnv:s\d+>> TypeConversion [<<Max>>] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: ArraySet [{{l\d+}},<<Phi>>,<<Cnv>>] loop:<<Loop>> outer_loop:none - // - /// CHECK-START-{ARM,ARM64,MIPS64}: void ShortSimdMinMax.doitMaxUnsigned(short[], short[], short[]) loop_optimization (after) - /// CHECK-DAG: <<Get1:d\d+>> VecLoad loop:<<Loop:B\d+>> outer_loop:none - /// CHECK-DAG: <<Get2:d\d+>> VecLoad loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Max:d\d+>> VecMax [<<Get1>>,<<Get2>>] packed_type:Uint16 loop:<<Loop>> outer_loop:none - /// CHECK-DAG: VecStore [{{l\d+}},{{i\d+}},<<Max>>] loop:<<Loop>> outer_loop:none - private static void doitMaxUnsigned(short[] x, short[] y, short[] z) { - int min = Math.min(x.length, Math.min(y.length, z.length)); - for (int i = 0; i < min; i++) { - x[i] = (short) Math.max(y[i] & 0xffff, z[i] & 0xffff); - } - } - - /// CHECK-START: void ShortSimdMinMax.doitMin100(short[], short[]) loop_optimization (before) - /// CHECK-DAG: <<I100:i\d+>> IntConstant 100 loop:none - /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none - /// CHECK-DAG: <<Get:s\d+>> ArrayGet loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Min:i\d+>> Min [<<Get>>,<<I100>>] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Cnv:s\d+>> TypeConversion [<<Min>>] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: ArraySet [{{l\d+}},<<Phi>>,<<Cnv>>] loop:<<Loop>> outer_loop:none - // - /// CHECK-START-{ARM,ARM64,MIPS64}: void ShortSimdMinMax.doitMin100(short[], short[]) loop_optimization (after) - /// CHECK-DAG: <<I100:i\d+>> IntConstant 100 loop:none - /// CHECK-DAG: <<Repl:d\d+>> VecReplicateScalar [<<I100>>] loop:none - /// CHECK-DAG: <<Get:d\d+>> VecLoad loop:<<Loop:B\d+>> outer_loop:none - /// CHECK-DAG: <<Min:d\d+>> VecMin [<<Get>>,<<Repl>>] packed_type:Int16 loop:<<Loop>> outer_loop:none - /// CHECK-DAG: VecStore [{{l\d+}},{{i\d+}},<<Min>>] loop:<<Loop>> outer_loop:none - private static void doitMin100(short[] x, short[] y) { - int min = Math.min(x.length, y.length); - for (int i = 0; i < min; i++) { - x[i] = (short) Math.min(y[i], 100); - } - } - - /// CHECK-START-{ARM,ARM64,MIPS64}: void ShortSimdMinMax.doitMinMax(short[], short[]) loop_optimization (after) - /// CHECK-DAG: <<I11:i\d+>> IntConstant -1111 loop:none - /// CHECK-DAG: <<I23:i\d+>> IntConstant 2323 loop:none - /// CHECK-DAG: <<Rpl1:d\d+>> VecReplicateScalar [<<I23>>] loop:none - /// CHECK-DAG: <<Rpl2:d\d+>> VecReplicateScalar [<<I11>>] loop:none - /// CHECK-DAG: <<Get:d\d+>> VecLoad loop:<<Loop:B\d+>> outer_loop:none - /// CHECK-DAG: <<Min:d\d+>> VecMin [<<Get>>,<<Rpl1>>] packed_type:Int16 loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Max:d\d+>> VecMax [<<Min>>,<<Rpl2>>] packed_type:Int16 loop:<<Loop>> outer_loop:none - /// CHECK-DAG: VecStore [{{l\d+}},{{i\d+}},<<Max>>] loop:<<Loop>> outer_loop:none - private static void doitMinMax(short[] x, short[] y) { - int n = Math.min(x.length, y.length); - for (int i = 0; i < n; i++) { - x[i] = (short) Math.max(-1111, Math.min(y[i], 2323)); - } - } - - /// CHECK-START-{ARM,ARM64,MIPS64}: void ShortSimdMinMax.doitMinMaxUnsigned(short[], short[]) loop_optimization (after) - /// CHECK-DAG: <<I11:i\d+>> IntConstant 1111 loop:none - /// CHECK-DAG: <<I23:i\d+>> IntConstant 2323 loop:none - /// CHECK-DAG: <<Rpl1:d\d+>> VecReplicateScalar [<<I23>>] loop:none - /// CHECK-DAG: <<Rpl2:d\d+>> VecReplicateScalar [<<I11>>] loop:none - /// CHECK-DAG: <<Get:d\d+>> VecLoad loop:<<Loop:B\d+>> outer_loop:none - /// CHECK-DAG: <<Min:d\d+>> VecMin [<<Get>>,<<Rpl1>>] packed_type:Uint16 loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Max:d\d+>> VecMax [<<Min>>,<<Rpl2>>] packed_type:Uint16 loop:<<Loop>> outer_loop:none - /// CHECK-DAG: VecStore [{{l\d+}},{{i\d+}},<<Max>>] loop:<<Loop>> outer_loop:none - private static void doitMinMaxUnsigned(short[] x, short[] y) { - int n = Math.min(x.length, y.length); - for (int i = 0; i < n; i++) { - x[i] = (short) Math.max(1111, Math.min(y[i] & 0xffff, 2323)); - } - } - - public static void main() { - short[] interesting = { - (short) 0x0000, (short) 0x0001, (short) 0x007f, - (short) 0x0080, (short) 0x0081, (short) 0x00ff, - (short) 0x0100, (short) 0x0101, (short) 0x017f, - (short) 0x0180, (short) 0x0181, (short) 0x01ff, - (short) 0x7f00, (short) 0x7f01, (short) 0x7f7f, - (short) 0x7f80, (short) 0x7f81, (short) 0x7fff, - (short) 0x8000, (short) 0x8001, (short) 0x807f, - (short) 0x8080, (short) 0x8081, (short) 0x80ff, - (short) 0x8100, (short) 0x8101, (short) 0x817f, - (short) 0x8180, (short) 0x8181, (short) 0x81ff, - (short) 0xff00, (short) 0xff01, (short) 0xff7f, - (short) 0xff80, (short) 0xff81, (short) 0xffff - }; - // Initialize cross-values for the interesting values. - int total = interesting.length * interesting.length; - short[] x = new short[total]; - short[] y = new short[total]; - short[] z = new short[total]; - int k = 0; - for (int i = 0; i < interesting.length; i++) { - for (int j = 0; j < interesting.length; j++) { - x[k] = 0; - y[k] = interesting[i]; - z[k] = interesting[j]; - k++; - } - } - - // And test. - doitMin(x, y, z); - for (int i = 0; i < total; i++) { - short expected = (short) Math.min(y[i], z[i]); - expectEquals(expected, x[i]); - } - doitMinUnsigned(x, y, z); - for (int i = 0; i < total; i++) { - short expected = (short) Math.min(y[i] & 0xffff, z[i] & 0xffff); - expectEquals(expected, x[i]); - } - doitMax(x, y, z); - for (int i = 0; i < total; i++) { - short expected = (short) Math.max(y[i], z[i]); - expectEquals(expected, x[i]); - } - doitMaxUnsigned(x, y, z); - for (int i = 0; i < total; i++) { - short expected = (short) Math.max(y[i] & 0xffff, z[i] & 0xffff); - expectEquals(expected, x[i]); - } - doitMin100(x, y); - for (int i = 0; i < total; i++) { - short expected = (short) Math.min(y[i], 100); - expectEquals(expected, x[i]); - } - doitMinMax(x, y); - for (int i = 0; i < total; i++) { - int s = y[i]; - short expected = (short) (s < -1111 ? -1111 : (s > 2323 ? 2323 : s)); - expectEquals(expected, x[i]); - } - doitMinMaxUnsigned(x, y); - for (int i = 0; i < total; i++) { - int u = y[i] & 0xffff; - short expected = (short) (u < 1111 ? 1111 : (u > 2323 ? 2323 : u)); - expectEquals(expected, x[i]); - } - - System.out.println("ShortSimdMinMax passed"); - } - - private static void expectEquals(short expected, short result) { - if (expected != result) { - throw new Error("Expected: " + expected + ", found: " + result); - } - } -} diff --git a/test/661-checker-simd-reduc/src/Main.java b/test/661-checker-simd-reduc/src/Main.java index fcd50a6d15..eff2018078 100644 --- a/test/661-checker-simd-reduc/src/Main.java +++ b/test/661-checker-simd-reduc/src/Main.java @@ -347,126 +347,6 @@ public class Main { return sum; } - private static byte reductionMinByte(byte[] x) { - byte min = Byte.MAX_VALUE; - for (int i = 0; i < x.length; i++) { - min = (byte) Math.min(min, x[i]); - } - return min; - } - - private static short reductionMinShort(short[] x) { - short min = Short.MAX_VALUE; - for (int i = 0; i < x.length; i++) { - min = (short) Math.min(min, x[i]); - } - return min; - } - - private static char reductionMinChar(char[] x) { - char min = Character.MAX_VALUE; - for (int i = 0; i < x.length; i++) { - min = (char) Math.min(min, x[i]); - } - return min; - } - - /// CHECK-START: int Main.reductionMinInt(int[]) loop_optimization (before) - /// CHECK-DAG: <<Cons0:i\d+>> IntConstant 0 loop:none - /// CHECK-DAG: <<Cons1:i\d+>> IntConstant 1 loop:none - /// CHECK-DAG: <<ConsM:i\d+>> IntConstant 2147483647 loop:none - /// CHECK-DAG: <<Phi1:i\d+>> Phi [<<Cons0>>,{{i\d+}}] loop:<<Loop:B\d+>> outer_loop:none - /// CHECK-DAG: <<Phi2:i\d+>> Phi [<<ConsM>>,{{i\d+}}] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Get:i\d+>> ArrayGet [{{l\d+}},<<Phi1>>] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: Min [<<Phi2>>,<<Get>>] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: Add [<<Phi1>>,<<Cons1>>] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: Return [<<Phi2>>] loop:none - // - /// CHECK-START-{ARM,ARM64,MIPS64}: int Main.reductionMinInt(int[]) loop_optimization (after) - /// CHECK-DAG: <<Cons:i\d+>> IntConstant {{2|4}} loop:none - /// CHECK-DAG: <<Set:d\d+>> VecReplicateScalar [{{i\d+}}] loop:none - /// CHECK-DAG: <<Phi:d\d+>> Phi [<<Set>>,{{d\d+}}] loop:<<Loop:B\d+>> outer_loop:none - /// CHECK-DAG: <<Load:d\d+>> VecLoad [{{l\d+}},<<I:i\d+>>] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: VecMin [<<Phi>>,<<Load>>] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: Add [<<I>>,<<Cons>>] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Red:d\d+>> VecReduce [<<Phi>>] loop:none - /// CHECK-DAG: <<Extr:i\d+>> VecExtractScalar [<<Red>>] loop:none - private static int reductionMinInt(int[] x) { - int min = Integer.MAX_VALUE; - for (int i = 0; i < x.length; i++) { - min = Math.min(min, x[i]); - } - return min; - } - - private static long reductionMinLong(long[] x) { - long min = Long.MAX_VALUE; - for (int i = 0; i < x.length; i++) { - min = Math.min(min, x[i]); - } - return min; - } - - private static byte reductionMaxByte(byte[] x) { - byte max = Byte.MIN_VALUE; - for (int i = 0; i < x.length; i++) { - max = (byte) Math.max(max, x[i]); - } - return max; - } - - private static short reductionMaxShort(short[] x) { - short max = Short.MIN_VALUE; - for (int i = 0; i < x.length; i++) { - max = (short) Math.max(max, x[i]); - } - return max; - } - - private static char reductionMaxChar(char[] x) { - char max = Character.MIN_VALUE; - for (int i = 0; i < x.length; i++) { - max = (char) Math.max(max, x[i]); - } - return max; - } - - /// CHECK-START: int Main.reductionMaxInt(int[]) loop_optimization (before) - /// CHECK-DAG: <<Cons0:i\d+>> IntConstant 0 loop:none - /// CHECK-DAG: <<Cons1:i\d+>> IntConstant 1 loop:none - /// CHECK-DAG: <<ConsM:i\d+>> IntConstant -2147483648 loop:none - /// CHECK-DAG: <<Phi1:i\d+>> Phi [<<Cons0>>,{{i\d+}}] loop:<<Loop:B\d+>> outer_loop:none - /// CHECK-DAG: <<Phi2:i\d+>> Phi [<<ConsM>>,{{i\d+}}] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Get:i\d+>> ArrayGet [{{l\d+}},<<Phi1>>] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: Max [<<Phi2>>,<<Get>>] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: Add [<<Phi1>>,<<Cons1>>] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: Return [<<Phi2>>] loop:none - // - /// CHECK-START-{ARM,ARM64,MIPS64}: int Main.reductionMaxInt(int[]) loop_optimization (after) - /// CHECK-DAG: <<Cons:i\d+>> IntConstant {{2|4}} loop:none - /// CHECK-DAG: <<Set:d\d+>> VecReplicateScalar [{{i\d+}}] loop:none - /// CHECK-DAG: <<Phi:d\d+>> Phi [<<Set>>,{{d\d+}}] loop:<<Loop:B\d+>> outer_loop:none - /// CHECK-DAG: <<Load:d\d+>> VecLoad [{{l\d+}},<<I:i\d+>>] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: VecMax [<<Phi>>,<<Load>>] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: Add [<<I>>,<<Cons>>] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Red:d\d+>> VecReduce [<<Phi>>] loop:none - /// CHECK-DAG: <<Extr:i\d+>> VecExtractScalar [<<Red>>] loop:none - private static int reductionMaxInt(int[] x) { - int max = Integer.MIN_VALUE; - for (int i = 0; i < x.length; i++) { - max = Math.max(max, x[i]); - } - return max; - } - - private static long reductionMaxLong(long[] x) { - long max = Long.MIN_VALUE; - for (int i = 0; i < x.length; i++) { - max = Math.max(max, x[i]); - } - return max; - } - // // A few special cases. // @@ -491,24 +371,6 @@ public class Main { return sum; } - private static int reductionMinInt10(int[] x) { - int min = Integer.MAX_VALUE; - // Amenable to complete unrolling. - for (int i = 10; i <= 10; i++) { - min = Math.min(min, x[i]); - } - return min; - } - - private static int reductionMaxInt10(int[] x) { - int max = Integer.MIN_VALUE; - // Amenable to complete unrolling. - for (int i = 10; i <= 10; i++) { - max = Math.max(max, x[i]); - } - return max; - } - // // Main driver. // @@ -587,40 +449,10 @@ public class Main { expectEquals(27466, reductionMinusChar(xc)); expectEquals(-365750, reductionMinusInt(xi)); expectEquals(-365750L, reductionMinusLong(xl)); - expectEquals(-128, reductionMinByte(xb)); - expectEquals(-17, reductionMinShort(xs)); - expectEquals(1, reductionMinChar(xc)); - expectEquals(-17, reductionMinInt(xi)); - expectEquals(-17L, reductionMinLong(xl)); - expectEquals(3, reductionMinByte(xpb)); - expectEquals(3, reductionMinShort(xps)); - expectEquals(3, reductionMinChar(xpc)); - expectEquals(3, reductionMinInt(xpi)); - expectEquals(3L, reductionMinLong(xpl)); - expectEquals(-103, reductionMinByte(xnb)); - expectEquals(-103, reductionMinShort(xns)); - expectEquals(-103, reductionMinInt(xni)); - expectEquals(-103L, reductionMinLong(xnl)); - expectEquals(127, reductionMaxByte(xb)); - expectEquals(1480, reductionMaxShort(xs)); - expectEquals(65534, reductionMaxChar(xc)); - expectEquals(1480, reductionMaxInt(xi)); - expectEquals(1480L, reductionMaxLong(xl)); - expectEquals(102, reductionMaxByte(xpb)); - expectEquals(102, reductionMaxShort(xps)); - expectEquals(102, reductionMaxChar(xpc)); - expectEquals(102, reductionMaxInt(xpi)); - expectEquals(102L, reductionMaxLong(xpl)); - expectEquals(-4, reductionMaxByte(xnb)); - expectEquals(-4, reductionMaxShort(xns)); - expectEquals(-4, reductionMaxInt(xni)); - expectEquals(-4L, reductionMaxLong(xnl)); // Test special cases. expectEquals(13, reductionInt10(xi)); expectEquals(-13, reductionMinusInt10(xi)); - expectEquals(13, reductionMinInt10(xi)); - expectEquals(13, reductionMaxInt10(xi)); System.out.println("passed"); } diff --git a/test/678-checker-simd-saturation/build b/test/678-checker-simd-saturation/build deleted file mode 100644 index d85147f17b..0000000000 --- a/test/678-checker-simd-saturation/build +++ /dev/null @@ -1,20 +0,0 @@ -#!/bin/bash -# -# Copyright 2018 The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# See b/65168732 -export USE_D8=false - -./default-build "$@" diff --git a/test/678-checker-simd-saturation/expected.txt b/test/678-checker-simd-saturation/expected.txt deleted file mode 100644 index b0aad4deb5..0000000000 --- a/test/678-checker-simd-saturation/expected.txt +++ /dev/null @@ -1 +0,0 @@ -passed diff --git a/test/678-checker-simd-saturation/info.txt b/test/678-checker-simd-saturation/info.txt deleted file mode 100644 index ab7a80241d..0000000000 --- a/test/678-checker-simd-saturation/info.txt +++ /dev/null @@ -1 +0,0 @@ -Functional tests on saturation arithmetic vectorization. diff --git a/test/678-checker-simd-saturation/src/Main.java b/test/678-checker-simd-saturation/src/Main.java deleted file mode 100644 index 7a22ca175d..0000000000 --- a/test/678-checker-simd-saturation/src/Main.java +++ /dev/null @@ -1,784 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Functional tests for saturation aritmethic vectorization. - */ -public class Main { - - static final int $inline$p15() { - return 15; - } - - static final int $inline$m15() { - return -15; - } - - // - // Direct min-max. - // - - /// CHECK-START: void Main.satAddUByte(byte[], byte[], byte[]) loop_optimization (before) - /// CHECK-DAG: <<Clip:i\d+>> IntConstant 255 loop:none - /// CHECK-DAG: <<Get1:a\d+>> ArrayGet [{{l\d+}},<<Phi:i\d+>>] loop:<<Loop:B\d+>> outer_loop:none - /// CHECK-DAG: <<Get2:a\d+>> ArrayGet [{{l\d+}},<<Phi>>] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Add:i\d+>> Add [<<Get1>>,<<Get2>>] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Min:i\d+>> Min [<<Add>>,<<Clip>>] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Conv:b\d+>> TypeConversion [<<Min>>] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: ArraySet [{{l\d+}},<<Phi>>,<<Conv>>] loop:<<Loop>> outer_loop:none - // - /// CHECK-START-{ARM,ARM64}: void Main.satAddUByte(byte[], byte[], byte[]) loop_optimization (after) - /// CHECK-DAG: <<Get1:d\d+>> VecLoad [{{l\d+}},<<Phi:i\d+>>] loop:<<Loop:B\d+>> outer_loop:none - /// CHECK-DAG: <<Get2:d\d+>> VecLoad [{{l\d+}},<<Phi>>] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Add:d\d+>> VecSaturationAdd [<<Get1>>,<<Get2>>] packed_type:Uint8 loop:<<Loop>> outer_loop:none - /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<Add>>] loop:<<Loop>> outer_loop:none - public static void satAddUByte(byte[] a, byte[] b, byte[] c) { - int n = Math.min(a.length, Math.min(b.length, c.length)); - for (int i = 0; i < n; i++) { - c[i] = (byte) Math.min((a[i] & 0xff) + (b[i] & 0xff), 255); - } - } - - /// CHECK-START: void Main.satAddSByte(byte[], byte[], byte[]) loop_optimization (before) - /// CHECK-DAG: <<Clp1:i\d+>> IntConstant -128 loop:none - /// CHECK-DAG: <<Clp2:i\d+>> IntConstant 127 loop:none - /// CHECK-DAG: <<Get1:b\d+>> ArrayGet [{{l\d+}},<<Phi:i\d+>>] loop:<<Loop:B\d+>> outer_loop:none - /// CHECK-DAG: <<Get2:b\d+>> ArrayGet [{{l\d+}},<<Phi>>] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Add:i\d+>> Add [<<Get1>>,<<Get2>>] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Min:i\d+>> Min [<<Add>>,<<Clp2>>] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Max:i\d+>> Max [<<Min>>,<<Clp1>>] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Conv:b\d+>> TypeConversion [<<Max>>] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: ArraySet [{{l\d+}},<<Phi>>,<<Conv>>] loop:<<Loop>> outer_loop:none - // - /// CHECK-START-{ARM,ARM64}: void Main.satAddSByte(byte[], byte[], byte[]) loop_optimization (after) - /// CHECK-DAG: <<Get1:d\d+>> VecLoad [{{l\d+}},<<Phi:i\d+>>] loop:<<Loop:B\d+>> outer_loop:none - /// CHECK-DAG: <<Get2:d\d+>> VecLoad [{{l\d+}},<<Phi>>] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Add:d\d+>> VecSaturationAdd [<<Get1>>,<<Get2>>] packed_type:Int8 loop:<<Loop>> outer_loop:none - /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<Add>>] loop:<<Loop>> outer_loop:none - public static void satAddSByte(byte[] a, byte[] b, byte[] c) { - int n = Math.min(a.length, Math.min(b.length, c.length)); - for (int i = 0; i < n; i++) { - c[i] = (byte) Math.max(Math.min(a[i] + b[i], 127), -128); - } - } - - /// CHECK-START: void Main.satAddUShort(short[], short[], short[]) loop_optimization (before) - /// CHECK-DAG: <<Clip:i\d+>> IntConstant 65535 loop:none - /// CHECK-DAG: <<Get1:c\d+>> ArrayGet [{{l\d+}},<<Phi:i\d+>>] loop:<<Loop:B\d+>> outer_loop:none - /// CHECK-DAG: <<Get2:c\d+>> ArrayGet [{{l\d+}},<<Phi>>] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Add:i\d+>> Add [<<Get1>>,<<Get2>>] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Min:i\d+>> Min [<<Add>>,<<Clip>>] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Conv:s\d+>> TypeConversion [<<Min>>] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: ArraySet [{{l\d+}},<<Phi>>,<<Conv>>] loop:<<Loop>> outer_loop:none - // - /// CHECK-START-{ARM,ARM64}: void Main.satAddUShort(short[], short[], short[]) loop_optimization (after) - /// CHECK-DAG: <<Get1:d\d+>> VecLoad [{{l\d+}},<<Phi:i\d+>>] loop:<<Loop:B\d+>> outer_loop:none - /// CHECK-DAG: <<Get2:d\d+>> VecLoad [{{l\d+}},<<Phi>>] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Add:d\d+>> VecSaturationAdd [<<Get1>>,<<Get2>>] packed_type:Uint16 loop:<<Loop>> outer_loop:none - /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<Add>>] loop:<<Loop>> outer_loop:none - public static void satAddUShort(short[] a, short[] b, short[] c) { - int n = Math.min(a.length, Math.min(b.length, c.length)); - for (int i = 0; i < n; i++) { - c[i] = (short) Math.min((a[i] & 0xffff) + (b[i] & 0xffff), 65535); - } - } - - /// CHECK-START: void Main.satAddSShort(short[], short[], short[]) loop_optimization (before) - /// CHECK-DAG: <<Clp1:i\d+>> IntConstant -32768 loop:none - /// CHECK-DAG: <<Clp2:i\d+>> IntConstant 32767 loop:none - /// CHECK-DAG: <<Get1:s\d+>> ArrayGet [{{l\d+}},<<Phi:i\d+>>] loop:<<Loop:B\d+>> outer_loop:none - /// CHECK-DAG: <<Get2:s\d+>> ArrayGet [{{l\d+}},<<Phi>>] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Add:i\d+>> Add [<<Get1>>,<<Get2>>] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Min:i\d+>> Min [<<Add>>,<<Clp2>>] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Max:i\d+>> Max [<<Min>>,<<Clp1>>] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Conv:s\d+>> TypeConversion [<<Max>>] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: ArraySet [{{l\d+}},<<Phi>>,<<Conv>>] loop:<<Loop>> outer_loop:none - // - /// CHECK-START-{ARM,ARM64}: void Main.satAddSShort(short[], short[], short[]) loop_optimization (after) - /// CHECK-DAG: <<Get1:d\d+>> VecLoad [{{l\d+}},<<Phi:i\d+>>] loop:<<Loop:B\d+>> outer_loop:none - /// CHECK-DAG: <<Get2:d\d+>> VecLoad [{{l\d+}},<<Phi>>] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Add:d\d+>> VecSaturationAdd [<<Get1>>,<<Get2>>] packed_type:Int16 loop:<<Loop>> outer_loop:none - /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<Add>>] loop:<<Loop>> outer_loop:none - public static void satAddSShort(short[] a, short[] b, short[] c) { - int n = Math.min(a.length, Math.min(b.length, c.length)); - for (int i = 0; i < n; i++) { - c[i] = (short) Math.max(Math.min(a[i] + b[i], 32767), -32768); - } - } - - /// CHECK-START: void Main.satSubUByte(byte[], byte[], byte[]) loop_optimization (before) - /// CHECK-DAG: <<Clip:i\d+>> IntConstant 0 loop:none - /// CHECK-DAG: <<Get1:a\d+>> ArrayGet [{{l\d+}},<<Phi:i\d+>>] loop:<<Loop:B\d+>> outer_loop:none - /// CHECK-DAG: <<Get2:a\d+>> ArrayGet [{{l\d+}},<<Phi>>] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Sub:i\d+>> Sub [<<Get1>>,<<Get2>>] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Max:i\d+>> Max [<<Sub>>,<<Clip>>] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Conv:b\d+>> TypeConversion [<<Max>>] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: ArraySet [{{l\d+}},<<Phi>>,<<Conv>>] loop:<<Loop>> outer_loop:none - // - /// CHECK-START-{ARM,ARM64}: void Main.satSubUByte(byte[], byte[], byte[]) loop_optimization (after) - /// CHECK-DAG: <<Get1:d\d+>> VecLoad [{{l\d+}},<<Phi:i\d+>>] loop:<<Loop:B\d+>> outer_loop:none - /// CHECK-DAG: <<Get2:d\d+>> VecLoad [{{l\d+}},<<Phi>>] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Sub:d\d+>> VecSaturationSub [<<Get1>>,<<Get2>>] packed_type:Uint8 loop:<<Loop>> outer_loop:none - /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<Sub>>] loop:<<Loop>> outer_loop:none - public static void satSubUByte(byte[] a, byte[] b, byte[] c) { - int n = Math.min(a.length, Math.min(b.length, c.length)); - for (int i = 0; i < n; i++) { - c[i] = (byte) Math.max((a[i] & 0xff) - (b[i] & 0xff), 0); - } - } - - /// CHECK-START: void Main.satSubSByte(byte[], byte[], byte[]) loop_optimization (before) - /// CHECK-DAG: <<Clp1:i\d+>> IntConstant -128 loop:none - /// CHECK-DAG: <<Clp2:i\d+>> IntConstant 127 loop:none - /// CHECK-DAG: <<Get1:b\d+>> ArrayGet [{{l\d+}},<<Phi:i\d+>>] loop:<<Loop:B\d+>> outer_loop:none - /// CHECK-DAG: <<Get2:b\d+>> ArrayGet [{{l\d+}},<<Phi>>] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Sub:i\d+>> Sub [<<Get1>>,<<Get2>>] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Min:i\d+>> Min [<<Sub>>,<<Clp2>>] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Max:i\d+>> Max [<<Min>>,<<Clp1>>] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Conv:b\d+>> TypeConversion [<<Max>>] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: ArraySet [{{l\d+}},<<Phi>>,<<Conv>>] loop:<<Loop>> outer_loop:none - // - /// CHECK-START-{ARM,ARM64}: void Main.satSubSByte(byte[], byte[], byte[]) loop_optimization (after) - /// CHECK-DAG: <<Get1:d\d+>> VecLoad [{{l\d+}},<<Phi:i\d+>>] loop:<<Loop:B\d+>> outer_loop:none - /// CHECK-DAG: <<Get2:d\d+>> VecLoad [{{l\d+}},<<Phi>>] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Sub:d\d+>> VecSaturationSub [<<Get1>>,<<Get2>>] packed_type:Int8 loop:<<Loop>> outer_loop:none - /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<Sub>>] loop:<<Loop>> outer_loop:none - public static void satSubSByte(byte[] a, byte[] b, byte[] c) { - int n = Math.min(a.length, Math.min(b.length, c.length)); - for (int i = 0; i < n; i++) { - c[i] = (byte) Math.max(Math.min(a[i] - b[i], 127), -128); - } - } - - /// CHECK-START: void Main.satSubUShort(short[], short[], short[]) loop_optimization (before) - /// CHECK-DAG: <<Clip:i\d+>> IntConstant 0 loop:none - /// CHECK-DAG: <<Get1:c\d+>> ArrayGet [{{l\d+}},<<Phi:i\d+>>] loop:<<Loop:B\d+>> outer_loop:none - /// CHECK-DAG: <<Get2:c\d+>> ArrayGet [{{l\d+}},<<Phi>>] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Sub:i\d+>> Sub [<<Get1>>,<<Get2>>] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Max:i\d+>> Max [<<Sub>>,<<Clip>>] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Conv:s\d+>> TypeConversion [<<Max>>] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: ArraySet [{{l\d+}},<<Phi>>,<<Conv>>] loop:<<Loop>> outer_loop:none - // - /// CHECK-START-{ARM,ARM64}: void Main.satSubUShort(short[], short[], short[]) loop_optimization (after) - /// CHECK-DAG: <<Get1:d\d+>> VecLoad [{{l\d+}},<<Phi:i\d+>>] loop:<<Loop:B\d+>> outer_loop:none - /// CHECK-DAG: <<Get2:d\d+>> VecLoad [{{l\d+}},<<Phi>>] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Sub:d\d+>> VecSaturationSub [<<Get1>>,<<Get2>>] packed_type:Uint16 loop:<<Loop>> outer_loop:none - /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<Sub>>] loop:<<Loop>> outer_loop:none - public static void satSubUShort(short[] a, short[] b, short[] c) { - int n = Math.min(a.length, Math.min(b.length, c.length)); - for (int i = 0; i < n; i++) { - c[i] = (short) Math.max((a[i] & 0xffff) - (b[i] & 0xffff), 0); - } - } - - /// CHECK-START: void Main.satSubSShort(short[], short[], short[]) loop_optimization (before) - /// CHECK-DAG: <<Clp1:i\d+>> IntConstant -32768 loop:none - /// CHECK-DAG: <<Clp2:i\d+>> IntConstant 32767 loop:none - /// CHECK-DAG: <<Get1:s\d+>> ArrayGet [{{l\d+}},<<Phi:i\d+>>] loop:<<Loop:B\d+>> outer_loop:none - /// CHECK-DAG: <<Get2:s\d+>> ArrayGet [{{l\d+}},<<Phi>>] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Sub:i\d+>> Sub [<<Get1>>,<<Get2>>] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Min:i\d+>> Min [<<Sub>>,<<Clp2>>] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Max:i\d+>> Max [<<Min>>,<<Clp1>>] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Conv:s\d+>> TypeConversion [<<Max>>] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: ArraySet [{{l\d+}},<<Phi>>,<<Conv>>] loop:<<Loop>> outer_loop:none - // - /// CHECK-START-{ARM,ARM64}: void Main.satSubSShort(short[], short[], short[]) loop_optimization (after) - /// CHECK-DAG: <<Get1:d\d+>> VecLoad [{{l\d+}},<<Phi:i\d+>>] loop:<<Loop:B\d+>> outer_loop:none - /// CHECK-DAG: <<Get2:d\d+>> VecLoad [{{l\d+}},<<Phi>>] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Sub:d\d+>> VecSaturationSub [<<Get1>>,<<Get2>>] packed_type:Int16 loop:<<Loop>> outer_loop:none - /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<Sub>>] loop:<<Loop>> outer_loop:none - public static void satSubSShort(short[] a, short[] b, short[] c) { - int n = Math.min(a.length, Math.min(b.length, c.length)); - for (int i = 0; i < n; i++) { - c[i] = (short) Math.max(Math.min(a[i] - b[i], 32767), -32768); - } - } - - // - // Single clipping signed 8-bit saturation. - // - - /// CHECK-START-{ARM,ARM64}: void Main.satAddPConstSByte(byte[], byte[]) loop_optimization (after) - /// CHECK-DAG: <<Get1:d\d+>> VecReplicateScalar loop:none - /// CHECK-DAG: <<Get2:d\d+>> VecLoad [{{l\d+}},<<Phi:i\d+>>] loop:<<Loop:B\d+>> outer_loop:none - /// CHECK-DAG: <<Add:d\d+>> VecSaturationAdd [<<Get2>>,<<Get1>>] packed_type:Int8 loop:<<Loop>> outer_loop:none - /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<Add>>] loop:<<Loop>> outer_loop:none - public static void satAddPConstSByte(byte[] a, byte[] b) { - int n = Math.min(a.length, b.length); - for (int i = 0; i < n; i++) { - b[i] = (byte) Math.min(a[i] + 15, 127); - } - } - - /// CHECK-START-{ARM,ARM64}: void Main.satAddNConstSByte(byte[], byte[]) loop_optimization (after) - /// CHECK-DAG: <<Get1:d\d+>> VecReplicateScalar loop:none - /// CHECK-DAG: <<Get2:d\d+>> VecLoad [{{l\d+}},<<Phi:i\d+>>] loop:<<Loop:B\d+>> outer_loop:none - /// CHECK-DAG: <<Add:d\d+>> VecSaturationAdd [<<Get2>>,<<Get1>>] packed_type:Int8 loop:<<Loop>> outer_loop:none - /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<Add>>] loop:<<Loop>> outer_loop:none - public static void satAddNConstSByte(byte[] a, byte[] b) { - int n = Math.min(a.length, b.length); - for (int i = 0; i < n; i++) { - b[i] = (byte) Math.max(a[i] - 15, -128); - } - } - - /// CHECK-START-{ARM,ARM64}: void Main.satSubPConstSByte(byte[], byte[]) loop_optimization (after) - /// CHECK-DAG: <<Get1:d\d+>> VecReplicateScalar loop:none - /// CHECK-DAG: <<Get2:d\d+>> VecLoad [{{l\d+}},<<Phi:i\d+>>] loop:<<Loop:B\d+>> outer_loop:none - /// CHECK-DAG: <<Sub:d\d+>> VecSaturationSub [<<Get1>>,<<Get2>>] packed_type:Int8 loop:<<Loop>> outer_loop:none - /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<Sub>>] loop:<<Loop>> outer_loop:none - public static void satSubPConstSByte(byte[] a, byte[] b) { - int n = Math.min(a.length, b.length); - for (int i = 0; i < n; i++) { - b[i] = (byte) Math.min(15 - a[i], 127); - } - } - - /// CHECK-START-{ARM,ARM64}: void Main.satSubNConstSByte(byte[], byte[]) loop_optimization (after) - /// CHECK-DAG: <<Get1:d\d+>> VecReplicateScalar loop:none - /// CHECK-DAG: <<Get2:d\d+>> VecLoad [{{l\d+}},<<Phi:i\d+>>] loop:<<Loop:B\d+>> outer_loop:none - /// CHECK-DAG: <<Sub:d\d+>> VecSaturationSub [<<Get1>>,<<Get2>>] packed_type:Int8 loop:<<Loop>> outer_loop:none - /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<Sub>>] loop:<<Loop>> outer_loop:none - public static void satSubNConstSByte(byte[] a, byte[] b) { - int n = Math.min(a.length, b.length); - for (int i = 0; i < n; i++) { - b[i] = (byte) Math.max(-15 - a[i], -128); - } - } - - // - // Single clipping signed 16-bit saturation. - // - - /// CHECK-START-{ARM,ARM64}: void Main.satAddPConstSShort(short[], short[]) loop_optimization (after) - /// CHECK-DAG: <<Get1:d\d+>> VecReplicateScalar loop:none - /// CHECK-DAG: <<Get2:d\d+>> VecLoad [{{l\d+}},<<Phi:i\d+>>] loop:<<Loop:B\d+>> outer_loop:none - /// CHECK-DAG: <<Add:d\d+>> VecSaturationAdd [<<Get2>>,<<Get1>>] packed_type:Int16 loop:<<Loop>> outer_loop:none - /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<Add>>] loop:<<Loop>> outer_loop:none - public static void satAddPConstSShort(short[] a, short[] b) { - int n = Math.min(a.length, b.length); - for (int i = 0; i < n; i++) { - b[i] = (short) Math.min(a[i] + 15, 32767); - } - } - - /// CHECK-START-{ARM,ARM64}: void Main.satAddNConstSShort(short[], short[]) loop_optimization (after) - /// CHECK-DAG: <<Get1:d\d+>> VecReplicateScalar loop:none - /// CHECK-DAG: <<Get2:d\d+>> VecLoad [{{l\d+}},<<Phi:i\d+>>] loop:<<Loop:B\d+>> outer_loop:none - /// CHECK-DAG: <<Add:d\d+>> VecSaturationAdd [<<Get2>>,<<Get1>>] packed_type:Int16 loop:<<Loop>> outer_loop:none - /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<Add>>] loop:<<Loop>> outer_loop:none - public static void satAddNConstSShort(short[] a, short[] b) { - int n = Math.min(a.length, b.length); - for (int i = 0; i < n; i++) { - b[i] = (short) Math.max(a[i] - 15, -32768); - } - } - - /// CHECK-START-{ARM,ARM64}: void Main.satSubPConstSShort(short[], short[]) loop_optimization (after) - /// CHECK-DAG: <<Get1:d\d+>> VecReplicateScalar loop:none - /// CHECK-DAG: <<Get2:d\d+>> VecLoad [{{l\d+}},<<Phi:i\d+>>] loop:<<Loop:B\d+>> outer_loop:none - /// CHECK-DAG: <<Sub:d\d+>> VecSaturationSub [<<Get1>>,<<Get2>>] packed_type:Int16 loop:<<Loop>> outer_loop:none - /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<Sub>>] loop:<<Loop>> outer_loop:none - public static void satSubPConstSShort(short[] a, short[] b) { - int n = Math.min(a.length, b.length); - for (int i = 0; i < n; i++) { - b[i] = (short) Math.min(15 - a[i], 32767); - } - } - - /// CHECK-START-{ARM,ARM64}: void Main.satSubNConstSShort(short[], short[]) loop_optimization (after) - /// CHECK-DAG: <<Get1:d\d+>> VecReplicateScalar loop:none - /// CHECK-DAG: <<Get2:d\d+>> VecLoad [{{l\d+}},<<Phi:i\d+>>] loop:<<Loop:B\d+>> outer_loop:none - /// CHECK-DAG: <<Sub:d\d+>> VecSaturationSub [<<Get1>>,<<Get2>>] packed_type:Int16 loop:<<Loop>> outer_loop:none - /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<Sub>>] loop:<<Loop>> outer_loop:none - public static void satSubNConstSShort(short[] a, short[] b) { - int n = Math.min(a.length, b.length); - for (int i = 0; i < n; i++) { - b[i] = (short) Math.max(-15 - a[i], -32768); - } - } - - // - // Alternatives 8-bit clipping. - // - - /// CHECK-START-{ARM,ARM64}: void Main.usatAddConst(byte[], byte[]) loop_optimization (after) - /// CHECK-DAG: <<Get1:d\d+>> VecReplicateScalar loop:none - /// CHECK-DAG: <<Get2:d\d+>> VecLoad [{{l\d+}},<<Phi:i\d+>>] loop:<<Loop:B\d+>> outer_loop:none - /// CHECK-DAG: <<Add:d\d+>> VecSaturationAdd [<<Get2>>,<<Get1>>] packed_type:Uint8 loop:<<Loop>> outer_loop:none - /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<Add>>] loop:<<Loop>> outer_loop:none - public static void usatAddConst(byte[] a, byte[] b) { - int n = Math.min(a.length, b.length); - for (int i = 0; i < n; i++) { - b[i] = (byte) Math.min((a[i] & 0xff) + $inline$p15(), 255); - } - } - - /// CHECK-START-{ARM,ARM64}: void Main.usatAddConstAlt(byte[], byte[]) loop_optimization (after) - /// CHECK-DAG: <<Get1:d\d+>> VecReplicateScalar loop:none - /// CHECK-DAG: <<Get2:d\d+>> VecLoad [{{l\d+}},<<Phi:i\d+>>] loop:<<Loop:B\d+>> outer_loop:none - /// CHECK-DAG: <<Add:d\d+>> VecSaturationAdd [<<Get2>>,<<Get1>>] packed_type:Uint8 loop:<<Loop>> outer_loop:none - /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<Add>>] loop:<<Loop>> outer_loop:none - public static void usatAddConstAlt(byte[] a, byte[] b) { - int n = Math.min(a.length, b.length); - for (int i = 0; i < n; i++) { - b[i] = (byte) Math.min((a[i] & 0xff) - $inline$m15(), 255); - } - } - - /// CHECK-START-{ARM,ARM64}: void Main.usatSubConst(byte[], byte[]) loop_optimization (after) - /// CHECK-DAG: <<Get1:d\d+>> VecReplicateScalar loop:none - /// CHECK-DAG: <<Get2:d\d+>> VecLoad [{{l\d+}},<<Phi:i\d+>>] loop:<<Loop:B\d+>> outer_loop:none - /// CHECK-DAG: <<Sub:d\d+>> VecSaturationSub [<<Get2>>,<<Get1>>] packed_type:Uint8 loop:<<Loop>> outer_loop:none - /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<Sub>>] loop:<<Loop>> outer_loop:none - public static void usatSubConst(byte[] a, byte[] b) { - int n = Math.min(a.length, b.length); - for (int i = 0; i < n; i++) { - b[i] = (byte) Math.max((a[i] & 0xff) - $inline$p15(), 0); - } - } - - /// CHECK-START-{ARM,ARM64}: void Main.usatSubConstAlt(byte[], byte[]) loop_optimization (after) - /// CHECK-DAG: <<Get1:d\d+>> VecReplicateScalar loop:none - /// CHECK-DAG: <<Get2:d\d+>> VecLoad [{{l\d+}},<<Phi:i\d+>>] loop:<<Loop:B\d+>> outer_loop:none - /// CHECK-DAG: <<Sub:d\d+>> VecSaturationSub [<<Get2>>,<<Get1>>] packed_type:Uint8 loop:<<Loop>> outer_loop:none - /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<Sub>>] loop:<<Loop>> outer_loop:none - public static void usatSubConstAlt(byte[] a, byte[] b) { - int n = Math.min(a.length, b.length); - for (int i = 0; i < n; i++) { - b[i] = (byte) Math.max((a[i] & 0xff) + $inline$m15(), 0); - } - } - - // - // Alternatives 16-bit clipping. - // - - /// CHECK-START: void Main.satAlt1(short[], short[], short[]) loop_optimization (before) - /// CHECK-DAG: <<Clp1:i\d+>> IntConstant -32768 loop:none - /// CHECK-DAG: <<Clp2:i\d+>> IntConstant 32767 loop:none - /// CHECK-DAG: <<Get1:s\d+>> ArrayGet [{{l\d+}},<<Phi:i\d+>>] loop:<<Loop:B\d+>> outer_loop:none - /// CHECK-DAG: <<Get2:s\d+>> ArrayGet [{{l\d+}},<<Phi>>] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Add:i\d+>> Add [<<Get1>>,<<Get2>>] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Min:i\d+>> Min [<<Add>>,<<Clp2>>] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Max:i\d+>> Max [<<Min>>,<<Clp1>>] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Conv:s\d+>> TypeConversion [<<Max>>] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: ArraySet [{{l\d+}},<<Phi>>,<<Conv>>] loop:<<Loop>> outer_loop:none - // - /// CHECK-START-{ARM,ARM64}: void Main.satAlt1(short[], short[], short[]) loop_optimization (after) - /// CHECK-DAG: <<Get1:d\d+>> VecLoad [{{l\d+}},<<Phi:i\d+>>] loop:<<Loop:B\d+>> outer_loop:none - /// CHECK-DAG: <<Get2:d\d+>> VecLoad [{{l\d+}},<<Phi>>] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Add:d\d+>> VecSaturationAdd [<<Get1>>,<<Get2>>] packed_type:Int16 loop:<<Loop>> outer_loop:none - /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<Add>>] loop:<<Loop>> outer_loop:none - public static void satAlt1(short[] a, short[] b, short[] c) { - int n = Math.min(a.length, Math.min(b.length, c.length)); - for (int i = 0; i < n; i++) { - int s = a[i] + b[i]; - if (s > 32767) { - s = 32767; - } - if (s < -32768) { - s = -32768; - } - c[i] = (short) s; - } - } - - /// CHECK-START: void Main.satAlt2(short[], short[], short[]) loop_optimization (before) - /// CHECK-DAG: <<Clp1:i\d+>> IntConstant -32768 loop:none - /// CHECK-DAG: <<Clp2:i\d+>> IntConstant 32767 loop:none - /// CHECK-DAG: <<Get1:s\d+>> ArrayGet [{{l\d+}},<<Phi:i\d+>>] loop:<<Loop:B\d+>> outer_loop:none - /// CHECK-DAG: <<Get2:s\d+>> ArrayGet [{{l\d+}},<<Phi>>] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Add:i\d+>> Add [<<Get1>>,<<Get2>>] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Max:i\d+>> Max [<<Add>>,<<Clp1>>] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Min:i\d+>> Min [<<Max>>,<<Clp2>>] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Conv:s\d+>> TypeConversion [<<Min>>] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: ArraySet [{{l\d+}},<<Phi>>,<<Conv>>] loop:<<Loop>> outer_loop:none - // - /// CHECK-START-{ARM,ARM64}: void Main.satAlt2(short[], short[], short[]) loop_optimization (after) - /// CHECK-DAG: <<Get1:d\d+>> VecLoad [{{l\d+}},<<Phi:i\d+>>] loop:<<Loop:B\d+>> outer_loop:none - /// CHECK-DAG: <<Get2:d\d+>> VecLoad [{{l\d+}},<<Phi>>] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Add:d\d+>> VecSaturationAdd [<<Get1>>,<<Get2>>] packed_type:Int16 loop:<<Loop>> outer_loop:none - /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<Add>>] loop:<<Loop>> outer_loop:none - public static void satAlt2(short[] a, short[] b, short[] c) { - int n = Math.min(a.length, Math.min(b.length, c.length)); - for (int i = 0; i < n; i++) { - int s = a[i] + b[i]; - if (s > 32767) { - s = 32767; - } else if (s < -32768) { - s = -32768; - } - c[i] = (short) s; - } - } - - /// CHECK-START-{ARM,ARM64}: void Main.satAlt3(short[], short[], short[]) loop_optimization (after) - /// CHECK-DAG: <<Get1:d\d+>> VecLoad [{{l\d+}},<<Phi:i\d+>>] loop:<<Loop:B\d+>> outer_loop:none - /// CHECK-DAG: <<Get2:d\d+>> VecLoad [{{l\d+}},<<Phi>>] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Add:d\d+>> VecSaturationAdd [<<Get1>>,<<Get2>>] packed_type:Int16 loop:<<Loop>> outer_loop:none - /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<Add>>] loop:<<Loop>> outer_loop:none - public static void satAlt3(short[] a, short[] b, short[] c) { - int n = Math.min(a.length, Math.min(b.length, c.length)); - for (int i = 0; i < n; i++) { - int s = a[i] + b[i]; - s = (s > 32767) ? 32767 : ((s < -32768) ? -32768 : s); - c[i] = (short) s; - } - } - - /// CHECK-START-{ARM,ARM64}: void Main.usatAlt1(short[], short[], short[]) loop_optimization (after) - /// CHECK-DAG: <<Get1:d\d+>> VecLoad [{{l\d+}},<<Phi:i\d+>>] loop:<<Loop:B\d+>> outer_loop:none - /// CHECK-DAG: <<Get2:d\d+>> VecLoad [{{l\d+}},<<Phi>>] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Add:d\d+>> VecSaturationAdd [<<Get1>>,<<Get2>>] packed_type:Uint16 loop:<<Loop>> outer_loop:none - /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<Add>>] loop:<<Loop>> outer_loop:none - public static void usatAlt1(short[] a, short[] b, short[] c) { - int n = Math.min(a.length, Math.min(b.length, c.length)); - for (int i = 0; i < n; i++) { - int t = (0xffff & a[i]) + (0xffff & b[i]); - c[i] = (short) (t <= 65535 ? t : 65535); - } - } - - /// CHECK-START-{ARM,ARM64}: void Main.usatAlt2(short[], short[], short[]) loop_optimization (after) - /// CHECK-DAG: <<Get1:d\d+>> VecLoad [{{l\d+}},<<Phi:i\d+>>] loop:<<Loop:B\d+>> outer_loop:none - /// CHECK-DAG: <<Get2:d\d+>> VecLoad [{{l\d+}},<<Phi>>] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Add:d\d+>> VecSaturationAdd [<<Get1>>,<<Get2>>] packed_type:Uint16 loop:<<Loop>> outer_loop:none - /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<Add>>] loop:<<Loop>> outer_loop:none - public static void usatAlt2(short[] a, short[] b, short[] c) { - int n = Math.min(a.length, Math.min(b.length, c.length)); - for (int i = 0; i < n; i++) { - int t = (a[i] & 0xffff) + (b[i] & 0xffff); - c[i] = (short) (t < 65535 ? t : 65535); - } - } - - /// CHECK-START-{ARM,ARM64}: void Main.usatAlt3(short[], short[], short[]) loop_optimization (after) - /// CHECK-DAG: <<Get1:d\d+>> VecLoad [{{l\d+}},<<Phi:i\d+>>] loop:<<Loop:B\d+>> outer_loop:none - /// CHECK-DAG: <<Get2:d\d+>> VecLoad [{{l\d+}},<<Phi>>] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Add:d\d+>> VecSaturationAdd [<<Get2>>,<<Get1>>] packed_type:Uint16 loop:<<Loop>> outer_loop:none - /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<Add>>] loop:<<Loop>> outer_loop:none - public static void usatAlt3(short[] a, short[] b, short[] c) { - int n = Math.min(a.length, Math.min(b.length, c.length)); - for (int i = 0; i < n; i++) { - int x = (a[i] & 0xffff); - int y = (b[i] & 0xffff); - int t = y + x ; - if (t >= 65535) t = 65535; - c[i] = (short) t; - } - } - - /// CHECK-START-{ARM,ARM64}: void Main.usatAlt4(short[], short[], short[]) loop_optimization (after) - /// CHECK-DAG: <<Get1:d\d+>> VecLoad [{{l\d+}},<<Phi:i\d+>>] loop:<<Loop:B\d+>> outer_loop:none - /// CHECK-DAG: <<Get2:d\d+>> VecLoad [{{l\d+}},<<Phi>>] loop:<<Loop>> outer_loop:none - /// CHECK-DAG: <<Add:d\d+>> VecSaturationAdd [<<Get2>>,<<Get1>>] packed_type:Uint16 loop:<<Loop>> outer_loop:none - /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<Add>>] loop:<<Loop>> outer_loop:none - public static void usatAlt4(short[] a, short[] b, short[] c) { - int n = Math.min(a.length, Math.min(b.length, c.length)); - for (int i = 0; i < n; i++) { - int x = (a[i] & 0xffff); - int y = (b[i] & 0xffff); - int t = y + x ; - if (t > 65535) t = 65535; - c[i] = (short) t; - } - } - - /// CHECK-START-{ARM,ARM64}: void Main.satRedundantClip(short[], short[]) loop_optimization (after) - /// CHECK-DAG: <<Get1:d\d+>> VecReplicateScalar loop:none - /// CHECK-DAG: <<Get2:d\d+>> VecLoad [{{l\d+}},<<Phi:i\d+>>] loop:<<Loop:B\d+>> outer_loop:none - /// CHECK-DAG: <<Add:d\d+>> VecSaturationAdd [<<Get2>>,<<Get1>>] packed_type:Int16 loop:<<Loop>> outer_loop:none - /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<Add>>] loop:<<Loop>> outer_loop:none - public static void satRedundantClip(short[] a, short[] b) { - int n = Math.min(a.length, b.length); - for (int i = 0; i < n; i++) { - // Max clipping redundant. - b[i] = (short) Math.max(Math.min(a[i] + 15, 32767), -32768 + 15); - } - } - - /// CHECK-START: void Main.satNonRedundantClip(short[], short[]) loop_optimization (after) - /// CHECK-NOT: VecSaturationAdd - public static void satNonRedundantClip(short[] a, short[] b) { - int n = Math.min(a.length, b.length); - for (int i = 0; i < n; i++) { - // Max clipping not redundant (one off). - b[i] = (short) Math.max(Math.min(a[i] + 15, 32767), -32768 + 16); - } - } - - /// CHECK-START-{ARM,ARM64}: void Main.usatSubConst(short[], short[]) loop_optimization (after) - /// CHECK-DAG: <<Get1:d\d+>> VecReplicateScalar loop:none - /// CHECK-DAG: <<Get2:d\d+>> VecLoad [{{l\d+}},<<Phi:i\d+>>] loop:<<Loop:B\d+>> outer_loop:none - /// CHECK-DAG: <<Sub:d\d+>> VecSaturationSub [<<Get2>>,<<Get1>>] packed_type:Uint16 loop:<<Loop>> outer_loop:none - /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<Sub>>] loop:<<Loop>> outer_loop:none - public static void usatSubConst(short[] a, short[] b) { - int n = Math.min(a.length, b.length); - for (int i = 0; i < n; i++) { - int t = a[i] & 0xffff; - int s = t - $inline$p15(); - b[i] = (short)(s > 0 ? s : 0); - } - } - - /// CHECK-START-{ARM,ARM64}: void Main.usatSubConstAlt(short[], short[]) loop_optimization (after) - /// CHECK-DAG: <<Get1:d\d+>> VecReplicateScalar loop:none - /// CHECK-DAG: <<Get2:d\d+>> VecLoad [{{l\d+}},<<Phi:i\d+>>] loop:<<Loop:B\d+>> outer_loop:none - /// CHECK-DAG: <<Sub:d\d+>> VecSaturationSub [<<Get2>>,<<Get1>>] packed_type:Uint16 loop:<<Loop>> outer_loop:none - /// CHECK-DAG: VecStore [{{l\d+}},<<Phi>>,<<Sub>>] loop:<<Loop>> outer_loop:none - public static void usatSubConstAlt(short[] a, short[] b) { - int n = Math.min(a.length, b.length); - for (int i = 0; i < n; i++) { - int t = a[i] & 0xffff; - int s = t + $inline$m15(); - b[i] = (short)(s > 0 ? s : 0); - } - } - - // - // Test drivers. - // - - private static void test08Bit() { - // Use cross-values to test all cases. - int n = 256; - int m = n * n; - int k = 0; - byte[] b1 = new byte[m]; - byte[] b2 = new byte[m]; - for (int i = 0; i < n; i++) { - for (int j = 0; j < n; j++) { - b1[k] = (byte) i; - b2[k] = (byte) j; - k++; - } - } - // Tests. - byte[] out = new byte[m]; - satAddUByte(b1, b2, out); - for (int i = 0; i < m; i++) { - byte e = (byte) Math.min((b1[i] & 0xff) + (b2[i] & 0xff), 255); - expectEquals(e, out[i]); - } - satAddSByte( b1, b2, out); - for (int i = 0; i < m; i++) { - byte e = (byte) Math.max(Math.min(b1[i] + b2[i], 127), -128); - expectEquals(e, out[i]); - } - satSubUByte(b1, b2, out); - for (int i = 0; i < m; i++) { - byte e = (byte) Math.max((b1[i] & 0xff) - (b2[i] & 0xff), 0); - expectEquals(e, out[i]); - } - satSubSByte(b1, b2, out); - for (int i = 0; i < m; i++) { - byte e = (byte) Math.max(Math.min(b1[i] - b2[i], 127), -128); - expectEquals(e, out[i]); - } - // Single clipping. - satAddPConstSByte(b1, out); - for (int i = 0; i < m; i++) { - byte e = (byte) Math.min(b1[i] + 15, 127); - expectEquals(e, out[i]); - } - satAddNConstSByte(b1, out); - for (int i = 0; i < m; i++) { - byte e = (byte) Math.max(b1[i] - 15, -128); - expectEquals(e, out[i]); - } - satSubPConstSByte(b1, out); - for (int i = 0; i < m; i++) { - byte e = (byte) Math.min(15 - b1[i], 127); - expectEquals(e, out[i]); - } - satSubNConstSByte(b1, out); - for (int i = 0; i < m; i++) { - byte e = (byte) Math.max(-15 - b1[i], -128); - expectEquals(e, out[i]); - } - // Alternatives. - usatAddConst(b1, out); - for (int i = 0; i < m; i++) { - byte e = (byte) Math.min((b1[i] & 0xff) + 15, 255); - expectEquals(e, out[i]); - } - usatAddConstAlt(b1, out); - for (int i = 0; i < m; i++) { - byte e = (byte) Math.min((b1[i] & 0xff) + 15, 255); - expectEquals(e, out[i]); - } - usatSubConst(b1, out); - for (int i = 0; i < m; i++) { - byte e = (byte) Math.max((b1[i] & 0xff) - 15, 0); - expectEquals(e, out[i]); - } - usatSubConstAlt(b1, out); - for (int i = 0; i < m; i++) { - byte e = (byte) Math.max((b1[i] & 0xff) - 15, 0); - expectEquals(e, out[i]); - } - } - - private static void test16Bit() { - // Use cross-values to test interesting cases. - short[] interesting = { - (short) 0x0000, - (short) 0x0001, - (short) 0x0002, - (short) 0x0003, - (short) 0x0004, - (short) 0x007f, - (short) 0x0080, - (short) 0x00ff, - (short) 0x7f00, - (short) 0x7f7f, - (short) 0x7f80, - (short) 0x7fff, - (short) 0x8000, - (short) 0x807f, - (short) 0x8080, - (short) 0x80ff, - (short) 0xff00, - (short) 0xff7f, - (short) 0xff80, - (short) 0xffff, - }; - int n = interesting.length; - int m = n * n; - short[] s1 = new short[m]; - short[] s2 = new short[m]; - int k = 0; - for (int i = 0; i < n; i++) { - for (int j = 0; j < n; j++) { - s1[k] = interesting[i]; - s2[k] = interesting[j]; - k++; - } - } - // Tests. - short[] out = new short[m]; - satAddUShort(s1, s2, out); - for (int i = 0; i < m; i++) { - short e = (short) Math.min((s1[i] & 0xffff) + (s2[i] & 0xffff), 65535); - expectEquals(e, out[i]); - } - satAddSShort(s1, s2, out); - for (int i = 0; i < m; i++) { - short e = (short) Math.max(Math.min(s1[i] + s2[i], 32767), -32768); - expectEquals(e, out[i]); - } - satSubUShort(s1, s2, out); - for (int i = 0; i < m; i++) { - short e = (short) Math.max((s1[i] & 0xffff) - (s2[i] & 0xffff), 0); - expectEquals(e, out[i]); - } - satSubSShort(s1, s2, out); - for (int i = 0; i < m; i++) { - short e = (short) Math.max(Math.min(s1[i] - s2[i], 32767), -32768); - expectEquals(e, out[i]); - } - // Single clipping. - satAddPConstSShort(s1, out); - for (int i = 0; i < m; i++) { - short e = (short) Math.min(s1[i] + 15, 32767); - expectEquals(e, out[i]); - } - satAddNConstSShort(s1, out); - for (int i = 0; i < m; i++) { - short e = (short) Math.max(s1[i] - 15, -32768); - expectEquals(e, out[i]); - } - satSubPConstSShort(s1, out); - for (int i = 0; i < m; i++) { - short e = (short) Math.min(15 - s1[i], 32767); - expectEquals(e, out[i]); - } - satSubNConstSShort(s1, out); - for (int i = 0; i < m; i++) { - short e = (short) Math.max(-15 - s1[i], -32768); - expectEquals(e, out[i]); - } - // Alternatives. - satAlt1(s1, s2, out); - for (int i = 0; i < m; i++) { - short e = (short) Math.max(Math.min(s1[i] + s2[i], 32767), -32768); - expectEquals(e, out[i]); - } - satAlt2(s1, s2, out); - for (int i = 0; i < m; i++) { - short e = (short) Math.max(Math.min(s1[i] + s2[i], 32767), -32768); - expectEquals(e, out[i]); - } - satAlt3(s1, s2, out); - for (int i = 0; i < m; i++) { - short e = (short) Math.max(Math.min(s1[i] + s2[i], 32767), -32768); - expectEquals(e, out[i]); - } - usatAlt1(s1, s2, out); - for (int i = 0; i < m; i++) { - short e = (short) Math.min((s1[i] & 0xffff) + (s2[i] & 0xffff), 65535); - expectEquals(e, out[i]); - } - usatAlt2(s1, s2, out); - for (int i = 0; i < m; i++) { - short e = (short) Math.min((s1[i] & 0xffff) + (s2[i] & 0xffff), 65535); - expectEquals(e, out[i]); - } - usatAlt3(s1, s2, out); - for (int i = 0; i < m; i++) { - short e = (short) Math.min((s1[i] & 0xffff) + (s2[i] & 0xffff), 65535); - expectEquals(e, out[i]); - } - usatAlt4(s1, s2, out); - for (int i = 0; i < m; i++) { - short e = (short) Math.min((s1[i] & 0xffff) + (s2[i] & 0xffff), 65535); - expectEquals(e, out[i]); - } - satRedundantClip(s1, out); - for (int i = 0; i < m; i++) { - short e = (short) Math.min(s1[i] + 15, 32767); - expectEquals(e, out[i]); - } - satNonRedundantClip(s1, out); - for (int i = 0; i < m; i++) { - short e = (short) Math.max(Math.min(s1[i] + 15, 32767), -32752); - expectEquals(e, out[i]); - } - usatSubConst(s1, out); - for (int i = 0; i < m; i++) { - short e = (short) Math.max((s1[i] & 0xffff) - 15, 0); - expectEquals(e, out[i]); - } - usatSubConstAlt(s1, out); - for (int i = 0; i < m; i++) { - short e = (short) Math.max((s1[i] & 0xffff) - 15, 0); - expectEquals(e, out[i]); - } - } - - public static void main(String[] args) { - test08Bit(); - test16Bit(); - System.out.println("passed"); - } - - private static void expectEquals(int expected, int result) { - if (expected != result) { - throw new Error("Expected: " + expected + ", found: " + result); - } - } -} |