Commit 50cabc63 authored by Tanya Lattner's avatar Tanya Lattner
Browse files

Merge from mainline

Don't dag combine floating point select to max and min intrinsics. Those
take v4f32 / v2f64 operands and may end up causing larger spills / restores.
Added X86 specific nodes X86ISD::FMAX, X86ISD::FMIN instead.

llvm-svn: 31651
parent 53a422c2
Loading
Loading
Loading
Loading
+13 −32
Original line number Diff line number Diff line
@@ -4967,6 +4967,8 @@ const char *X86TargetLowering::getTargetNodeName(unsigned Opcode) const {
  case X86ISD::S2VEC:              return "X86ISD::S2VEC";
  case X86ISD::PEXTRW:             return "X86ISD::PEXTRW";
  case X86ISD::PINSRW:             return "X86ISD::PINSRW";
  case X86ISD::FMAX:               return "X86ISD::FMAX";
  case X86ISD::FMIN:               return "X86ISD::FMIN";
  }
}

@@ -5347,7 +5349,7 @@ static SDOperand PerformSELECTCombine(SDNode *N, SelectionDAG &DAG,
      SDOperand RHS = N->getOperand(2);
      ISD::CondCode CC = cast<CondCodeSDNode>(Cond.getOperand(2))->get();
      
      unsigned IntNo = 0;
      unsigned Opcode = 0;
      if (LHS == Cond.getOperand(0) && RHS == Cond.getOperand(1)) {
        switch (CC) {
        default: break;
@@ -5358,8 +5360,7 @@ static SDOperand PerformSELECTCombine(SDNode *N, SelectionDAG &DAG,
          // FALL THROUGH.
        case ISD::SETOLT:  // (X olt/lt Y) ? X : Y -> min
        case ISD::SETLT:
          IntNo = LHS.getValueType() == MVT::f32 ? Intrinsic::x86_sse_min_ss :
                                                   Intrinsic::x86_sse2_min_sd;
          Opcode = X86ISD::FMIN;  
	  break;
          
        case ISD::SETOGT: // (X > Y) ? X : Y -> max
@@ -5369,8 +5370,7 @@ static SDOperand PerformSELECTCombine(SDNode *N, SelectionDAG &DAG,
          // FALL THROUGH.
        case ISD::SETUGE:  // (X uge/ge Y) ? X : Y -> max
        case ISD::SETGE:
          IntNo = LHS.getValueType() == MVT::f32 ? Intrinsic::x86_sse_max_ss :
                                                   Intrinsic::x86_sse2_max_sd;
	  Opcode = X86ISD::FMAX; 
	  break;
        }
      } else if (LHS == Cond.getOperand(1) && RHS == Cond.getOperand(0)) {
@@ -5383,8 +5383,7 @@ static SDOperand PerformSELECTCombine(SDNode *N, SelectionDAG &DAG,
          // FALL THROUGH.
        case ISD::SETUGE:  // (X uge/ge Y) ? Y : X -> min
        case ISD::SETGE:
          IntNo = LHS.getValueType() == MVT::f32 ? Intrinsic::x86_sse_min_ss :
                                                   Intrinsic::x86_sse2_min_sd;
          Opcode = X86ISD::FMIN; 
	  break;
          
        case ISD::SETOLE:   // (X <= Y) ? Y : X -> max
@@ -5394,30 +5393,12 @@ static SDOperand PerformSELECTCombine(SDNode *N, SelectionDAG &DAG,
          // FALL THROUGH.
        case ISD::SETOLT:   // (X olt/lt Y) ? Y : X -> max
        case ISD::SETLT:
          IntNo = LHS.getValueType() == MVT::f32 ? Intrinsic::x86_sse_max_ss :
                                                   Intrinsic::x86_sse2_max_sd;
          Opcode = X86ISD::FMAX; 
	  break;
        }
      }
      
      // minss/maxss take a v4f32 operand.
      if (IntNo) {
        if (LHS.getValueType() == MVT::f32) {
          LHS = DAG.getNode(ISD::SCALAR_TO_VECTOR, MVT::v4f32, LHS);
          RHS = DAG.getNode(ISD::SCALAR_TO_VECTOR, MVT::v4f32, RHS);
        } else {
          LHS = DAG.getNode(ISD::SCALAR_TO_VECTOR, MVT::v2f64, LHS);
          RHS = DAG.getNode(ISD::SCALAR_TO_VECTOR, MVT::v2f64, RHS);
        }
        
        MVT::ValueType PtrTy = Subtarget->is64Bit() ? MVT::i64 : MVT::i32;
        SDOperand IntNoN = DAG.getConstant(IntNo, PtrTy);
        
        SDOperand Val = DAG.getNode(ISD::INTRINSIC_WO_CHAIN, LHS.getValueType(),
                                    IntNoN, LHS, RHS);
        return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, N->getValueType(0), Val,
                           DAG.getConstant(0, PtrTy));
      }
      if (Opcode)
        return DAG.getNode(Opcode, N->getValueType(0), LHS, RHS);  
    }
    
  }
+5 −1
Original line number Diff line number Diff line
@@ -160,7 +160,11 @@ namespace llvm {

      /// PINSRW - Insert the lower 16-bits of a 32-bit value to a vector,
      /// corresponds to X86::PINSRW.
      PINSRW
      PINSRW,

      /// FMAX, FMIN - Floating point max and min.
      ///
      FMAX, FMIN
    };
  }

