diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp --- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp +++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp @@ -14248,11 +14248,15 @@ DAGCombinerInfo &DCI) const { assert(N->getOpcode() == ISD::SETCC && "Should be called with a SETCC node"); + EVT VT = N->getValueType(0); + SDValue LHS = N->getOperand(0); + SDValue RHS = N->getOperand(1); + EVT OpVT = LHS.getValueType(); + SDLoc DL(N); + SelectionDAG &DAG = DCI.DAG; ISD::CondCode CC = cast(N->getOperand(2))->get(); if (CC == ISD::SETNE || CC == ISD::SETEQ) { - SDValue LHS = N->getOperand(0); - SDValue RHS = N->getOperand(1); // If there is a '0 - y' pattern, canonicalize the pattern to the RHS. if (LHS.getOpcode() == ISD::SUB && isNullConstant(LHS.getOperand(0)) && @@ -14263,13 +14267,32 @@ // x != 0-y --> x+y != 0 if (RHS.getOpcode() == ISD::SUB && isNullConstant(RHS.getOperand(0)) && RHS.hasOneUse()) { - SDLoc DL(N); - SelectionDAG &DAG = DCI.DAG; - EVT VT = N->getValueType(0); EVT OpVT = LHS.getValueType(); SDValue Add = DAG.getNode(ISD::ADD, DL, OpVT, LHS, RHS.getOperand(1)); return DAG.getSetCC(DL, VT, Add, DAG.getConstant(0, DL, OpVT), CC); } + } else if (CC == ISD::SETOEQ && Subtarget.hasP9Vector() && !OpVT.isVector()) { + bool IsAbsolute = LHS.getOpcode() == ISD::FABS; + if (IsAbsolute) + LHS = LHS.getOperand(0); + + if (const auto *CFP = dyn_cast(RHS.getNode())) { + const APFloat &APF = CFP->getValueAPF(); + unsigned Flag = 0; + if (APF.isNegative() && IsAbsolute) + return DAG.getBoolConstant(false, DL, VT, OpVT); + if (APF.isPosInfinity()) + Flag = IsAbsolute ? fcInf : fcPosInf; + else if (APF.isPosZero()) + Flag = IsAbsolute ? fcZero : fcPosZero; + else if (APF.isNegInfinity()) + Flag = fcNegInf; + else if (APF.isNegZero()) + Flag = fcNegZero; + if (Flag) + return DAG.getNode(ISD::IS_FPCLASS, DL, VT, LHS, + DAG.getConstant(Flag, DL, MVT::i32)); + } } return DAGCombineTruncBoolExt(N, DCI); 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: @@ -168,10 +158,9 @@ ; ; P9-LABEL: iszerof: ; P9: # %bb.0: # %entry -; P9-NEXT: xxlxor 0, 0, 0 +; P9-NEXT: xststdcsp 0, 1, 8 ; P9-NEXT: li 3, 0 ; P9-NEXT: li 4, 1 -; P9-NEXT: fcmpu 0, 1, 0 ; P9-NEXT: iseleq 3, 4, 3 ; P9-NEXT: blr entry: @@ -191,10 +180,9 @@ ; ; P9-LABEL: iszero: ; P9: # %bb.0: # %entry -; P9-NEXT: xxlxor 0, 0, 0 +; P9-NEXT: xststdcdp 0, 1, 8 ; P9-NEXT: li 3, 0 ; P9-NEXT: li 4, 1 -; P9-NEXT: fcmpu 0, 1, 0 ; P9-NEXT: iseleq 3, 4, 3 ; P9-NEXT: blr entry: @@ -225,12 +213,9 @@ ; ; P9-LABEL: iszeroq: ; P9: # %bb.0: # %entry -; P9-NEXT: addis 3, 2, .LCPI7_0@toc@ha -; P9-NEXT: li 4, 1 -; P9-NEXT: addi 3, 3, .LCPI7_0@toc@l -; P9-NEXT: lxv 35, 0(3) +; P9-NEXT: xststdcqp 0, 2, 8 ; 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: