[llvm] expandIS_FPCLASS: Support fcNegative and fcPositive (PR #184788)
Nikita Popov via llvm-commits
llvm-commits at lists.llvm.org
Mon Jun 29 02:12:48 PDT 2026
================
@@ -10524,6 +10568,49 @@ SDValue TargetLowering::expandIS_FPCLASS(EVT ResultVT, SDValue Op,
// Tests that involve more than one class should be processed first.
SDValue PartialRes;
+ // Handle sign bit tests first (fcPositive/fcNegative).
+ // These test only the sign bit, if not NaN.
+ // On 32-bit platforms with 64-bit floats, we need to be careful about
+ // integer comparisons. We use FP_ROUND to convert to a smaller float type
+ // that matches ResultVT's size, then compare with 0.
+ FPClassTest FPTestSign = Test & (~fcNan);
+ FPClassTest FPTestNaN = Test & fcNan;
+ // FPTestSign must be exactly fcNegative or fcPositive; combined flags are
+ // not supported.
+ bool testNegative = FPTestSign == fcNegative;
+ bool testPositive = FPTestSign == fcPositive;
+ // FPTestNaN must be fcNan or fcNone; testing sNan or qNan individually is
+ // not supported.
+ bool testNaN = FPTestNaN == fcNan;
+ bool testNotNaN = FPTestNaN == fcNone;
+ if ((testPositive || testNegative) && (testNaN || testNotNaN)) {
+ bool NeedFPTrunc = false;
+
+ SDValue SignBitResult =
+ getFloatSign(ResultVT, NeedFPTrunc, Op, DAG, DL, *this);
+ // This logic is not needed if we are sure that Op is not NaN,
+ // while combiner will help us to remove it: maybe in future.
+ if (testNaN) {
+ SDValue IsNaN = DAG.getSetCC(DL, ResultVT, Op, Op, ISD::SETUO);
+ SignBitResult = DAG.getNode(ISD::OR, DL, ResultVT, IsNaN, SignBitResult);
+ } else {
+ SDValue NotNaN = DAG.getSetCC(DL, ResultVT, Op, Op, ISD::SETO);
+ SignBitResult =
+ DAG.getNode(ISD::AND, DL, ResultVT, NotNaN, SignBitResult);
+ }
+
+ bool IsICmpImmLegal =
+ isLegalICmpImmediate(APInt::getAllOnes(BitSize).getSExtValue());
+ if (NeedFPTrunc || DAG.isKnownNeverNaN(Op) ||
+ (OperandVT.isVector() && isTypeLegal(OperandVT)) || testNegative ||
+ !IsICmpImmLegal) {
+ if (!testNegative)
+ SignBitResult = DAG.getNode(ISD::XOR, DL, ResultVT, SignBitResult,
+ ResultInversionMask);
----------------
nikic wrote:
Doesn't this incorrectly also revert the NaN result, rather than just the sign result?
https://github.com/llvm/llvm-project/pull/184788
More information about the llvm-commits
mailing list