Skip to content

Commit

Permalink
Revert the PR#2804 handling specials input of fract(x)
Browse files Browse the repository at this point in the history
This change reverts the PR
GPUOpen-Drivers#2804. After SPIR-V workgroup
discussed the issues of fract(x), they decide to align fract(-0.0),
fract(-INF), and fract(INF) with DXIL's definitions. Our original
implementation is fine enough to meet the spec requirements.
  • Loading branch information
amdrexu committed Nov 20, 2023
1 parent 4a90a56 commit bcf1bb0
Showing 1 changed file with 2 additions and 35 deletions.
37 changes: 2 additions & 35 deletions llpc/translator/lib/SPIRV/SPIRVReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8808,42 +8808,9 @@ Value *SPIRVToLLVM::transGLSLExtInst(SPIRVExtInst *extInst, BasicBlock *bb) {
// Round up to whole number
return getBuilder()->CreateUnaryIntrinsic(Intrinsic::ceil, args[0]);

case GLSLstd450Fract: {
case GLSLstd450Fract:
// Get fractional part
auto fract = getBuilder()->CreateFract(args[0]);

// NOTE: Although SPIR-V spec says nothing about such cases: fract(-0.0), fract(+INF), fract(-INF), OpenCL spec does
// have following definitions:
//
// fract(-0.0) = -0.0
// fract(+INF) = +0.0
// fract(-INF) = -0.0
//
// When we follow it, we have two issues that are similar to modf(x):
//
// 1. When we input x=+INF/-INF to above formula, we finally get the computation of (-INF) + INF or INF - INF.
// The result is NaN returned by HW.
// 2. When we input x=-0.0 to above formula, we finally get the addition of (-0.0) + 0.0. The result is +0.0
// returned by HW.
//
// Hence, we have to manually check those special cases:
//
// y = fract(x)
// y = x == -0.0 || x == INF ? copysign(0.0, x) : y, when either NSZ or NoInfs is not present
unsigned checkFlags = 0;
if (!getBuilder()->getFastMathFlags().noSignedZeros())
checkFlags |= lgc::Builder::CmpClass::NegativeZero;
if (!getBuilder()->getFastMathFlags().noInfs())
checkFlags |= (lgc::Builder::CmpClass::NegativeZero | lgc::Builder::CmpClass::NegativeZero);

if (checkFlags) {
Value *isNegZeroOrInf = getBuilder()->createIsFPClass(args[0], checkFlags);
Value *signedZero = getBuilder()->CreateCopySign(ConstantFP::getNullValue(args[0]->getType()), args[0]);
fract = getBuilder()->CreateSelect(isNegZeroOrInf, signedZero, fract);
}

return fract;
}
return getBuilder()->CreateFract(args[0]);

case GLSLstd450Radians:
// Convert from degrees to radians
Expand Down

0 comments on commit bcf1bb0

Please sign in to comment.