mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-11-01 00:17:01 +00:00
R600/SI: implement range reduction for sin/cos
These instructions can only take a limited input range, and return the constant value 1 out of range. We should do range reduction to be able to process arbitrary values. Use a FRACT instruction after normalization to achieve this. Also add a test for constant folding with the lowered code with unsafe-fp-math enabled. v2: use DAG lowering instead of intrinsic, adapt test v3: calculate constant, fold pattern into instruction definition v4: misc style fixes, add sin-fold testcase, cosmetics Patch by Grigori Goronzy git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@213458 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -80,6 +80,9 @@ SITargetLowering::SITargetLowering(TargetMachine &TM) :
|
||||
setOperationAction(ISD::SUBC, MVT::i32, Legal);
|
||||
setOperationAction(ISD::SUBE, MVT::i32, Legal);
|
||||
|
||||
setOperationAction(ISD::FSIN, MVT::f32, Custom);
|
||||
setOperationAction(ISD::FCOS, MVT::f32, Custom);
|
||||
|
||||
// We need to custom lower vector stores from local memory
|
||||
setOperationAction(ISD::LOAD, MVT::v2i32, Custom);
|
||||
setOperationAction(ISD::LOAD, MVT::v4i32, Custom);
|
||||
@@ -637,6 +640,9 @@ SDValue SITargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const {
|
||||
}
|
||||
}
|
||||
|
||||
case ISD::FSIN:
|
||||
case ISD::FCOS:
|
||||
return LowerTrig(Op, DAG);
|
||||
case ISD::SELECT: return LowerSELECT(Op, DAG);
|
||||
case ISD::FDIV: return LowerFDIV(Op, DAG);
|
||||
case ISD::STORE: return LowerSTORE(Op, DAG);
|
||||
@@ -1116,6 +1122,23 @@ SDValue SITargetLowering::LowerSTORE(SDValue Op, SelectionDAG &DAG) const {
|
||||
return Chain;
|
||||
}
|
||||
|
||||
SDValue SITargetLowering::LowerTrig(SDValue Op, SelectionDAG &DAG) const {
|
||||
EVT VT = Op.getValueType();
|
||||
SDValue Arg = Op.getOperand(0);
|
||||
SDValue FractPart = DAG.getNode(AMDGPUISD::FRACT, SDLoc(Op), VT,
|
||||
DAG.getNode(ISD::FMUL, SDLoc(Op), VT, Arg,
|
||||
DAG.getConstantFP(0.5 / M_PI, VT)));
|
||||
|
||||
switch (Op.getOpcode()) {
|
||||
case ISD::FCOS:
|
||||
return DAG.getNode(AMDGPUISD::COS_HW, SDLoc(Op), VT, FractPart);
|
||||
case ISD::FSIN:
|
||||
return DAG.getNode(AMDGPUISD::SIN_HW, SDLoc(Op), VT, FractPart);
|
||||
default:
|
||||
llvm_unreachable("Wrong trig opcode");
|
||||
}
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Custom DAG optimizations
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
Reference in New Issue
Block a user