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)