Commit 8b759f31 by Nicolas Capens

Implement min/max.

Bug swiftshader:15 Change-Id: I785e31724e802a3ed1bca75186e012ccc7cb336e Reviewed-on: https://swiftshader-review.googlesource.com/7850Reviewed-by: 's avatarNicolas Capens <capn@google.com> Tested-by: 's avatarNicolas Capens <capn@google.com>
parent cb2e94fe
...@@ -342,6 +342,97 @@ TEST(SubzeroReactorTest, Branching) ...@@ -342,6 +342,97 @@ TEST(SubzeroReactorTest, Branching)
delete routine; delete routine;
} }
TEST(SubzeroReactorTest, MinMax)
{
Routine *routine = nullptr;
{
Function<Int(Pointer<Byte>)> function;
{
Pointer<Byte> out = function.Arg<0>();
*Pointer<Float4>(out + 16 * 0) = Min(Float4(1.0f, 0.0f, -0.0f, +0.0f), Float4(0.0f, 1.0f, +0.0f, -0.0f));
*Pointer<Float4>(out + 16 * 1) = Max(Float4(1.0f, 0.0f, -0.0f, +0.0f), Float4(0.0f, 1.0f, +0.0f, -0.0f));
*Pointer<Int4>(out + 16 * 2) = Min(Int4(1, 0, -1, -0), Int4(0, 1, 0, +0));
*Pointer<Int4>(out + 16 * 3) = Max(Int4(1, 0, -1, -0), Int4(0, 1, 0, +0));
*Pointer<UInt4>(out + 16 * 4) = Min(UInt4(1, 0, -1, -0), UInt4(0, 1, 0, +0));
*Pointer<UInt4>(out + 16 * 5) = Max(UInt4(1, 0, -1, -0), UInt4(0, 1, 0, +0));
*Pointer<Short4>(out + 16 * 6) = Min(Short4(1, 0, -1, -0), Short4(0, 1, 0, +0));
*Pointer<Short4>(out + 16 * 7) = Max(Short4(1, 0, -1, -0), Short4(0, 1, 0, +0));
*Pointer<UShort4>(out + 16 * 8) = Min(UShort4(1, 0, -1, -0), UShort4(0, 1, 0, +0));
*Pointer<UShort4>(out + 16 * 9) = Max(UShort4(1, 0, -1, -0), UShort4(0, 1, 0, +0));
Return(0);
}
routine = function(L"one");
if(routine)
{
int out[10][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], 0x00000000);
EXPECT_EQ(out[0][2], 0x80000000);
EXPECT_EQ(out[0][3], 0x00000000);
EXPECT_EQ(out[1][0], 0x3F800000);
EXPECT_EQ(out[1][1], 0x3F800000);
EXPECT_EQ(out[1][2], 0x00000000);
EXPECT_EQ(out[1][3], 0x80000000);
EXPECT_EQ(out[2][0], 0x00000000);
EXPECT_EQ(out[2][1], 0x00000000);
EXPECT_EQ(out[2][2], 0xFFFFFFFF);
EXPECT_EQ(out[2][3], 0x00000000);
EXPECT_EQ(out[3][0], 0x00000001);
EXPECT_EQ(out[3][1], 0x00000001);
EXPECT_EQ(out[3][2], 0x00000000);
EXPECT_EQ(out[3][3], 0x00000000);
EXPECT_EQ(out[4][0], 0x00000000);
EXPECT_EQ(out[4][1], 0x00000000);
EXPECT_EQ(out[4][2], 0x00000000);
EXPECT_EQ(out[4][3], 0x00000000);
EXPECT_EQ(out[5][0], 0x00000001);
EXPECT_EQ(out[5][1], 0x00000001);
EXPECT_EQ(out[5][2], 0xFFFFFFFF);
EXPECT_EQ(out[5][3], 0x00000000);
EXPECT_EQ(out[6][0], 0x00000000);
EXPECT_EQ(out[6][1], 0x0000FFFF);
EXPECT_EQ(out[6][2], 0x00000000);
EXPECT_EQ(out[6][3], 0x00000000);
EXPECT_EQ(out[7][0], 0x00010001);
EXPECT_EQ(out[7][1], 0x00000000);
EXPECT_EQ(out[7][2], 0x00000000);
EXPECT_EQ(out[7][3], 0x00000000);
EXPECT_EQ(out[8][0], 0x00000000);
EXPECT_EQ(out[8][1], 0x00000000);
EXPECT_EQ(out[8][2], 0x00000000);
EXPECT_EQ(out[8][3], 0x00000000);
EXPECT_EQ(out[9][0], 0x00010001);
EXPECT_EQ(out[9][1], 0x0000FFFF);
EXPECT_EQ(out[9][2], 0x00000000);
EXPECT_EQ(out[9][3], 0x00000000);
}
}
delete routine;
}
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
::testing::InitGoogleTest(&argc, argv); ::testing::InitGoogleTest(&argc, argv);
......
...@@ -1013,7 +1013,13 @@ namespace sw ...@@ -1013,7 +1013,13 @@ namespace sw
Value *Nucleus::createSelect(Value *C, Value *ifTrue, Value *ifFalse) Value *Nucleus::createSelect(Value *C, Value *ifTrue, Value *ifFalse)
{ {
assert(false && "UNIMPLEMENTED"); return nullptr; assert(ifTrue->getType() == ifFalse->getType());
auto result = ::function->makeVariable(ifTrue->getType());
auto *select = Ice::InstSelect::create(::function, result, C, ifTrue, ifFalse);
::basicBlock->appendInst(select);
return V(result);
} }
Value *Nucleus::createSwitch(Value *v, BasicBlock *Dest, unsigned NumCases) Value *Nucleus::createSwitch(Value *v, BasicBlock *Dest, unsigned NumCases)
...@@ -3162,12 +3168,28 @@ namespace sw ...@@ -3162,12 +3168,28 @@ namespace sw
RValue<Short4> Max(RValue<Short4> x, RValue<Short4> y) RValue<Short4> Max(RValue<Short4> x, RValue<Short4> y)
{ {
assert(false && "UNIMPLEMENTED"); return RValue<Short4>(V(nullptr)); Ice::Variable *condition = ::function->makeVariable(Ice::IceType_v8i1);
auto cmp = Ice::InstIcmp::create(::function, Ice::InstIcmp::Sle, condition, x.value, y.value);
::basicBlock->appendInst(cmp);
Ice::Variable *result = ::function->makeVariable(Ice::IceType_v8i16);
auto select = Ice::InstSelect::create(::function, result, condition, y.value, x.value);
::basicBlock->appendInst(select);
return RValue<Short4>(V(result));
} }
RValue<Short4> Min(RValue<Short4> x, RValue<Short4> y) RValue<Short4> Min(RValue<Short4> x, RValue<Short4> y)
{ {
assert(false && "UNIMPLEMENTED"); return RValue<Short4>(V(nullptr)); Ice::Variable *condition = ::function->makeVariable(Ice::IceType_v8i1);
auto cmp = Ice::InstIcmp::create(::function, Ice::InstIcmp::Sgt, condition, x.value, y.value);
::basicBlock->appendInst(cmp);
Ice::Variable *result = ::function->makeVariable(Ice::IceType_v8i16);
auto select = Ice::InstSelect::create(::function, result, condition, y.value, x.value);
::basicBlock->appendInst(select);
return RValue<Short4>(V(result));
} }
RValue<Short4> AddSat(RValue<Short4> x, RValue<Short4> y) RValue<Short4> AddSat(RValue<Short4> x, RValue<Short4> y)
...@@ -3459,12 +3481,28 @@ namespace sw ...@@ -3459,12 +3481,28 @@ namespace sw
RValue<UShort4> Max(RValue<UShort4> x, RValue<UShort4> y) RValue<UShort4> Max(RValue<UShort4> x, RValue<UShort4> y)
{ {
assert(false && "UNIMPLEMENTED"); return RValue<UShort4>(V(nullptr)); Ice::Variable *condition = ::function->makeVariable(Ice::IceType_v8i1);
auto cmp = Ice::InstIcmp::create(::function, Ice::InstIcmp::Ule, condition, x.value, y.value);
::basicBlock->appendInst(cmp);
Ice::Variable *result = ::function->makeVariable(Ice::IceType_v8i16);
auto select = Ice::InstSelect::create(::function, result, condition, y.value, x.value);
::basicBlock->appendInst(select);
return RValue<UShort4>(V(result));
} }
RValue<UShort4> Min(RValue<UShort4> x, RValue<UShort4> y) RValue<UShort4> Min(RValue<UShort4> x, RValue<UShort4> y)
{ {
assert(false && "UNIMPLEMENTED"); return RValue<UShort4>(V(nullptr)); Ice::Variable *condition = ::function->makeVariable(Ice::IceType_v8i1);
auto cmp = Ice::InstIcmp::create(::function, Ice::InstIcmp::Ugt, condition, x.value, y.value);
::basicBlock->appendInst(cmp);
Ice::Variable *result = ::function->makeVariable(Ice::IceType_v8i16);
auto select = Ice::InstSelect::create(::function, result, condition, y.value, x.value);
::basicBlock->appendInst(select);
return RValue<UShort4>(V(result));
} }
RValue<UShort4> AddSat(RValue<UShort4> x, RValue<UShort4> y) RValue<UShort4> AddSat(RValue<UShort4> x, RValue<UShort4> y)
...@@ -5181,12 +5219,28 @@ namespace sw ...@@ -5181,12 +5219,28 @@ namespace sw
RValue<Int4> Max(RValue<Int4> x, RValue<Int4> y) RValue<Int4> Max(RValue<Int4> x, RValue<Int4> y)
{ {
assert(false && "UNIMPLEMENTED"); return RValue<Int4>(V(nullptr)); Ice::Variable *condition = ::function->makeVariable(Ice::IceType_v4i1);
auto cmp = Ice::InstIcmp::create(::function, Ice::InstIcmp::Sle, condition, x.value, y.value);
::basicBlock->appendInst(cmp);
Ice::Variable *result = ::function->makeVariable(Ice::IceType_v4i32);
auto select = Ice::InstSelect::create(::function, result, condition, y.value, x.value);
::basicBlock->appendInst(select);
return RValue<Int4>(V(result));
} }
RValue<Int4> Min(RValue<Int4> x, RValue<Int4> y) RValue<Int4> Min(RValue<Int4> x, RValue<Int4> y)
{ {
assert(false && "UNIMPLEMENTED"); return RValue<Int4>(V(nullptr)); Ice::Variable *condition = ::function->makeVariable(Ice::IceType_v4i1);
auto cmp = Ice::InstIcmp::create(::function, Ice::InstIcmp::Sgt, condition, x.value, y.value);
::basicBlock->appendInst(cmp);
Ice::Variable *result = ::function->makeVariable(Ice::IceType_v4i32);
auto select = Ice::InstSelect::create(::function, result, condition, y.value, x.value);
::basicBlock->appendInst(select);
return RValue<Int4>(V(result));
} }
RValue<Int4> RoundInt(RValue<Float4> cast) RValue<Int4> RoundInt(RValue<Float4> cast)
...@@ -5510,12 +5564,28 @@ namespace sw ...@@ -5510,12 +5564,28 @@ namespace sw
RValue<UInt4> Max(RValue<UInt4> x, RValue<UInt4> y) RValue<UInt4> Max(RValue<UInt4> x, RValue<UInt4> y)
{ {
assert(false && "UNIMPLEMENTED"); return RValue<UInt4>(V(nullptr)); Ice::Variable *condition = ::function->makeVariable(Ice::IceType_v4i1);
auto cmp = Ice::InstIcmp::create(::function, Ice::InstIcmp::Ule, condition, x.value, y.value);
::basicBlock->appendInst(cmp);
Ice::Variable *result = ::function->makeVariable(Ice::IceType_v4i32);
auto select = Ice::InstSelect::create(::function, result, condition, y.value, x.value);
::basicBlock->appendInst(select);
return RValue<UInt4>(V(result));
} }
RValue<UInt4> Min(RValue<UInt4> x, RValue<UInt4> y) RValue<UInt4> Min(RValue<UInt4> x, RValue<UInt4> y)
{ {
assert(false && "UNIMPLEMENTED"); return RValue<UInt4>(V(nullptr)); Ice::Variable *condition = ::function->makeVariable(Ice::IceType_v4i1);
auto cmp = Ice::InstIcmp::create(::function, Ice::InstIcmp::Ugt, condition, x.value, y.value);
::basicBlock->appendInst(cmp);
Ice::Variable *result = ::function->makeVariable(Ice::IceType_v4i32);
auto select = Ice::InstSelect::create(::function, result, condition, y.value, x.value);
::basicBlock->appendInst(select);
return RValue<UInt4>(V(result));
} }
RValue<UShort8> Pack(RValue<UInt4> x, RValue<UInt4> y) RValue<UShort8> Pack(RValue<UInt4> x, RValue<UInt4> y)
...@@ -5977,12 +6047,28 @@ namespace sw ...@@ -5977,12 +6047,28 @@ namespace sw
RValue<Float4> Max(RValue<Float4> x, RValue<Float4> y) RValue<Float4> Max(RValue<Float4> x, RValue<Float4> y)
{ {
assert(false && "UNIMPLEMENTED"); return RValue<Float4>(V(nullptr)); Ice::Variable *condition = ::function->makeVariable(Ice::IceType_v4i1);
auto cmp = Ice::InstFcmp::create(::function, Ice::InstFcmp::Ule, condition, x.value, y.value);
::basicBlock->appendInst(cmp);
Ice::Variable *result = ::function->makeVariable(Ice::IceType_v4f32);
auto select = Ice::InstSelect::create(::function, result, condition, y.value, x.value);
::basicBlock->appendInst(select);
return RValue<Float4>(V(result));
} }
RValue<Float4> Min(RValue<Float4> x, RValue<Float4> y) RValue<Float4> Min(RValue<Float4> x, RValue<Float4> y)
{ {
assert(false && "UNIMPLEMENTED"); return RValue<Float4>(V(nullptr)); Ice::Variable *condition = ::function->makeVariable(Ice::IceType_v4i1);
auto cmp = Ice::InstFcmp::create(::function, Ice::InstFcmp::Ugt, condition, x.value, y.value);
::basicBlock->appendInst(cmp);
Ice::Variable *result = ::function->makeVariable(Ice::IceType_v4f32);
auto select = Ice::InstSelect::create(::function, result, condition, y.value, x.value);
::basicBlock->appendInst(select);
return RValue<Float4>(V(result));
} }
RValue<Float4> Rcp_pp(RValue<Float4> x, bool exactAtPow2) RValue<Float4> Rcp_pp(RValue<Float4> x, bool exactAtPow2)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment