xref: /aosp_15_r20/external/llvm-libc/test/src/fenv/feenableexcept_test.cpp (revision 71db0c75aadcf003ffe3238005f61d7618a3fead)
1 //===-- Unittests for feenableexcept  -------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "src/__support/macros/properties/architectures.h"
10 #include "src/fenv/fedisableexcept.h"
11 #include "src/fenv/feenableexcept.h"
12 #include "src/fenv/fegetexcept.h"
13 
14 #include "test/UnitTest/FEnvSafeTest.h"
15 #include "test/UnitTest/Test.h"
16 
17 #include "hdr/fenv_macros.h"
18 
19 #include "excepts.h"
20 
21 using LlvmLibcFEnvTest = LIBC_NAMESPACE::testing::FEnvSafeTest;
22 
TEST_F(LlvmLibcFEnvTest,EnableTest)23 TEST_F(LlvmLibcFEnvTest, EnableTest) {
24 #if defined(LIBC_TARGET_ARCH_IS_ANY_ARM) ||                                    \
25     defined(LIBC_TARGET_ARCH_IS_ANY_RISCV)
26   // Few Arm HW implementations do not trap exceptions. We skip this test
27   // completely on such HW.
28   //
29   // Whether HW supports trapping exceptions or not is deduced by enabling an
30   // exception and reading back to see if the exception got enabled. If the
31   // exception did not get enabled, then it means that the HW does not support
32   // trapping exceptions.
33   LIBC_NAMESPACE::fedisableexcept(FE_ALL_EXCEPT);
34   LIBC_NAMESPACE::feenableexcept(FE_DIVBYZERO);
35   if (LIBC_NAMESPACE::fegetexcept() == 0)
36     return;
37 #endif // Architectures where exception trapping is not supported
38 
39   int excepts[] = {FE_DIVBYZERO, FE_INVALID, FE_INEXACT, FE_OVERFLOW,
40                    FE_UNDERFLOW};
41   LIBC_NAMESPACE::fedisableexcept(FE_ALL_EXCEPT);
42   ASSERT_EQ(0, LIBC_NAMESPACE::fegetexcept());
43 
44   for (int e : excepts) {
45     LIBC_NAMESPACE::feenableexcept(e);
46     ASSERT_EQ(e, LIBC_NAMESPACE::fegetexcept());
47     LIBC_NAMESPACE::fedisableexcept(e);
48   }
49 
50   for (int e1 : excepts) {
51     for (int e2 : excepts) {
52       LIBC_NAMESPACE::feenableexcept(e1 | e2);
53       ASSERT_EQ(e1 | e2, LIBC_NAMESPACE::fegetexcept());
54       LIBC_NAMESPACE::fedisableexcept(e1 | e2);
55     }
56   }
57 
58   for (int e1 : excepts) {
59     for (int e2 : excepts) {
60       for (int e3 : excepts) {
61         LIBC_NAMESPACE::feenableexcept(e1 | e2 | e3);
62         ASSERT_EQ(e1 | e2 | e3, LIBC_NAMESPACE::fegetexcept());
63         LIBC_NAMESPACE::fedisableexcept(e1 | e2 | e3);
64       }
65     }
66   }
67 
68   for (int e1 : excepts) {
69     for (int e2 : excepts) {
70       for (int e3 : excepts) {
71         for (int e4 : excepts) {
72           LIBC_NAMESPACE::feenableexcept(e1 | e2 | e3 | e4);
73           ASSERT_EQ(e1 | e2 | e3 | e4, LIBC_NAMESPACE::fegetexcept());
74           LIBC_NAMESPACE::fedisableexcept(e1 | e2 | e3 | e4);
75         }
76       }
77     }
78   }
79 
80   for (int e1 : excepts) {
81     for (int e2 : excepts) {
82       for (int e3 : excepts) {
83         for (int e4 : excepts) {
84           for (int e5 : excepts) {
85             LIBC_NAMESPACE::feenableexcept(e1 | e2 | e3 | e4 | e5);
86             ASSERT_EQ(e1 | e2 | e3 | e4 | e5, LIBC_NAMESPACE::fegetexcept());
87             LIBC_NAMESPACE::fedisableexcept(e1 | e2 | e3 | e4 | e5);
88           }
89         }
90       }
91     }
92   }
93 }
94