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}
176
178 // Ignores NaN
179 Mask &= ~fcNan;
180 // Since the classes are ordered bits, we can get all classes which are
181 // smaller than all classes in Known by setting all trailing 0 bits to 1,
182 // and setting the other bits to 0.
183 // This is done by counting the number of trailing 0 bits and creating a
184 // mask based on that.
185 // For example: 0b1111000000 = fcPositive
186 // -> 0b0000111111 = fcNegative | fcNan
187 FPClassTest NewMask = static_cast<FPClassTest>(
189 // Remove NaNs
190 NewMask &= ~fcNan;
191 // We cannot conclude that only one zero is smaller
192 // if the zeroes are not ordered
193 if (!OrderedZeroSign && ((NewMask & fcZero) != fcZero))
194 NewMask &= ~fcZero;
195 return NewMask;
196}
197
199 bool OrderedZeroSign) {
200 // Counting the number of leading 0 bits and create a mask based on that,
201 // removing the leading 1s that are outside the bitfield:
202 // For example: 0b0000111100 = fcNegative
203 // -> 0b1111000000 = fcPositive
204 FPClassTest NewMask = static_cast<FPClassTest>(
206 // Remove NaNs
207 NewMask &= ~fcNan;
208 // We cannot conclude that only one zero is greater
209 // if the zeroes are not ordered
210 if (!OrderedZeroSign && ((NewMask & fcZero) != fcZero))
211 NewMask &= ~fcZero;
212 return NewMask;
213}
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.
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 FPClassTest orderedStrictlyGreater(FPClassTest Mask, bool OrderedZeroSign=false)
Returns all FPClasses which are greater than all values in Mask That is, return all classes for which...
constexpr T maskLeadingOnes(unsigned N)
Create a bitmask with the N left-most bits set to 1, and all other bits set to 0.
Definition MathExtras.h:88
int countr_zero(T Val)
Count number of 0's from the least significant bit to the most stopping at the first 1.
Definition bit.h:204
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
int countl_zero(T Val)
Count number of 0's from the most significant bit to the least stopping at the first 1.
Definition bit.h:263
LLVM_ABI FPClassTest fneg(FPClassTest Mask)
Return the test mask which returns true if the value's sign bit is flipped.
LLVM_ABI FPClassTest orderedStrictlyLess(FPClassTest Mask, bool OrderedZeroSign=false)
Returns all FPClasses which are less than all values in Mask That is, return all classes for which th...
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)
constexpr T maskTrailingOnes(unsigned N)
Create a bitmask with the N right-most bits set to 1, and all other bits set to 0.
Definition MathExtras.h:77
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.