diff --git a/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp b/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp index 201082fac57f90..a621d7ed740857 100644 --- a/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp +++ b/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp @@ -1128,10 +1128,40 @@ void X86DAGToDAGISel::PreprocessISelDAG() { // FIXME: optimize the case where the src/dest is a load or store? //Since the operation is StrictFP, use the preexisting chain. - SDValue Store = CurDAG->getTruncStore(N->getOperand(0), dl, N->getOperand(1), - MemTmp, MachinePointerInfo(), MemVT); - SDValue Result = CurDAG->getExtLoad(ISD::EXTLOAD, dl, DstVT, Store, MemTmp, - MachinePointerInfo(), MemVT); + SDValue Store, Result; + if (!SrcIsSSE) { + SDVTList VTs = CurDAG->getVTList(MVT::Other); + SDValue Ops[] = {N->getOperand(0), N->getOperand(1), MemTmp}; + Store = CurDAG->getMemIntrinsicNode(X86ISD::FST, dl, VTs, Ops, MemVT, + MachinePointerInfo(), 0, + MachineMemOperand::MOStore); + if (N->getFlags().hasNoFPExcept()) { + SDNodeFlags Flags = Store->getFlags(); + Flags.setNoFPExcept(true); + Store->setFlags(Flags); + } + } else { + assert(SrcVT == MemVT && "Unexpected VT!"); + Store = CurDAG->getStore(N->getOperand(0), dl, N->getOperand(1), MemTmp, + MachinePointerInfo()); + } + + if (!DstIsSSE) { + SDVTList VTs = CurDAG->getVTList(DstVT, MVT::Other); + SDValue Ops[] = {Store, MemTmp}; + Result = CurDAG->getMemIntrinsicNode(X86ISD::FLD, dl, VTs, Ops, MemVT, + MachinePointerInfo(), 0, + MachineMemOperand::MOLoad); + if (N->getFlags().hasNoFPExcept()) { + SDNodeFlags Flags = Result->getFlags(); + Flags.setNoFPExcept(true); + Result->setFlags(Flags); + } + } else { + assert(DstVT == MemVT && "Unexpected VT!"); + Result = + CurDAG->getLoad(DstVT, dl, Store, MemTmp, MachinePointerInfo()); + } // We're about to replace all uses of the FP_ROUND/FP_EXTEND with the // extload we created. This will cause general havok on the dag because diff --git a/llvm/lib/Target/X86/X86InstrFPStack.td b/llvm/lib/Target/X86/X86InstrFPStack.td index 1bd9ea47c2e751..2cdf2ae15ce4f3 100644 --- a/llvm/lib/Target/X86/X86InstrFPStack.td +++ b/llvm/lib/Target/X86/X86InstrFPStack.td @@ -777,7 +777,10 @@ def FXRSTOR64 : RI<0xAE, MRM1m, (outs), (ins opaquemem:$src), // Required for RET of f32 / f64 / f80 values. def : Pat<(X86fldf32 addr:$src), (LD_Fp32m addr:$src)>; +def : Pat<(X86fldf32 addr:$src), (LD_Fp32m64 addr:$src)>; def : Pat<(X86fldf64 addr:$src), (LD_Fp64m addr:$src)>; +def : Pat<(X86fldf32 addr:$src), (LD_Fp32m80 addr:$src)>; +def : Pat<(X86fldf64 addr:$src), (LD_Fp64m80 addr:$src)>; def : Pat<(X86fldf80 addr:$src), (LD_Fp80m addr:$src)>; // Required for CALL which return f32 / f64 / f80 values.