Coverage Report

Created: 2020-06-26 05:44

/home/arjun/llvm-project/llvm/include/llvm/ADT/FloatingPointMode.h
Line
Count
Source (jump to first uncovered line)
1
//===- llvm/Support/FloatingPointMode.h -------------------------*- C++ -*-===//
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
// Utilities for dealing with flags related to floating point mode controls.
10
//
11
//===----------------------------------------------------------------------===/
12
13
#ifndef LLVM_FLOATINGPOINTMODE_H
14
#define LLVM_FLOATINGPOINTMODE_H
15
16
#include "llvm/ADT/StringSwitch.h"
17
#include "llvm/Support/raw_ostream.h"
18
19
namespace llvm {
20
21
/// Rounding mode.
22
///
23
/// Enumerates supported rounding modes, as well as some special values. The set
24
/// of the modes must agree with IEEE-754, 4.3.1 and 4.3.2. The constants
25
/// assigned to the IEEE rounding modes must agree with the values used by
26
/// FLT_ROUNDS (C11, 5.2.4.2.2p8).
27
///
28
/// This value is packed into bitfield in some cases, including \c FPOptions, so
29
/// the rounding mode values and the special value \c Dynamic must fit into the
30
/// the bit field (now - 3 bits). The value \c Invalid is used only in values
31
/// returned by intrinsics to indicate errors, it should never be stored as
32
/// rounding mode value, so it does not need to fit the bit fields.
33
///
34
enum class RoundingMode : int8_t {
35
  // Rounding mode defined in IEEE-754.
36
  TowardZero        = 0,    ///< roundTowardZero.
37
  NearestTiesToEven = 1,    ///< roundTiesToEven.
38
  TowardPositive    = 2,    ///< roundTowardPositive.
39
  TowardNegative    = 3,    ///< roundTowardNegative.
40
  NearestTiesToAway = 4,    ///< roundTiesToAway.
41
42
  // Special values.
43
  Dynamic = 7,    ///< Denotes mode unknown at compile time.
44
  Invalid = -1    ///< Denotes invalid value.
45
};
46
47
/// Represent subnormal handling kind for floating point instruction inputs and
48
/// outputs.
49
struct DenormalMode {
50
  /// Represent handled modes for denormal (aka subnormal) modes in the floating
51
  /// point environment.
52
  enum DenormalModeKind : int8_t {
53
    Invalid = -1,
54
55
    /// IEEE-754 denormal numbers preserved.
56
    IEEE,
57
58
    /// The sign of a flushed-to-zero number is preserved in the sign of 0
59
    PreserveSign,
60
61
    /// Denormals are flushed to positive zero.
62
    PositiveZero
63
  };
64
65
  /// Denormal flushing mode for floating point instruction results in the
66
  /// default floating point environment.
67
  DenormalModeKind Output = DenormalModeKind::Invalid;
68
69
  /// Denormal treatment kind for floating point instruction inputs in the
70
  /// default floating-point environment. If this is not DenormalModeKind::IEEE,
71
  /// floating-point instructions implicitly treat the input value as 0.
72
  DenormalModeKind Input = DenormalModeKind::Invalid;
73
74
  constexpr DenormalMode() = default;
75
  constexpr DenormalMode(DenormalModeKind Out, DenormalModeKind In) :
76
0
    Output(Out), Input(In) {}
77
78
79
0
  static constexpr DenormalMode getInvalid() {
80
0
    return DenormalMode(DenormalModeKind::Invalid, DenormalModeKind::Invalid);
81
0
  }
82
83
0
  static constexpr DenormalMode getIEEE() {
84
0
    return DenormalMode(DenormalModeKind::IEEE, DenormalModeKind::IEEE);
85
0
  }
86
87
0
  static constexpr DenormalMode getPreserveSign() {
88
0
    return DenormalMode(DenormalModeKind::PreserveSign,
89
0
                        DenormalModeKind::PreserveSign);
90
0
  }
91
92
0
  static constexpr DenormalMode getPositiveZero() {
93
0
    return DenormalMode(DenormalModeKind::PositiveZero,
94
0
                        DenormalModeKind::PositiveZero);
95
0
  }
96
97
0
  bool operator==(DenormalMode Other) const {
98
0
    return Output == Other.Output && Input == Other.Input;
99
0
  }
100
101
0
  bool operator!=(DenormalMode Other) const {
102
0
    return !(*this == Other);
103
0
  }
104
105
0
  bool isSimple() const {
106
0
    return Input == Output;
107
0
  }
108
109
0
  bool isValid() const {
110
0
    return Output != DenormalModeKind::Invalid &&
111
0
           Input != DenormalModeKind::Invalid;
112
0
  }
113
114
  inline void print(raw_ostream &OS) const;
115
116
0
  inline std::string str() const {
117
0
    std::string storage;
118
0
    raw_string_ostream OS(storage);
119
0
    print(OS);
120
0
    return OS.str();
121
0
  }
122
};
123
124
0
inline raw_ostream& operator<<(raw_ostream &OS, DenormalMode Mode) {
125
0
  Mode.print(OS);
126
0
  return OS;
127
0
}
128
129
/// Parse the expected names from the denormal-fp-math attribute.
130
inline DenormalMode::DenormalModeKind
131
0
parseDenormalFPAttributeComponent(StringRef Str) {
132
0
  // Assume ieee on unspecified attribute.
133
0
  return StringSwitch<DenormalMode::DenormalModeKind>(Str)
134
0
    .Cases("", "ieee", DenormalMode::IEEE)
135
0
    .Case("preserve-sign", DenormalMode::PreserveSign)
136
0
    .Case("positive-zero", DenormalMode::PositiveZero)
137
0
    .Default(DenormalMode::Invalid);
138
0
}
139
140
/// Return the name used for the denormal handling mode used by the the
141
/// expected names from the denormal-fp-math attribute.
142
0
inline StringRef denormalModeKindName(DenormalMode::DenormalModeKind Mode) {
143
0
  switch (Mode) {
144
0
  case DenormalMode::IEEE:
145
0
    return "ieee";
146
0
  case DenormalMode::PreserveSign:
147
0
    return "preserve-sign";
148
0
  case DenormalMode::PositiveZero:
149
0
    return "positive-zero";
150
0
  default:
151
0
    return "";
152
0
  }
153
0
}
154
155
/// Returns the denormal mode to use for inputs and outputs.
156
0
inline DenormalMode parseDenormalFPAttribute(StringRef Str) {
157
0
  StringRef OutputStr, InputStr;
158
0
  std::tie(OutputStr, InputStr) = Str.split(',');
159
0
160
0
  DenormalMode Mode;
161
0
  Mode.Output = parseDenormalFPAttributeComponent(OutputStr);
162
0
163
0
  // Maintain compatability with old form of the attribute which only specified
164
0
  // one component.
165
0
  Mode.Input = InputStr.empty() ? Mode.Output  :
166
0
               parseDenormalFPAttributeComponent(InputStr);
167
0
168
0
  return Mode;
169
0
}
170
171
0
void DenormalMode::print(raw_ostream &OS) const {
172
0
  OS << denormalModeKindName(Output) << ',' << denormalModeKindName(Input);
173
0
}
174
175
}
176
177
#endif // LLVM_FLOATINGPOINTMODE_H