Commit 551279e5 by Arun Patole Committed by Jamie Madill

Support constant folding of more common built-ins

This change adds const folding support for below mentioned common built-ins: - isnan, ininf, floatBitsToInt, floatBitsToUint, intBitsToFloat and uintBitsToFloat BUG=angleproject:913 TEST=angle_unittests(new: MathUtilTest.isNan/inInf), dEQP Tests dEQP-GLES3.functional.shaders.constant_expressions.builtin_functions.common.* (20 more tests started passing with this change) Change-Id: Ifdedb251cd8b183b4999314c0f5de857bc20702f Reviewed-on: https://chromium-review.googlesource.com/283767Reviewed-by: 's avatarOlli Etuaho <oetuaho@nvidia.com> Tested-by: 's avatarOlli Etuaho <oetuaho@nvidia.com> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org>
parent bcab6426
......@@ -622,6 +622,24 @@ inline void unpackHalf2x16(uint32_t u, float *f1, float *f2)
*f2 = float16ToFloat32(mostSignificantBits);
}
// Returns whether the argument is Not a Number.
// IEEE 754 single precision NaN representation: Exponent(8 bits) - 255, Mantissa(23 bits) - non-zero.
inline bool isNaN(float f)
{
// Exponent mask: ((1u << 8) - 1u) << 23 = 0x7f800000u
// Mantissa mask: ((1u << 23) - 1u) = 0x7fffffu
return ((bitCast<uint32_t>(f) & 0x7f800000u) == 0x7f800000u) && (bitCast<uint32_t>(f) & 0x7fffffu);
}
// Returns whether the argument is infinity.
// IEEE 754 single precision infinity representation: Exponent(8 bits) - 255, Mantissa(23 bits) - zero.
inline bool isInf(float f)
{
// Exponent mask: ((1u << 8) - 1u) << 23 = 0x7f800000u
// Mantissa mask: ((1u << 23) - 1u) = 0x7fffffu
return ((bitCast<uint32_t>(f) & 0x7f800000u) == 0x7f800000u) && !(bitCast<uint32_t>(f) & 0x7fffffu);
}
}
namespace rx
......
......@@ -142,5 +142,31 @@ TEST(MathUtilTest, packAndUnpackHalf2x16)
}
}
// Test the correctness of gl::isNaN function.
TEST(MathUtilTest, isNaN)
{
EXPECT_TRUE(isNaN(bitCast<float>(0xffu << 23 | 1u)));
EXPECT_TRUE(isNaN(bitCast<float>(1u << 31 | 0xffu << 23 | 1u)));
EXPECT_TRUE(isNaN(bitCast<float>(1u << 31 | 0xffu << 23 | 0x400000u)));
EXPECT_TRUE(isNaN(bitCast<float>(1u << 31 | 0xffu << 23 | 0x7fffffu)));
EXPECT_FALSE(isNaN(0.0f));
EXPECT_FALSE(isNaN(bitCast<float>(1u << 31 | 0xffu << 23)));
EXPECT_FALSE(isNaN(bitCast<float>(0xffu << 23)));
}
// Test the correctness of gl::isInf function.
TEST(MathUtilTest, isInf)
{
EXPECT_TRUE(isInf(bitCast<float>(0xffu << 23)));
EXPECT_TRUE(isInf(bitCast<float>(1u << 31 | 0xffu << 23)));
EXPECT_FALSE(isInf(0.0f));
EXPECT_FALSE(isInf(bitCast<float>(0xffu << 23 | 1u)));
EXPECT_FALSE(isInf(bitCast<float>(1u << 31 | 0xffu << 23 | 1u)));
EXPECT_FALSE(isInf(bitCast<float>(1u << 31 | 0xffu << 23 | 0x400000u)));
EXPECT_FALSE(isInf(bitCast<float>(1u << 31 | 0xffu << 23 | 0x7fffffu)));
EXPECT_FALSE(isInf(bitCast<float>(0xfeu << 23 | 0x7fffffu)));
EXPECT_FALSE(isInf(bitCast<float>(1u << 31 | 0xfeu << 23 | 0x7fffffu)));
}
}
......@@ -1698,6 +1698,60 @@ TConstantUnion *TIntermConstantUnion::foldUnaryWithSameReturnType(TOperator op,
"Unary operation not folded into constant");
return nullptr;
case EOpIsNan:
if (getType().getBasicType() == EbtFloat)
{
resultArray[i].setBConst(gl::isNaN(operandArray[0].getFConst()));
break;
}
infoSink.info.message(EPrefixInternalError, getLine(), "Unary operation not folded into constant");
return nullptr;
case EOpIsInf:
if (getType().getBasicType() == EbtFloat)
{
resultArray[i].setBConst(gl::isInf(operandArray[0].getFConst()));
break;
}
infoSink.info.message(EPrefixInternalError, getLine(), "Unary operation not folded into constant");
return nullptr;
case EOpFloatBitsToInt:
if (getType().getBasicType() == EbtFloat)
{
resultArray[i].setIConst(gl::bitCast<int32_t>(operandArray[0].getFConst()));
break;
}
infoSink.info.message(EPrefixInternalError, getLine(), "Unary operation not folded into constant");
return nullptr;
case EOpFloatBitsToUint:
if (getType().getBasicType() == EbtFloat)
{
resultArray[i].setUConst(gl::bitCast<uint32_t>(operandArray[0].getFConst()));
break;
}
infoSink.info.message(EPrefixInternalError, getLine(), "Unary operation not folded into constant");
return nullptr;
case EOpIntBitsToFloat:
if (getType().getBasicType() == EbtInt)
{
resultArray[i].setFConst(gl::bitCast<float>(operandArray[0].getIConst()));
break;
}
infoSink.info.message(EPrefixInternalError, getLine(), "Unary operation not folded into constant");
return nullptr;
case EOpUintBitsToFloat:
if (getType().getBasicType() == EbtUInt)
{
resultArray[i].setFConst(gl::bitCast<float>(operandArray[0].getUConst()));
break;
}
infoSink.info.message(EPrefixInternalError, getLine(), "Unary operation not folded into constant");
return nullptr;
case EOpExp:
if (!foldFloatTypeUnary(operandArray[i], &expf, infoSink, &resultArray[i]))
return nullptr;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment