Expand tan to sin/cos in DxilExpandTrigIntrinsics. (#343)
This commit is contained in:
Родитель
31ca7d8cc6
Коммит
9c8aca547a
|
@ -89,6 +89,7 @@ private:
|
|||
Value *expandHCos(IRBuilder<> &builder, DxilInst_Hcos hcos, DxilModule &DM);
|
||||
Value *expandHSin(IRBuilder<> &builder, DxilInst_Hsin hsin, DxilModule &DM);
|
||||
Value *expandHTan(IRBuilder<> &builder, DxilInst_Htan htan, DxilModule &DM);
|
||||
Value *expandTan(IRBuilder<> &builder, DxilInst_Tan tan, DxilModule &DM);
|
||||
};
|
||||
|
||||
// Math constants.
|
||||
|
@ -119,6 +120,7 @@ CallInst *DxilExpandTrigIntrinsics::isExpandableTrigIntrinsicCall(Instruction *I
|
|||
case OP::OpCode::Hcos:
|
||||
case OP::OpCode::Hsin:
|
||||
case OP::OpCode::Htan:
|
||||
case OP::OpCode::Tan:
|
||||
return cast<CallInst>(I);
|
||||
default: break;
|
||||
}
|
||||
|
@ -168,6 +170,7 @@ bool DxilExpandTrigIntrinsics::expandTrigIntrinsics(DxilModule &DM, const Intrin
|
|||
case OP::OpCode::Hcos: expansion = expandHCos(builder, intrinsic, DM); break;
|
||||
case OP::OpCode::Hsin: expansion = expandHSin(builder, intrinsic, DM); break;
|
||||
case OP::OpCode::Htan: expansion = expandHTan(builder, intrinsic, DM); break;
|
||||
case OP::OpCode::Tan: expansion = expandTan(builder, intrinsic, DM); break;
|
||||
default:
|
||||
assert(false && "unexpected intrinsic");
|
||||
break;
|
||||
|
@ -508,6 +511,27 @@ Value *DxilExpandTrigIntrinsics::expandHTan(IRBuilder<> &builder, DxilInst_Htan
|
|||
return r;
|
||||
}
|
||||
|
||||
// Tan
|
||||
// ----------------------------------------------------------------------------
|
||||
// We use the following identity for computing tan(x)
|
||||
//
|
||||
// tan(x) = sin(x) / cos(x)
|
||||
//
|
||||
// No range reduction is needed.
|
||||
//
|
||||
Value *DxilExpandTrigIntrinsics::expandTan(IRBuilder<> &builder,
|
||||
DxilInst_Tan tan, DxilModule &DM) {
|
||||
assert(tan);
|
||||
StringRef name = "tan.x";
|
||||
Value *X = tan.get_value();
|
||||
OP *dxOp = DM.GetOP();
|
||||
Value *sin = emitUnaryFloat(builder, X, dxOp, OP::OpCode::Sin, name);
|
||||
Value *cos = emitUnaryFloat(builder, X, dxOp, OP::OpCode::Cos, name);
|
||||
Value *r = builder.CreateFDiv(sin, cos, name);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
char DxilExpandTrigIntrinsics::ID = 0;
|
||||
|
||||
FunctionPass *llvm::createDxilExpandTrigIntrinsicsPass() {
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
// RUN: %dxc -Emain -Tps_6_0 %s | %opt -S -hlsl-dxil-expand-trig-intrinsics | %FileCheck %s
|
||||
|
||||
// CHECK: [[r0:%.*]] = call float @dx.op.unary.f32(i32 13
|
||||
// CHECK: [[r1:%.*]] = call float @dx.op.unary.f32(i32 12
|
||||
// CHECK: fdiv fast float [[r0]], [[r1]]
|
||||
// CHECK-NOT: call float @dx.op.unary.f32(i32 14
|
||||
|
||||
[RootSignature("")]
|
||||
float main(float x : A) : SV_Target {
|
||||
return tan(x);
|
||||
}
|
|
@ -2544,6 +2544,7 @@ TEST_F(CompilerTest, CodeGenExpandTrig) {
|
|||
CodeGenTestCheck(L"expand_trig\\hsin_h.hlsl");
|
||||
CodeGenTestCheck(L"expand_trig\\htan.hlsl");
|
||||
CodeGenTestCheck(L"expand_trig\\htan_h.hlsl");
|
||||
CodeGenTestCheck(L"expand_trig\\tan.hlsl");
|
||||
CodeGenTestCheck(L"expand_trig\\keep_precise.0.hlsl");
|
||||
CodeGenTestCheck(L"expand_trig\\keep_precise.1.hlsl");
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче