diff options
5 files changed, 352 insertions, 0 deletions
diff --git a/compiler/optimizing/constant_folding.cc b/compiler/optimizing/constant_folding.cc index e20d9e83e6..5506604e9e 100644 --- a/compiler/optimizing/constant_folding.cc +++ b/compiler/optimizing/constant_folding.cc @@ -19,6 +19,7 @@ #include <algorithm> #include "dex/dex_file-inl.h" +#include "intrinsics_enum.h" #include "optimizing/data_type.h" #include "optimizing/nodes.h" @@ -47,10 +48,15 @@ class HConstantFoldingVisitor final : public HGraphDelegateVisitor { void VisitArrayLength(HArrayLength* inst) override; void VisitDivZeroCheck(HDivZeroCheck* inst) override; void VisitIf(HIf* inst) override; + void VisitInvoke(HInvoke* inst) override; void VisitTypeConversion(HTypeConversion* inst) override; void PropagateValue(HBasicBlock* starting_block, HInstruction* variable, HConstant* constant); + // Intrinsics foldings + void FoldNumberOfLeadingZerosIntrinsic(HInvoke* invoke); + void FoldNumberOfTrailingZerosIntrinsic(HInvoke* invoke); + // Use all optimizations without restrictions. bool use_all_optimizations_; @@ -350,6 +356,63 @@ void HConstantFoldingVisitor::VisitIf(HIf* inst) { } } +void HConstantFoldingVisitor::VisitInvoke(HInvoke* inst) { + switch (inst->GetIntrinsic()) { + case Intrinsics::kIntegerNumberOfLeadingZeros: + case Intrinsics::kLongNumberOfLeadingZeros: + FoldNumberOfLeadingZerosIntrinsic(inst); + break; + case Intrinsics::kIntegerNumberOfTrailingZeros: + case Intrinsics::kLongNumberOfTrailingZeros: + FoldNumberOfTrailingZerosIntrinsic(inst); + break; + default: + break; + } +} + +void HConstantFoldingVisitor::FoldNumberOfLeadingZerosIntrinsic(HInvoke* inst) { + DCHECK(inst->GetIntrinsic() == Intrinsics::kIntegerNumberOfLeadingZeros || + inst->GetIntrinsic() == Intrinsics::kLongNumberOfLeadingZeros); + + if (!inst->InputAt(0)->IsConstant()) { + return; + } + + DCHECK_IMPLIES(inst->GetIntrinsic() == Intrinsics::kIntegerNumberOfLeadingZeros, + inst->InputAt(0)->IsIntConstant()); + DCHECK_IMPLIES(inst->GetIntrinsic() == Intrinsics::kLongNumberOfLeadingZeros, + inst->InputAt(0)->IsLongConstant()); + + // Note that both the Integer and Long intrinsics return an int as a result. + int result = inst->InputAt(0)->IsIntConstant() ? + JAVASTYLE_CLZ(inst->InputAt(0)->AsIntConstant()->GetValue()) : + JAVASTYLE_CLZ(inst->InputAt(0)->AsLongConstant()->GetValue()); + inst->ReplaceWith(GetGraph()->GetIntConstant(result)); + inst->GetBlock()->RemoveInstruction(inst); +} + +void HConstantFoldingVisitor::FoldNumberOfTrailingZerosIntrinsic(HInvoke* inst) { + DCHECK(inst->GetIntrinsic() == Intrinsics::kIntegerNumberOfTrailingZeros || + inst->GetIntrinsic() == Intrinsics::kLongNumberOfTrailingZeros); + + if (!inst->InputAt(0)->IsConstant()) { + return; + } + + DCHECK_IMPLIES(inst->GetIntrinsic() == Intrinsics::kIntegerNumberOfTrailingZeros, + inst->InputAt(0)->IsIntConstant()); + DCHECK_IMPLIES(inst->GetIntrinsic() == Intrinsics::kLongNumberOfTrailingZeros, + inst->InputAt(0)->IsLongConstant()); + + // Note that both the Integer and Long intrinsics return an int as a result. + int result = inst->InputAt(0)->IsIntConstant() ? + JAVASTYLE_CTZ(inst->InputAt(0)->AsIntConstant()->GetValue()) : + JAVASTYLE_CTZ(inst->InputAt(0)->AsLongConstant()->GetValue()); + inst->ReplaceWith(GetGraph()->GetIntConstant(result)); + inst->GetBlock()->RemoveInstruction(inst); +} + void HConstantFoldingVisitor::VisitArrayLength(HArrayLength* inst) { HInstruction* input = inst->InputAt(0); if (input->IsLoadString()) { diff --git a/test/2269-checker-constant-folding-instrinsics/expected-stderr.txt b/test/2269-checker-constant-folding-instrinsics/expected-stderr.txt new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/test/2269-checker-constant-folding-instrinsics/expected-stderr.txt diff --git a/test/2269-checker-constant-folding-instrinsics/expected-stdout.txt b/test/2269-checker-constant-folding-instrinsics/expected-stdout.txt new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/test/2269-checker-constant-folding-instrinsics/expected-stdout.txt diff --git a/test/2269-checker-constant-folding-instrinsics/info.txt b/test/2269-checker-constant-folding-instrinsics/info.txt new file mode 100644 index 0000000000..a76788216d --- /dev/null +++ b/test/2269-checker-constant-folding-instrinsics/info.txt @@ -0,0 +1 @@ +Tests we properly optimize intrinsics during constant folding diff --git a/test/2269-checker-constant-folding-instrinsics/src/Main.java b/test/2269-checker-constant-folding-instrinsics/src/Main.java new file mode 100644 index 0000000000..5ee9d05b6f --- /dev/null +++ b/test/2269-checker-constant-folding-instrinsics/src/Main.java @@ -0,0 +1,288 @@ +/* + * Copyright (C) 2023 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) { + $noinline$testLeadingZerosInt(); + $noinline$testLeadingZerosLong(); + $noinline$testTrailingZerosInt(); + $noinline$testTrailingZerosLong(); + } + + /// CHECK-START: void Main.$noinline$testLeadingZerosInt() constant_folding (before) + /// CHECK-DAG: InvokeStaticOrDirect intrinsic:IntegerNumberOfLeadingZeros + + /// CHECK-START: void Main.$noinline$testLeadingZerosInt() constant_folding (after) + /// CHECK-NOT: InvokeStaticOrDirect intrinsic:IntegerNumberOfLeadingZeros + private static void $noinline$testLeadingZerosInt() { + $noinline$assertIntEquals(32, Integer.numberOfLeadingZeros(0)); + $noinline$assertIntEquals(31, Integer.numberOfLeadingZeros(1 << 0)); + $noinline$assertIntEquals(30, Integer.numberOfLeadingZeros(1 << 1)); + $noinline$assertIntEquals(29, Integer.numberOfLeadingZeros(1 << 2)); + $noinline$assertIntEquals(28, Integer.numberOfLeadingZeros(1 << 3)); + $noinline$assertIntEquals(27, Integer.numberOfLeadingZeros(1 << 4)); + $noinline$assertIntEquals(26, Integer.numberOfLeadingZeros(1 << 5)); + $noinline$assertIntEquals(25, Integer.numberOfLeadingZeros(1 << 6)); + $noinline$assertIntEquals(24, Integer.numberOfLeadingZeros(1 << 7)); + $noinline$assertIntEquals(23, Integer.numberOfLeadingZeros(1 << 8)); + $noinline$assertIntEquals(22, Integer.numberOfLeadingZeros(1 << 9)); + $noinline$assertIntEquals(21, Integer.numberOfLeadingZeros(1 << 10)); + $noinline$assertIntEquals(20, Integer.numberOfLeadingZeros(1 << 11)); + $noinline$assertIntEquals(19, Integer.numberOfLeadingZeros(1 << 12)); + $noinline$assertIntEquals(18, Integer.numberOfLeadingZeros(1 << 13)); + $noinline$assertIntEquals(17, Integer.numberOfLeadingZeros(1 << 14)); + $noinline$assertIntEquals(16, Integer.numberOfLeadingZeros(1 << 15)); + $noinline$assertIntEquals(15, Integer.numberOfLeadingZeros(1 << 16)); + $noinline$assertIntEquals(14, Integer.numberOfLeadingZeros(1 << 17)); + $noinline$assertIntEquals(13, Integer.numberOfLeadingZeros(1 << 18)); + $noinline$assertIntEquals(12, Integer.numberOfLeadingZeros(1 << 19)); + $noinline$assertIntEquals(11, Integer.numberOfLeadingZeros(1 << 20)); + $noinline$assertIntEquals(10, Integer.numberOfLeadingZeros(1 << 21)); + $noinline$assertIntEquals(9, Integer.numberOfLeadingZeros(1 << 22)); + $noinline$assertIntEquals(8, Integer.numberOfLeadingZeros(1 << 23)); + $noinline$assertIntEquals(7, Integer.numberOfLeadingZeros(1 << 24)); + $noinline$assertIntEquals(6, Integer.numberOfLeadingZeros(1 << 25)); + $noinline$assertIntEquals(5, Integer.numberOfLeadingZeros(1 << 26)); + $noinline$assertIntEquals(4, Integer.numberOfLeadingZeros(1 << 27)); + $noinline$assertIntEquals(3, Integer.numberOfLeadingZeros(1 << 28)); + $noinline$assertIntEquals(2, Integer.numberOfLeadingZeros(1 << 29)); + $noinline$assertIntEquals(1, Integer.numberOfLeadingZeros(1 << 30)); + $noinline$assertIntEquals(0, Integer.numberOfLeadingZeros(1 << 31)); + } + + private static void $noinline$testLeadingZerosLong() { + // We need to do two smaller methods because otherwise we don't compile it due to our + // heuristics. + $noinline$testLeadingZerosLongFirst32(); + $noinline$testLeadingZerosLongLast32(); + } + + /// CHECK-START: void Main.$noinline$testLeadingZerosLongFirst32() constant_folding (before) + /// CHECK-DAG: InvokeStaticOrDirect intrinsic:LongNumberOfLeadingZeros + + /// CHECK-START: void Main.$noinline$testLeadingZerosLongFirst32() constant_folding (after) + /// CHECK-NOT: InvokeStaticOrDirect intrinsic:LongNumberOfLeadingZeros + private static void $noinline$testLeadingZerosLongFirst32() { + $noinline$assertIntEquals(64, Long.numberOfLeadingZeros(0L)); + $noinline$assertIntEquals(63, Long.numberOfLeadingZeros(1L << 0L)); + $noinline$assertIntEquals(62, Long.numberOfLeadingZeros(1L << 1L)); + $noinline$assertIntEquals(61, Long.numberOfLeadingZeros(1L << 2L)); + $noinline$assertIntEquals(60, Long.numberOfLeadingZeros(1L << 3L)); + $noinline$assertIntEquals(59, Long.numberOfLeadingZeros(1L << 4L)); + $noinline$assertIntEquals(58, Long.numberOfLeadingZeros(1L << 5L)); + $noinline$assertIntEquals(57, Long.numberOfLeadingZeros(1L << 6L)); + $noinline$assertIntEquals(56, Long.numberOfLeadingZeros(1L << 7L)); + $noinline$assertIntEquals(55, Long.numberOfLeadingZeros(1L << 8L)); + $noinline$assertIntEquals(54, Long.numberOfLeadingZeros(1L << 9L)); + $noinline$assertIntEquals(53, Long.numberOfLeadingZeros(1L << 10L)); + $noinline$assertIntEquals(52, Long.numberOfLeadingZeros(1L << 11L)); + $noinline$assertIntEquals(51, Long.numberOfLeadingZeros(1L << 12L)); + $noinline$assertIntEquals(50, Long.numberOfLeadingZeros(1L << 13L)); + $noinline$assertIntEquals(49, Long.numberOfLeadingZeros(1L << 14L)); + $noinline$assertIntEquals(48, Long.numberOfLeadingZeros(1L << 15L)); + $noinline$assertIntEquals(47, Long.numberOfLeadingZeros(1L << 16L)); + $noinline$assertIntEquals(46, Long.numberOfLeadingZeros(1L << 17L)); + $noinline$assertIntEquals(45, Long.numberOfLeadingZeros(1L << 18L)); + $noinline$assertIntEquals(44, Long.numberOfLeadingZeros(1L << 19L)); + $noinline$assertIntEquals(43, Long.numberOfLeadingZeros(1L << 20L)); + $noinline$assertIntEquals(42, Long.numberOfLeadingZeros(1L << 21L)); + $noinline$assertIntEquals(41, Long.numberOfLeadingZeros(1L << 22L)); + $noinline$assertIntEquals(40, Long.numberOfLeadingZeros(1L << 23L)); + $noinline$assertIntEquals(39, Long.numberOfLeadingZeros(1L << 24L)); + $noinline$assertIntEquals(38, Long.numberOfLeadingZeros(1L << 25L)); + $noinline$assertIntEquals(37, Long.numberOfLeadingZeros(1L << 26L)); + $noinline$assertIntEquals(36, Long.numberOfLeadingZeros(1L << 27L)); + $noinline$assertIntEquals(35, Long.numberOfLeadingZeros(1L << 28L)); + $noinline$assertIntEquals(34, Long.numberOfLeadingZeros(1L << 29L)); + $noinline$assertIntEquals(33, Long.numberOfLeadingZeros(1L << 30L)); + } + + /// CHECK-START: void Main.$noinline$testLeadingZerosLongLast32() constant_folding (before) + /// CHECK-DAG: InvokeStaticOrDirect intrinsic:LongNumberOfLeadingZeros + + /// CHECK-START: void Main.$noinline$testLeadingZerosLongLast32() constant_folding (after) + /// CHECK-NOT: InvokeStaticOrDirect intrinsic:LongNumberOfLeadingZeros + private static void $noinline$testLeadingZerosLongLast32() { + $noinline$assertIntEquals(32, Long.numberOfLeadingZeros(1L << 31L)); + $noinline$assertIntEquals(31, Long.numberOfLeadingZeros(1L << 32L)); + $noinline$assertIntEquals(30, Long.numberOfLeadingZeros(1L << 33L)); + $noinline$assertIntEquals(29, Long.numberOfLeadingZeros(1L << 34L)); + $noinline$assertIntEquals(28, Long.numberOfLeadingZeros(1L << 35L)); + $noinline$assertIntEquals(27, Long.numberOfLeadingZeros(1L << 36L)); + $noinline$assertIntEquals(26, Long.numberOfLeadingZeros(1L << 37L)); + $noinline$assertIntEquals(25, Long.numberOfLeadingZeros(1L << 38L)); + $noinline$assertIntEquals(24, Long.numberOfLeadingZeros(1L << 39L)); + $noinline$assertIntEquals(23, Long.numberOfLeadingZeros(1L << 40L)); + $noinline$assertIntEquals(22, Long.numberOfLeadingZeros(1L << 41L)); + $noinline$assertIntEquals(21, Long.numberOfLeadingZeros(1L << 42L)); + $noinline$assertIntEquals(20, Long.numberOfLeadingZeros(1L << 43L)); + $noinline$assertIntEquals(19, Long.numberOfLeadingZeros(1L << 44L)); + $noinline$assertIntEquals(18, Long.numberOfLeadingZeros(1L << 45L)); + $noinline$assertIntEquals(17, Long.numberOfLeadingZeros(1L << 46L)); + $noinline$assertIntEquals(16, Long.numberOfLeadingZeros(1L << 47L)); + $noinline$assertIntEquals(15, Long.numberOfLeadingZeros(1L << 48L)); + $noinline$assertIntEquals(14, Long.numberOfLeadingZeros(1L << 49L)); + $noinline$assertIntEquals(13, Long.numberOfLeadingZeros(1L << 50L)); + $noinline$assertIntEquals(12, Long.numberOfLeadingZeros(1L << 51L)); + $noinline$assertIntEquals(11, Long.numberOfLeadingZeros(1L << 52L)); + $noinline$assertIntEquals(10, Long.numberOfLeadingZeros(1L << 53L)); + $noinline$assertIntEquals(9, Long.numberOfLeadingZeros(1L << 54L)); + $noinline$assertIntEquals(8, Long.numberOfLeadingZeros(1L << 55L)); + $noinline$assertIntEquals(7, Long.numberOfLeadingZeros(1L << 56L)); + $noinline$assertIntEquals(6, Long.numberOfLeadingZeros(1L << 57L)); + $noinline$assertIntEquals(5, Long.numberOfLeadingZeros(1L << 58L)); + $noinline$assertIntEquals(4, Long.numberOfLeadingZeros(1L << 59L)); + $noinline$assertIntEquals(3, Long.numberOfLeadingZeros(1L << 60L)); + $noinline$assertIntEquals(2, Long.numberOfLeadingZeros(1L << 61L)); + $noinline$assertIntEquals(1, Long.numberOfLeadingZeros(1L << 62L)); + $noinline$assertIntEquals(0, Long.numberOfLeadingZeros(1L << 63L)); + } + + /// CHECK-START: void Main.$noinline$testTrailingZerosInt() constant_folding (before) + /// CHECK-DAG: InvokeStaticOrDirect intrinsic:IntegerNumberOfTrailingZeros + + /// CHECK-START: void Main.$noinline$testTrailingZerosInt() constant_folding (after) + /// CHECK-NOT: InvokeStaticOrDirect intrinsic:IntegerNumberOfTrailingZeros + private static void $noinline$testTrailingZerosInt() { + $noinline$assertIntEquals(32, Integer.numberOfTrailingZeros(0)); + $noinline$assertIntEquals(0, Integer.numberOfTrailingZeros(1 << 0)); + $noinline$assertIntEquals(1, Integer.numberOfTrailingZeros(1 << 1)); + $noinline$assertIntEquals(2, Integer.numberOfTrailingZeros(1 << 2)); + $noinline$assertIntEquals(3, Integer.numberOfTrailingZeros(1 << 3)); + $noinline$assertIntEquals(4, Integer.numberOfTrailingZeros(1 << 4)); + $noinline$assertIntEquals(5, Integer.numberOfTrailingZeros(1 << 5)); + $noinline$assertIntEquals(6, Integer.numberOfTrailingZeros(1 << 6)); + $noinline$assertIntEquals(7, Integer.numberOfTrailingZeros(1 << 7)); + $noinline$assertIntEquals(8, Integer.numberOfTrailingZeros(1 << 8)); + $noinline$assertIntEquals(9, Integer.numberOfTrailingZeros(1 << 9)); + $noinline$assertIntEquals(10, Integer.numberOfTrailingZeros(1 << 10)); + $noinline$assertIntEquals(11, Integer.numberOfTrailingZeros(1 << 11)); + $noinline$assertIntEquals(12, Integer.numberOfTrailingZeros(1 << 12)); + $noinline$assertIntEquals(13, Integer.numberOfTrailingZeros(1 << 13)); + $noinline$assertIntEquals(14, Integer.numberOfTrailingZeros(1 << 14)); + $noinline$assertIntEquals(15, Integer.numberOfTrailingZeros(1 << 15)); + $noinline$assertIntEquals(16, Integer.numberOfTrailingZeros(1 << 16)); + $noinline$assertIntEquals(17, Integer.numberOfTrailingZeros(1 << 17)); + $noinline$assertIntEquals(18, Integer.numberOfTrailingZeros(1 << 18)); + $noinline$assertIntEquals(19, Integer.numberOfTrailingZeros(1 << 19)); + $noinline$assertIntEquals(20, Integer.numberOfTrailingZeros(1 << 20)); + $noinline$assertIntEquals(21, Integer.numberOfTrailingZeros(1 << 21)); + $noinline$assertIntEquals(22, Integer.numberOfTrailingZeros(1 << 22)); + $noinline$assertIntEquals(23, Integer.numberOfTrailingZeros(1 << 23)); + $noinline$assertIntEquals(24, Integer.numberOfTrailingZeros(1 << 24)); + $noinline$assertIntEquals(25, Integer.numberOfTrailingZeros(1 << 25)); + $noinline$assertIntEquals(26, Integer.numberOfTrailingZeros(1 << 26)); + $noinline$assertIntEquals(27, Integer.numberOfTrailingZeros(1 << 27)); + $noinline$assertIntEquals(28, Integer.numberOfTrailingZeros(1 << 28)); + $noinline$assertIntEquals(29, Integer.numberOfTrailingZeros(1 << 29)); + $noinline$assertIntEquals(30, Integer.numberOfTrailingZeros(1 << 30)); + $noinline$assertIntEquals(31, Integer.numberOfTrailingZeros(1 << 31)); + } + + private static void $noinline$testTrailingZerosLong() { + // We need to do two smaller methods because otherwise we don't compile it due to our + // heuristics. + $noinline$testTrailingZerosLongFirst32(); + $noinline$testTrailingZerosLongLast32(); + } + + /// CHECK-START: void Main.$noinline$testTrailingZerosLongFirst32() constant_folding (before) + /// CHECK-DAG: InvokeStaticOrDirect intrinsic:LongNumberOfTrailingZeros + + /// CHECK-START: void Main.$noinline$testTrailingZerosLongFirst32() constant_folding (after) + /// CHECK-NOT: InvokeStaticOrDirect intrinsic:LongNumberOfTrailingZeros + private static void $noinline$testTrailingZerosLongFirst32() { + $noinline$assertIntEquals(64, Long.numberOfTrailingZeros(0L)); + $noinline$assertIntEquals(0, Long.numberOfTrailingZeros(1L << 0L)); + $noinline$assertIntEquals(1, Long.numberOfTrailingZeros(1L << 1L)); + $noinline$assertIntEquals(2, Long.numberOfTrailingZeros(1L << 2L)); + $noinline$assertIntEquals(3, Long.numberOfTrailingZeros(1L << 3L)); + $noinline$assertIntEquals(4, Long.numberOfTrailingZeros(1L << 4L)); + $noinline$assertIntEquals(5, Long.numberOfTrailingZeros(1L << 5L)); + $noinline$assertIntEquals(6, Long.numberOfTrailingZeros(1L << 6L)); + $noinline$assertIntEquals(7, Long.numberOfTrailingZeros(1L << 7L)); + $noinline$assertIntEquals(8, Long.numberOfTrailingZeros(1L << 8L)); + $noinline$assertIntEquals(9, Long.numberOfTrailingZeros(1L << 9L)); + $noinline$assertIntEquals(10, Long.numberOfTrailingZeros(1L << 10L)); + $noinline$assertIntEquals(11, Long.numberOfTrailingZeros(1L << 11L)); + $noinline$assertIntEquals(12, Long.numberOfTrailingZeros(1L << 12L)); + $noinline$assertIntEquals(13, Long.numberOfTrailingZeros(1L << 13L)); + $noinline$assertIntEquals(14, Long.numberOfTrailingZeros(1L << 14L)); + $noinline$assertIntEquals(15, Long.numberOfTrailingZeros(1L << 15L)); + $noinline$assertIntEquals(16, Long.numberOfTrailingZeros(1L << 16L)); + $noinline$assertIntEquals(17, Long.numberOfTrailingZeros(1L << 17L)); + $noinline$assertIntEquals(18, Long.numberOfTrailingZeros(1L << 18L)); + $noinline$assertIntEquals(19, Long.numberOfTrailingZeros(1L << 19L)); + $noinline$assertIntEquals(20, Long.numberOfTrailingZeros(1L << 20L)); + $noinline$assertIntEquals(21, Long.numberOfTrailingZeros(1L << 21L)); + $noinline$assertIntEquals(22, Long.numberOfTrailingZeros(1L << 22L)); + $noinline$assertIntEquals(23, Long.numberOfTrailingZeros(1L << 23L)); + $noinline$assertIntEquals(24, Long.numberOfTrailingZeros(1L << 24L)); + $noinline$assertIntEquals(25, Long.numberOfTrailingZeros(1L << 25L)); + $noinline$assertIntEquals(26, Long.numberOfTrailingZeros(1L << 26L)); + $noinline$assertIntEquals(27, Long.numberOfTrailingZeros(1L << 27L)); + $noinline$assertIntEquals(28, Long.numberOfTrailingZeros(1L << 28L)); + $noinline$assertIntEquals(29, Long.numberOfTrailingZeros(1L << 29L)); + $noinline$assertIntEquals(30, Long.numberOfTrailingZeros(1L << 30L)); + $noinline$assertIntEquals(31, Long.numberOfTrailingZeros(1L << 31L)); + } + + /// CHECK-START: void Main.$noinline$testTrailingZerosLongLast32() constant_folding (before) + /// CHECK-DAG: InvokeStaticOrDirect intrinsic:LongNumberOfTrailingZeros + + /// CHECK-START: void Main.$noinline$testTrailingZerosLongLast32() constant_folding (after) + /// CHECK-NOT: InvokeStaticOrDirect intrinsic:LongNumberOfTrailingZeros + private static void $noinline$testTrailingZerosLongLast32() { + $noinline$assertIntEquals(32, Long.numberOfTrailingZeros(1L << 32L)); + $noinline$assertIntEquals(33, Long.numberOfTrailingZeros(1L << 33L)); + $noinline$assertIntEquals(34, Long.numberOfTrailingZeros(1L << 34L)); + $noinline$assertIntEquals(35, Long.numberOfTrailingZeros(1L << 35L)); + $noinline$assertIntEquals(36, Long.numberOfTrailingZeros(1L << 36L)); + $noinline$assertIntEquals(37, Long.numberOfTrailingZeros(1L << 37L)); + $noinline$assertIntEquals(38, Long.numberOfTrailingZeros(1L << 38L)); + $noinline$assertIntEquals(39, Long.numberOfTrailingZeros(1L << 39L)); + $noinline$assertIntEquals(40, Long.numberOfTrailingZeros(1L << 40L)); + $noinline$assertIntEquals(41, Long.numberOfTrailingZeros(1L << 41L)); + $noinline$assertIntEquals(42, Long.numberOfTrailingZeros(1L << 42L)); + $noinline$assertIntEquals(43, Long.numberOfTrailingZeros(1L << 43L)); + $noinline$assertIntEquals(44, Long.numberOfTrailingZeros(1L << 44L)); + $noinline$assertIntEquals(45, Long.numberOfTrailingZeros(1L << 45L)); + $noinline$assertIntEquals(46, Long.numberOfTrailingZeros(1L << 46L)); + $noinline$assertIntEquals(47, Long.numberOfTrailingZeros(1L << 47L)); + $noinline$assertIntEquals(48, Long.numberOfTrailingZeros(1L << 48L)); + $noinline$assertIntEquals(49, Long.numberOfTrailingZeros(1L << 49L)); + $noinline$assertIntEquals(50, Long.numberOfTrailingZeros(1L << 50L)); + $noinline$assertIntEquals(51, Long.numberOfTrailingZeros(1L << 51L)); + $noinline$assertIntEquals(52, Long.numberOfTrailingZeros(1L << 52L)); + $noinline$assertIntEquals(53, Long.numberOfTrailingZeros(1L << 53L)); + $noinline$assertIntEquals(54, Long.numberOfTrailingZeros(1L << 54L)); + $noinline$assertIntEquals(55, Long.numberOfTrailingZeros(1L << 55L)); + $noinline$assertIntEquals(56, Long.numberOfTrailingZeros(1L << 56L)); + $noinline$assertIntEquals(57, Long.numberOfTrailingZeros(1L << 57L)); + $noinline$assertIntEquals(58, Long.numberOfTrailingZeros(1L << 58L)); + $noinline$assertIntEquals(59, Long.numberOfTrailingZeros(1L << 59L)); + $noinline$assertIntEquals(60, Long.numberOfTrailingZeros(1L << 60L)); + $noinline$assertIntEquals(61, Long.numberOfTrailingZeros(1L << 61L)); + $noinline$assertIntEquals(62, Long.numberOfTrailingZeros(1L << 62L)); + $noinline$assertIntEquals(63, Long.numberOfTrailingZeros(1L << 63L)); + } + + public static void $noinline$assertIntEquals(int expected, int result) { + if (expected != result) { + throw new Error("Expected: " + expected + ", found: " + result); + } + } +} |