[llvm] Revert "[PowerPC] improve performance on the isNan and !isNan function in case of -ffp-model=strict" (PR #212509)

zhijian lin via llvm-commits llvm-commits at lists.llvm.org
Tue Jul 28 07:33:31 PDT 2026


https://github.com/diggerlin created https://github.com/llvm/llvm-project/pull/212509

The PR cause a regression on the test_suite fail as
Check '!__builtin_issignaling(X)' in file '/home/buildbots/llvm-external-buildbots/workers/ppc64le-clang-test-suite/clang-ppc64le-test-suite/test/test-suite/SingleSource/UnitTests/Float/classify-f32.h' at line 101 failed for the value '7fffffff' 

This patch reverts commit 624569002f06a27543ac964b2b338d677deb4e37.
 , we will reland a new version fix of  "improve performance on the isNan and !isNan function in case of -ffp-model=strict" later after the regression is fixed.

>From 570f3661d6c7cd36f04b1f0a92df91704dc0a0a7 Mon Sep 17 00:00:00 2001
From: zhijian <zhijian at ca.ibm.com>
Date: Tue, 28 Jul 2026 14:13:27 +0000
Subject: [PATCH] Revert "[PowerPC] improve performance on the isNan and !isNan
 function  in case of -ffp-model=strict (#204170)"

This reverts commit 624569002f06a27543ac964b2b338d677deb4e37.
---
 llvm/lib/Target/PowerPC/PPCISelLowering.cpp  |  72 +----------
 llvm/test/CodeGen/PowerPC/fp-classify-nan.ll | 126 -------------------
 2 files changed, 6 insertions(+), 192 deletions(-)
 delete mode 100644 llvm/test/CodeGen/PowerPC/fp-classify-nan.ll

diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
index 8a03946a2ca10..91125abb89504 100644
--- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
+++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
@@ -817,9 +817,6 @@ PPCTargetLowering::PPCTargetLowering(const PPCTargetMachine &TM,
     setOperationAction(ISD::FCANONICALIZE, MVT::f32, Legal);
   }
 
-  setOperationAction(ISD::IS_FPCLASS, MVT::f32, Custom);
-  setOperationAction(ISD::IS_FPCLASS, MVT::f64, Custom);
-
   if (Subtarget.hasAltivec()) {
     for (MVT VT : { MVT::v16i8, MVT::v8i16, MVT::v4i32 }) {
       setOperationAction(ISD::AVGCEILS, VT, Legal);
@@ -1261,8 +1258,11 @@ PPCTargetLowering::PPCTargetLowering(const PPCTargetMachine &TM,
     if (Subtarget.hasP9Vector()) {
       setOperationAction(ISD::INSERT_VECTOR_ELT, MVT::v4i32, Custom);
       setOperationAction(ISD::INSERT_VECTOR_ELT, MVT::v4f32, Custom);
+
       // Test data class instructions store results in CR bits.
       if (Subtarget.useCRBits()) {
+        setOperationAction(ISD::IS_FPCLASS, MVT::f32, Custom);
+        setOperationAction(ISD::IS_FPCLASS, MVT::f64, Custom);
         setOperationAction(ISD::IS_FPCLASS, MVT::f128, Custom);
         setOperationAction(ISD::IS_FPCLASS, MVT::ppcf128, Custom);
       }
@@ -11962,78 +11962,18 @@ static SDValue getDataClassTest(SDValue Op, FPClassTest Mask, const SDLoc &Dl,
 
 SDValue PPCTargetLowering::LowerIS_FPCLASS(SDValue Op,
                                            SelectionDAG &DAG) const {
+  assert(Subtarget.hasP9Vector() && "Test data class requires Power9");
   SDValue LHS = Op.getOperand(0);
   uint64_t RHSC = Op.getConstantOperandVal(1);
   SDLoc Dl(Op);
   FPClassTest Category = static_cast<FPClassTest>(RHSC);
-  EVT VT = LHS.getValueType();
-
-  assert((VT == MVT::f32 || VT == MVT::f64 ||
-          ((VT == MVT::f128 || VT == MVT::ppcf128) && Subtarget.hasVSX() &&
-           Subtarget.useCRBits())) &&
-         "invalid customize type for IS_FPCLASS.");
-  // Handle ppcf128 by extracting the higher part
-  if (VT == MVT::ppcf128) {
+  if (LHS.getValueType() == MVT::ppcf128) {
     // The higher part determines the value class.
     LHS = DAG.getNode(ISD::EXTRACT_ELEMENT, Dl, MVT::f64, LHS,
                       DAG.getConstant(1, Dl, MVT::i32));
-    VT = MVT::f64;
-  }
-
-  // If we have P9Vector and useCRBits, use the data class test instructions
-  if (Subtarget.hasP9Vector() && Subtarget.useCRBits()) {
-    return getDataClassTest(LHS, Category, Dl, DAG, Subtarget);
-  }
-
-  // For non-P9Vector targets, we can only check for NaN using fcmpu/xscmpudp
-  // These instructions set CR bits based on comparison with itself:
-  // - If value is NaN, the comparison is unordered (FU bit set)
-  // - If value is not NaN, the comparison is equal (EQ bit set)
-
-  if ((Category & ~fcNan) && (Category != ~fcNan)) {
-    // If not checking for NaN or non-NaN, we can't handle this without P9Vector
-    return SDValue();
   }
 
-  // Determine which comparison instruction to use based on vector support
-  unsigned CmpOp;
-
-  if (Subtarget.hasVSX()) {
-    // Use xscmpudp for VSX targets (both f32 and f64)
-    // For f32, extend to f64 first
-    if (VT == MVT::f32) {
-      LHS = DAG.getNode(ISD::FP_EXTEND, Dl, MVT::f64, LHS);
-    } else if (VT != MVT::f64) {
-      return SDValue();
-    }
-    CmpOp = PPC::XSCMPUDP;
-  } else {
-    // Use fcmpu for non-VSX targets
-    // FCMPUS and FCMPUD both map to the same fcmpu instruction,
-    // just with different register classes (f4rc vs f8rc)
-    if (VT == MVT::f64) {
-      CmpOp = PPC::FCMPUD;
-    } else if (VT == MVT::f32) {
-      CmpOp = PPC::FCMPUS;
-    } else {
-      return SDValue();
-    }
-  }
-
-  // Create the comparison: fcmpu/xscmpudp CR, LHS, LHS
-  // The CR field output will be allocated by the register allocator
-  SDValue Cmp = SDValue(DAG.getMachineNode(CmpOp, Dl, MVT::i32, LHS, LHS), 0);
-
-  // Extract the unordered bit (FU) from the CR field
-  // For NaN detection: FU bit is set if operands are unordered (i.e., NaN)
-  SDValue NanCheck = SDValue(
-      DAG.getMachineNode(
-          TargetOpcode::EXTRACT_SUBREG, Dl, MVT::i1, Cmp,
-          DAG.getTargetConstant(Category == ~fcNan ? PPC::sub_un : PPC::sub_eq,
-                                Dl, MVT::i32)),
-      0);
-
-  return DAG.getNOT(Dl, NanCheck, MVT::i1);
+  return getDataClassTest(LHS, Category, Dl, DAG, Subtarget);
 }
 
 // Adjust the length value for a load/store with length to account for the
diff --git a/llvm/test/CodeGen/PowerPC/fp-classify-nan.ll b/llvm/test/CodeGen/PowerPC/fp-classify-nan.ll
deleted file mode 100644
index 3a866984f2ba7..0000000000000
--- a/llvm/test/CodeGen/PowerPC/fp-classify-nan.ll
+++ /dev/null
@@ -1,126 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
-; RUN: llc -mtriple=powerpc64le-unknown-linux-gnu -mcpu=pwr8 < %s \
-; RUN:   -verify-machineinstrs -ppc-asm-full-reg-names | FileCheck %s --check-prefix=P8
-; RUN: llc -mtriple=powerpc64le-unknown-linux-gnu -mcpu=pwr9 < %s \
-; RUN:   -verify-machineinstrs -ppc-asm-full-reg-names | FileCheck %s --check-prefix=P9
-; RUN: llc -mtriple=powerpc64le-unknown-linux-gnu -mcpu=pwr8 -mattr=-vsx < %s \
-; RUN:   -verify-machineinstrs -ppc-asm-full-reg-names | FileCheck %s --check-prefix=P8-NO-VSX
-
-; RUN: llc -mtriple=powerpc-ibm-aix7.2.0.0 -mcpu=pwr8 < %s \
-; RUN:   -verify-machineinstrs -ppc-asm-full-reg-names | FileCheck %s --check-prefix=P8
-; RUN: llc -mtriple=powerpc-ibm-aix7.2.0.0 -mcpu=pwr9 < %s \
-; RUN:   -verify-machineinstrs -ppc-asm-full-reg-names | FileCheck %s --check-prefix=P9
-; RUN: llc -mtriple=powerpc-ibm-aix7.2.0.0 -mcpu=pwr8 -mattr=-vsx < %s \
-; RUN:   -verify-machineinstrs -ppc-asm-full-reg-names | FileCheck %s --check-prefix=P8-NO-VSX
-;
-define zeroext i1 @test_is_nan_f64(double %x) #0 {
-; P8-LABEL: test_is_nan_f64:
-; P8:       # %bb.0:
-; P8-NEXT:    xscmpudp cr0, f1, f1
-; P8-NEXT:    li r3, 1
-; P8-NEXT:    iseleq r3, 0, r3
-; P8-NEXT:    blr
-;
-; P9-LABEL: test_is_nan_f64:
-; P9:       # %bb.0:
-; P9-NEXT:    xststdcdp cr0, f1, 64
-; P9-NEXT:    li r3, 0
-; P9-NEXT:    li r4, 1
-; P9-NEXT:    iseleq r3, r4, r3
-; P9-NEXT:    blr
-;
-; P8-NO-VSX-LABEL: test_is_nan_f64:
-; P8-NO-VSX:       # %bb.0:
-; P8-NO-VSX-NEXT:    fcmpu cr0, f1, f1
-; P8-NO-VSX-NEXT:    li r3, 1
-; P8-NO-VSX-NEXT:    iseleq r3, 0, r3
-; P8-NO-VSX-NEXT:    blr
-  %result = call i1 @llvm.is.fpclass.f64(double %x, i32 3)
-  ret i1 %result
-}
-
-define zeroext i1 @test_is_not_nan_f64(double %x) #0 {
-; P8-LABEL: test_is_not_nan_f64:
-; P8:       # %bb.0:
-; P8-NEXT:    xscmpudp cr0, f1, f1
-; P8-NEXT:    li r3, 1
-; P8-NEXT:    isel r3, 0, r3, un
-; P8-NEXT:    blr
-;
-; P9-LABEL: test_is_not_nan_f64:
-; P9:       # %bb.0:
-; P9-NEXT:    xststdcdp cr0, f1, 64
-; P9-NEXT:    li r3, 1
-; P9-NEXT:    iseleq r3, 0, r3
-; P9-NEXT:    blr
-;
-; P8-NO-VSX-LABEL: test_is_not_nan_f64:
-; P8-NO-VSX:       # %bb.0:
-; P8-NO-VSX-NEXT:    fcmpu cr0, f1, f1
-; P8-NO-VSX-NEXT:    li r3, 1
-; P8-NO-VSX-NEXT:    isel r3, 0, r3, un
-; P8-NO-VSX-NEXT:    blr
-  %result = call i1 @llvm.is.fpclass.f64(double %x, i32 1020)
-  ret i1 %result
-}
-
-define zeroext i1 @test_is_nan_f32(float %x) #0 {
-; P8-LABEL: test_is_nan_f32:
-; P8:       # %bb.0:
-; P8-NEXT:    xscmpudp cr0, f1, f1
-; P8-NEXT:    li r3, 1
-; P8-NEXT:    iseleq r3, 0, r3
-; P8-NEXT:    blr
-;
-; P9-LABEL: test_is_nan_f32:
-; P9:       # %bb.0:
-; P9-NEXT:    xststdcsp cr0, f1, 64
-; P9-NEXT:    li r3, 0
-; P9-NEXT:    li r4, 1
-; P9-NEXT:    iseleq r3, r4, r3
-; P9-NEXT:    blr
-;
-; P8-NO-VSX-LABEL: test_is_nan_f32:
-; P8-NO-VSX:       # %bb.0:
-; P8-NO-VSX-NEXT:    fcmpu cr0, f1, f1
-; P8-NO-VSX-NEXT:    li r3, 1
-; P8-NO-VSX-NEXT:    iseleq r3, 0, r3
-; P8-NO-VSX-NEXT:    blr
-  %result = call i1 @llvm.is.fpclass.f32(float %x, i32 3)
-  ret i1 %result
-}
-
-define zeroext i1 @test_is_not_nan_f32(float %x) #0 {
-; P8-LABEL: test_is_not_nan_f32:
-; P8:       # %bb.0:
-; P8-NEXT:    xscmpudp cr0, f1, f1
-; P8-NEXT:    li r3, 1
-; P8-NEXT:    isel r3, 0, r3, un
-; P8-NEXT:    blr
-;
-; P9-LABEL: test_is_not_nan_f32:
-; P9:       # %bb.0:
-; P9-NEXT:    xststdcsp cr0, f1, 64
-; P9-NEXT:    li r3, 1
-; P9-NEXT:    iseleq r3, 0, r3
-; P9-NEXT:    blr
-;
-; P8-NO-VSX-LABEL: test_is_not_nan_f32:
-; P8-NO-VSX:       # %bb.0:
-; P8-NO-VSX-NEXT:    fcmpu cr0, f1, f1
-; P8-NO-VSX-NEXT:    li r3, 1
-; P8-NO-VSX-NEXT:    isel r3, 0, r3, un
-; P8-NO-VSX-NEXT:    blr
-  %result = call i1 @llvm.is.fpclass.f32(float %x, i32 1020)
-  ret i1 %result
-}
-
-declare i1 @llvm.is.fpclass.f64(double, i32)
-declare i1 @llvm.is.fpclass.f32(float, i32)
-declare float @llvm.fabs.f32(float)
-declare double @llvm.fabs.f64(double)
-declare fp128 @llvm.fabs.f128(fp128)
-declare <4 x float> @llvm.fabs.v4f32(<4 x float>)
-declare <2 x double> @llvm.fabs.v2f64(<2 x double>)
-
-attributes #0 = {strictfp}



More information about the llvm-commits mailing list