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