[clang] [llvm] [LLVM][ConstantFP] Replace uses of isExactlyValue(+/-1.0) with isOne/isMinusOne. (PR #204333)
Paul Walker via cfe-commits
cfe-commits at lists.llvm.org
Wed Jun 17 03:32:30 PDT 2026
https://github.com/paulwalker-arm created https://github.com/llvm/llvm-project/pull/204333
This follows on from https://github.com/llvm/llvm-project/pull/198496#discussion_r3266473201 and https://github.com/llvm/llvm-project/pull/198496#discussion_r3267459947.
I opted for isMinusOne() rather than isNegOne() because the former is already in use, plus I think it reads better.
I haven't surfaced isPowerOf2(N) into the constant classes because I'm unsure if we really want to use it. I'll take recommendations because I didn't fancy adding functions for every number (i.e. if Half(), isTwo() ...) and yet isPowerOf2(-2), isPowerOf2(1) seems less clear than isExactValue(0.5), isExactValue(2.0). I wondered about using an enum variant of isPowerOf2(), but figured that's no better than adding dedicated functions. With +-0.0/1.0 covered there are not many uses of isExactlyValue() so perhaps it's not worth worrying about?
>From 17e3058fc8ca8beb2c78d07f15080758e78a7776 Mon Sep 17 00:00:00 2001
From: Paul Walker <paul.walker at arm.com>
Date: Wed, 20 May 2026 14:24:56 +0000
Subject: [PATCH 1/2] [APFloat] Add is{Neg}PowerOf2(N) methods.
---
llvm/include/llvm/ADT/APFloat.h | 10 ++++++++++
llvm/unittests/ADT/APFloatTest.cpp | 26 ++++++++++++++++++++++++++
2 files changed, 36 insertions(+)
diff --git a/llvm/include/llvm/ADT/APFloat.h b/llvm/include/llvm/ADT/APFloat.h
index b2eb5b93d5331..e791e36fcc925 100644
--- a/llvm/include/llvm/ADT/APFloat.h
+++ b/llvm/include/llvm/ADT/APFloat.h
@@ -1603,6 +1603,16 @@ class APFloat : public APFloatBase {
return isNegative() ? INT_MIN : getExactLog2Abs();
}
+ // Returns true if this value is exactly 2^N.
+ LLVM_READONLY
+ bool isPowerOf2(int N) const { return N != INT_MIN && getExactLog2() == N; }
+
+ // Returns true if this value is exactly -(2^N).
+ LLVM_READONLY
+ bool isNegPowerOf2(int N) const {
+ return N != INT_MIN && isNegative() && getExactLog2Abs() == N;
+ }
+
LLVM_ABI friend hash_code hash_value(const APFloat &Arg);
friend int ilogb(const APFloat &Arg);
friend APFloat scalbn(APFloat X, int Exp, roundingMode RM);
diff --git a/llvm/unittests/ADT/APFloatTest.cpp b/llvm/unittests/ADT/APFloatTest.cpp
index 6841d4bcb6093..0913a44f7effb 100644
--- a/llvm/unittests/ADT/APFloatTest.cpp
+++ b/llvm/unittests/ADT/APFloatTest.cpp
@@ -9420,6 +9420,32 @@ TEST(APFloatTest, getExactLog2) {
}
}
+TEST(APFloatTest, isPowerOf2) {
+ const fltSemantics &Semantics = APFloat::IEEEdouble();
+
+ EXPECT_TRUE(APFloat(Semantics, "1.0").isPowerOf2(0));
+ EXPECT_TRUE(APFloat(Semantics, "8.0").isPowerOf2(3));
+ EXPECT_TRUE(APFloat(Semantics, "0.25").isPowerOf2(-2));
+
+ EXPECT_FALSE(APFloat(Semantics, "3.0").isPowerOf2(1));
+ EXPECT_FALSE(APFloat(Semantics, "-8.0").isPowerOf2(3));
+ EXPECT_FALSE(APFloat(Semantics, "-8.0").isPowerOf2(INT_MIN));
+ EXPECT_FALSE(APFloat::getZero(Semantics, false).isPowerOf2(0));
+ EXPECT_FALSE(APFloat::getInf(Semantics).isPowerOf2(0));
+ EXPECT_FALSE(APFloat::getNaN(Semantics, false).isPowerOf2(0));
+
+ EXPECT_TRUE(APFloat(Semantics, "-1.0").isNegPowerOf2(0));
+ EXPECT_TRUE(APFloat(Semantics, "-8.0").isNegPowerOf2(3));
+ EXPECT_TRUE(APFloat(Semantics, "-0.25").isNegPowerOf2(-2));
+
+ EXPECT_FALSE(APFloat(Semantics, "-3.0").isNegPowerOf2(1));
+ EXPECT_FALSE(APFloat(Semantics, "8.0").isNegPowerOf2(3));
+ EXPECT_FALSE(APFloat(Semantics, "8.0").isNegPowerOf2(INT_MIN));
+ EXPECT_FALSE(APFloat::getZero(Semantics, false).isNegPowerOf2(0));
+ EXPECT_FALSE(APFloat::getInf(Semantics).isNegPowerOf2(0));
+ EXPECT_FALSE(APFloat::getNaN(Semantics, false).isNegPowerOf2(0));
+}
+
TEST(APFloatTest, Float8E8M0FNUGetZero) {
#ifdef GTEST_HAS_DEATH_TEST
#ifndef NDEBUG
>From daf915a6260abd1a0a2f06b84c9e29d31b05f039 Mon Sep 17 00:00:00 2001
From: Paul Walker <paul.walker at arm.com>
Date: Wed, 27 May 2026 17:18:06 +0100
Subject: [PATCH 2/2] Replace instance of isExactlyValue(+/-1.0) with
isOne/isMinusOne.
---
clang/lib/AST/ByteCode/Floating.h | 4 +--
llvm/include/llvm/ADT/APFloat.h | 6 ++++
llvm/include/llvm/CodeGen/SelectionDAGNodes.h | 6 ++++
llvm/include/llvm/IR/Constants.h | 6 ++++
llvm/lib/Analysis/ConstantFolding.cpp | 6 ++--
.../lib/CodeGen/GlobalISel/CombinerHelper.cpp | 2 +-
llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 28 +++++++++----------
.../lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 8 +++---
.../lib/Target/AArch64/AArch64InstrFormats.td | 2 +-
.../Target/AMDGPU/AMDGPUCodeGenPrepare.cpp | 7 ++---
llvm/lib/Target/AMDGPU/AMDGPUInstructions.td | 2 +-
.../lib/Target/AMDGPU/AMDGPULegalizerInfo.cpp | 8 +++---
llvm/lib/Target/AMDGPU/AMDGPULibCalls.cpp | 4 +--
.../Target/AMDGPU/AMDGPURegBankCombiner.cpp | 6 ++--
llvm/lib/Target/AMDGPU/R600ISelLowering.cpp | 4 +--
llvm/lib/Target/AMDGPU/SIISelLowering.cpp | 17 ++++++-----
.../LoongArch/LoongArchISelLowering.cpp | 4 +--
.../Target/LoongArch/LoongArchInstrInfo.td | 2 +-
llvm/lib/Target/NVPTX/NVPTXInstrInfo.td | 4 +--
llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 6 ++--
llvm/lib/Target/SPIRV/SPIRVCombinerHelper.cpp | 2 +-
llvm/lib/Target/X86/X86InstrFragments.td | 4 +--
llvm/lib/Transforms/Scalar/Reassociate.cpp | 2 +-
.../llvm-reduce/deltas/ReduceOperands.cpp | 3 +-
llvm/unittests/IR/MDBuilderTest.cpp | 2 +-
25 files changed, 80 insertions(+), 65 deletions(-)
diff --git a/clang/lib/AST/ByteCode/Floating.h b/clang/lib/AST/ByteCode/Floating.h
index cc918dc12deb6..f848538a73b90 100644
--- a/clang/lib/AST/ByteCode/Floating.h
+++ b/clang/lib/AST/ByteCode/Floating.h
@@ -144,7 +144,7 @@ class Floating final {
bool isZero() const { return getValue().isZero(); }
bool isNonZero() const { return getValue().isNonZero(); }
bool isMin() const { return getValue().isSmallest(); }
- bool isMinusOne() const { return getValue().isExactlyValue(-1.0); }
+ bool isMinusOne() const { return getValue().isMinusOne(); }
bool isNan() const { return getValue().isNaN(); }
bool isSignaling() const { return getValue().isSignaling(); }
bool isInf() const { return getValue().isInfinity(); }
@@ -166,7 +166,7 @@ class Floating final {
case llvm::APFloatBase::cmpUnordered:
return ComparisonCategoryResult::Unordered;
}
- llvm_unreachable("Inavlid cmpResult value");
+ llvm_unreachable("Invalid cmpResult value");
}
static APFloat::opStatus fromIntegral(APSInt Val,
diff --git a/llvm/include/llvm/ADT/APFloat.h b/llvm/include/llvm/ADT/APFloat.h
index e791e36fcc925..32f846b9c9594 100644
--- a/llvm/include/llvm/ADT/APFloat.h
+++ b/llvm/include/llvm/ADT/APFloat.h
@@ -1613,6 +1613,12 @@ class APFloat : public APFloatBase {
return N != INT_MIN && isNegative() && getExactLog2Abs() == N;
}
+ // Returns true if this value is exactly +1.0.
+ LLVM_READONLY bool isOne() const { return isPowerOf2(0); }
+
+ // Returns true if this value is exactly -1.0.
+ LLVM_READONLY bool isMinusOne() const { return isNegPowerOf2(0); }
+
LLVM_ABI friend hash_code hash_value(const APFloat &Arg);
friend int ilogb(const APFloat &Arg);
friend APFloat scalbn(APFloat X, int Exp, roundingMode RM);
diff --git a/llvm/include/llvm/CodeGen/SelectionDAGNodes.h b/llvm/include/llvm/CodeGen/SelectionDAGNodes.h
index 6292dcd97fc8d..b280bd48c94e9 100644
--- a/llvm/include/llvm/CodeGen/SelectionDAGNodes.h
+++ b/llvm/include/llvm/CodeGen/SelectionDAGNodes.h
@@ -1895,6 +1895,12 @@ class ConstantFPSDNode : public SDNode {
/// Return true if the value is negative.
bool isNegative() const { return Value->isNegative(); }
+ /// Returns true if this value is exactly +1.0.
+ bool isOne() const { return Value->isOne(); }
+
+ /// Returns true if this value is exactly -1.0.
+ bool isMinusOne() const { return Value->isMinusOne(); }
+
/// We don't rely on operator== working on double values, as
/// it returns true for things that are clearly not equal, like -0.0 and 0.0.
/// As such, this method can be used to do an exact bit-for-bit comparison of
diff --git a/llvm/include/llvm/IR/Constants.h b/llvm/include/llvm/IR/Constants.h
index d1a65db0af31f..d5299aebd16fe 100644
--- a/llvm/include/llvm/IR/Constants.h
+++ b/llvm/include/llvm/IR/Constants.h
@@ -481,6 +481,12 @@ class ConstantFP final : public ConstantData {
/// Return true if the value is a NaN.
bool isNaN() const { return Val.isNaN(); }
+ /// Returns true if this value is exactly +1.0.
+ bool isOne() const { return Val.isOne(); }
+
+ /// Returns true if this value is exactly -1.0.
+ bool isMinusOne() const { return Val.isMinusOne(); }
+
/// We don't rely on operator== working on double values, as it returns true
/// for things that are clearly not equal, like -0.0 and 0.0.
/// As such, this method can be used to do an exact bit-for-bit comparison of
diff --git a/llvm/lib/Analysis/ConstantFolding.cpp b/llvm/lib/Analysis/ConstantFolding.cpp
index 3fe78d6c4322d..92d3dadced29b 100644
--- a/llvm/lib/Analysis/ConstantFolding.cpp
+++ b/llvm/lib/Analysis/ConstantFolding.cpp
@@ -2845,7 +2845,7 @@ static Constant *ConstantFoldScalarCall1(StringRef Name,
return ConstantFP::getInfinity(Ty, true);
if (U.isNegative())
return ConstantFP::getNaN(Ty);
- if (U.isExactlyValue(1.0))
+ if (U.isOne())
return ConstantFP::getZero(Ty);
return ConstantFoldFP(log, APF, Ty);
case Intrinsic::log2:
@@ -2853,7 +2853,7 @@ static Constant *ConstantFoldScalarCall1(StringRef Name,
return ConstantFP::getInfinity(Ty, true);
if (U.isNegative())
return ConstantFP::getNaN(Ty);
- if (U.isExactlyValue(1.0))
+ if (U.isOne())
return ConstantFP::getZero(Ty);
// TODO: What about hosts that lack a C99 library?
return ConstantFoldFP(log2, APF, Ty);
@@ -2862,7 +2862,7 @@ static Constant *ConstantFoldScalarCall1(StringRef Name,
return ConstantFP::getInfinity(Ty, true);
if (U.isNegative())
return ConstantFP::getNaN(Ty);
- if (U.isExactlyValue(1.0))
+ if (U.isOne())
return ConstantFP::getZero(Ty);
// TODO: What about hosts that lack a C99 library?
return ConstantFoldFP(log10, APF, Ty);
diff --git a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
index 3cc00d816c0e6..5b1f9a744514e 100644
--- a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
@@ -7017,7 +7017,7 @@ bool CombinerHelper::matchRepeatedFPDivisor(
auto IsOne = [this](Register X) {
auto N0CFP = isConstantOrConstantSplatVectorFP(*MRI.getVRegDef(X), MRI);
- return N0CFP && (N0CFP->isExactlyValue(1.0) || N0CFP->isExactlyValue(-1.0));
+ return N0CFP && (N0CFP->isOne() || N0CFP->isMinusOne());
};
// Skip if current node is a reciprocal/fneg-reciprocal.
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index 7fdaacff0582d..05358ebea8cd9 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -18781,10 +18781,10 @@ SDValue DAGCombiner::visitFMULForFMADistributiveCombine(SDNode *N) {
auto FuseFADD = [&](SDValue X, SDValue Y) {
if (X.getOpcode() == ISD::FADD && (Aggressive || X->hasOneUse())) {
if (auto *C = isConstOrConstSplatFP(X.getOperand(1), true)) {
- if (C->isExactlyValue(+1.0))
+ if (C->isOne())
return DAG.getNode(PreferredFusedOpcode, SL, VT, X.getOperand(0), Y,
Y);
- if (C->isExactlyValue(-1.0))
+ if (C->isMinusOne())
return DAG.getNode(PreferredFusedOpcode, SL, VT, X.getOperand(0), Y,
DAG.getNode(ISD::FNEG, SL, VT, Y));
}
@@ -18804,20 +18804,20 @@ SDValue DAGCombiner::visitFMULForFMADistributiveCombine(SDNode *N) {
auto FuseFSUB = [&](SDValue X, SDValue Y) {
if (X.getOpcode() == ISD::FSUB && (Aggressive || X->hasOneUse())) {
if (auto *C0 = isConstOrConstSplatFP(X.getOperand(0), true)) {
- if (C0->isExactlyValue(+1.0))
+ if (C0->isOne())
return DAG.getNode(PreferredFusedOpcode, SL, VT,
DAG.getNode(ISD::FNEG, SL, VT, X.getOperand(1)), Y,
Y);
- if (C0->isExactlyValue(-1.0))
+ if (C0->isMinusOne())
return DAG.getNode(PreferredFusedOpcode, SL, VT,
DAG.getNode(ISD::FNEG, SL, VT, X.getOperand(1)), Y,
DAG.getNode(ISD::FNEG, SL, VT, Y));
}
if (auto *C1 = isConstOrConstSplatFP(X.getOperand(1), true)) {
- if (C1->isExactlyValue(+1.0))
+ if (C1->isOne())
return DAG.getNode(PreferredFusedOpcode, SL, VT, X.getOperand(0), Y,
DAG.getNode(ISD::FNEG, SL, VT, Y));
- if (C1->isExactlyValue(-1.0))
+ if (C1->isMinusOne())
return DAG.getNode(PreferredFusedOpcode, SL, VT, X.getOperand(0), Y,
Y);
}
@@ -19300,7 +19300,7 @@ SDValue DAGCombiner::visitFMUL(SDNode *N) {
return DAG.getNode(ISD::FADD, DL, VT, N0, N0);
// fold (fmul X, -1.0) -> (fsub -0.0, X)
- if (N1CFP && N1CFP->isExactlyValue(-1.0)) {
+ if (N1CFP && N1CFP->isMinusOne()) {
if (!LegalOperations || TLI.isOperationLegal(ISD::FSUB, VT)) {
return DAG.getNode(ISD::FSUB, DL, VT,
DAG.getConstantFP(-0.0, DL, VT), N0, Flags);
@@ -19356,11 +19356,11 @@ SDValue DAGCombiner::visitFMUL(SDNode *N) {
case ISD::SETUGE:
case ISD::SETGT:
case ISD::SETGE:
- if (TrueOpnd->isExactlyValue(-1.0) && FalseOpnd->isExactlyValue(1.0) &&
+ if (TrueOpnd->isMinusOne() && FalseOpnd->isOne() &&
TLI.isOperationLegal(ISD::FNEG, VT))
return DAG.getNode(ISD::FNEG, DL, VT,
DAG.getNode(ISD::FABS, DL, VT, X));
- if (TrueOpnd->isExactlyValue(1.0) && FalseOpnd->isExactlyValue(-1.0))
+ if (TrueOpnd->isOne() && FalseOpnd->isMinusOne())
return DAG.getNode(ISD::FABS, DL, VT, X);
break;
@@ -19424,9 +19424,9 @@ SDValue DAGCombiner::visitFMA(SDNode *N) {
}
}
- if (N0CFP && N0CFP->isExactlyValue(1.0))
+ if (N0CFP && N0CFP->isOne())
return DAG.getNode(ISD::FADD, DL, VT, N1, N2);
- if (N1CFP && N1CFP->isExactlyValue(1.0))
+ if (N1CFP && N1CFP->isOne())
return DAG.getNode(ISD::FADD, DL, VT, N0, N2);
// Canonicalize (fma c, x, y) -> (fma x, c, y)
@@ -19456,10 +19456,10 @@ SDValue DAGCombiner::visitFMA(SDNode *N) {
// (fma x, -1, y) -> (fadd (fneg x), y)
if (N1CFP) {
- if (N1CFP->isExactlyValue(1.0))
+ if (N1CFP->isOne())
return DAG.getNode(ISD::FADD, DL, VT, N0, N2);
- if (N1CFP->isExactlyValue(-1.0) &&
+ if (N1CFP->isMinusOne() &&
(!LegalOperations || TLI.isOperationLegal(ISD::FNEG, VT))) {
SDValue RHSNeg = DAG.getNode(ISD::FNEG, DL, VT, N0);
AddToWorklist(RHSNeg.getNode());
@@ -19548,7 +19548,7 @@ SDValue DAGCombiner::combineRepeatedFPDivisors(SDNode *N) {
// Skip if current node is a reciprocal/fneg-reciprocal.
SDValue N0 = N->getOperand(0), N1 = N->getOperand(1);
ConstantFPSDNode *N0CFP = isConstOrConstSplatFP(N0, /* AllowUndefs */ true);
- if (N0CFP && (N0CFP->isExactlyValue(1.0) || N0CFP->isExactlyValue(-1.0)))
+ if (N0CFP && (N0CFP->isOne() || N0CFP->isMinusOne()))
return SDValue();
// Exit early if the target does not want this transform or if there can't
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index 534ba48bd5d1a..631b4d07e8004 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -11682,7 +11682,7 @@ SDValue SelectionDAG::simplifyFPBinop(unsigned Opcode, SDValue X, SDValue Y,
// X * 1.0 --> X
// X / 1.0 --> X
if (Opcode == ISD::FMUL || Opcode == ISD::FDIV)
- if (YC->getValueAPF().isExactlyValue(1.0))
+ if (YC->getValueAPF().isOne())
return X;
// X * 0.0 --> 0.0
@@ -13699,9 +13699,9 @@ bool SelectionDAG::isIdentityElement(unsigned Opcode, SDNodeFlags Flags,
return OperandNo == 1 && ConstFP->isZero() &&
(Flags.hasNoSignedZeros() || !ConstFP->isNegative());
case ISD::FMUL:
- return ConstFP->isExactlyValue(1.0);
+ return ConstFP->isOne();
case ISD::FDIV:
- return OperandNo == 1 && ConstFP->isExactlyValue(1.0);
+ return OperandNo == 1 && ConstFP->isOne();
case ISD::FMINNUM:
case ISD::FMAXNUM: {
// Neutral element for fminnum is NaN, Inf or FLT_MAX, depending on FMF.
@@ -13856,7 +13856,7 @@ bool llvm::isOneOrOneSplat(SDValue N, bool AllowUndefs) {
bool llvm::isOneOrOneSplatFP(SDValue N, bool AllowUndefs) {
ConstantFPSDNode *C = isConstOrConstSplatFP(N, AllowUndefs);
- return C && C->isExactlyValue(1.0);
+ return C && C->isOne();
}
bool llvm::isAllOnesOrAllOnesSplat(SDValue N, bool AllowUndefs) {
diff --git a/llvm/lib/Target/AArch64/AArch64InstrFormats.td b/llvm/lib/Target/AArch64/AArch64InstrFormats.td
index 787a11401cb6e..daf53c99988b0 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrFormats.td
+++ b/llvm/lib/Target/AArch64/AArch64InstrFormats.td
@@ -1568,7 +1568,7 @@ def fpimm_half : FPImmLeaf<fAny, [{
}]>;
def fpimm_one : FPImmLeaf<fAny, [{
- return Imm.isExactlyValue(+1.0);
+ return Imm.isOne();
}]>;
def fpimm_two : FPImmLeaf<fAny, [{
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUCodeGenPrepare.cpp b/llvm/lib/Target/AMDGPU/AMDGPUCodeGenPrepare.cpp
index 394c2326a64ef..486b0dd62d371 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUCodeGenPrepare.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUCodeGenPrepare.cpp
@@ -738,7 +738,7 @@ Value *AMDGPUCodeGenPrepareImpl::optimizeWithRsq(
bool IsNegative = false;
// TODO: Handle other numerator values with arcp.
- if (CLHS->isExactlyValue(1.0) || (IsNegative = CLHS->isExactlyValue(-1.0))) {
+ if (CLHS->isOne() || (IsNegative = CLHS->isMinusOne())) {
// Add in the sqrt flags.
IRBuilder<>::FastMathFlagGuard Guard(Builder);
Builder.setFastMathFlags(DivFMF | SqrtFMF);
@@ -779,8 +779,7 @@ AMDGPUCodeGenPrepareImpl::optimizeWithRcp(IRBuilder<> &Builder, Value *Num,
if (const ConstantFP *CLHS = dyn_cast<ConstantFP>(Num)) {
bool IsNegative = false;
- if (CLHS->isExactlyValue(1.0) ||
- (IsNegative = CLHS->isExactlyValue(-1.0))) {
+ if (CLHS->isOne() || (IsNegative = CLHS->isMinusOne())) {
Value *Src = Den;
if (HasFP32DenormalFlush || FMF.approxFunc()) {
@@ -843,7 +842,7 @@ Value *AMDGPUCodeGenPrepareImpl::optimizeWithFDivFast(
bool NumIsOne = false;
if (const ConstantFP *CNum = dyn_cast<ConstantFP>(Num)) {
- if (CNum->isExactlyValue(+1.0) || CNum->isExactlyValue(-1.0))
+ if (CNum->isOne() || CNum->isMinusOne())
NumIsOne = true;
}
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUInstructions.td b/llvm/lib/Target/AMDGPU/AMDGPUInstructions.td
index 11d8aef61c858..2387afe1cd362 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUInstructions.td
+++ b/llvm/lib/Target/AMDGPU/AMDGPUInstructions.td
@@ -766,7 +766,7 @@ int BF16_NEG_ONE = 0xBF80;
def CONST : Constants;
def fpimm_zero : FPImmLeaf<fAny, [{ return Imm.isZero(); }]> ;
-def fpimm_one : FPImmLeaf<fAny, [{ return Imm.isExactlyValue(+1.0); }]> ;
+def fpimm_one : FPImmLeaf<fAny, [{ return Imm.isOne(); }]> ;
def fpimm_half : FPImmLeaf<fAny, [{ return Imm.isExactlyValue(+0.5); }]> ;
/* Generic helper patterns for intrinsics */
diff --git a/llvm/lib/Target/AMDGPU/AMDGPULegalizerInfo.cpp b/llvm/lib/Target/AMDGPU/AMDGPULegalizerInfo.cpp
index 65ae77cec0846..57d7d42bb5b9c 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPULegalizerInfo.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPULegalizerInfo.cpp
@@ -5514,7 +5514,7 @@ bool AMDGPULegalizerInfo::legalizeFastUnsafeFDIV(MachineInstr &MI,
// v_rcp_f16 and v_rsq_f16 DO support denormals and 0.51ulp.
// 1 / x -> RCP(x)
- if (CLHS->isExactlyValue(1.0)) {
+ if (CLHS->isOne()) {
B.buildIntrinsic(Intrinsic::amdgcn_rcp, Res)
.addUse(RHS)
.setMIFlags(Flags);
@@ -5524,7 +5524,7 @@ bool AMDGPULegalizerInfo::legalizeFastUnsafeFDIV(MachineInstr &MI,
}
// -1 / x -> RCP( FNEG(x) )
- if (CLHS->isExactlyValue(-1.0)) {
+ if (CLHS->isMinusOne()) {
auto FNeg = B.buildFNeg(ResTy, RHS, Flags);
B.buildIntrinsic(Intrinsic::amdgcn_rcp, Res)
.addUse(FNeg.getReg(0))
@@ -5566,7 +5566,7 @@ bool AMDGPULegalizerInfo::legalizeFastUnsafeFDIV64(MachineInstr &MI,
return false;
const ConstantFP *CLHS = getConstantFPVRegVal(X, MRI);
- bool IsNegRcp = CLHS && CLHS->isExactlyValue(-1.0);
+ bool IsNegRcp = CLHS && CLHS->isMinusOne();
// Pull out the negation so it folds for free into the source modifiers.
if (IsNegRcp)
@@ -5588,7 +5588,7 @@ bool AMDGPULegalizerInfo::legalizeFastUnsafeFDIV64(MachineInstr &MI,
R = B.buildFMA(ResTy, Tmp1, R, R);
// Skip the last 2 correction terms for reciprocal.
- if (IsNegRcp || (CLHS && CLHS->isExactlyValue(1.0))) {
+ if (IsNegRcp || (CLHS && CLHS->isOne())) {
B.buildCopy(Res, R);
MI.eraseFromParent();
return true;
diff --git a/llvm/lib/Target/AMDGPU/AMDGPULibCalls.cpp b/llvm/lib/Target/AMDGPU/AMDGPULibCalls.cpp
index 2d1cc1c0c66c0..f01487effb8ad 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPULibCalls.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPULibCalls.cpp
@@ -908,7 +908,7 @@ bool AMDGPULibCalls::fold_pow(FPMathOperator *FPOp, IRBuilder<> &B,
replaceCall(FPOp, cnval);
return true;
}
- if ((CF && CF->isExactlyValue(1.0)) || (CINT && ci_opr1 == 1)) {
+ if ((CF && CF->isOne()) || (CINT && ci_opr1 == 1)) {
// pow/powr/pown(x, 1.0) = x
LLVM_DEBUG(errs() << "AMDIC: " << *FPOp << " ---> " << *opr0 << "\n");
replaceCall(FPOp, opr0);
@@ -922,7 +922,7 @@ bool AMDGPULibCalls::fold_pow(FPMathOperator *FPOp, IRBuilder<> &B,
replaceCall(FPOp, nval);
return true;
}
- if ((CF && CF->isExactlyValue(-1.0)) || (CINT && ci_opr1 == -1)) {
+ if ((CF && CF->isMinusOne()) || (CINT && ci_opr1 == -1)) {
// pow/powr/pown(x, -1.0) = 1.0/x
LLVM_DEBUG(errs() << "AMDIC: " << *FPOp << " ---> 1 / " << *opr0 << "\n");
Constant *cnval = ConstantFP::get(eltType, 1.0);
diff --git a/llvm/lib/Target/AMDGPU/AMDGPURegBankCombiner.cpp b/llvm/lib/Target/AMDGPU/AMDGPURegBankCombiner.cpp
index 74184333e5b69..f9d8a09e29b0d 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPURegBankCombiner.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPURegBankCombiner.cpp
@@ -297,7 +297,7 @@ bool AMDGPURegBankCombinerImpl::matchFPMinMaxToClamp(MachineInstr &MI,
if (!matchMed<GFCstOrSplatGFCstMatch>(MI, MRI, OpcodeTriple, Val, K0, K1))
return false;
- if (!K0->Value.isPosZero() || !K1->Value.isExactlyValue(1.0))
+ if (!K0->Value.isPosZero() || !K1->Value.isOne())
return false;
// For IEEE=false perform combine only when it's safe to assume that there are
@@ -596,8 +596,8 @@ bool AMDGPURegBankCombinerImpl::isClampZeroToOne(MachineInstr *K0,
if (isFCst(K0) && isFCst(K1)) {
const ConstantFP *KO_FPImm = K0->getOperand(1).getFPImm();
const ConstantFP *K1_FPImm = K1->getOperand(1).getFPImm();
- return (KO_FPImm->isPosZero() && K1_FPImm->isExactlyValue(1.0)) ||
- (KO_FPImm->isExactlyValue(1.0) && K1_FPImm->isPosZero());
+ return (KO_FPImm->isPosZero() && K1_FPImm->isOne()) ||
+ (KO_FPImm->isOne() && K1_FPImm->isPosZero());
}
return false;
}
diff --git a/llvm/lib/Target/AMDGPU/R600ISelLowering.cpp b/llvm/lib/Target/AMDGPU/R600ISelLowering.cpp
index ae8e73eb5f329..79ef880fb569a 100644
--- a/llvm/lib/Target/AMDGPU/R600ISelLowering.cpp
+++ b/llvm/lib/Target/AMDGPU/R600ISelLowering.cpp
@@ -791,7 +791,7 @@ bool R600TargetLowering::isZero(SDValue Op) const {
bool R600TargetLowering::isHWTrueValue(SDValue Op) const {
if (ConstantFPSDNode * CFP = dyn_cast<ConstantFPSDNode>(Op)) {
- return CFP->isExactlyValue(1.0);
+ return CFP->isOne();
}
return isAllOnesConstant(Op);
}
@@ -1586,7 +1586,7 @@ static SDValue CompactSwizzlableVector(
if (C->isZero()) {
RemapSwizzle[i] = 4; // SEL_0
NewBldVec[i] = DAG.getUNDEF(MVT::f32);
- } else if (C->isExactlyValue(1.0)) {
+ } else if (C->isOne()) {
RemapSwizzle[i] = 5; // SEL_1
NewBldVec[i] = DAG.getUNDEF(MVT::f32);
}
diff --git a/llvm/lib/Target/AMDGPU/SIISelLowering.cpp b/llvm/lib/Target/AMDGPU/SIISelLowering.cpp
index e22acbe288d0d..375ed3a6eb1ce 100644
--- a/llvm/lib/Target/AMDGPU/SIISelLowering.cpp
+++ b/llvm/lib/Target/AMDGPU/SIISelLowering.cpp
@@ -13274,7 +13274,7 @@ SDValue SITargetLowering::lowerFastUnsafeFDIV(SDValue Op,
if (!AllowInaccurateRcp && VT != MVT::f16 && VT != MVT::bf16)
return SDValue();
- if (CLHS->isExactlyValue(1.0)) {
+ if (CLHS->isOne()) {
// v_rcp_f32 and v_rsq_f32 do not support denormals, and according to
// the CI documentation has a worst case error of 1 ulp.
// OpenCL requires <= 2.5 ulp for 1.0 / x, so it should always be OK to
@@ -13291,7 +13291,7 @@ SDValue SITargetLowering::lowerFastUnsafeFDIV(SDValue Op,
}
// Same as for 1.0, but expand the sign out of the constant.
- if (CLHS->isExactlyValue(-1.0)) {
+ if (CLHS->isMinusOne()) {
// -1.0 / x -> rcp (fneg x)
SDValue FNegRHS = DAG.getNode(ISD::FNEG, SL, VT, RHS);
return DAG.getNode(AMDGPUISD::RCP, SL, VT, FNegRHS);
@@ -13323,7 +13323,7 @@ SDValue SITargetLowering::lowerFastUnsafeFDIV64(SDValue Op,
return SDValue();
const ConstantFPSDNode *CLHS = dyn_cast<ConstantFPSDNode>(X);
- bool IsNegRcp = CLHS && CLHS->isExactlyValue(-1.0);
+ bool IsNegRcp = CLHS && CLHS->isMinusOne();
// Pull out the negation so it folds for free into the source modifiers.
if (IsNegRcp)
@@ -13343,7 +13343,7 @@ SDValue SITargetLowering::lowerFastUnsafeFDIV64(SDValue Op,
R = DAG.getNode(ISD::FMA, SL, VT, Tmp1, R, R);
// Skip the last 2 correction terms for reciprocal.
- if (IsNegRcp || (CLHS && CLHS->isExactlyValue(1.0)))
+ if (IsNegRcp || (CLHS && CLHS->isOne()))
return R;
SDValue Ret = DAG.getNode(ISD::FMUL, SL, VT, X, R);
@@ -16228,7 +16228,7 @@ SDValue SITargetLowering::performFPMed3ImmCombine(SelectionDAG &DAG,
// If dx10_clamp is enabled, NaNs clamp to 0.0. This is the same as the
// hardware fmed3 behavior converting to a min.
// FIXME: Should this be allowing -0.0?
- if (K1->isExactlyValue(1.0) && K0->isPosZero())
+ if (K1->isOne() && K0->isPosZero())
return DAG.getNode(AMDGPUISD::CLAMP, SL, VT, Op0.getOperand(0));
}
@@ -16426,8 +16426,8 @@ static bool isClampZeroToOne(SDValue A, SDValue B) {
if (ConstantFPSDNode *CA = dyn_cast<ConstantFPSDNode>(A)) {
if (ConstantFPSDNode *CB = dyn_cast<ConstantFPSDNode>(B)) {
// FIXME: Should this be allowing -0.0?
- return (CA->isPosZero() && CB->isExactlyValue(1.0)) ||
- (CA->isExactlyValue(1.0) && CB->isPosZero());
+ return (CA->isPosZero() && CB->isOne()) ||
+ (CA->isOne() && CB->isPosZero());
}
}
@@ -17817,8 +17817,7 @@ SDValue SITargetLowering::performFDivCombine(SDNode *N,
if (const ConstantFPSDNode *CLHS = dyn_cast<ConstantFPSDNode>(LHS)) {
bool IsNegative = false;
- if (CLHS->isExactlyValue(1.0) ||
- (IsNegative = CLHS->isExactlyValue(-1.0))) {
+ if (CLHS->isOne() || (IsNegative = CLHS->isMinusOne())) {
// fdiv contract 1.0, (sqrt contract x) -> rsq
// fdiv contract -1.0, (sqrt contract x) -> fneg(rsq)
if (RHS.getOpcode() == ISD::FSQRT) {
diff --git a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
index 4e71b6d3949fb..0ad651c03abde 100644
--- a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
+++ b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
@@ -924,7 +924,7 @@ SDValue LoongArchTargetLowering::lowerConstantFP(SDValue Op,
// use floating point load from the constant pool.
auto Seq = LoongArchMatInt::generateInstSeq(INTVal.getSExtValue());
int InsNum = Seq.size() + ((VT == MVT::f64 && !Subtarget.is64Bit()) ? 2 : 1);
- if (InsNum > MaterializeFPImmInsNum && !FPVal.isExactlyValue(+1.0))
+ if (InsNum > MaterializeFPImmInsNum && !FPVal.isOne())
return SDValue();
switch (VT.getSimpleVT().SimpleTy) {
@@ -10419,7 +10419,7 @@ bool LoongArchTargetLowering::isFPImmLegal(const APFloat &Imm, EVT VT,
return false;
if (VT == MVT::f64 && !Subtarget.hasBasicD())
return false;
- return (Imm.isZero() || Imm.isExactlyValue(1.0) || isFPImmVLDILegal(Imm, VT));
+ return (Imm.isZero() || Imm.isOne() || isFPImmVLDILegal(Imm, VT));
}
bool LoongArchTargetLowering::isCheapToSpeculateCttz(Type *) const {
diff --git a/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td b/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td
index 019539fbeab47..6aacfd8138ff5 100644
--- a/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td
+++ b/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td
@@ -579,7 +579,7 @@ def NegImm : SDNodeXForm<imm, [{
// FP immediate patterns.
def fpimm0 : PatLeaf<(fpimm), [{return N->isPosZero();}]>;
def fpimm0neg : PatLeaf<(fpimm), [{return N->isNegZero();}]>;
-def fpimm1 : PatLeaf<(fpimm), [{return N->isExactlyValue(+1.0);}]>;
+def fpimm1 : PatLeaf<(fpimm), [{return N->isOne();}]>;
// Return an immediate subtracted from 32.
def ImmSubFrom32 : SDNodeXForm<imm, [{
diff --git a/llvm/lib/Target/NVPTX/NVPTXInstrInfo.td b/llvm/lib/Target/NVPTX/NVPTXInstrInfo.td
index ff3e5144c6fbe..5f1c16dc7f0fb 100644
--- a/llvm/lib/Target/NVPTX/NVPTXInstrInfo.td
+++ b/llvm/lib/Target/NVPTX/NVPTXInstrInfo.td
@@ -187,8 +187,8 @@ class zeroinitializer<ValueType vt> :
def fpimm_pos_inf : FPImmLeaf<fAny, [{ return Imm.isPosInfinity(); }]>;
def fpimm_0 : FPImmLeaf<fAny, [{ return Imm.isZero(); }]>;
-def fpimm_1 : FPImmLeaf<fAny, [{ return Imm.isExactlyValue(1.0); }]>;
-def fpimm_neg_1 : FPImmLeaf<fAny, [{ return Imm.isExactlyValue(-1.0); }]>;
+def fpimm_1 : FPImmLeaf<fAny, [{ return Imm.isOne(); }]>;
+def fpimm_neg_1 : FPImmLeaf<fAny, [{ return Imm.isMinusOne(); }]>;
// Operands which can hold a Register or an Immediate.
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index c7010c95bfc07..cb7c3d823eeb5 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -10227,9 +10227,9 @@ SDValue RISCVTargetLowering::lowerSELECT(SDValue Op, SelectionDAG &DAG) const {
const ConstantFPSDNode *FPTV = dyn_cast<ConstantFPSDNode>(TrueV);
const ConstantFPSDNode *FPFV = dyn_cast<ConstantFPSDNode>(FalseV);
if (FPTV && FPFV) {
- if (FPTV->isExactlyValue(1.0) && FPFV->isPosZero())
+ if (FPTV->isOne() && FPFV->isPosZero())
return DAG.getNode(ISD::SINT_TO_FP, DL, VT, CondV);
- if (FPTV->isPosZero() && FPFV->isExactlyValue(1.0)) {
+ if (FPTV->isPosZero() && FPFV->isOne()) {
SDValue XOR = DAG.getNode(ISD::XOR, DL, XLenVT, CondV,
DAG.getConstant(1, DL, XLenVT));
return DAG.getNode(ISD::SINT_TO_FP, DL, VT, XOR);
@@ -21779,7 +21779,7 @@ SDValue RISCVTargetLowering::PerformDAGCombine(SDNode *N,
if (N0->getOpcode() != ISD::FCOPYSIGN)
return SDValue();
ConstantFPSDNode *C = dyn_cast<ConstantFPSDNode>(N0->getOperand(0));
- if (!C || !C->getValueAPF().isExactlyValue(+1.0))
+ if (!C || !C->getValueAPF().isOne())
return SDValue();
if (VT.isVector() || !isOperationLegal(ISD::FCOPYSIGN, VT))
return SDValue();
diff --git a/llvm/lib/Target/SPIRV/SPIRVCombinerHelper.cpp b/llvm/lib/Target/SPIRV/SPIRVCombinerHelper.cpp
index e4af82b11e7d8..660bee0f7a2cd 100644
--- a/llvm/lib/Target/SPIRV/SPIRVCombinerHelper.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVCombinerHelper.cpp
@@ -150,7 +150,7 @@ bool SPIRVCombinerHelper::matchSelectToFaceForward(MachineInstr &MI) const {
mi_match(FalseReg, MRI,
m_GFMul(m_GFCstOrSplat(MulConstant),
m_SpecificReg(TrueReg)))) {
- if (!MulConstant || !MulConstant->Value.isExactlyValue(-1.0))
+ if (!MulConstant || !MulConstant->Value.isMinusOne())
return false;
} else if (!AreNegatedConstantsOrSplats(TrueReg, FalseReg))
return false;
diff --git a/llvm/lib/Target/X86/X86InstrFragments.td b/llvm/lib/Target/X86/X86InstrFragments.td
index 9316360c5e02a..fb5cdb21c8d7e 100644
--- a/llvm/lib/Target/X86/X86InstrFragments.td
+++ b/llvm/lib/Target/X86/X86InstrFragments.td
@@ -1056,9 +1056,9 @@ def fpimmneg0 : FPImmLeaf<fAny, [{
}]>;
def fpimm1 : FPImmLeaf<fAny, [{
- return Imm.isExactlyValue(+1.0);
+ return Imm.isOne();
}]>;
def fpimmneg1 : FPImmLeaf<fAny, [{
- return Imm.isExactlyValue(-1.0);
+ return Imm.isMinusOne();
}]>;
diff --git a/llvm/lib/Transforms/Scalar/Reassociate.cpp b/llvm/lib/Transforms/Scalar/Reassociate.cpp
index 1d90cd5fe87e7..636e9ccb265ca 100644
--- a/llvm/lib/Transforms/Scalar/Reassociate.cpp
+++ b/llvm/lib/Transforms/Scalar/Reassociate.cpp
@@ -2333,7 +2333,7 @@ void ReassociatePass::ReassociateExpression(BinaryOperator *I) {
cast<Instruction>(I->user_back())->getOpcode() ==
Instruction::FAdd &&
isa<ConstantFP>(Ops.back().Op) &&
- cast<ConstantFP>(Ops.back().Op)->isExactlyValue(-1.0)) {
+ cast<ConstantFP>(Ops.back().Op)->isMinusOne()) {
ValueEntry Tmp = Ops.pop_back_val();
Ops.insert(Ops.begin(), Tmp);
}
diff --git a/llvm/tools/llvm-reduce/deltas/ReduceOperands.cpp b/llvm/tools/llvm-reduce/deltas/ReduceOperands.cpp
index 79272fe2eaeb7..a85131e6e01dd 100644
--- a/llvm/tools/llvm-reduce/deltas/ReduceOperands.cpp
+++ b/llvm/tools/llvm-reduce/deltas/ReduceOperands.cpp
@@ -57,8 +57,7 @@ static bool isZero(Use &Op) {
static bool isZeroOrOneFP(Value *Op) {
const APFloat *C;
- return match(Op, m_APFloat(C)) &&
- ((C->isZero() && !C->isNegative()) || C->isExactlyValue(1.0));
+ return match(Op, m_APFloat(C)) && (C->isPosZero() || C->isOne());
}
static bool shouldReduceOperand(Use &Op) {
diff --git a/llvm/unittests/IR/MDBuilderTest.cpp b/llvm/unittests/IR/MDBuilderTest.cpp
index 4656c70ce9cad..a923418a05d64 100644
--- a/llvm/unittests/IR/MDBuilderTest.cpp
+++ b/llvm/unittests/IR/MDBuilderTest.cpp
@@ -40,7 +40,7 @@ TEST_F(MDBuilderTest, createFPMath) {
EXPECT_TRUE(mdconst::hasa<ConstantFP>(Op));
ConstantFP *Val = mdconst::extract<ConstantFP>(Op);
EXPECT_TRUE(Val->getType()->isFloatingPointTy());
- EXPECT_TRUE(Val->isExactlyValue(1.0));
+ EXPECT_TRUE(Val->isOne());
}
TEST_F(MDBuilderTest, createRangeMetadata) {
MDBuilder MDHelper(Context);
More information about the cfe-commits
mailing list