LLVM 23.0.0git
FloatingPointMode.cpp
Go to the documentation of this file.
1//===- FloatingPointMode.cpp ------------------------------------*- 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
11
12using namespace llvm;
13
15 FPClassTest NewMask = Mask & fcNan;
16 if (Mask & fcNegInf)
17 NewMask |= fcPosInf;
18 if (Mask & fcNegNormal)
19 NewMask |= fcPosNormal;
20 if (Mask & fcNegSubnormal)
21 NewMask |= fcPosSubnormal;
22 if (Mask & fcNegZero)
23 NewMask |= fcPosZero;
24 if (Mask & fcPosZero)
25 NewMask |= fcNegZero;
26 if (Mask & fcPosSubnormal)
27 NewMask |= fcNegSubnormal;
28 if (Mask & fcPosNormal)
29 NewMask |= fcNegNormal;
30 if (Mask & fcPosInf)
31 NewMask |= fcNegInf;
32 return NewMask;
33}
34
36 FPClassTest NewMask = Mask & fcNan;
37 if (Mask & fcPosZero)
38 NewMask |= fcZero;
39 if (Mask & fcPosSubnormal)
40 NewMask |= fcSubnormal;
41 if (Mask & fcPosNormal)
42 NewMask |= fcNormal;
43 if (Mask & fcPosInf)
44 NewMask |= fcInf;
45 return NewMask;
46}
47
49 FPClassTest NewMask = Mask & fcNan;
50 if (Mask & fcZero)
51 NewMask |= fcZero;
52 if (Mask & fcSubnormal)
53 NewMask |= fcSubnormal;
54 if (Mask & fcNormal)
55 NewMask |= fcNormal;
56 if (Mask & fcInf)
57 NewMask |= fcInf;
58 return NewMask;
59}
60
61// Every bitfield has a unique name and one or more aliasing names that cover
62// multiple bits. Names should be listed in order of preference, with higher
63// popcounts listed first.
64//
65// Bits are consumed as printed. Each field should only be represented in one
66// printed field.
67static constexpr std::pair<FPClassTest, StringLiteral> NoFPClassName[] = {
68 {fcAllFlags, "all"},
69 {fcNan, "nan"},
70 {fcSNan, "snan"},
71 {fcQNan, "qnan"},
72 {fcInf, "inf"},
73 {fcNegInf, "ninf"},
74 {fcPosInf, "pinf"},
75 {fcZero, "zero"},
76 {fcNegZero, "nzero"},
77 {fcPosZero, "pzero"},
78 {fcSubnormal, "sub"},
79 {fcNegSubnormal, "nsub"},
80 {fcPosSubnormal, "psub"},
81 {fcNormal, "norm"},
82 {fcNegNormal, "nnorm"},
83 {fcPosNormal, "pnorm"}
84};
85
87 OS << '(';
88
89 if (Mask == fcNone) {
90 OS << "none)";
91 return OS;
92 }
93
94 ListSeparator LS(" ");
95 for (auto [BitTest, Name] : NoFPClassName) {
96 if ((Mask & BitTest) == BitTest) {
97 OS << LS << Name;
98
99 // Clear the bits so we don't print any aliased names later.
100 Mask &= ~BitTest;
101 }
102 }
103
104 assert(Mask == 0 && "didn't print some mask bits");
105
106 OS << ')';
107 return OS;
108}
109
110void DenormalFPEnv::print(raw_ostream &OS, bool OmitIfSame) const {
111 if (F32Mode == DefaultMode) {
112 DefaultMode.print(OS, /*Legacy=*/false, OmitIfSame);
113 return;
114 }
115
116 // Omit printing the base mode if only the f32 mode isn't the default.
118 DefaultMode.print(OS, /*Legacy=*/false, OmitIfSame);
119 OS << ", ";
120 }
121
122 OS << "float: ";
123 F32Mode.print(OS, /*Legacy=*/false, OmitIfSame);
124}
125
127 bool OrEqual, bool OrderedZero) {
128 LHS &= ~fcNan;
129 RHS &= ~fcNan;
130
131 if (LHS == fcNone || RHS == fcNone)
132 return true;
133
134 FPClassTest LowestBitRHS = static_cast<FPClassTest>(RHS & -RHS);
135 FPClassTest HighestBitLHS = static_cast<FPClassTest>(1 << Log2_32(LHS));
136
137 if (!OrderedZero) {
138 // Introduce conflict in zero bits if we're treating them as equal.
139 if (LowestBitRHS == fcNegZero)
140 LowestBitRHS = fcPosZero;
141 if (HighestBitLHS == fcNegZero)
142 HighestBitLHS = fcPosZero;
143 }
144
145 if (LowestBitRHS > HighestBitLHS) {
146 assert((LHS & RHS) == fcNone && "no bits should intersect");
147 return true;
148 }
149
150 if (LowestBitRHS < HighestBitLHS)
151 return false;
152
153 constexpr FPClassTest ExactValuesMask = fcZero | fcInf;
154 return !OrEqual && (LowestBitRHS & ExactValuesMask) != fcNone;
155}
156
158 bool OrderedZeroSign) {
159 return cannotOrderStrictlyGreaterImpl(LHS, RHS, false, OrderedZeroSign);
160}
161
163 bool OrderedZeroSign) {
164 return cannotOrderStrictlyGreaterImpl(LHS, RHS, true, OrderedZeroSign);
165}
166
168 bool OrderedZeroSign) {
169 return cannotOrderStrictlyGreaterImpl(RHS, LHS, false, OrderedZeroSign);
170}
171
173 bool OrderedZeroSign) {
174 return cannotOrderStrictlyGreaterImpl(RHS, LHS, true, OrderedZeroSign);
175}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static constexpr std::pair< FPClassTest, StringLiteral > NoFPClassName[]
static bool cannotOrderStrictlyGreaterImpl(FPClassTest LHS, FPClassTest RHS, bool OrEqual, bool OrderedZero)
Utilities for dealing with flags related to floating point properties and mode controls.
This file contains some functions that are useful when dealing with strings.
Value * RHS
Value * LHS
A helper class to return the specified delimiter string after the first invocation of operator String...
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
This is an optimization pass for GlobalISel generic memory operations.
Definition Types.h:26
LLVM_ABI bool cannotOrderStrictlyGreaterEq(FPClassTest LHS, FPClassTest RHS, bool OrderedZeroSign=false)
Returns true if all values in LHS must be less than those in RHS.
LLVM_ABI bool cannotOrderStrictlyLess(FPClassTest LHS, FPClassTest RHS, bool OrderedZeroSign=false)
Returns true if all values in LHS must be greater than or equal to those in RHS.
LLVM_ABI bool cannotOrderStrictlyLessEq(FPClassTest LHS, FPClassTest RHS, bool OrderedZeroSign=false)
Returns true if all values in LHS must be greater than to those in RHS.
LLVM_ABI bool cannotOrderStrictlyGreater(FPClassTest LHS, FPClassTest RHS, bool OrderedZeroSign=false)
Returns true if all values in LHS must be less than or equal to those in RHS.
unsigned Log2_32(uint32_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
Definition MathExtras.h:331
LLVM_ABI FPClassTest fneg(FPClassTest Mask)
Return the test mask which returns true if the value's sign bit is flipped.
FPClassTest
Floating-point class tests, supported by 'is_fpclass' intrinsic.
LLVM_ABI FPClassTest inverse_fabs(FPClassTest Mask)
Return the test mask which returns true after fabs is applied to the value.
LLVM_ABI FPClassTest unknown_sign(FPClassTest Mask)
Return the test mask which returns true if the value could have the same set of classes,...
raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)
LLVM_ABI void print(raw_ostream &OS, bool OmitIfSame=true) const
static constexpr DenormalMode getDefault()
Return the assumed default mode for a function without denormal-fp-math.