Skip to content

[llvm] add GenericFloatingPointPredicateUtils #140254

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
May 21, 2025
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
479 changes: 479 additions & 0 deletions llvm/include/llvm/ADT/GenericFloatingPointPredicateUtils.h

Large diffs are not rendered by default.

73 changes: 73 additions & 0 deletions llvm/include/llvm/Analysis/FloatingPointPredicateUtils.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
//===- llvm/Analysis/FloatingPointPredicateUtils.h ------------*- C++ -*00-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_ANALYSIS_FLOATINGPOINTPREDICATEUTILS_H
#define LLVM_ANALYSIS_FLOATINGPOINTPREDICATEUTILS_H

#include "llvm/ADT/GenericFloatingPointPredicateUtils.h"
#include "llvm/IR/SSAContext.h"

namespace llvm {

using FloatingPointPredicateUtils =
GenericFloatingPointPredicateUtils<SSAContext>;

/// Returns a pair of values, which if passed to llvm.is.fpclass, returns the
/// same result as an fcmp with the given operands.
///
/// If \p LookThroughSrc is true, consider the input value when computing the
/// mask.
///
/// If \p LookThroughSrc is false, ignore the source value (i.e. the first pair
/// element will always be LHS.
inline std::pair<Value *, FPClassTest>
fcmpToClassTest(FCmpInst::Predicate Pred, const Function &F, Value *LHS,
Value *RHS, bool LookThroughSrc = true) {
return FloatingPointPredicateUtils::fcmpToClassTest(Pred, F, LHS, RHS,
LookThroughSrc = true);
}

/// Returns a pair of values, which if passed to llvm.is.fpclass, returns the
/// same result as an fcmp with the given operands.
///
/// If \p LookThroughSrc is true, consider the input value when computing the
/// mask.
///
/// If \p LookThroughSrc is false, ignore the source value (i.e. the first pair
/// element will always be LHS.
inline std::pair<Value *, FPClassTest>
fcmpToClassTest(FCmpInst::Predicate Pred, const Function &F, Value *LHS,
const APFloat *ConstRHS, bool LookThroughSrc = true) {
return FloatingPointPredicateUtils::fcmpToClassTest(Pred, F, LHS, *ConstRHS,
LookThroughSrc);
}

inline std::tuple<Value *, FPClassTest, FPClassTest>
fcmpImpliesClass(CmpInst::Predicate Pred, const Function &F, Value *LHS,
FPClassTest RHSClass, bool LookThroughSrc = true) {
return FloatingPointPredicateUtils::fcmpImpliesClass(Pred, F, LHS, RHSClass,
LookThroughSrc);
}

inline std::tuple<Value *, FPClassTest, FPClassTest>
fcmpImpliesClass(CmpInst::Predicate Pred, const Function &F, Value *LHS,
const APFloat &ConstRHS, bool LookThroughSrc = true) {
return FloatingPointPredicateUtils::fcmpImpliesClass(Pred, F, LHS, ConstRHS,
LookThroughSrc);
}

inline std::tuple<Value *, FPClassTest, FPClassTest>
fcmpImpliesClass(CmpInst::Predicate Pred, const Function &F, Value *LHS,
Value *RHS, bool LookThroughSrc = true) {
return FloatingPointPredicateUtils::fcmpImpliesClass(Pred, F, LHS, RHS,
LookThroughSrc);
}

} // namespace llvm

