File indexing completed on 2026-05-10 08:44:00
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #ifndef LLVM_IR_FMF_H
0014 #define LLVM_IR_FMF_H
0015
0016 namespace llvm {
0017 class raw_ostream;
0018
0019
0020 class FastMathFlags {
0021 private:
0022 friend class FPMathOperator;
0023
0024 unsigned Flags = 0;
0025
0026 FastMathFlags(unsigned F) {
0027
0028
0029
0030 if (F == 0x7F) Flags = ~0U;
0031 else Flags = F;
0032 }
0033
0034 public:
0035
0036
0037
0038
0039 enum {
0040 AllowReassoc = (1 << 0),
0041 NoNaNs = (1 << 1),
0042 NoInfs = (1 << 2),
0043 NoSignedZeros = (1 << 3),
0044 AllowReciprocal = (1 << 4),
0045 AllowContract = (1 << 5),
0046 ApproxFunc = (1 << 6)
0047 };
0048
0049 FastMathFlags() = default;
0050
0051 static FastMathFlags getFast() {
0052 FastMathFlags FMF;
0053 FMF.setFast();
0054 return FMF;
0055 }
0056
0057 bool any() const { return Flags != 0; }
0058 bool none() const { return Flags == 0; }
0059 bool all() const { return Flags == ~0U; }
0060
0061 void clear() { Flags = 0; }
0062 void set() { Flags = ~0U; }
0063
0064
0065 bool allowReassoc() const { return 0 != (Flags & AllowReassoc); }
0066 bool noNaNs() const { return 0 != (Flags & NoNaNs); }
0067 bool noInfs() const { return 0 != (Flags & NoInfs); }
0068 bool noSignedZeros() const { return 0 != (Flags & NoSignedZeros); }
0069 bool allowReciprocal() const { return 0 != (Flags & AllowReciprocal); }
0070 bool allowContract() const { return 0 != (Flags & AllowContract); }
0071 bool approxFunc() const { return 0 != (Flags & ApproxFunc); }
0072
0073 bool isFast() const { return all(); }
0074
0075
0076 void setAllowReassoc(bool B = true) {
0077 Flags = (Flags & ~AllowReassoc) | B * AllowReassoc;
0078 }
0079 void setNoNaNs(bool B = true) {
0080 Flags = (Flags & ~NoNaNs) | B * NoNaNs;
0081 }
0082 void setNoInfs(bool B = true) {
0083 Flags = (Flags & ~NoInfs) | B * NoInfs;
0084 }
0085 void setNoSignedZeros(bool B = true) {
0086 Flags = (Flags & ~NoSignedZeros) | B * NoSignedZeros;
0087 }
0088 void setAllowReciprocal(bool B = true) {
0089 Flags = (Flags & ~AllowReciprocal) | B * AllowReciprocal;
0090 }
0091 void setAllowContract(bool B = true) {
0092 Flags = (Flags & ~AllowContract) | B * AllowContract;
0093 }
0094 void setApproxFunc(bool B = true) {
0095 Flags = (Flags & ~ApproxFunc) | B * ApproxFunc;
0096 }
0097 void setFast(bool B = true) { B ? set() : clear(); }
0098
0099 void operator&=(const FastMathFlags &OtherFlags) {
0100 Flags &= OtherFlags.Flags;
0101 }
0102 void operator|=(const FastMathFlags &OtherFlags) {
0103 Flags |= OtherFlags.Flags;
0104 }
0105 bool operator!=(const FastMathFlags &OtherFlags) const {
0106 return Flags != OtherFlags.Flags;
0107 }
0108
0109
0110 void print(raw_ostream &O) const;
0111
0112
0113 static inline FastMathFlags intersectRewrite(FastMathFlags LHS,
0114 FastMathFlags RHS) {
0115 const unsigned RewriteMask =
0116 AllowReassoc | AllowReciprocal | AllowContract | ApproxFunc;
0117 return FastMathFlags(RewriteMask & LHS.Flags & RHS.Flags);
0118 }
0119
0120
0121 static inline FastMathFlags unionValue(FastMathFlags LHS, FastMathFlags RHS) {
0122 const unsigned ValueMask = NoNaNs | NoInfs | NoSignedZeros;
0123 return FastMathFlags(ValueMask & (LHS.Flags | RHS.Flags));
0124 }
0125 };
0126
0127 inline FastMathFlags operator|(FastMathFlags LHS, FastMathFlags RHS) {
0128 LHS |= RHS;
0129 return LHS;
0130 }
0131
0132 inline FastMathFlags operator&(FastMathFlags LHS, FastMathFlags RHS) {
0133 LHS &= RHS;
0134 return LHS;
0135 }
0136
0137 inline raw_ostream &operator<<(raw_ostream &O, FastMathFlags FMF) {
0138 FMF.print(O);
0139 return O;
0140 }
0141
0142 }
0143
0144 #endif