Backed out 2 changesets (bug 903746) for causing non-unified build bustages on nsIPri...
[gecko.git] / third_party / highway / hwy / targets_test.cc
blob050e8018d001c527716e67aa36519d8429663f4f
1 // Copyright 2020 Google LLC
2 // SPDX-License-Identifier: Apache-2.0
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 // http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
16 #include "hwy/targets.h"
18 #include "hwy/detect_targets.h"
19 #include "hwy/tests/test_util-inl.h"
21 namespace fake {
23 #define DECLARE_FUNCTION(TGT) \
24 namespace N_##TGT { \
25 /* Function argument is just to ensure/demonstrate they are possible. */ \
26 int64_t FakeFunction(int) { return HWY_##TGT; } \
29 DECLARE_FUNCTION(AVX3_ZEN4)
30 DECLARE_FUNCTION(AVX3_DL)
31 DECLARE_FUNCTION(AVX3)
32 DECLARE_FUNCTION(AVX2)
33 DECLARE_FUNCTION(SSE4)
34 DECLARE_FUNCTION(SSSE3)
35 DECLARE_FUNCTION(SSE2)
37 DECLARE_FUNCTION(SVE2_128)
38 DECLARE_FUNCTION(SVE_256)
39 DECLARE_FUNCTION(SVE2)
40 DECLARE_FUNCTION(SVE)
41 DECLARE_FUNCTION(NEON)
42 DECLARE_FUNCTION(NEON_WITHOUT_AES)
44 DECLARE_FUNCTION(PPC10)
45 DECLARE_FUNCTION(PPC9)
46 DECLARE_FUNCTION(PPC8)
48 DECLARE_FUNCTION(WASM)
49 DECLARE_FUNCTION(WASM_EMU256)
51 DECLARE_FUNCTION(RVV)
53 DECLARE_FUNCTION(SCALAR)
54 DECLARE_FUNCTION(EMU128)
56 HWY_EXPORT(FakeFunction);
58 void CallFunctionForTarget(int64_t target, int line) {
59 if ((HWY_TARGETS & target) == 0) return;
60 hwy::SetSupportedTargetsForTest(target);
62 // Call Update() first to make &HWY_DYNAMIC_DISPATCH() return
63 // the pointer to the already cached function.
64 hwy::GetChosenTarget().Update(hwy::SupportedTargets());
66 EXPECT_EQ(target, HWY_DYNAMIC_DISPATCH(FakeFunction)(42)) << line;
68 // Calling DeInit() will test that the initializer function
69 // also calls the right function.
70 hwy::GetChosenTarget().DeInit();
72 #if HWY_DISPATCH_WORKAROUND
73 EXPECT_EQ(HWY_STATIC_TARGET, HWY_DYNAMIC_DISPATCH(FakeFunction)(42)) << line;
74 #else
75 EXPECT_EQ(target, HWY_DYNAMIC_DISPATCH(FakeFunction)(42)) << line;
76 #endif
78 // Second call uses the cached value from the previous call.
79 EXPECT_EQ(target, HWY_DYNAMIC_DISPATCH(FakeFunction)(42)) << line;
82 void CheckFakeFunction() {
83 // When adding a target, also add to DECLARE_FUNCTION above.
84 CallFunctionForTarget(HWY_AVX3_ZEN4, __LINE__);
85 CallFunctionForTarget(HWY_AVX3_DL, __LINE__);
86 CallFunctionForTarget(HWY_AVX3, __LINE__);
87 CallFunctionForTarget(HWY_AVX2, __LINE__);
88 CallFunctionForTarget(HWY_SSE4, __LINE__);
89 CallFunctionForTarget(HWY_SSSE3, __LINE__);
90 CallFunctionForTarget(HWY_SSE2, __LINE__);
92 CallFunctionForTarget(HWY_SVE2_128, __LINE__);
93 CallFunctionForTarget(HWY_SVE_256, __LINE__);
94 CallFunctionForTarget(HWY_SVE2, __LINE__);
95 CallFunctionForTarget(HWY_SVE, __LINE__);
96 CallFunctionForTarget(HWY_NEON, __LINE__);
97 CallFunctionForTarget(HWY_NEON_WITHOUT_AES, __LINE__);
99 CallFunctionForTarget(HWY_PPC10, __LINE__);
100 CallFunctionForTarget(HWY_PPC9, __LINE__);
101 CallFunctionForTarget(HWY_PPC8, __LINE__);
103 CallFunctionForTarget(HWY_WASM, __LINE__);
104 CallFunctionForTarget(HWY_WASM_EMU256, __LINE__);
106 CallFunctionForTarget(HWY_RVV, __LINE__);
107 // The tables only have space for either HWY_SCALAR or HWY_EMU128; the former
108 // is opt-in only.
109 #if defined(HWY_COMPILE_ONLY_SCALAR) || HWY_BROKEN_EMU128
110 CallFunctionForTarget(HWY_SCALAR, __LINE__);
111 #else
112 CallFunctionForTarget(HWY_EMU128, __LINE__);
113 #endif
116 } // namespace fake
118 namespace hwy {
120 class HwyTargetsTest : public testing::Test {
121 protected:
122 void TearDown() override {
123 SetSupportedTargetsForTest(0);
124 DisableTargets(0); // Reset the mask.
128 // Test that the order in the HWY_EXPORT static array matches the expected
129 // value of the target bits. This is only checked for the targets that are
130 // enabled in the current compilation.
131 TEST_F(HwyTargetsTest, ChosenTargetOrderTest) { fake::CheckFakeFunction(); }
133 TEST_F(HwyTargetsTest, DisabledTargetsTest) {
134 DisableTargets(~0LL);
135 // Check that disabling everything at least leaves the static target.
136 HWY_ASSERT(HWY_STATIC_TARGET == SupportedTargets());
138 DisableTargets(0); // Reset the mask.
139 const int64_t current_targets = SupportedTargets();
140 const int64_t enabled_baseline = static_cast<int64_t>(HWY_ENABLED_BASELINE);
141 // Exclude these two because they are always returned by SupportedTargets.
142 const int64_t fallback = HWY_SCALAR | HWY_EMU128;
143 if ((current_targets & ~enabled_baseline & ~fallback) == 0) {
144 // We can't test anything else if the only compiled target is the baseline.
145 return;
148 // Get the lowest bit in the mask (the best target) and disable that one.
149 const int64_t best_target = current_targets & (~current_targets + 1);
150 DisableTargets(best_target);
152 // Check that the other targets are still enabled.
153 HWY_ASSERT((best_target ^ current_targets) == SupportedTargets());
154 DisableTargets(0); // Reset the mask.
157 } // namespace hwy