Fix Subzero vector comparison.
Subzero returns vNi1 type results for vector comparisons, which we were
sign-extending to v4i32, even for smaller fields. We don't actually
ever have to sign-extend these results.
Change-Id: Ifdd30edd498d66fc4c557804035794a659eacd87
Reviewed-on: https://swiftshader-review.googlesource.com/8449
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/Main.cpp b/src/Reactor/Main.cpp
index ae23773..362200a 100644
--- a/src/Reactor/Main.cpp
+++ b/src/Reactor/Main.cpp
@@ -55,7 +55,7 @@
z = As<Int>(Float(Float4(v.xzxx).y));
Int sum = x + y + z;
-
+
Return(sum);
}
@@ -93,7 +93,7 @@
{
c = p;
}
-
+
Return(a + z + q + c);
}
@@ -125,7 +125,7 @@
*Pointer<Byte8>(out + 16 * 2) = *Pointer<Byte8>(in + 16 * 2);
*Pointer<Byte4>(out + 16 * 3) = *Pointer<Byte4>(in + 16 * 3);
*Pointer<Short2>(out + 16 * 4) = *Pointer<Short2>(in + 16 * 4);
-
+
Return(0);
}
@@ -144,7 +144,7 @@
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1};
-
+
int (*callable)(void*, void*) = (int(*)(void*,void*))routine->getEntry();
callable(in, out);
@@ -243,7 +243,7 @@
int8_t out[16 * 5] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1};
-
+
int (*callable)(void*) = (int(*)(void*))routine->getEntry();
callable(out);
@@ -513,7 +513,6 @@
delete routine;
}
-
TEST(SubzeroReactorTest, NotNeg)
{
Routine *routine = nullptr;
@@ -583,7 +582,7 @@
EXPECT_EQ(out[6][1], 0x55555556);
EXPECT_EQ(out[6][2], 0x00000000);
EXPECT_EQ(out[6][3], 0x00000001);
-
+
EXPECT_EQ(out[7][0], 0x5556AAAB);
EXPECT_EQ(out[7][1], 0x00010000);
EXPECT_EQ(out[7][2], 0x00000000);
@@ -599,6 +598,68 @@
delete routine;
}
+TEST(SubzeroReactorTest, VectorCompare)
+{
+ Routine *routine = nullptr;
+
+ {
+ Function<Int(Pointer<Byte>)> function;
+ {
+ Pointer<Byte> out = function.Arg<0>();
+
+ *Pointer<Int4>(out + 16 * 0) = CmpEQ(Float4(1.0f, 1.0f, -0.0f, +0.0f), Float4(0.0f, 1.0f, +0.0f, -0.0f));
+ *Pointer<Int4>(out + 16 * 1) = CmpEQ(Int4(1, 0, -1, -0), Int4(0, 1, 0, +0));
+ *Pointer<Byte8>(out + 16 * 2) = CmpEQ(SByte8(1, 2, 3, 4, 5, 6, 7, 8), SByte8(7, 6, 5, 4, 3, 2, 1, 0));
+
+ *Pointer<Int4>(out + 16 * 3) = CmpNLT(Float4(1.0f, 1.0f, -0.0f, +0.0f), Float4(0.0f, 1.0f, +0.0f, -0.0f));
+ *Pointer<Int4>(out + 16 * 4) = CmpNLT(Int4(1, 0, -1, -0), Int4(0, 1, 0, +0));
+ *Pointer<Byte8>(out + 16 * 5) = CmpGT(SByte8(1, 2, 3, 4, 5, 6, 7, 8), SByte8(7, 6, 5, 4, 3, 2, 1, 0));
+
+ Return(0);
+ }
+
+ routine = function(L"one");
+
+ if(routine)
+ {
+ int out[6][4];
+
+ memset(&out, 0, sizeof(out));
+
+ int(*callable)(void*) = (int(*)(void*))routine->getEntry();
+ callable(&out);
+
+ EXPECT_EQ(out[0][0], 0x00000000);
+ EXPECT_EQ(out[0][1], 0xFFFFFFFF);
+ EXPECT_EQ(out[0][2], 0xFFFFFFFF);
+ EXPECT_EQ(out[0][3], 0xFFFFFFFF);
+
+ EXPECT_EQ(out[1][0], 0x00000000);
+ EXPECT_EQ(out[1][1], 0x00000000);
+ EXPECT_EQ(out[1][2], 0x00000000);
+ EXPECT_EQ(out[1][3], 0xFFFFFFFF);
+
+ EXPECT_EQ(out[2][0], 0xFF000000);
+ EXPECT_EQ(out[2][1], 0x00000000);
+
+ EXPECT_EQ(out[3][0], 0xFFFFFFFF);
+ EXPECT_EQ(out[3][1], 0xFFFFFFFF);
+ EXPECT_EQ(out[3][2], 0xFFFFFFFF);
+ EXPECT_EQ(out[3][3], 0xFFFFFFFF);
+
+ EXPECT_EQ(out[4][0], 0xFFFFFFFF);
+ EXPECT_EQ(out[4][1], 0x00000000);
+ EXPECT_EQ(out[4][2], 0x00000000);
+ EXPECT_EQ(out[4][3], 0xFFFFFFFF);
+
+ EXPECT_EQ(out[5][0], 0x00000000);
+ EXPECT_EQ(out[5][1], 0xFFFFFFFF);
+ }
+ }
+
+ delete routine;
+}
+
int main(int argc, char **argv)
{
::testing::InitGoogleTest(&argc, argv);
diff --git a/src/Reactor/SubzeroReactor.cpp b/src/Reactor/SubzeroReactor.cpp
index c8d7e1c..cf32cc7 100644
--- a/src/Reactor/SubzeroReactor.cpp
+++ b/src/Reactor/SubzeroReactor.cpp
@@ -2606,7 +2606,7 @@
RValue<Byte8> CmpEQ(RValue<Byte8> x, RValue<Byte8> y)
{
- return RValue<Byte8>(Nucleus::createSExt(Nucleus::createICmpEQ(x.value, y.value), Int4::getType()));
+ return RValue<Byte8>(Nucleus::createICmpEQ(x.value, y.value));
}
Type *Byte8::getType()
@@ -2848,7 +2848,7 @@
RValue<Byte8> CmpEQ(RValue<SByte8> x, RValue<SByte8> y)
{
- return RValue<Byte8>(Nucleus::createSExt(Nucleus::createICmpEQ(x.value, y.value), Int4::getType()));
+ return RValue<Byte8>(Nucleus::createICmpEQ(x.value, y.value));
}
Type *SByte8::getType()
@@ -3333,7 +3333,7 @@
RValue<Short4> CmpEQ(RValue<Short4> x, RValue<Short4> y)
{
- return RValue<Short4>(Nucleus::createSExt(Nucleus::createICmpEQ(x.value, y.value), Int4::getType()));
+ return RValue<Short4>(Nucleus::createICmpEQ(x.value, y.value));
}
Type *Short4::getType()
@@ -5292,32 +5292,32 @@
RValue<Int4> CmpEQ(RValue<Int4> x, RValue<Int4> y)
{
- return RValue<Int4>(Nucleus::createSExt(Nucleus::createICmpEQ(x.value, y.value), Int4::getType()));
+ return RValue<Int4>(Nucleus::createICmpEQ(x.value, y.value));
}
RValue<Int4> CmpLT(RValue<Int4> x, RValue<Int4> y)
{
- return RValue<Int4>(Nucleus::createSExt(Nucleus::createICmpSLT(x.value, y.value), Int4::getType()));
+ return RValue<Int4>(Nucleus::createICmpSLT(x.value, y.value));
}
RValue<Int4> CmpLE(RValue<Int4> x, RValue<Int4> y)
{
- return RValue<Int4>(Nucleus::createSExt(Nucleus::createICmpSLE(x.value, y.value), Int4::getType()));
+ return RValue<Int4>(Nucleus::createICmpSLE(x.value, y.value));
}
RValue<Int4> CmpNEQ(RValue<Int4> x, RValue<Int4> y)
{
- return RValue<Int4>(Nucleus::createSExt(Nucleus::createICmpNE(x.value, y.value), Int4::getType()));
+ return RValue<Int4>(Nucleus::createICmpNE(x.value, y.value));
}
RValue<Int4> CmpNLT(RValue<Int4> x, RValue<Int4> y)
{
- return RValue<Int4>(Nucleus::createSExt(Nucleus::createICmpSGE(x.value, y.value), Int4::getType()));
+ return RValue<Int4>(Nucleus::createICmpSGE(x.value, y.value));
}
RValue<Int4> CmpNLE(RValue<Int4> x, RValue<Int4> y)
{
- return RValue<Int4>(Nucleus::createSExt(Nucleus::createICmpSGT(x.value, y.value), Int4::getType()));
+ return RValue<Int4>(Nucleus::createICmpSGT(x.value, y.value));
}
RValue<Int4> Max(RValue<Int4> x, RValue<Int4> y)
@@ -5657,32 +5657,32 @@
RValue<UInt4> CmpEQ(RValue<UInt4> x, RValue<UInt4> y)
{
- return RValue<UInt4>(Nucleus::createSExt(Nucleus::createICmpEQ(x.value, y.value), Int4::getType()));
+ return RValue<UInt4>(Nucleus::createICmpEQ(x.value, y.value));
}
RValue<UInt4> CmpLT(RValue<UInt4> x, RValue<UInt4> y)
{
- return RValue<UInt4>(Nucleus::createSExt(Nucleus::createICmpULT(x.value, y.value), Int4::getType()));
+ return RValue<UInt4>(Nucleus::createICmpULT(x.value, y.value));
}
RValue<UInt4> CmpLE(RValue<UInt4> x, RValue<UInt4> y)
{
- return RValue<UInt4>(Nucleus::createSExt(Nucleus::createICmpULE(x.value, y.value), Int4::getType()));
+ return RValue<UInt4>(Nucleus::createICmpULE(x.value, y.value));
}
RValue<UInt4> CmpNEQ(RValue<UInt4> x, RValue<UInt4> y)
{
- return RValue<UInt4>(Nucleus::createSExt(Nucleus::createICmpNE(x.value, y.value), Int4::getType()));
+ return RValue<UInt4>(Nucleus::createICmpNE(x.value, y.value));
}
RValue<UInt4> CmpNLT(RValue<UInt4> x, RValue<UInt4> y)
{
- return RValue<UInt4>(Nucleus::createSExt(Nucleus::createICmpUGE(x.value, y.value), Int4::getType()));
+ return RValue<UInt4>(Nucleus::createICmpUGE(x.value, y.value));
}
RValue<UInt4> CmpNLE(RValue<UInt4> x, RValue<UInt4> y)
{
- return RValue<UInt4>(Nucleus::createSExt(Nucleus::createICmpUGT(x.value, y.value), Int4::getType()));
+ return RValue<UInt4>(Nucleus::createICmpUGT(x.value, y.value));
}
RValue<UInt4> Max(RValue<UInt4> x, RValue<UInt4> y)
@@ -6303,32 +6303,32 @@
RValue<Int4> CmpEQ(RValue<Float4> x, RValue<Float4> y)
{
- return RValue<Int4>(Nucleus::createSExt(Nucleus::createFCmpOEQ(x.value, y.value), Int4::getType()));
+ return RValue<Int4>(Nucleus::createFCmpOEQ(x.value, y.value));
}
RValue<Int4> CmpLT(RValue<Float4> x, RValue<Float4> y)
{
- return RValue<Int4>(Nucleus::createSExt(Nucleus::createFCmpOLT(x.value, y.value), Int4::getType()));
+ return RValue<Int4>(Nucleus::createFCmpOLT(x.value, y.value));
}
RValue<Int4> CmpLE(RValue<Float4> x, RValue<Float4> y)
{
- return RValue<Int4>(Nucleus::createSExt(Nucleus::createFCmpOLE(x.value, y.value), Int4::getType()));
+ return RValue<Int4>(Nucleus::createFCmpOLE(x.value, y.value));
}
RValue<Int4> CmpNEQ(RValue<Float4> x, RValue<Float4> y)
{
- return RValue<Int4>(Nucleus::createSExt(Nucleus::createFCmpONE(x.value, y.value), Int4::getType()));
+ return RValue<Int4>(Nucleus::createFCmpONE(x.value, y.value));
}
RValue<Int4> CmpNLT(RValue<Float4> x, RValue<Float4> y)
{
- return RValue<Int4>(Nucleus::createSExt(Nucleus::createFCmpOGE(x.value, y.value), Int4::getType()));
+ return RValue<Int4>(Nucleus::createFCmpOGE(x.value, y.value));
}
RValue<Int4> CmpNLE(RValue<Float4> x, RValue<Float4> y)
{
- return RValue<Int4>(Nucleus::createSExt(Nucleus::createFCmpOGT(x.value, y.value), Int4::getType()));
+ return RValue<Int4>(Nucleus::createFCmpOGT(x.value, y.value));
}
RValue<Float4> Round(RValue<Float4> x)