aboutsummaryrefslogtreecommitdiff
path: root/include/llvm/IR
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2017-06-16 21:03:24 +0000
committerDimitry Andric <dim@FreeBSD.org>2017-06-16 21:03:24 +0000
commit7c7aba6e5fef47a01a136be655b0a92cfd7090f6 (patch)
tree99ec531924f6078534b100ab9d7696abce848099 /include/llvm/IR
parent7ab83427af0f77b59941ceba41d509d7d097b065 (diff)
Notes
Diffstat (limited to 'include/llvm/IR')
-rw-r--r--include/llvm/IR/Constants.h9
-rw-r--r--include/llvm/IR/DebugInfoMetadata.h3
-rw-r--r--include/llvm/IR/GlobalVariable.h2
-rw-r--r--include/llvm/IR/IRBuilder.h24
-rw-r--r--include/llvm/IR/InstrTypes.h8
-rw-r--r--include/llvm/IR/Instructions.h29
-rw-r--r--include/llvm/IR/IntrinsicInst.h90
-rw-r--r--include/llvm/IR/Intrinsics.td15
-rw-r--r--include/llvm/IR/ModuleSummaryIndex.h26
-rw-r--r--include/llvm/IR/ModuleSummaryIndexYAML.h18
-rw-r--r--include/llvm/IR/Operator.h1
-rw-r--r--include/llvm/IR/PatternMatch.h36
12 files changed, 153 insertions, 108 deletions
diff --git a/include/llvm/IR/Constants.h b/include/llvm/IR/Constants.h
index bb5e1931393b8..003a6d5d075dd 100644
--- a/include/llvm/IR/Constants.h
+++ b/include/llvm/IR/Constants.h
@@ -68,11 +68,8 @@ protected:
void *operator new(size_t s) { return User::operator new(s, 0); }
public:
- ConstantData() = delete;
ConstantData(const ConstantData &) = delete;
- void *operator new(size_t, unsigned) = delete;
-
/// Methods to support type inquiry through isa, cast, and dyn_cast.
static bool classof(const Value *V) {
return V->getValueID() >= ConstantDataFirstVal &&
@@ -691,8 +688,6 @@ class ConstantDataArray final : public ConstantDataSequential {
public:
ConstantDataArray(const ConstantDataArray &) = delete;
- void *operator new(size_t, unsigned) = delete;
-
/// get() constructors - Return a constant with array type with an element
/// count and element type matching the ArrayRef passed in. Note that this
/// can return a ConstantAggregateZero object.
@@ -752,8 +747,6 @@ class ConstantDataVector final : public ConstantDataSequential {
public:
ConstantDataVector(const ConstantDataVector &) = delete;
- void *operator new(size_t, unsigned) = delete;
-
/// get() constructors - Return a constant with vector type with an element
/// count and element type matching the ArrayRef passed in. Note that this
/// can return a ConstantAggregateZero object.
@@ -830,8 +823,6 @@ class BlockAddress final : public Constant {
Value *handleOperandChangeImpl(Value *From, Value *To);
public:
- void *operator new(size_t, unsigned) = delete;
-
/// Return a BlockAddress for the specified function and basic block.
static BlockAddress *get(Function *F, BasicBlock *BB);
diff --git a/include/llvm/IR/DebugInfoMetadata.h b/include/llvm/IR/DebugInfoMetadata.h
index 2174e1f301ee1..9374fe4fae766 100644
--- a/include/llvm/IR/DebugInfoMetadata.h
+++ b/include/llvm/IR/DebugInfoMetadata.h
@@ -2117,9 +2117,6 @@ public:
/// variable, or the location of a single piece of a variable, or (when using
/// DW_OP_stack_value) is the constant variable value.
///
-/// FIXME: Instead of DW_OP_plus taking an argument, this should use DW_OP_const
-/// and have DW_OP_plus consume the topmost elements on the stack.
-///
/// TODO: Co-allocate the expression elements.
/// TODO: Separate from MDNode, or otherwise drop Distinct and Temporary
/// storage types.
diff --git a/include/llvm/IR/GlobalVariable.h b/include/llvm/IR/GlobalVariable.h
index 454492769c8b8..8255a4f298c08 100644
--- a/include/llvm/IR/GlobalVariable.h
+++ b/include/llvm/IR/GlobalVariable.h
@@ -78,8 +78,6 @@ public:
return User::operator new(s, 1);
}
- void *operator new(size_t, unsigned) = delete;
-
/// Provide fast operand accessors
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
diff --git a/include/llvm/IR/IRBuilder.h b/include/llvm/IR/IRBuilder.h
index 5ddaf2b1733be..ec33f82f70224 100644
--- a/include/llvm/IR/IRBuilder.h
+++ b/include/llvm/IR/IRBuilder.h
@@ -435,27 +435,25 @@ public:
MDNode *ScopeTag = nullptr,
MDNode *NoAliasTag = nullptr);
- /// \brief Create and insert an atomic memcpy between the specified
- /// pointers.
+ /// \brief Create and insert an element unordered-atomic memcpy between the
+ /// specified pointers.
///
/// If the pointers aren't i8*, they will be converted. If a TBAA tag is
/// specified, it will be added to the instruction. Likewise with alias.scope
/// and noalias tags.
- CallInst *CreateElementAtomicMemCpy(
- Value *Dst, Value *Src, uint64_t NumElements, uint32_t ElementSize,
+ CallInst *CreateElementUnorderedAtomicMemCpy(
+ Value *Dst, Value *Src, uint64_t Size, uint32_t ElementSize,
MDNode *TBAATag = nullptr, MDNode *TBAAStructTag = nullptr,
MDNode *ScopeTag = nullptr, MDNode *NoAliasTag = nullptr) {
- return CreateElementAtomicMemCpy(Dst, Src, getInt64(NumElements),
- ElementSize, TBAATag, TBAAStructTag,
- ScopeTag, NoAliasTag);
+ return CreateElementUnorderedAtomicMemCpy(
+ Dst, Src, getInt64(Size), ElementSize, TBAATag, TBAAStructTag, ScopeTag,
+ NoAliasTag);
}
- CallInst *CreateElementAtomicMemCpy(Value *Dst, Value *Src,
- Value *NumElements, uint32_t ElementSize,
- MDNode *TBAATag = nullptr,
- MDNode *TBAAStructTag = nullptr,
- MDNode *ScopeTag = nullptr,
- MDNode *NoAliasTag = nullptr);
+ CallInst *CreateElementUnorderedAtomicMemCpy(
+ Value *Dst, Value *Src, Value *Size, uint32_t ElementSize,
+ MDNode *TBAATag = nullptr, MDNode *TBAAStructTag = nullptr,
+ MDNode *ScopeTag = nullptr, MDNode *NoAliasTag = nullptr);
/// \brief Create and insert a memmove between the specified
/// pointers.
diff --git a/include/llvm/IR/InstrTypes.h b/include/llvm/IR/InstrTypes.h
index ff63da50afee0..b3c6644c7e811 100644
--- a/include/llvm/IR/InstrTypes.h
+++ b/include/llvm/IR/InstrTypes.h
@@ -294,8 +294,6 @@ public:
return User::operator new(s, 1);
}
- void *operator new(size_t, unsigned) = delete;
-
/// Transparently provide more efficient getOperand methods.
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
@@ -343,8 +341,6 @@ public:
return User::operator new(s, 2);
}
- void *operator new(size_t, unsigned) = delete;
-
/// Transparently provide more efficient getOperand methods.
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
@@ -907,15 +903,11 @@ protected:
BasicBlock *InsertAtEnd);
public:
- CmpInst() = delete;
-
// allocate space for exactly two operands
void *operator new(size_t s) {
return User::operator new(s, 2);
}
- void *operator new(size_t, unsigned) = delete;
-
/// Construct a compare instruction, given the opcode, the predicate and
/// the two operands. Optionally (if InstBefore is specified) insert the
/// instruction into a BasicBlock right before the specified instruction.
diff --git a/include/llvm/IR/Instructions.h b/include/llvm/IR/Instructions.h
index 6029b0a7c5719..b3032f54aa424 100644
--- a/include/llvm/IR/Instructions.h
+++ b/include/llvm/IR/Instructions.h
@@ -337,8 +337,6 @@ public:
return User::operator new(s, 2);
}
- void *operator new(size_t, unsigned) = delete;
-
/// Return true if this is a store to a volatile memory location.
bool isVolatile() const { return getSubclassDataFromInstruction() & 1; }
@@ -460,8 +458,6 @@ public:
return User::operator new(s, 0);
}
- void *operator new(size_t, unsigned) = delete;
-
/// Returns the ordering effect of this fence.
AtomicOrdering getOrdering() const {
return AtomicOrdering(getSubclassDataFromInstruction() >> 1);
@@ -538,8 +534,6 @@ public:
return User::operator new(s, 3);
}
- void *operator new(size_t, unsigned) = delete;
-
/// Return true if this is a cmpxchg from a volatile memory
/// location.
///
@@ -728,8 +722,6 @@ public:
return User::operator new(s, 2);
}
- void *operator new(size_t, unsigned) = delete;
-
BinOp getOperation() const {
return static_cast<BinOp>(getSubclassDataFromInstruction() >> 5);
}
@@ -2234,8 +2226,6 @@ public:
return User::operator new(s, 3);
}
- void *operator new(size_t, unsigned) = delete;
-
/// Return true if a shufflevector instruction can be
/// formed with the specified operands.
static bool isValidOperands(const Value *V1, const Value *V2,
@@ -2467,8 +2457,6 @@ public:
return User::operator new(s, 2);
}
- void *operator new(size_t, unsigned) = delete;
-
static InsertValueInst *Create(Value *Agg, Value *Val,
ArrayRef<unsigned> Idxs,
const Twine &NameStr = "",
@@ -2596,11 +2584,6 @@ class PHINode : public Instruction {
allocHungoffUses(ReservedSpace);
}
- // allocate space for exactly zero operands
- void *operator new(size_t s) {
- return User::operator new(s);
- }
-
protected:
// Note: Instruction needs to be a friend here to call cloneImpl.
friend class Instruction;
@@ -2615,8 +2598,6 @@ protected:
}
public:
- void *operator new(size_t, unsigned) = delete;
-
/// Constructors - NumReservedValues is a hint for the number of incoming
/// edges that this phi node will have (use 0 if you really have no idea).
static PHINode *Create(Type *Ty, unsigned NumReservedValues,
@@ -2834,8 +2815,6 @@ protected:
LandingPadInst *cloneImpl() const;
public:
- void *operator new(size_t, unsigned) = delete;
-
/// Constructors - NumReservedClauses is a hint for the number of incoming
/// clauses that this landingpad will have (use 0 if you really have no idea).
static LandingPadInst *Create(Type *RetTy, unsigned NumReservedClauses,
@@ -3134,8 +3113,6 @@ protected:
SwitchInst *cloneImpl() const;
public:
- void *operator new(size_t, unsigned) = delete;
-
// -2
static const unsigned DefaultPseudoIndex = static_cast<unsigned>(~0L-1);
@@ -3489,8 +3466,6 @@ protected:
IndirectBrInst *cloneImpl() const;
public:
- void *operator new(size_t, unsigned) = delete;
-
static IndirectBrInst *Create(Value *Address, unsigned NumDests,
Instruction *InsertBefore = nullptr) {
return new IndirectBrInst(Address, NumDests, InsertBefore);
@@ -4173,8 +4148,6 @@ protected:
CatchSwitchInst *cloneImpl() const;
public:
- void *operator new(size_t, unsigned) = delete;
-
static CatchSwitchInst *Create(Value *ParentPad, BasicBlock *UnwindDest,
unsigned NumHandlers,
const Twine &NameStr = "",
@@ -4609,8 +4582,6 @@ public:
return User::operator new(s, 0);
}
- void *operator new(size_t, unsigned) = delete;
-
unsigned getNumSuccessors() const { return 0; }
// Methods for support type inquiry through isa, cast, and dyn_cast:
diff --git a/include/llvm/IR/IntrinsicInst.h b/include/llvm/IR/IntrinsicInst.h
index 2ae98d9e35b0f..e0dd3ca7d01e3 100644
--- a/include/llvm/IR/IntrinsicInst.h
+++ b/include/llvm/IR/IntrinsicInst.h
@@ -205,25 +205,91 @@ namespace llvm {
};
/// This class represents atomic memcpy intrinsic
- /// TODO: Integrate this class into MemIntrinsic hierarchy.
- class ElementAtomicMemCpyInst : public IntrinsicInst {
+ /// TODO: Integrate this class into MemIntrinsic hierarchy; for now this is
+ /// C&P of all methods from that hierarchy
+ class ElementUnorderedAtomicMemCpyInst : public IntrinsicInst {
+ private:
+ enum { ARG_DEST = 0, ARG_SOURCE = 1, ARG_LENGTH = 2, ARG_ELEMENTSIZE = 3 };
+
public:
- Value *getRawDest() const { return getArgOperand(0); }
- Value *getRawSource() const { return getArgOperand(1); }
+ Value *getRawDest() const {
+ return const_cast<Value *>(getArgOperand(ARG_DEST));
+ }
+ const Use &getRawDestUse() const { return getArgOperandUse(ARG_DEST); }
+ Use &getRawDestUse() { return getArgOperandUse(ARG_DEST); }
+
+ /// Return the arguments to the instruction.
+ Value *getRawSource() const {
+ return const_cast<Value *>(getArgOperand(ARG_SOURCE));
+ }
+ const Use &getRawSourceUse() const { return getArgOperandUse(ARG_SOURCE); }
+ Use &getRawSourceUse() { return getArgOperandUse(ARG_SOURCE); }
+
+ Value *getLength() const {
+ return const_cast<Value *>(getArgOperand(ARG_LENGTH));
+ }
+ const Use &getLengthUse() const { return getArgOperandUse(ARG_LENGTH); }
+ Use &getLengthUse() { return getArgOperandUse(ARG_LENGTH); }
+
+ bool isVolatile() const { return false; }
+
+ Value *getRawElementSizeInBytes() const {
+ return const_cast<Value *>(getArgOperand(ARG_ELEMENTSIZE));
+ }
+
+ ConstantInt *getElementSizeInBytesCst() const {
+ return cast<ConstantInt>(getRawElementSizeInBytes());
+ }
+
+ uint32_t getElementSizeInBytes() const {
+ return getElementSizeInBytesCst()->getZExtValue();
+ }
+
+ /// This is just like getRawDest, but it strips off any cast
+ /// instructions that feed it, giving the original input. The returned
+ /// value is guaranteed to be a pointer.
+ Value *getDest() const { return getRawDest()->stripPointerCasts(); }
+
+ /// This is just like getRawSource, but it strips off any cast
+ /// instructions that feed it, giving the original input. The returned
+ /// value is guaranteed to be a pointer.
+ Value *getSource() const { return getRawSource()->stripPointerCasts(); }
+
+ unsigned getDestAddressSpace() const {
+ return cast<PointerType>(getRawDest()->getType())->getAddressSpace();
+ }
- Value *getNumElements() const { return getArgOperand(2); }
- void setNumElements(Value *V) { setArgOperand(2, V); }
+ unsigned getSourceAddressSpace() const {
+ return cast<PointerType>(getRawSource()->getType())->getAddressSpace();
+ }
- uint64_t getSrcAlignment() const { return getParamAlignment(0); }
- uint64_t getDstAlignment() const { return getParamAlignment(1); }
+ /// Set the specified arguments of the instruction.
+ void setDest(Value *Ptr) {
+ assert(getRawDest()->getType() == Ptr->getType() &&
+ "setDest called with pointer of wrong type!");
+ setArgOperand(ARG_DEST, Ptr);
+ }
+
+ void setSource(Value *Ptr) {
+ assert(getRawSource()->getType() == Ptr->getType() &&
+ "setSource called with pointer of wrong type!");
+ setArgOperand(ARG_SOURCE, Ptr);
+ }
+
+ void setLength(Value *L) {
+ assert(getLength()->getType() == L->getType() &&
+ "setLength called with value of wrong type!");
+ setArgOperand(ARG_LENGTH, L);
+ }
- uint64_t getElementSizeInBytes() const {
- Value *Arg = getArgOperand(3);
- return cast<ConstantInt>(Arg)->getZExtValue();
+ void setElementSizeInBytes(Constant *V) {
+ assert(V->getType() == Type::getInt8Ty(getContext()) &&
+ "setElementSizeInBytes called with value of wrong type!");
+ setArgOperand(ARG_ELEMENTSIZE, V);
}
static inline bool classof(const IntrinsicInst *I) {
- return I->getIntrinsicID() == Intrinsic::memcpy_element_atomic;
+ return I->getIntrinsicID() == Intrinsic::memcpy_element_unordered_atomic;
}
static inline bool classof(const Value *V) {
return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
diff --git a/include/llvm/IR/Intrinsics.td b/include/llvm/IR/Intrinsics.td
index 291d16fb0d9b7..45936a6e9b66d 100644
--- a/include/llvm/IR/Intrinsics.td
+++ b/include/llvm/IR/Intrinsics.td
@@ -862,11 +862,16 @@ def int_xray_customevent : Intrinsic<[], [llvm_ptr_ty, llvm_i32_ty],
//===------ Memory intrinsics with element-wise atomicity guarantees ------===//
//
-def int_memcpy_element_atomic : Intrinsic<[],
- [llvm_anyptr_ty, llvm_anyptr_ty,
- llvm_i64_ty, llvm_i32_ty],
- [IntrArgMemOnly, NoCapture<0>, NoCapture<1>,
- WriteOnly<0>, ReadOnly<1>]>;
+// @llvm.memcpy.element.unordered.atomic.*(dest, src, length, elementsize)
+def int_memcpy_element_unordered_atomic
+ : Intrinsic<[],
+ [
+ llvm_anyptr_ty, llvm_anyptr_ty, llvm_anyint_ty, llvm_i32_ty
+ ],
+ [
+ IntrArgMemOnly, NoCapture<0>, NoCapture<1>, WriteOnly<0>,
+ ReadOnly<1>
+ ]>;
//===------------------------ Reduction Intrinsics ------------------------===//
//
diff --git a/include/llvm/IR/ModuleSummaryIndex.h b/include/llvm/IR/ModuleSummaryIndex.h
index 144e45f18d2c5..b43d588658628 100644
--- a/include/llvm/IR/ModuleSummaryIndex.h
+++ b/include/llvm/IR/ModuleSummaryIndex.h
@@ -32,6 +32,7 @@
#include <cstdint>
#include <map>
#include <memory>
+#include <set>
#include <string>
#include <utility>
#include <vector>
@@ -542,6 +543,9 @@ private:
/// considered live.
bool WithGlobalValueDeadStripping = false;
+ std::set<std::string> CfiFunctionDefs;
+ std::set<std::string> CfiFunctionDecls;
+
// YAML I/O support.
friend yaml::MappingTraits<ModuleSummaryIndex>;
@@ -567,6 +571,7 @@ public:
bool isGlobalValueLive(const GlobalValueSummary *GVS) const {
return !WithGlobalValueDeadStripping || GVS->isLive();
}
+ bool isGUIDLive(GlobalValue::GUID GUID) const;
/// Return a ValueInfo for GUID if it exists, otherwise return ValueInfo().
ValueInfo getValueInfo(GlobalValue::GUID GUID) const {
@@ -592,6 +597,12 @@ public:
return I == OidGuidMap.end() ? 0 : I->second;
}
+ std::set<std::string> &cfiFunctionDefs() { return CfiFunctionDefs; }
+ const std::set<std::string> &cfiFunctionDefs() const { return CfiFunctionDefs; }
+
+ std::set<std::string> &cfiFunctionDecls() { return CfiFunctionDecls; }
+ const std::set<std::string> &cfiFunctionDecls() const { return CfiFunctionDecls; }
+
/// Add a global value summary for a value of the given name.
void addGlobalValueSummary(StringRef ValueName,
std::unique_ptr<GlobalValueSummary> Summary) {
@@ -691,14 +702,13 @@ public:
return Pair.first;
}
- /// Add a new module path with the given \p Hash, mapped to the given \p
- /// ModID, and return an iterator to the entry in the index.
- ModulePathStringTableTy::iterator
- addModulePath(StringRef ModPath, uint64_t ModId,
- ModuleHash Hash = ModuleHash{{0}}) {
- return ModulePathStringTable.insert(std::make_pair(
- ModPath,
- std::make_pair(ModId, Hash))).first;
+ typedef ModulePathStringTableTy::value_type ModuleInfo;
+
+ /// Add a new module with the given \p Hash, mapped to the given \p
+ /// ModID, and return a reference to the module.
+ ModuleInfo *addModule(StringRef ModPath, uint64_t ModId,
+ ModuleHash Hash = ModuleHash{{0}}) {
+ return &*ModulePathStringTable.insert({ModPath, {ModId, Hash}}).first;
}
/// Check if the given Module has any functions available for exporting
diff --git a/include/llvm/IR/ModuleSummaryIndexYAML.h b/include/llvm/IR/ModuleSummaryIndexYAML.h
index 891d84c2dbcae..8950c527cc181 100644
--- a/include/llvm/IR/ModuleSummaryIndexYAML.h
+++ b/include/llvm/IR/ModuleSummaryIndexYAML.h
@@ -188,6 +188,7 @@ template <> struct MappingTraits<FunctionSummaryYaml> {
LLVM_YAML_IS_STRING_MAP(TypeIdSummary)
LLVM_YAML_IS_SEQUENCE_VECTOR(FunctionSummaryYaml)
+LLVM_YAML_IS_SEQUENCE_VECTOR(std::string)
namespace llvm {
namespace yaml {
@@ -240,6 +241,23 @@ template <> struct MappingTraits<ModuleSummaryIndex> {
io.mapOptional("TypeIdMap", index.TypeIdMap);
io.mapOptional("WithGlobalValueDeadStripping",
index.WithGlobalValueDeadStripping);
+
+ if (io.outputting()) {
+ std::vector<std::string> CfiFunctionDefs(index.CfiFunctionDefs.begin(),
+ index.CfiFunctionDefs.end());
+ io.mapOptional("CfiFunctionDefs", CfiFunctionDefs);
+ std::vector<std::string> CfiFunctionDecls(index.CfiFunctionDecls.begin(),
+ index.CfiFunctionDecls.end());
+ io.mapOptional("CfiFunctionDecls", CfiFunctionDecls);
+ } else {
+ std::vector<std::string> CfiFunctionDefs;
+ io.mapOptional("CfiFunctionDefs", CfiFunctionDefs);
+ index.CfiFunctionDefs = {CfiFunctionDefs.begin(), CfiFunctionDefs.end()};
+ std::vector<std::string> CfiFunctionDecls;
+ io.mapOptional("CfiFunctionDecls", CfiFunctionDecls);
+ index.CfiFunctionDecls = {CfiFunctionDecls.begin(),
+ CfiFunctionDecls.end()};
+ }
}
};
diff --git a/include/llvm/IR/Operator.h b/include/llvm/IR/Operator.h
index 49fa6a6a877aa..6eb5998478c65 100644
--- a/include/llvm/IR/Operator.h
+++ b/include/llvm/IR/Operator.h
@@ -35,7 +35,6 @@ public:
Operator() = delete;
~Operator() = delete;
- void *operator new(size_t, unsigned) = delete;
void *operator new(size_t s) = delete;
/// Return the opcode for this Instruction or ConstantExpr.
diff --git a/include/llvm/IR/PatternMatch.h b/include/llvm/IR/PatternMatch.h
index 542570aaaa241..015a17e8e7ca5 100644
--- a/include/llvm/IR/PatternMatch.h
+++ b/include/llvm/IR/PatternMatch.h
@@ -1027,7 +1027,7 @@ struct MaxMin_match {
(TrueVal != RHS || FalseVal != LHS))
return false;
typename CmpInst_t::Predicate Pred =
- LHS == TrueVal ? Cmp->getPredicate() : Cmp->getSwappedPredicate();
+ LHS == TrueVal ? Cmp->getPredicate() : Cmp->getInversePredicate();
// Does "(x pred y) ? x : y" represent the desired max/min operation?
if (!Pred_t::match(Pred))
return false;
@@ -1138,7 +1138,7 @@ inline MaxMin_match<FCmpInst, LHS, RHS, ofmax_pred_ty> m_OrdFMax(const LHS &L,
/// semantics. In the presence of 'NaN' we have to preserve the original
/// select(fcmp(olt/le, L, R), L, R) semantics matched by this predicate.
///
-/// max(L, R) iff L and R are not NaN
+/// min(L, R) iff L and R are not NaN
/// m_OrdFMin(L, R) = R iff L or R are NaN
template <typename LHS, typename RHS>
inline MaxMin_match<FCmpInst, LHS, RHS, ofmin_pred_ty> m_OrdFMin(const LHS &L,
@@ -1154,13 +1154,28 @@ inline MaxMin_match<FCmpInst, LHS, RHS, ofmin_pred_ty> m_OrdFMin(const LHS &L,
/// select(fcmp(ugt/ge, L, R), L, R) semantics matched by this predicate.
///
/// max(L, R) iff L and R are not NaN
-/// m_UnordFMin(L, R) = L iff L or R are NaN
+/// m_UnordFMax(L, R) = L iff L or R are NaN
template <typename LHS, typename RHS>
inline MaxMin_match<FCmpInst, LHS, RHS, ufmax_pred_ty>
m_UnordFMax(const LHS &L, const RHS &R) {
return MaxMin_match<FCmpInst, LHS, RHS, ufmax_pred_ty>(L, R);
}
+/// \brief Match an 'unordered' floating point minimum function.
+/// Floating point has one special value 'NaN'. Therefore, there is no total
+/// order. However, if we can ignore the 'NaN' value (for example, because of a
+/// 'no-nans-float-math' flag) a combination of a fcmp and select has 'minimum'
+/// semantics. In the presence of 'NaN' we have to preserve the original
+/// select(fcmp(ult/le, L, R), L, R) semantics matched by this predicate.
+///
+/// min(L, R) iff L and R are not NaN
+/// m_UnordFMin(L, R) = L iff L or R are NaN
+template <typename LHS, typename RHS>
+inline MaxMin_match<FCmpInst, LHS, RHS, ufmin_pred_ty>
+m_UnordFMin(const LHS &L, const RHS &R) {
+ return MaxMin_match<FCmpInst, LHS, RHS, ufmin_pred_ty>(L, R);
+}
+
//===----------------------------------------------------------------------===//
// Matchers for overflow check patterns: e.g. (a + b) u< a
//
@@ -1207,21 +1222,6 @@ m_UAddWithOverflow(const LHS_t &L, const RHS_t &R, const Sum_t &S) {
return UAddWithOverflow_match<LHS_t, RHS_t, Sum_t>(L, R, S);
}
-/// \brief Match an 'unordered' floating point minimum function.
-/// Floating point has one special value 'NaN'. Therefore, there is no total
-/// order. However, if we can ignore the 'NaN' value (for example, because of a
-/// 'no-nans-float-math' flag) a combination of a fcmp and select has 'minimum'
-/// semantics. In the presence of 'NaN' we have to preserve the original
-/// select(fcmp(ult/le, L, R), L, R) semantics matched by this predicate.
-///
-/// max(L, R) iff L and R are not NaN
-/// m_UnordFMin(L, R) = L iff L or R are NaN
-template <typename LHS, typename RHS>
-inline MaxMin_match<FCmpInst, LHS, RHS, ufmin_pred_ty>
-m_UnordFMin(const LHS &L, const RHS &R) {
- return MaxMin_match<FCmpInst, LHS, RHS, ufmin_pred_ty>(L, R);
-}
-
template <typename Opnd_t> struct Argument_match {
unsigned OpI;
Opnd_t Val;