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)