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
111 bool OrEqual, bool OrderedZero) {
112 LHS &= ~fcNan;
113 RHS &= ~fcNan;
114
115 if (LHS == fcNone || RHS == fcNone)
116 return true;
117
118 FPClassTest LowestBitRHS = static_cast<FPClassTest>(RHS & -RHS);
119 FPClassTest HighestBitLHS = static_cast<FPClassTest>(1 << Log2_32(LHS));
120
121 if (!OrderedZero) {
122 // Introduce conflict in zero bits if we're treating them as equal.
123 if (LowestBitRHS == fcNegZero)
124 LowestBitRHS = fcPosZero;
125 if (HighestBitLHS == fcNegZero)
126 HighestBitLHS = fcPosZero;
127 }
128
129 if (LowestBitRHS > HighestBitLHS) {
130 assert((LHS & RHS) == fcNone && "no bits should intersect");
131 return true;
132 }
133
134 if (LowestBitRHS < HighestBitLHS)
135 return false;
136
137 constexpr FPClassTest ExactValuesMask = fcZero | fcInf;
138 return !OrEqual && (LowestBitRHS & ExactValuesMask) != fcNone;
139}
140
142 bool OrderedZeroSign) {
143 return cannotOrderStrictlyGreaterImpl(LHS, RHS, false, OrderedZeroSign);
144}
145
147 bool OrderedZeroSign) {
148 return cannotOrderStrictlyGreaterImpl(LHS, RHS, true, OrderedZeroSign);
149}
150
152 bool OrderedZeroSign) {
153 return cannotOrderStrictlyGreaterImpl(RHS, LHS, false, OrderedZeroSign);
154}
155
157 bool OrderedZeroSign) {
158 return cannotOrderStrictlyGreaterImpl(RHS, LHS, true, OrderedZeroSign);
159}
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)