mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2026-04-27 04:18:42 +00:00
Merging r229239:
------------------------------------------------------------------------ r229239 | Matthew.Arsenault | 2015-02-13 23:30:08 -0500 (Fri, 13 Feb 2015) | 4 lines R600/SI: Implement correct f64 fdiv This version passes the OpenCL conformance test. ------------------------------------------------------------------------ git-svn-id: https://llvm.org/svn/llvm-project/llvm/branches/release_36@236016 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
1 parent
1086572d29
commit
65a11a8d52
10 files changed
+184
-43
No files matched your search
@@ -649,17 +649,10 @@ class RcpPat<Instruction RcpInst, ValueType vt> : Pat <
|
||||
(RcpInst $src)
|
||||
>;
|
||||
|
||||
multiclass RsqPat<Instruction RsqInst, ValueType vt> {
|
||||
def : Pat <
|
||||
(fdiv FP_ONE, (fsqrt vt:$src)),
|
||||
(RsqInst $src)
|
||||
>;
|
||||
|
||||
def : Pat <
|
||||
(AMDGPUrcp (fsqrt vt:$src)),
|
||||
(RsqInst $src)
|
||||
>;
|
||||
}
|
||||
class RsqPat<Instruction RsqInst, ValueType vt> : Pat <
|
||||
(AMDGPUrcp (fsqrt vt:$src)),
|
||||
(RsqInst $src)
|
||||
>;
|
||||
|
||||
include "R600Instructions.td"
|
||||
include "R700Instructions.td"
|
||||
|
||||
@@ -46,7 +46,7 @@ def SIN_cm : SIN_Common<0x8D>;
|
||||
def COS_cm : COS_Common<0x8E>;
|
||||
} // End isVector = 1
|
||||
|
||||
defm : RsqPat<RECIPSQRT_IEEE_cm, f32>;
|
||||
def : RsqPat<RECIPSQRT_IEEE_cm, f32>;
|
||||
|
||||
def : POW_Common <LOG_IEEE_cm, EXP_IEEE_cm, MUL>;
|
||||
|
||||
|
||||
@@ -69,7 +69,7 @@ def EXP_IEEE_eg : EXP_IEEE_Common<0x81>;
|
||||
def LOG_IEEE_eg : LOG_IEEE_Common<0x83>;
|
||||
def RECIP_CLAMPED_eg : RECIP_CLAMPED_Common<0x84>;
|
||||
def RECIPSQRT_IEEE_eg : RECIPSQRT_IEEE_Common<0x89>;
|
||||
defm : RsqPat<RECIPSQRT_IEEE_eg, f32>;
|
||||
def : RsqPat<RECIPSQRT_IEEE_eg, f32>;
|
||||
def SIN_eg : SIN_Common<0x8D>;
|
||||
def COS_eg : COS_Common<0x8E>;
|
||||
|
||||
|
||||
@@ -1193,7 +1193,7 @@ let Predicates = [isR600] in {
|
||||
def TGSI_LIT_Z_r600 : TGSI_LIT_Z_Common<MUL_LIT_r600, LOG_CLAMPED_r600, EXP_IEEE_r600>;
|
||||
|
||||
def : Pat<(fsqrt f32:$src), (MUL $src, (RECIPSQRT_CLAMPED_r600 $src))>;
|
||||
defm : RsqPat<RECIPSQRT_IEEE_r600, f32>;
|
||||
def : RsqPat<RECIPSQRT_IEEE_r600, f32>;
|
||||
|
||||
def : FROUNDPat <CNDGE_r600, CNDGT_r600>;
|
||||
|
||||
|
||||
@@ -210,6 +210,7 @@ SITargetLowering::SITargetLowering(TargetMachine &TM) :
|
||||
}
|
||||
|
||||
setOperationAction(ISD::FDIV, MVT::f32, Custom);
|
||||
setOperationAction(ISD::FDIV, MVT::f64, Custom);
|
||||
|
||||
setTargetDAGCombine(ISD::FADD);
|
||||
setTargetDAGCombine(ISD::FSUB);
|
||||
@@ -1105,7 +1106,70 @@ SDValue SITargetLowering::LowerFDIV32(SDValue Op, SelectionDAG &DAG) const {
|
||||
}
|
||||
|
||||
SDValue SITargetLowering::LowerFDIV64(SDValue Op, SelectionDAG &DAG) const {
|
||||
return SDValue();
|
||||
if (DAG.getTarget().Options.UnsafeFPMath)
|
||||
return LowerFastFDIV(Op, DAG);
|
||||
|
||||
SDLoc SL(Op);
|
||||
SDValue X = Op.getOperand(0);
|
||||
SDValue Y = Op.getOperand(1);
|
||||
|
||||
const SDValue One = DAG.getConstantFP(1.0, MVT::f64);
|
||||
|
||||
SDVTList ScaleVT = DAG.getVTList(MVT::f64, MVT::i1);
|
||||
|
||||
SDValue DivScale0 = DAG.getNode(AMDGPUISD::DIV_SCALE, SL, ScaleVT, Y, Y, X);
|
||||
|
||||
SDValue NegDivScale0 = DAG.getNode(ISD::FNEG, SL, MVT::f64, DivScale0);
|
||||
|
||||
SDValue Rcp = DAG.getNode(AMDGPUISD::RCP, SL, MVT::f64, DivScale0);
|
||||
|
||||
SDValue Fma0 = DAG.getNode(ISD::FMA, SL, MVT::f64, NegDivScale0, Rcp, One);
|
||||
|
||||
SDValue Fma1 = DAG.getNode(ISD::FMA, SL, MVT::f64, Rcp, Fma0, Rcp);
|
||||
|
||||
SDValue Fma2 = DAG.getNode(ISD::FMA, SL, MVT::f64, NegDivScale0, Fma1, One);
|
||||
|
||||
SDValue DivScale1 = DAG.getNode(AMDGPUISD::DIV_SCALE, SL, ScaleVT, X, Y, X);
|
||||
|
||||
SDValue Fma3 = DAG.getNode(ISD::FMA, SL, MVT::f64, Fma1, Fma2, Fma1);
|
||||
SDValue Mul = DAG.getNode(ISD::FMUL, SL, MVT::f64, DivScale1, Fma3);
|
||||
|
||||
SDValue Fma4 = DAG.getNode(ISD::FMA, SL, MVT::f64,
|
||||
NegDivScale0, Mul, DivScale1);
|
||||
|
||||
SDValue Scale;
|
||||
|
||||
if (Subtarget->getGeneration() == AMDGPUSubtarget::SOUTHERN_ISLANDS) {
|
||||
// Workaround a hardware bug on SI where the condition output from div_scale
|
||||
// is not usable.
|
||||
|
||||
const SDValue Hi = DAG.getConstant(1, MVT::i32);
|
||||
|
||||
// Figure out if the scale to use for div_fmas.
|
||||
SDValue NumBC = DAG.getNode(ISD::BITCAST, SL, MVT::v2i32, X);
|
||||
SDValue DenBC = DAG.getNode(ISD::BITCAST, SL, MVT::v2i32, Y);
|
||||
SDValue Scale0BC = DAG.getNode(ISD::BITCAST, SL, MVT::v2i32, DivScale0);
|
||||
SDValue Scale1BC = DAG.getNode(ISD::BITCAST, SL, MVT::v2i32, DivScale1);
|
||||
|
||||
SDValue NumHi = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, SL, MVT::i32, NumBC, Hi);
|
||||
SDValue DenHi = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, SL, MVT::i32, DenBC, Hi);
|
||||
|
||||
SDValue Scale0Hi
|
||||
= DAG.getNode(ISD::EXTRACT_VECTOR_ELT, SL, MVT::i32, Scale0BC, Hi);
|
||||
SDValue Scale1Hi
|
||||
= DAG.getNode(ISD::EXTRACT_VECTOR_ELT, SL, MVT::i32, Scale1BC, Hi);
|
||||
|
||||
SDValue CmpDen = DAG.getSetCC(SL, MVT::i1, DenHi, Scale0Hi, ISD::SETEQ);
|
||||
SDValue CmpNum = DAG.getSetCC(SL, MVT::i1, NumHi, Scale1Hi, ISD::SETEQ);
|
||||
Scale = DAG.getNode(ISD::XOR, SL, MVT::i1, CmpNum, CmpDen);
|
||||
} else {
|
||||
Scale = DivScale1.getValue(1);
|
||||
}
|
||||
|
||||
SDValue Fmas = DAG.getNode(AMDGPUISD::DIV_FMAS, SL, MVT::f64,
|
||||
Fma4, Fma3, Mul, Scale);
|
||||
|
||||
return DAG.getNode(AMDGPUISD::DIV_FIXUP, SL, MVT::f64, Fmas, Y, X);
|
||||
}
|
||||
|
||||
SDValue SITargetLowering::LowerFDIV(SDValue Op, SelectionDAG &DAG) const {
|
||||
|
||||
@@ -2164,9 +2164,13 @@ def : Pat <
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
let Predicates = [UnsafeFPMath] in {
|
||||
def : RcpPat<V_RCP_F64_e32, f64>;
|
||||
defm : RsqPat<V_RSQ_F64_e32, f64>;
|
||||
defm : RsqPat<V_RSQ_F32_e32, f32>;
|
||||
|
||||
//def : RcpPat<V_RCP_F64_e32, f64>;
|
||||
//defm : RsqPat<V_RSQ_F64_e32, f64>;
|
||||
//defm : RsqPat<V_RSQ_F32_e32, f32>;
|
||||
|
||||
def : RsqPat<V_RSQ_F32_e32, f32>;
|
||||
def : RsqPat<V_RSQ_F64_e32, f64>;
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
@@ -2683,13 +2687,6 @@ def : Pat <
|
||||
(V_MUL_LEGACY_F32_e32 $src0, (V_RCP_LEGACY_F32_e32 $src1))
|
||||
>;
|
||||
|
||||
def : Pat<
|
||||
(fdiv f64:$src0, f64:$src1),
|
||||
(V_MUL_F64 0 /* src0_modifiers */, $src0,
|
||||
0 /* src1_modifiers */, (V_RCP_F64_e32 $src1),
|
||||
0 /* clamp */, 0 /* omod */)
|
||||
>;
|
||||
|
||||
def : Pat <
|
||||
(int_AMDGPU_cube v4f32:$src),
|
||||
(REG_SEQUENCE VReg_128,
|
||||
|
||||
Reference in new issue
Block a user