Index: lib/Target/PowerPC/PPCISelDAGToDAG.cpp =================================================================== --- lib/Target/PowerPC/PPCISelDAGToDAG.cpp +++ lib/Target/PowerPC/PPCISelDAGToDAG.cpp @@ -458,6 +458,25 @@ && isInt32Immediate(N->getOperand(1).getNode(), Imm); } +static bool isDoubleLegalMinOrMax(SDNode *N) { + + if (N->getValueType(0) != MVT::f64) + return false; + + ISD::CondCode CC = cast(N->getOperand(4))->get(); + + if (CC != ISD::CondCode::SETOGT && CC != ISD::CondCode::SETOLT) + return false; + + if (!((N->getOperand(0) == N->getOperand(2) && + N->getOperand(1) == N->getOperand(3)) || + (N->getOperand(0) == N->getOperand(3) && + N->getOperand(1) == N->getOperand(2)))) + return false; + + return true; +} + SDNode *PPCDAGToDAGISel::getFrameIndex(SDNode *SN, SDNode *N, unsigned Offset) { SDLoc dl(SN); int FI = cast(N)->getIndex(); @@ -2731,6 +2750,8 @@ SDValue(AndI.getNode(), 1) /* glue */); } case ISD::SELECT_CC: { + if (PPCSubTarget->hasP9Vector() && isDoubleLegalMinOrMax(N)) + break; ISD::CondCode CC = cast(N->getOperand(4))->get(); EVT PtrVT = CurDAG->getTargetLoweringInfo().getPointerTy(CurDAG->getDataLayout()); Index: lib/Target/PowerPC/PPCInstrVSX.td =================================================================== --- lib/Target/PowerPC/PPCInstrVSX.td +++ lib/Target/PowerPC/PPCInstrVSX.td @@ -2053,16 +2053,23 @@ //===--------------------------------------------------------------------===// // Maximum/Minimum Type-C/Type-J DP - // XT.dword[1] = 0xUUUU_UUUU_UUUU_UUUU, so we use vsrc for XT - def XSMAXCDP : XX3_XT5_XA5_XB5<60, 128, "xsmaxcdp", vsrc, vsfrc, vsfrc, - IIC_VecFP, []>; + def XSMAXCDP : XX3_XT5_XA5_XB5<60, 128, "xsmaxcdp", vsfrc, vsfrc, vsfrc, + IIC_VecFP, [(set f64:$XT, + (selectcc f64:$XA, f64:$XB, + f64:$XA, f64:$XB, SETOGT))]>; def XSMAXJDP : XX3_XT5_XA5_XB5<60, 144, "xsmaxjdp", vsrc, vsfrc, vsfrc, IIC_VecFP, []>; - def XSMINCDP : XX3_XT5_XA5_XB5<60, 136, "xsmincdp", vsrc, vsfrc, vsfrc, - IIC_VecFP, []>; + def XSMINCDP : XX3_XT5_XA5_XB5<60, 136, "xsmincdp", vsfrc, vsfrc, vsfrc, + IIC_VecFP, [(set f64:$XT, + (selectcc f64:$XA, f64:$XB, + f64:$XA, f64:$XB, SETOLT))]>; def XSMINJDP : XX3_XT5_XA5_XB5<60, 152, "xsminjdp", vsrc, vsfrc, vsfrc, IIC_VecFP, []>; + def : Pat <(f64 (selectcc f64:$XB, f64:$XA, f64:$XA, f64:$XB, SETOLT)), + (XSMAXCDP $XA, $XB)>; + def : Pat <(f64 (selectcc f64:$XB, f64:$XA, f64:$XA, f64:$XB, SETOGT)), + (XSMINCDP $XA, $XB)>; //===--------------------------------------------------------------------===// // Vector Byte-Reverse H/W/D/Q Word Index: test/CodeGen/PowerPC/vsx-p9.ll =================================================================== --- /dev/null +++ test/CodeGen/PowerPC/vsx-p9.ll @@ -0,0 +1,57 @@ +; RUN: llc -mcpu=pwr9 -mattr=+power9-vector < %s | FileCheck %s + +define double @max_test1(double %x, double %y) #0 { + +; CHECK-LABEL: @max_test1 + +entry: + %cmp = fcmp ogt double %x, %y + %x.y = select i1 %cmp, double %x, double %y + ret double %x.y + +; CHECK: xsmaxcdp 1, 1, 2 +; CHECK: blr + +} + +define double @max_test2(double %x, double %y) #0 { + +; CHECK-LABEL: @max_test2 + +entry: + %cmp = fcmp olt double %x, %y + %y.x = select i1 %cmp, double %y, double %x + ret double %y.x + +; CHECK: xsmaxcdp 1, 2, 1 +; CHECK: blr + +} + +define double @min_test1(double %x, double %y) #0 { + +; CHECK-LABEL: @min_test1 + +entry: + %cmp = fcmp ogt double %x, %y + %y.x = select i1 %cmp, double %y, double %x + ret double %y.x + +; CHECK: xsmincdp 1, 2, 1 +; CHECK: blr + +} + +define double @min_test2(double %x, double %y) #0 { + +; CHECK-LABEL: @min_test2 + +entry: + %cmp = fcmp olt double %x, %y + %x.y = select i1 %cmp, double %x, double %y + ret double %x.y + +; CHECK: xsmincdp 1, 1, 2 +; CHECK: blr + +}