mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-03 15:36:21 +00:00
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. This fixes PR996. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@31645 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
734c91d250
commit
8ca29326e1
@ -4983,6 +4983,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";
|
||||
}
|
||||
}
|
||||
|
||||
@ -5363,7 +5365,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;
|
||||
@ -5374,8 +5376,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
|
||||
@ -5385,8 +5386,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)) {
|
||||
@ -5399,8 +5399,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
|
||||
@ -5410,30 +5409,13 @@ 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);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
@ -380,6 +382,11 @@ defm SUB : scalar_sse12_fp_binop_rm<0x5C, "sub", fsub,
|
||||
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),
|
||||
"sqrtss {$src, $dst|$dst, $src}",
|
||||
@ -394,24 +401,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>;
|
||||
@ -419,19 +408,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}",
|
||||
|
Loading…
x
Reference in New Issue
Block a user