Expand tan to sin/cos in DxilExpandTrigIntrinsics. (#343)

This commit is contained in:
Xiang Li 2017-06-07 18:36:00 -07:00 коммит произвёл GitHub
Родитель 31ca7d8cc6
Коммит 9c8aca547a
3 изменённых файлов: 36 добавлений и 0 удалений

Просмотреть файл

@ -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");
}