Fix RValue<T> construction from incorrect types.

When constructing an RValue<T> from a Value, the types should match.
Else a bitcast is required.

Bug swiftshader:48

Change-Id: I5073091524d2f56681dab052c9f84a06b3be7b4f
Reviewed-on: https://swiftshader-review.googlesource.com/10908
Tested-by: Nicolas Capens <nicolascapens@google.com>
Reviewed-by: Alexis Hétu <sugoi@google.com>
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
diff --git a/src/Reactor/LLVMReactor.cpp b/src/Reactor/LLVMReactor.cpp
index c3a59ff..5dd4a8b 100644
--- a/src/Reactor/LLVMReactor.cpp
+++ b/src/Reactor/LLVMReactor.cpp
@@ -2541,7 +2541,7 @@
 	Short4::Short4(RValue<Int> cast)
 	{
 		Value *extend = Nucleus::createZExt(cast.value, Long::getType());
-		Value *swizzle = Swizzle(RValue<Short4>(extend), 0x00).value;
+		Value *swizzle = Swizzle(As<Short4>(extend), 0x00).value;
 
 		storeValue(swizzle);
 	}
@@ -2584,7 +2584,7 @@
 				Value *element = Nucleus::createExtractElement(qword2, 0);
 				Value *short4 = Nucleus::createBitCast(element, Short4::getType());
 			#else   // FIXME: Requires SSE
-				Value *int2 = RValue<Int2>(Int2(RValue<Int4>(packed))).value;
+				Value *int2 = RValue<Int2>(Int2(As<Int4>(packed))).value;
 				Value *short4 = Nucleus::createBitCast(int2, Short4::getType());
 			#endif
 		#endif
diff --git a/src/Reactor/Reactor.hpp b/src/Reactor/Reactor.hpp
index 186f739..98eb6fd 100644
--- a/src/Reactor/Reactor.hpp
+++ b/src/Reactor/Reactor.hpp
@@ -18,6 +18,7 @@
 #include "Nucleus.hpp"
 #include "Routine.hpp"
 
+#include <assert.h>
 #include <cstddef>
 #include <cwchar>
 #undef Bool
@@ -2306,6 +2307,8 @@
 	template<class T>
 	RValue<T>::RValue(Value *rvalue)
 	{
+		assert(Nucleus::createBitCast(rvalue, T::getType()) == rvalue);   // Run-time type should match T, so bitcast is no-op.
+
 		value = rvalue;
 	}
 
diff --git a/src/Reactor/SubzeroReactor.cpp b/src/Reactor/SubzeroReactor.cpp
index 9f01b2a..23bcedc 100644
--- a/src/Reactor/SubzeroReactor.cpp
+++ b/src/Reactor/SubzeroReactor.cpp
@@ -2655,7 +2655,7 @@
 	RValue<Short4> Unpack(RValue<Byte4> x)
 	{
 		int shuffle[16] = {0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7};   // Real type is v16i8
-		return RValue<Short4>(Nucleus::createShuffleVector(x.value, x.value, shuffle));
+		return As<Short4>(Nucleus::createShuffleVector(x.value, x.value, shuffle));
 	}
 
 	RValue<Short4> Unpack(RValue<Byte4> x, RValue<Byte4> y)
@@ -2666,7 +2666,7 @@
 	RValue<Short4> UnpackLow(RValue<Byte8> x, RValue<Byte8> y)
 	{
 		int shuffle[16] = {0, 16, 1, 17, 2, 18, 3, 19, 4, 20, 5, 21, 6, 22, 7, 23};   // Real type is v16i8
-		return RValue<Short4>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
+		return As<Short4>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
 	}
 
 	RValue<Short4> UnpackHigh(RValue<Byte8> x, RValue<Byte8> y)
@@ -2895,7 +2895,7 @@
 	RValue<Short4> UnpackLow(RValue<SByte8> x, RValue<SByte8> y)
 	{
 		int shuffle[16] = {0, 16, 1, 17, 2, 18, 3, 19, 4, 20, 5, 21, 6, 22, 7, 23};   // Real type is v16i8
-		return RValue<Short4>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
+		return As<Short4>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
 	}
 
 	RValue<Short4> UnpackHigh(RValue<SByte8> x, RValue<SByte8> y)
@@ -3018,7 +3018,7 @@
 		Value *short8 = Nucleus::createBitCast(cast.value, Short8::getType());
 		Value *packed = Nucleus::createShuffleVector(short8, short8, select);
 
-		Value *int2 = RValue<Int2>(Int2(RValue<Int4>(packed))).value;
+		Value *int2 = RValue<Int2>(Int2(As<Int4>(packed))).value;
 		Value *short4 = Nucleus::createBitCast(int2, Short4::getType());
 
 		storeValue(short4);
@@ -3319,7 +3319,7 @@
 		pmaddwd->addArg(y.value);
 		::basicBlock->appendInst(pmaddwd);
 
-		return RValue<Int2>(V(result));
+		return As<Int2>(V(result));
 	}
 
 	RValue<SByte8> Pack(RValue<Short4> x, RValue<Short4> y)
@@ -3338,7 +3338,7 @@
 	RValue<Int2> UnpackLow(RValue<Short4> x, RValue<Short4> y)
 	{
 		int shuffle[8] = {0, 8, 1, 9, 2, 10, 3, 11};   // Real type is v8i16
-		return RValue<Int2>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
+		return As<Int2>(Nucleus::createShuffleVector(x.value, y.value, shuffle));
 	}
 
 	RValue<Int2> UnpackHigh(RValue<Short4> x, RValue<Short4> y)