Remove Float->UInt conversion workaround
In LLVM3, this conversion was subtly broken. We're now on LLVM7, where this should be
fixed.
Mostly a revert of
https://swiftshader-review.googlesource.com/c/SwiftShader/+/7354, but
also includes a subzero implementation
Bug: b/31816482
Change-Id: I154a221b44b985a35bcc5e15923a0deb9b51c711
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/39148
Tested-by: Chris Forbes <chrisforbes@google.com>
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
Kokoro-Presubmit: kokoro <noreply+kokoro@google.com>
diff --git a/src/Reactor/LLVMReactor.cpp b/src/Reactor/LLVMReactor.cpp
index af39027..9654292 100644
--- a/src/Reactor/LLVMReactor.cpp
+++ b/src/Reactor/LLVMReactor.cpp
@@ -1956,6 +1956,12 @@
return V(jit->builder->CreateSExt(V(v), T(destType)));
}
+ Value *Nucleus::createFPToUI(Value *v, Type *destType)
+ {
+ RR_DEBUG_INFO_UPDATE_LOC();
+ return V(jit->builder->CreateFPToUI(V(v), T(destType)));
+ }
+
Value *Nucleus::createFPToSI(Value *v, Type *destType)
{
RR_DEBUG_INFO_UPDATE_LOC();
@@ -2919,21 +2925,8 @@
UInt::UInt(RValue<Float> cast)
{
RR_DEBUG_INFO_UPDATE_LOC();
- // Note: createFPToUI is broken, must perform conversion using createFPtoSI
- // Value *integer = Nucleus::createFPToUI(cast.value, UInt::getType());
-
- // Smallest positive value representable in UInt, but not in Int
- const unsigned int ustart = 0x80000000u;
- const float ustartf = float(ustart);
-
- // If the value is negative, store 0, otherwise store the result of the conversion
- storeValue((~(As<Int>(cast) >> 31) &
- // Check if the value can be represented as an Int
- IfThenElse(cast >= ustartf,
- // If the value is too large, subtract ustart and re-add it after conversion.
- As<Int>(As<UInt>(Int(cast - Float(ustartf))) + UInt(ustart)),
- // Otherwise, just convert normally
- Int(cast))).value);
+ Value *integer = Nucleus::createFPToUI(cast.value, UInt::getType());
+ storeValue(integer);
}
RValue<UInt> operator++(UInt &val, int) // Post-increment
@@ -3301,21 +3294,8 @@
UInt4::UInt4(RValue<Float4> cast) : XYZW(this)
{
RR_DEBUG_INFO_UPDATE_LOC();
- // Note: createFPToUI is broken, must perform conversion using createFPtoSI
- // Value *xyzw = Nucleus::createFPToUI(cast.value, UInt4::getType());
-
- // Smallest positive value representable in UInt, but not in Int
- const unsigned int ustart = 0x80000000u;
- const float ustartf = float(ustart);
-
- // Check if the value can be represented as an Int
- Int4 uiValue = CmpNLT(cast, Float4(ustartf));
- // If the value is too large, subtract ustart and re-add it after conversion.
- uiValue = (uiValue & As<Int4>(As<UInt4>(Int4(cast - Float4(ustartf))) + UInt4(ustart))) |
- // Otherwise, just convert normally
- (~uiValue & Int4(cast));
- // If the value is negative, store 0, otherwise store the result of the conversion
- storeValue((~(As<Int4>(cast) >> 31) & uiValue).value);
+ Value *xyzw = Nucleus::createFPToUI(cast.value, UInt4::getType());
+ storeValue(xyzw);
}
UInt4::UInt4(RValue<UInt> rhs) : XYZW(this)
diff --git a/src/Reactor/Nucleus.hpp b/src/Reactor/Nucleus.hpp
index fd202a3..a552b41 100644
--- a/src/Reactor/Nucleus.hpp
+++ b/src/Reactor/Nucleus.hpp
@@ -229,6 +229,7 @@
static Value *createTrunc(Value *V, Type *destType);
static Value *createZExt(Value *V, Type *destType);
static Value *createSExt(Value *V, Type *destType);
+ static Value *createFPToUI(Value *V, Type *destType);
static Value *createFPToSI(Value *V, Type *destType);
static Value *createSIToFP(Value *V, Type *destType);
static Value *createFPTrunc(Value *V, Type *destType);
diff --git a/src/Reactor/SubzeroReactor.cpp b/src/Reactor/SubzeroReactor.cpp
index 552b80e..8b2d19c 100644
--- a/src/Reactor/SubzeroReactor.cpp
+++ b/src/Reactor/SubzeroReactor.cpp
@@ -1221,6 +1221,11 @@
return createCast(Ice::InstCast::Sext, v, destType);
}
+ Value *Nucleus::createFPToUI(Value *v, Type *destType)
+ {
+ return createCast(Ice::InstCast::Fptoui, v, destType);
+ }
+
Value *Nucleus::createFPToSI(Value *v, Type *destType)
{
return createCast(Ice::InstCast::Fptosi, v, destType);