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