diff options
| author | Matt Arsenault <Matthew.Arsenault@amd.com> | 2014-08-29 16:01:14 +0000 |
|---|---|---|
| committer | Matt Arsenault <Matthew.Arsenault@amd.com> | 2014-08-29 16:01:14 +0000 |
| commit | 8675db15da46792ea79cebb4c58bd0193167d741 (patch) | |
| tree | 9c6314fb764a172d2434b97c8382838651edaed1 /llvm/lib/Target | |
| parent | 3c0915e85813c2e40e20dac884d4283d44a42be4 (diff) | |
| download | bcm5719-llvm-8675db15da46792ea79cebb4c58bd0193167d741.tar.gz bcm5719-llvm-8675db15da46792ea79cebb4c58bd0193167d741.zip | |
R600/SI: Use mad for fsub + fmul
We can use a negate source modifier to match
this for fsub.
llvm-svn: 216735
Diffstat (limited to 'llvm/lib/Target')
| -rw-r--r-- | llvm/lib/Target/R600/AMDGPUISelLowering.cpp | 1 | ||||
| -rw-r--r-- | llvm/lib/Target/R600/AMDGPUISelLowering.h | 1 | ||||
| -rw-r--r-- | llvm/lib/Target/R600/AMDGPUInstrInfo.td | 1 | ||||
| -rw-r--r-- | llvm/lib/Target/R600/SIISelLowering.cpp | 37 | ||||
| -rw-r--r-- | llvm/lib/Target/R600/SIInstrInfo.td | 11 | ||||
| -rw-r--r-- | llvm/lib/Target/R600/SIInstructions.td | 3 |
6 files changed, 54 insertions, 0 deletions
diff --git a/llvm/lib/Target/R600/AMDGPUISelLowering.cpp b/llvm/lib/Target/R600/AMDGPUISelLowering.cpp index 9f22239556e..d7f12ef7a52 100644 --- a/llvm/lib/Target/R600/AMDGPUISelLowering.cpp +++ b/llvm/lib/Target/R600/AMDGPUISelLowering.cpp @@ -2157,6 +2157,7 @@ const char* AMDGPUTargetLowering::getTargetNodeName(unsigned Opcode) const { NODE_NAME_CASE(DWORDADDR) NODE_NAME_CASE(FRACT) NODE_NAME_CASE(CLAMP) + NODE_NAME_CASE(MAD) NODE_NAME_CASE(FMAX) NODE_NAME_CASE(SMAX) NODE_NAME_CASE(UMAX) diff --git a/llvm/lib/Target/R600/AMDGPUISelLowering.h b/llvm/lib/Target/R600/AMDGPUISelLowering.h index 2e78ba6a918..3dc703520cb 100644 --- a/llvm/lib/Target/R600/AMDGPUISelLowering.h +++ b/llvm/lib/Target/R600/AMDGPUISelLowering.h @@ -180,6 +180,7 @@ enum { DWORDADDR, FRACT, CLAMP, + MAD, // Multiply + add with same result as the separate operations. // SIN_HW, COS_HW - f32 for SI, 1 ULP max error, valid from -100 pi to 100 pi. // Denormals handled on some parts. diff --git a/llvm/lib/Target/R600/AMDGPUInstrInfo.td b/llvm/lib/Target/R600/AMDGPUInstrInfo.td index 06962eba6e2..3d70791bd5a 100644 --- a/llvm/lib/Target/R600/AMDGPUInstrInfo.td +++ b/llvm/lib/Target/R600/AMDGPUInstrInfo.td @@ -64,6 +64,7 @@ def AMDGPUfmax : SDNode<"AMDGPUISD::FMAX", SDTFPBinOp, >; def AMDGPUclamp : SDNode<"AMDGPUISD::CLAMP", SDTFPTernaryOp, []>; +def AMDGPUmad : SDNode<"AMDGPUISD::MAD", SDTFPTernaryOp, []>; // out = max(a, b) a and b are signed ints def AMDGPUsmax : SDNode<"AMDGPUISD::SMAX", SDTIntBinOp, diff --git a/llvm/lib/Target/R600/SIISelLowering.cpp b/llvm/lib/Target/R600/SIISelLowering.cpp index c72d6174e6e..874a0af0af5 100644 --- a/llvm/lib/Target/R600/SIISelLowering.cpp +++ b/llvm/lib/Target/R600/SIISelLowering.cpp @@ -226,6 +226,7 @@ SITargetLowering::SITargetLowering(TargetMachine &TM) : setOperationAction(ISD::FDIV, MVT::f32, Custom); + setTargetDAGCombine(ISD::FSUB); setTargetDAGCombine(ISD::SELECT_CC); setTargetDAGCombine(ISD::SETCC); @@ -1386,6 +1387,42 @@ SDValue SITargetLowering::PerformDAGCombine(SDNode *N, case ISD::UINT_TO_FP: { return performUCharToFloatCombine(N, DCI); + + case ISD::FSUB: { + if (DCI.getDAGCombineLevel() < AfterLegalizeDAG) + break; + + EVT VT = N->getValueType(0); + + // Try to get the fneg to fold into the source modifier. This undoes generic + // DAG combines and folds them into the mad. + if (VT == MVT::f32) { + SDValue LHS = N->getOperand(0); + SDValue RHS = N->getOperand(1); + + if (LHS.getOpcode() == ISD::FMUL) { + // (fsub (fmul a, b), c) -> mad a, b, (fneg c) + + SDValue A = LHS.getOperand(0); + SDValue B = LHS.getOperand(1); + SDValue C = DAG.getNode(ISD::FNEG, DL, VT, RHS); + + return DAG.getNode(AMDGPUISD::MAD, DL, VT, A, B, C); + } + + if (RHS.getOpcode() == ISD::FMUL) { + // (fsub c, (fmul a, b)) -> mad (fneg a), b, c + + SDValue A = DAG.getNode(ISD::FNEG, DL, VT, RHS.getOperand(0)); + SDValue B = RHS.getOperand(1); + SDValue C = LHS; + + return DAG.getNode(AMDGPUISD::MAD, DL, VT, A, B, C); + } + } + + break; + } } case ISD::LOAD: case ISD::STORE: diff --git a/llvm/lib/Target/R600/SIInstrInfo.td b/llvm/lib/Target/R600/SIInstrInfo.td index 064a67efb7a..4bb60fbffc9 100644 --- a/llvm/lib/Target/R600/SIInstrInfo.td +++ b/llvm/lib/Target/R600/SIInstrInfo.td @@ -796,6 +796,17 @@ multiclass VOP3b_64 <bits<9> op, string opName, list<dag> pattern> : multiclass VOP3b_32 <bits<9> op, string opName, list<dag> pattern> : VOP3b_Helper <op, VReg_32, VSrc_32, opName, pattern>; + +class Vop3ModPat<Instruction Inst, VOPProfile P, SDPatternOperator node> : Pat< + (node (P.Src0VT (VOP3Mods0 P.Src0VT:$src0, i32:$src0_modifiers, i32:$clamp, i32:$omod)), + (P.Src1VT (VOP3Mods P.Src1VT:$src1, i32:$src1_modifiers)), + (P.Src2VT (VOP3Mods P.Src2VT:$src2, i32:$src2_modifiers))), + (Inst i32:$src0_modifiers, P.Src0VT:$src0, + i32:$src1_modifiers, P.Src1VT:$src1, + i32:$src2_modifiers, P.Src2VT:$src2, + i32:$clamp, + i32:$omod)>; + //===----------------------------------------------------------------------===// // Vector I/O classes //===----------------------------------------------------------------------===// diff --git a/llvm/lib/Target/R600/SIInstructions.td b/llvm/lib/Target/R600/SIInstructions.td index 059789223d7..47ca42c00b1 100644 --- a/llvm/lib/Target/R600/SIInstructions.td +++ b/llvm/lib/Target/R600/SIInstructions.td @@ -2513,6 +2513,9 @@ def : Pat < (V_MUL_HI_I32 $src0, $src1) >; +def : Vop3ModPat<V_MAD_F32, VOP_F32_F32_F32_F32, AMDGPUmad>; + + defm : BFIPatterns <V_BFI_B32, S_MOV_B32>; def : ROTRPattern <V_ALIGNBIT_B32>; |

