SpirvShader: Add relational ops for ordered and unordered floats
Bug: b/127282157
Change-Id: Id2c5b29d744f6f7ddcbb853db0a95228425d7f83
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/26108
Tested-by: Ben Clayton <bclayton@google.com>
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
Kokoro-Presubmit: kokoro <noreply+kokoro@google.com>
diff --git a/src/Reactor/SubzeroReactor.cpp b/src/Reactor/SubzeroReactor.cpp
index 7048640..b4f1971 100644
--- a/src/Reactor/SubzeroReactor.cpp
+++ b/src/Reactor/SubzeroReactor.cpp
@@ -6387,38 +6387,38 @@
return T(Ice::IceType_v4i32);
}
- Half::Half(RValue<Float> cast)
- {
- UInt fp32i = As<UInt>(cast);
- UInt abs = fp32i & 0x7FFFFFFF;
- UShort fp16i((fp32i & 0x80000000) >> 16); // sign
-
- If(abs > 0x47FFEFFF) // Infinity
- {
- fp16i |= UShort(0x7FFF);
- }
- Else
- {
- If(abs < 0x38800000) // Denormal
- {
- Int mantissa = (abs & 0x007FFFFF) | 0x00800000;
- Int e = 113 - (abs >> 23);
- abs = IfThenElse(e < 24, mantissa >> e, Int(0));
- fp16i |= UShort((abs + 0x00000FFF + ((abs >> 13) & 1)) >> 13);
- }
- Else
- {
- fp16i |= UShort((abs + 0xC8000000 + 0x00000FFF + ((abs >> 13) & 1)) >> 13);
- }
- }
-
- storeValue(fp16i.loadValue());
- }
-
- Type *Half::getType()
- {
- return T(Ice::IceType_i16);
- }
+ Half::Half(RValue<Float> cast)
+ {
+ UInt fp32i = As<UInt>(cast);
+ UInt abs = fp32i & 0x7FFFFFFF;
+ UShort fp16i((fp32i & 0x80000000) >> 16); // sign
+
+ If(abs > 0x47FFEFFF) // Infinity
+ {
+ fp16i |= UShort(0x7FFF);
+ }
+ Else
+ {
+ If(abs < 0x38800000) // Denormal
+ {
+ Int mantissa = (abs & 0x007FFFFF) | 0x00800000;
+ Int e = 113 - (abs >> 23);
+ abs = IfThenElse(e < 24, mantissa >> e, Int(0));
+ fp16i |= UShort((abs + 0x00000FFF + ((abs >> 13) & 1)) >> 13);
+ }
+ Else
+ {
+ fp16i |= UShort((abs + 0xC8000000 + 0x00000FFF + ((abs >> 13) & 1)) >> 13);
+ }
+ }
+
+ storeValue(fp16i.loadValue());
+ }
+
+ Type *Half::getType()
+ {
+ return T(Ice::IceType_i16);
+ }
Float::Float(RValue<Int> cast)
{
@@ -6435,34 +6435,34 @@
storeValue(result.value);
}
- Float::Float(RValue<Half> cast)
- {
- Int fp16i(As<UShort>(cast));
-
- Int s = (fp16i >> 15) & 0x00000001;
- Int e = (fp16i >> 10) & 0x0000001F;
- Int m = fp16i & 0x000003FF;
-
- UInt fp32i(s << 31);
- If(e == 0)
- {
- If(m != 0)
- {
- While((m & 0x00000400) == 0)
- {
- m <<= 1;
- e -= 1;
- }
-
- fp32i |= As<UInt>(((e + (127 - 15) + 1) << 23) | ((m & ~0x00000400) << 13));
- }
- }
- Else
- {
- fp32i |= As<UInt>(((e + (127 - 15)) << 23) | (m << 13));
- }
-
- storeValue(As<Float>(fp32i).value);
+ Float::Float(RValue<Half> cast)
+ {
+ Int fp16i(As<UShort>(cast));
+
+ Int s = (fp16i >> 15) & 0x00000001;
+ Int e = (fp16i >> 10) & 0x0000001F;
+ Int m = fp16i & 0x000003FF;
+
+ UInt fp32i(s << 31);
+ If(e == 0)
+ {
+ If(m != 0)
+ {
+ While((m & 0x00000400) == 0)
+ {
+ m <<= 1;
+ e -= 1;
+ }
+
+ fp32i |= As<UInt>(((e + (127 - 15) + 1) << 23) | ((m & ~0x00000400) << 13));
+ }
+ }
+ Else
+ {
+ fp32i |= As<UInt>(((e + (127 - 15)) << 23) | (m << 13));
+ }
+
+ storeValue(As<Float>(fp32i).value);
}
Float::Float(float x)
@@ -7049,6 +7049,36 @@
return RValue<Int4>(Nucleus::createFCmpOGT(x.value, y.value));
}
+ RValue<Int4> CmpUEQ(RValue<Float4> x, RValue<Float4> y)
+ {
+ return RValue<Int4>(Nucleus::createFCmpUEQ(x.value, y.value));
+ }
+
+ RValue<Int4> CmpULT(RValue<Float4> x, RValue<Float4> y)
+ {
+ return RValue<Int4>(Nucleus::createFCmpULT(x.value, y.value));
+ }
+
+ RValue<Int4> CmpULE(RValue<Float4> x, RValue<Float4> y)
+ {
+ return RValue<Int4>(Nucleus::createFCmpULE(x.value, y.value));
+ }
+
+ RValue<Int4> CmpUNEQ(RValue<Float4> x, RValue<Float4> y)
+ {
+ return RValue<Int4>(Nucleus::createFCmpUNE(x.value, y.value));
+ }
+
+ RValue<Int4> CmpUNLT(RValue<Float4> x, RValue<Float4> y)
+ {
+ return RValue<Int4>(Nucleus::createFCmpUGE(x.value, y.value));
+ }
+
+ RValue<Int4> CmpUNLE(RValue<Float4> x, RValue<Float4> y)
+ {
+ return RValue<Int4>(Nucleus::createFCmpUGT(x.value, y.value));
+ }
+
RValue<Int4> IsInf(RValue<Float4> x)
{
return CmpEQ(As<Int4>(x) & Int4(0x7FFFFFFF), Int4(0x7F800000));