#endif // LLVM_ANALYSIS_FLOATINGPOINTPREDICATEUTILS_H
43 changes: 0 additions & 43 deletions llvm/include/llvm/Analysis/ValueTracking.h
Original file line number Diff line number Diff line change
Expand Up @@ -213,49 +213,6 @@ Intrinsic::ID getIntrinsicForCallSite(const CallBase &CB,
bool isSignBitCheck(ICmpInst::Predicate Pred, const APInt &RHS,
bool &TrueIfSigned);

/// Returns a pair of values, which if passed to llvm.is.fpclass, returns the
/// same result as an fcmp with the given operands.
///
/// If \p LookThroughSrc is true, consider the input value when computing the
/// mask.
///
/// If \p LookThroughSrc is false, ignore the source value (i.e. the first pair
/// element will always be LHS.
std::pair<Value *, FPClassTest> fcmpToClassTest(CmpInst::Predicate Pred,
const Function &F, Value *LHS,
Value *RHS,
bool LookThroughSrc = true);
std::pair<Value *, FPClassTest> fcmpToClassTest(CmpInst::Predicate Pred,
const Function &F, Value *LHS,
const APFloat *ConstRHS,
bool LookThroughSrc = true);

/// Compute the possible floating-point classes that \p LHS could be based on
/// fcmp \Pred \p LHS, \p RHS.
///
/// \returns { TestedValue, ClassesIfTrue, ClassesIfFalse }
///
/// If the compare returns an exact class test, ClassesIfTrue == ~ClassesIfFalse
///
/// This is a less exact version of fcmpToClassTest (e.g. fcmpToClassTest will
/// only succeed for a test of x > 0 implies positive, but not x > 1).
///
/// If \p LookThroughSrc is true, consider the input value when computing the
/// mask. This may look through sign bit operations.
///
/// If \p LookThroughSrc is false, ignore the source value (i.e. the first pair
/// element will always be LHS.
///
std::tuple<Value *, FPClassTest, FPClassTest>
fcmpImpliesClass(CmpInst::Predicate Pred, const Function &F, Value *LHS,
Value *RHS, bool LookThroughSrc = true);
std::tuple<Value *, FPClassTest, FPClassTest>
fcmpImpliesClass(CmpInst::Predicate Pred, const Function &F, Value *LHS,
FPClassTest RHS, bool LookThroughSrc = true);
std::tuple<Value *, FPClassTest, FPClassTest>
fcmpImpliesClass(CmpInst::Predicate Pred, const Function &F, Value *LHS,
const APFloat &RHS, bool LookThroughSrc = true);

/// Determine which floating-point classes are valid for \p V, and return them
/// in KnownFPClass bit sets.
///
Expand Down
46 changes: 46 additions & 0 deletions llvm/include/llvm/CodeGen/MachineFloatingPointPredicateUtils.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
//===-- MachineFloatingPointModeUtils.h -----*- C++ ---------------------*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_CODEGEN_MACHINEFLOATINGPOINTPREDICATEUTILS_H
#define LLVM_CODEGEN_MACHINEFLOATINGPOINTPREDICATEUTILS_H

#include "llvm/ADT/GenericFloatingPointPredicateUtils.h"
#include "llvm/CodeGen/MachineSSAContext.h"

namespace llvm {

using MachineFloatingPointPredicateUtils =
GenericFloatingPointPredicateUtils<MachineSSAContext>;

/// Compute the possible floating-point classes that \p LHS could be based on
/// fcmp \Pred \p LHS, \p RHS.
///
/// \returns { TestedValue, ClassesIfTrue, ClassesIfFalse }
///
/// If the compare returns an exact class test, ClassesIfTrue ==
/// ~ClassesIfFalse
///
/// This is a less exact version of fcmpToClassTest (e.g. fcmpToClassTest will
/// only succeed for a test of x > 0 implies positive, but not x > 1).
///
/// If \p LookThroughSrc is true, consider the input value when computing the
/// mask. This may look through sign bit operations.
///
/// If \p LookThroughSrc is false, ignore the source value (i.e. the first
/// pair element will always be LHS.
///
inline std::tuple<Register, FPClassTest, FPClassTest>
fcmpImpliesClass(CmpInst::Predicate Pred, const MachineFunction &MF,
Register LHS, Register RHS, bool LookThroughSrc = true) {
return MachineFloatingPointPredicateUtils::fcmpImpliesClass(
Pred, MF, LHS, RHS, LookThroughSrc);
}

} // namespace llvm

#endif // LLVM_CODEGEN_MACHINEFLOATINGPOINTPREDICATEUTILS_H
1 change: 1 addition & 0 deletions llvm/lib/Analysis/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ add_llvm_component_library(LLVMAnalysis
DXILResource.cpp
DXILMetadataAnalysis.cpp
EphemeralValuesCache.cpp
FloatingPointPredicateUtils.cpp
FunctionPropertiesAnalysis.cpp
GlobalsModRef.cpp
GuardUtils.cpp
Expand Down
41 changes: 41 additions & 0 deletions llvm/lib/Analysis/FloatingPointPredicateUtils.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
//===- FloatingPointPredicateUtils.cpp - -----------*- C++ -*--------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "llvm/Analysis/FloatingPointPredicateUtils.h"
#include "llvm/IR/PatternMatch.h"
#include <optional>

namespace llvm {

using namespace PatternMatch;

template <>
DenormalMode FloatingPointPredicateUtils::queryDenormalMode(const Function &F,
Value *Val) {
Type *Ty = Val->getType()->getScalarType();
return F.getDenormalMode(Ty->getFltSemantics());
}

template <>
bool FloatingPointPredicateUtils::lookThroughFAbs(const Function &F, Value *LHS,
Value *&Src) {
return match(LHS, m_FAbs(m_Value(Src)));
}

template <>
std::optional<APFloat>
FloatingPointPredicateUtils::matchConstantFloat(const Function &F, Value *Val) {
const APFloat *ConstVal;

if (!match(Val, m_APFloatAllowPoison(ConstVal)))
return std::nullopt;

return *ConstVal;
}

} // namespace llvm
1 change: 1 addition & 0 deletions llvm/lib/Analysis/InstructionSimplify.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include "llvm/Analysis/CaptureTracking.h"
#include "llvm/Analysis/CmpInstAnalysis.h"
#include "llvm/Analysis/ConstantFolding.h"
#include "llvm/Analysis/FloatingPointPredicateUtils.h"
#include "llvm/Analysis/InstSimplifyFolder.h"
#include "llvm/Analysis/Loads.h"
#include "llvm/Analysis/LoopAnalysisManager.h"
Expand Down
Loading
Loading