Manually convert unsigned integer to floating-point.
Subzero uses a helper function to convert uint to float. It's faster to
just emit a sequence of operations to perform the cast manually.
This implementation converts the lower 31 bits as a signed integer, and
adds 0x80000000 as a floating-point value when the upper bit is set.
This approach does not produce the correct rounding in rare cases, but
should still be adequate. For consistency, we're also using this method
with the LLVM back-end.
Change-Id: Ic5d7b73cd2a9e154056365cdbe9af0962bdbe1cb
Reviewed-on: https://swiftshader-review.googlesource.com/8312
Tested-by: Nicolas Capens <capn@google.com>
Reviewed-by: Alexis Hétu <sugoi@google.com>
Reviewed-by: Nicolas Capens <capn@google.com>
diff --git a/src/Reactor/LLVMReactor.cpp b/src/Reactor/LLVMReactor.cpp
index 2b7da2c..d319445 100644
--- a/src/Reactor/LLVMReactor.cpp
+++ b/src/Reactor/LLVMReactor.cpp
@@ -482,11 +482,6 @@
return V(::builder->CreateFPToSI(v, destType));
}
- Value *Nucleus::createUIToFP(Value *v, Type *destType)
- {
- return V(::builder->CreateUIToFP(v, destType));
- }
-
Value *Nucleus::createSIToFP(Value *v, Type *destType)
{
return V(::builder->CreateSIToFP(v, destType));
@@ -952,7 +947,7 @@
return rhs;
}
- RValue<Byte> Byte::operator=(const Byte &rhs)
+ RValue<Byte> Byte::operator=(const Byte &rhs)
{
Value *value = rhs.loadValue();
storeValue(value);
@@ -6101,9 +6096,10 @@
{
xyzw.parent = this;
- Value *xyzw = Nucleus::createUIToFP(cast.value, Float4::getType());
+ RValue<Float4> result = Float4(Int4(cast & UInt4(0x7FFFFFFF))) +
+ As<Float4>((As<Int4>(cast) >> 31) & As<Int4>(Float4(0x80000000u)));
- storeValue(xyzw);
+ storeValue(result.value);
}
Float4::Float4()
diff --git a/src/Reactor/Nucleus.hpp b/src/Reactor/Nucleus.hpp
index 8307800..196ca76 100644
--- a/src/Reactor/Nucleus.hpp
+++ b/src/Reactor/Nucleus.hpp
@@ -106,7 +106,6 @@
static Value *createZExt(Value *V, Type *destType);
static Value *createSExt(Value *V, Type *destType);
static Value *createFPToSI(Value *V, Type *destType);
- static Value *createUIToFP(Value *V, Type *destType);
static Value *createSIToFP(Value *V, Type *destType);
static Value *createFPTrunc(Value *V, Type *destType);
static Value *createFPExt(Value *V, Type *destType);
diff --git a/src/Reactor/SubzeroReactor.cpp b/src/Reactor/SubzeroReactor.cpp
index ab4c109..c8d7e1c 100644
--- a/src/Reactor/SubzeroReactor.cpp
+++ b/src/Reactor/SubzeroReactor.cpp
@@ -853,11 +853,6 @@
return createCast(Ice::InstCast::Fptosi, v, destType);
}
- Value *Nucleus::createUIToFP(Value *v, Type *destType)
- {
- return createCast(Ice::InstCast::Uitofp, v, destType);
- }
-
Value *Nucleus::createSIToFP(Value *v, Type *destType)
{
return createCast(Ice::InstCast::Sitofp, v, destType);
@@ -5996,9 +5991,10 @@
{
xyzw.parent = this;
- Value *xyzw = Nucleus::createUIToFP(cast.value, Float4::getType());
+ RValue<Float4> result = Float4(Int4(cast & UInt4(0x7FFFFFFF))) +
+ As<Float4>((As<Int4>(cast) >> 31) & As<Int4>(Float4(0x80000000u)));
- storeValue(xyzw);
+ storeValue(result.value);
}
Float4::Float4()