diff --git a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp --- a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp @@ -5064,6 +5064,20 @@ } } + if (isOperationLegalOrCustom(ISD::IS_FPCLASS, N0.getValueType()) && + !isFPImmLegal(CFP->getValueAPF(), CFP->getValueType(0))) { + bool IsFabs = N0.getOpcode() == ISD::FABS; + SDValue Op = IsFabs ? N0.getOperand(0) : N0; + if ((Cond == ISD::SETOEQ || Cond == ISD::SETUEQ) && CFP->isInfinity()) { + FPClassTest Flag = CFP->isNegative() ? (IsFabs ? fcNone : fcNegInf) + : (IsFabs ? fcInf : fcPosInf); + if (Cond == ISD::SETUEQ) + Flag |= fcNan; + return DAG.getNode(ISD::IS_FPCLASS, dl, VT, Op, + DAG.getTargetConstant(Flag, dl, MVT::i32)); + } + } + // If the condition is not legal, see if we can find an equivalent one // which is legal. if (!isCondCodeLegal(Cond, N0.getSimpleValueType())) { diff --git a/llvm/test/CodeGen/PowerPC/fp-classify.ll b/llvm/test/CodeGen/PowerPC/fp-classify.ll --- a/llvm/test/CodeGen/PowerPC/fp-classify.ll +++ b/llvm/test/CodeGen/PowerPC/fp-classify.ll @@ -18,12 +18,9 @@ ; ; P9-LABEL: abs_isinff: ; P9: # %bb.0: # %entry -; P9-NEXT: addis 3, 2, .LCPI0_0@toc@ha -; P9-NEXT: xsabsdp 0, 1 -; P9-NEXT: li 4, 1 -; P9-NEXT: lfs 1, .LCPI0_0@toc@l(3) +; P9-NEXT: xststdcsp 0, 1, 48 ; P9-NEXT: li 3, 0 -; P9-NEXT: fcmpu 0, 0, 1 +; P9-NEXT: li 4, 1 ; P9-NEXT: iseleq 3, 4, 3 ; P9-NEXT: blr entry: @@ -46,12 +43,9 @@ ; ; P9-LABEL: abs_isinf: ; P9: # %bb.0: # %entry -; P9-NEXT: addis 3, 2, .LCPI1_0@toc@ha -; P9-NEXT: xsabsdp 0, 1 -; P9-NEXT: li 4, 1 -; P9-NEXT: lfs 1, .LCPI1_0@toc@l(3) +; P9-NEXT: xststdcdp 0, 1, 48 ; P9-NEXT: li 3, 0 -; P9-NEXT: fcmpu 0, 0, 1 +; P9-NEXT: li 4, 1 ; P9-NEXT: iseleq 3, 4, 3 ; P9-NEXT: blr entry: @@ -91,13 +85,9 @@ ; ; P9-LABEL: abs_isinfq: ; P9: # %bb.0: # %entry -; P9-NEXT: addis 3, 2, .LCPI2_0@toc@ha -; P9-NEXT: xsabsqp 2, 2 -; P9-NEXT: li 4, 1 -; P9-NEXT: addi 3, 3, .LCPI2_0@toc@l -; P9-NEXT: lxv 35, 0(3) +; P9-NEXT: xststdcqp 0, 2, 48 ; P9-NEXT: li 3, 0 -; P9-NEXT: xscmpuqp 0, 2, 3 +; P9-NEXT: li 4, 1 ; P9-NEXT: iseleq 3, 4, 3 ; P9-NEXT: blr entry: @@ -119,12 +109,10 @@ ; ; P9-LABEL: abs_isinfornanf: ; P9: # %bb.0: # %entry -; P9-NEXT: addis 3, 2, .LCPI3_0@toc@ha -; P9-NEXT: xsabsdp 0, 1 -; P9-NEXT: lfs 1, .LCPI3_0@toc@l(3) -; P9-NEXT: li 3, 1 -; P9-NEXT: fcmpu 0, 0, 1 -; P9-NEXT: isellt 3, 0, 3 +; P9-NEXT: xststdcsp 0, 1, 112 +; P9-NEXT: li 3, 0 +; P9-NEXT: li 4, 1 +; P9-NEXT: iseleq 3, 4, 3 ; P9-NEXT: blr entry: %0 = tail call float @llvm.fabs.f32(float %x) @@ -145,12 +133,10 @@ ; ; P9-LABEL: abs_isinfornan: ; P9: # %bb.0: # %entry -; P9-NEXT: addis 3, 2, .LCPI4_0@toc@ha -; P9-NEXT: xsabsdp 0, 1 -; P9-NEXT: lfs 1, .LCPI4_0@toc@l(3) -; P9-NEXT: li 3, 1 -; P9-NEXT: fcmpu 0, 0, 1 -; P9-NEXT: isellt 3, 0, 3 +; P9-NEXT: xststdcdp 0, 1, 112 +; P9-NEXT: li 3, 0 +; P9-NEXT: li 4, 1 +; P9-NEXT: iseleq 3, 4, 3 ; P9-NEXT: blr entry: %0 = tail call double @llvm.fabs.f64(double %x) @@ -212,13 +198,10 @@ ; ; P9-LABEL: abs_isinfornanq: ; P9: # %bb.0: # %entry -; P9-NEXT: addis 3, 2, .LCPI5_0@toc@ha -; P9-NEXT: xsabsqp 2, 2 -; P9-NEXT: addi 3, 3, .LCPI5_0@toc@l -; P9-NEXT: lxv 35, 0(3) -; P9-NEXT: li 3, 1 -; P9-NEXT: xscmpuqp 0, 2, 3 -; P9-NEXT: isellt 3, 0, 3 +; P9-NEXT: xststdcqp 0, 2, 112 +; P9-NEXT: li 3, 0 +; P9-NEXT: li 4, 1 +; P9-NEXT: iseleq 3, 4, 3 ; P9-NEXT: blr entry: %0 = tail call fp128 @llvm.fabs.f128(fp128 %x) diff --git a/llvm/test/CodeGen/PowerPC/is_fpclass.ll b/llvm/test/CodeGen/PowerPC/is_fpclass.ll --- a/llvm/test/CodeGen/PowerPC/is_fpclass.ll +++ b/llvm/test/CodeGen/PowerPC/is_fpclass.ll @@ -117,12 +117,9 @@ define i1 @isinf_ppc_fp128(ppc_fp128 %x) nounwind { ; CHECK-LABEL: isinf_ppc_fp128: ; CHECK: # %bb.0: -; CHECK-NEXT: addis 3, 2, .LCPI9_0@toc@ha -; CHECK-NEXT: xsabsdp 0, 1 -; CHECK-NEXT: li 4, 1 -; CHECK-NEXT: lfs 1, .LCPI9_0@toc@l(3) +; CHECK-NEXT: xststdcdp 0, 1, 48 ; CHECK-NEXT: li 3, 0 -; CHECK-NEXT: fcmpu 0, 0, 1 +; CHECK-NEXT: li 4, 1 ; CHECK-NEXT: iseleq 3, 4, 3 ; CHECK-NEXT: blr %1 = call i1 @llvm.is.fpclass.ppcf128(ppc_fp128 %x, i32 516) ; 0x204 = "inf"