1 //===-- llvm/FMF.h - Fast math flags subclass -------------------*- 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 // This file defines the fast math flags. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #ifndef LLVM_IR_FMF_H 14 #define LLVM_IR_FMF_H 15 16 namespace llvm { 17 class raw_ostream; 18 19 /// Convenience struct for specifying and reasoning about fast-math flags. 20 class FastMathFlags { 21 private: 22 friend class FPMathOperator; 23 24 unsigned Flags = 0; 25 26 FastMathFlags(unsigned F) { 27 // If all 7 bits are set, turn this into -1. If the number of bits grows, 28 // this must be updated. This is intended to provide some forward binary 29 // compatibility insurance for the meaning of 'fast' in case bits are added. 30 if (F == 0x7F) Flags = ~0U; 31 else Flags = F; 32 } 33 34 public: 35 // This is how the bits are used in Value::SubclassOptionalData so they 36 // should fit there too. 37 // WARNING: We're out of space. SubclassOptionalData only has 7 bits. New 38 // functionality will require a change in how this information is stored. 39 enum { 40 AllowReassoc = (1 << 0), 41 NoNaNs = (1 << 1), 42 NoInfs = (1 << 2), 43 NoSignedZeros = (1 << 3), 44 AllowReciprocal = (1 << 4), 45 AllowContract = (1 << 5), 46 ApproxFunc = (1 << 6) 47 }; 48 49 FastMathFlags() = default; 50 51 static FastMathFlags getFast() { 52 FastMathFlags FMF; 53 FMF.setFast(); 54 return FMF; 55 } 56 57 bool any() const { return Flags != 0; } 58 bool none() const { return Flags == 0; } 59 bool all() const { return Flags == ~0U; } 60 61 void clear() { Flags = 0; } 62 void set() { Flags = ~0U; } 63 64 /// Flag queries 65 bool allowReassoc() const { return 0 != (Flags & AllowReassoc); } 66 bool noNaNs() const { return 0 != (Flags & NoNaNs); } 67 bool noInfs() const { return 0 != (Flags & NoInfs); } 68 bool noSignedZeros() const { return 0 != (Flags & NoSignedZeros); } 69 bool allowReciprocal() const { return 0 != (Flags & AllowReciprocal); } 70 bool allowContract() const { return 0 != (Flags & AllowContract); } 71 bool approxFunc() const { return 0 != (Flags & ApproxFunc); } 72 /// 'Fast' means all bits are set. 73 bool isFast() const { return all(); } 74 75 /// Flag setters 76 void setAllowReassoc(bool B = true) { 77 Flags = (Flags & ~AllowReassoc) | B * AllowReassoc; 78 } 79 void setNoNaNs(bool B = true) { 80 Flags = (Flags & ~NoNaNs) | B * NoNaNs; 81 } 82 void setNoInfs(bool B = true) { 83 Flags = (Flags & ~NoInfs) | B * NoInfs; 84 } 85 void setNoSignedZeros(bool B = true) { 86 Flags = (Flags & ~NoSignedZeros) | B * NoSignedZeros; 87 } 88 void setAllowReciprocal(bool B = true) { 89 Flags = (Flags & ~AllowReciprocal) | B * AllowReciprocal; 90 } 91 void setAllowContract(bool B = true) { 92 Flags = (Flags & ~AllowContract) | B * AllowContract; 93 } 94 void setApproxFunc(bool B = true) { 95 Flags = (Flags & ~ApproxFunc) | B * ApproxFunc; 96 } 97 void setFast(bool B = true) { B ? set() : clear(); } 98 99 void operator&=(const FastMathFlags &OtherFlags) { 100 Flags &= OtherFlags.Flags; 101 } 102 void operator|=(const FastMathFlags &OtherFlags) { 103 Flags |= OtherFlags.Flags; 104 } 105 bool operator!=(const FastMathFlags &OtherFlags) const { 106 return Flags != OtherFlags.Flags; 107 } 108 109 /// Print fast-math flags to \p O. 110 void print(raw_ostream &O) const; 111 }; 112 113 inline FastMathFlags operator|(FastMathFlags LHS, FastMathFlags RHS) { 114 LHS |= RHS; 115 return LHS; 116 } 117 118 inline FastMathFlags operator&(FastMathFlags LHS, FastMathFlags RHS) { 119 LHS &= RHS; 120 return LHS; 121 } 122 123 inline raw_ostream &operator<<(raw_ostream &O, FastMathFlags FMF) { 124 FMF.print(O); 125 return O; 126 } 127 128 } // end namespace llvm 129 130 #endif // LLVM_IR_FMF_H 131