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/architectures.h"
10 #include "src/fenv/fedisableexcept.h"
11 #include "src/fenv/feenableexcept.h"
12 #include "src/fenv/fegetexcept.h"
13
14 #include "utils/UnitTest/Test.h"
15
16 #include <fenv.h>
17
TEST(LlvmLibcFEnvTest,EnableTest)18 TEST(LlvmLibcFEnvTest, EnableTest) {
19 #if defined(LLVM_LIBC_ARCH_AARCH64)
20 // Few aarch64 HW implementations do not trap exceptions. We skip this test
21 // completely on such HW.
22 //
23 // Whether HW supports trapping exceptions or not is deduced by enabling an
24 // exception and reading back to see if the exception got enabled. If the
25 // exception did not get enabled, then it means that the HW does not support
26 // trapping exceptions.
27 __llvm_libc::fedisableexcept(FE_ALL_EXCEPT);
28 __llvm_libc::feenableexcept(FE_DIVBYZERO);
29 if (__llvm_libc::fegetexcept() == 0)
30 return;
31 #endif // defined(LLVM_LIBC_ARCH_AARCH64)
32
33 int excepts[] = {FE_DIVBYZERO, FE_INVALID, FE_INEXACT, FE_OVERFLOW,
34 FE_UNDERFLOW};
35 __llvm_libc::fedisableexcept(FE_ALL_EXCEPT);
36 ASSERT_EQ(0, __llvm_libc::fegetexcept());
37
38 for (int e : excepts) {
39 __llvm_libc::feenableexcept(e);
40 ASSERT_EQ(e, __llvm_libc::fegetexcept());
41 __llvm_libc::fedisableexcept(e);
42 }
43
44 for (int e1 : excepts) {
45 for (int e2 : excepts) {
46 __llvm_libc::feenableexcept(e1 | e2);
47 ASSERT_EQ(e1 | e2, __llvm_libc::fegetexcept());
48 __llvm_libc::fedisableexcept(e1 | e2);
49 }
50 }
51
52 for (int e1 : excepts) {
53 for (int e2 : excepts) {
54 for (int e3 : excepts) {
55 __llvm_libc::feenableexcept(e1 | e2 | e3);
56 ASSERT_EQ(e1 | e2 | e3, __llvm_libc::fegetexcept());
57 __llvm_libc::fedisableexcept(e1 | e2 | e3);
58 }
59 }
60 }
61
62 for (int e1 : excepts) {
63 for (int e2 : excepts) {
64 for (int e3 : excepts) {
65 for (int e4 : excepts) {
66 __llvm_libc::feenableexcept(e1 | e2 | e3 | e4);
67 ASSERT_EQ(e1 | e2 | e3 | e4, __llvm_libc::fegetexcept());
68 __llvm_libc::fedisableexcept(e1 | e2 | e3 | e4);
69 }
70 }
71 }
72 }
73
74 for (int e1 : excepts) {
75 for (int e2 : excepts) {
76 for (int e3 : excepts) {
77 for (int e4 : excepts) {
78 for (int e5 : excepts) {
79 __llvm_libc::feenableexcept(e1 | e2 | e3 | e4 | e5);
80 ASSERT_EQ(e1 | e2 | e3 | e4 | e5, __llvm_libc::fegetexcept());
81 __llvm_libc::fedisableexcept(e1 | e2 | e3 | e4 | e5);
82 }
83 }
84 }
85 }
86 }
87 }
88