+6 −31
Original line number Diff line number Diff line
@@ -20,6 +20,8 @@

def X86loadp   : SDNode<"X86ISD::LOAD_PACK", SDTLoad, [SDNPHasChain]>;
def X86loadu   : SDNode<"X86ISD::LOAD_UA",   SDTLoad, [SDNPHasChain]>;
def X86fmin    : SDNode<"X86ISD::FMIN",      SDTFPBinOp>;
def X86fmax    : SDNode<"X86ISD::FMAX",      SDTFPBinOp>;
def X86fand    : SDNode<"X86ISD::FAND",      SDTFPBinOp,
                        [SDNPCommutative, SDNPAssociative]>;
def X86fxor    : SDNode<"X86ISD::FXOR",      SDTFPBinOp,
@@ -375,6 +377,10 @@ defm SUB : scalar_sse12_fp_binop_rm<0x5C, "sub", fsub,
                                    int_x86_sse_sub_ss, int_x86_sse2_sub_sd>;
defm DIV : scalar_sse12_fp_binop_rm<0x5E, "div", fdiv,
                                    int_x86_sse_div_ss, int_x86_sse2_div_sd>;
defm MAX : scalar_sse12_fp_binop_rm<0x5F, "max", X86fmax,
                                    int_x86_sse_max_ss, int_x86_sse2_max_sd>;
defm MIN : scalar_sse12_fp_binop_rm<0x5D, "min", X86fmin,
                                    int_x86_sse_min_ss, int_x86_sse2_min_sd>;


def SQRTSSr : SSI<0x51, MRMSrcReg, (ops FR32:$dst, FR32:$src),
@@ -390,24 +396,6 @@ def SQRTSDm : SDI<0x51, MRMSrcMem, (ops FR64:$dst, f64mem:$src),
                 "sqrtsd {$src, $dst|$dst, $src}",
                 [(set FR64:$dst, (fsqrt (loadf64 addr:$src)))]>;

class SS_Intrr<bits<8> o, string OpcodeStr, Intrinsic IntId>
  : SSI<o, MRMSrcReg, (ops VR128:$dst, VR128:$src1, VR128:$src2),
        !strconcat(OpcodeStr, " {$src2, $dst|$dst, $src2}"),
        [(set VR128:$dst, (v4f32 (IntId VR128:$src1, VR128:$src2)))]>;
class SS_Intrm<bits<8> o, string OpcodeStr, Intrinsic IntId>
  : SSI<o, MRMSrcMem, (ops VR128:$dst, VR128:$src1, ssmem:$src2),
        !strconcat(OpcodeStr, " {$src2, $dst|$dst, $src2}"),
        [(set VR128:$dst, (v4f32 (IntId VR128:$src1, sse_load_f32:$src2)))]>;
class SD_Intrr<bits<8> o, string OpcodeStr, Intrinsic IntId>
  : SDI<o, MRMSrcReg, (ops VR128:$dst, VR128:$src1, VR128:$src2),
        !strconcat(OpcodeStr, " {$src2, $dst|$dst, $src2}"),
        [(set VR128:$dst, (v2f64 (IntId VR128:$src1, VR128:$src2)))]>;
class SD_Intrm<bits<8> o, string OpcodeStr, Intrinsic IntId>
  : SDI<o, MRMSrcMem, (ops VR128:$dst, VR128:$src1, sdmem:$src2),
        !strconcat(OpcodeStr, " {$src2, $dst|$dst, $src2}"),
        [(set VR128:$dst, (v2f64 (IntId VR128:$src1, sse_load_f64:$src2)))]>;


// Aliases to match intrinsics which expect XMM operand(s).

defm SQRTSS_Int  : SS_IntUnary<0x51, "sqrtss" , int_x86_sse_sqrt_ss>;
@@ -415,19 +403,6 @@ defm SQRTSD_Int : SD_IntUnary<0x51, "sqrtsd" , int_x86_sse2_sqrt_sd>;
defm RSQRTSS_Int : SS_IntUnary<0x52, "rsqrtss", int_x86_sse_rsqrt_ss>;
defm RCPSS_Int   : SS_IntUnary<0x53, "rcpss"  , int_x86_sse_rcp_ss>;

let isTwoAddress = 1 in {
let isCommutable = 1 in {
def Int_MAXSSrr : SS_Intrr<0x5F, "maxss", int_x86_sse_max_ss>;
def Int_MAXSDrr : SD_Intrr<0x5F, "maxsd", int_x86_sse2_max_sd>;
def Int_MINSSrr : SS_Intrr<0x5D, "minss", int_x86_sse_min_ss>;
def Int_MINSDrr : SD_Intrr<0x5D, "minsd", int_x86_sse2_min_sd>;
}
def Int_MAXSSrm : SS_Intrm<0x5F, "maxss", int_x86_sse_max_ss>;
def Int_MAXSDrm : SD_Intrm<0x5F, "maxsd", int_x86_sse2_max_sd>;
def Int_MINSSrm : SS_Intrm<0x5D, "minss", int_x86_sse_min_ss>;
def Int_MINSDrm : SD_Intrm<0x5D, "minsd", int_x86_sse2_min_sd>;
}

// Conversion instructions
def CVTTSS2SIrr: SSI<0x2C, MRMSrcReg, (ops GR32:$dst, FR32:$src),
                    "cvttss2si {$src, $dst|$dst, $src}",