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()