-
Notifications
You must be signed in to change notification settings - Fork 14.9k
[DirectX] Add isinf f16 emulation for SM6.8 and lower #156932
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 3 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -51,6 +51,43 @@ static bool resourceAccessNeeds64BitExpansion(Module *M, Type *OverloadTy, | |
return ScalarTy->isDoubleTy() || ScalarTy->isIntegerTy(64); | ||
} | ||
|
||
static Value *expand16BitIsInf(CallInst *Orig) { | ||
Module *M = Orig->getModule(); | ||
if (M->getTargetTriple().getDXILVersion() >= VersionTuple(1, 9)) | ||
return nullptr; | ||
|
||
Value *Val = Orig->getOperand(0); | ||
Type *ValTy = Val->getType(); | ||
if (!(ValTy->isHalfTy() || | ||
|
||
(ValTy->isVectorTy() && | ||
cast<FixedVectorType>(ValTy)->getElementType()->isHalfTy()))) | ||
return nullptr; | ||
|
||
IRBuilder<> Builder(Orig); | ||
Type *IType = Type::getInt16Ty(M->getContext()); | ||
Constant *PosInf = | ||
ValTy->isVectorTy() | ||
? ConstantVector::getSplat( | ||
ElementCount::getFixed( | ||
cast<FixedVectorType>(ValTy)->getNumElements()), | ||
ConstantInt::get(IType, 0x7c00)) | ||
: ConstantInt::get(IType, 0x7c00); | ||
|
||
Constant *NegInf = | ||
ValTy->isVectorTy() | ||
? ConstantVector::getSplat( | ||
ElementCount::getFixed( | ||
cast<FixedVectorType>(ValTy)->getNumElements()), | ||
ConstantInt::get(IType, 0xfc00)) | ||
: ConstantInt::get(IType, 0xfc00); | ||
|
||
Value *IVal = Builder.CreateBitCast(Val, PosInf->getType()); | ||
Value *B1 = Builder.CreateICmpEQ(IVal, PosInf); | ||
Value *B2 = Builder.CreateICmpEQ(IVal, NegInf); | ||
Value *B3 = Builder.CreateOr(B1, B2); | ||
return B3; | ||
} | ||
|
||
static bool isIntrinsicExpansion(Function &F) { | ||
switch (F.getIntrinsicID()) { | ||
case Intrinsic::abs: | ||
|
@@ -68,6 +105,7 @@ static bool isIntrinsicExpansion(Function &F) { | |
case Intrinsic::dx_sclamp: | ||
case Intrinsic::dx_nclamp: | ||
case Intrinsic::dx_degrees: | ||
case Intrinsic::dx_isinf: | ||
case Intrinsic::dx_lerp: | ||
case Intrinsic::dx_normalize: | ||
case Intrinsic::dx_fdot: | ||
|
@@ -301,9 +339,10 @@ static Value *expandIsFPClass(CallInst *Orig) { | |
auto *TCI = dyn_cast<ConstantInt>(T); | ||
|
||
// These FPClassTest cases have DXIL opcodes, so they will be handled in | ||
// DXIL Op Lowering instead. | ||
// DXIL Op Lowering instead for all non f16 cases. | ||
switch (TCI->getZExtValue()) { | ||
case FPClassTest::fcInf: | ||
return expand16BitIsInf(Orig); | ||
case FPClassTest::fcNan: | ||
case FPClassTest::fcNormal: | ||
case FPClassTest::fcFinite: | ||
|
@@ -873,6 +912,9 @@ static bool expandIntrinsic(Function &F, CallInst *Orig) { | |
case Intrinsic::dx_degrees: | ||
Result = expandDegreesIntrinsic(Orig); | ||
break; | ||
case Intrinsic::dx_isinf: | ||
Result = expand16BitIsInf(Orig); | ||
break; | ||
case Intrinsic::dx_lerp: | ||
Result = expandLerpIntrinsic(Orig); | ||
break; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i'm not familiar with this code. What is the effect of the latestdxilsubarch? is it ok to set it to 1.9?
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LatestDXILSubArch
must always match the latest dxil version. Its uses for the6.x
target triple format.