V_ADD3_U32 and V_OR3_B32 (#4326)

This commit is contained in:
Marcin Mikołajczyk 2026-04-27 22:35:37 +02:00 committed by GitHub
parent fba374442c
commit d47b0524ce
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 107 additions and 0 deletions

View File

@ -275,6 +275,8 @@ public:
void V_MUL_LO_U32(const GcnInst& inst);
void V_MUL_HI_U32(bool is_signed, const GcnInst& inst);
void V_MAD_U64_U32(const GcnInst& inst);
void V_ADD3_U32(const GcnInst& inst);
void V_OR3_B32(const GcnInst& inst);
// Vector interpolation
// VINTRP

View File

@ -456,6 +456,10 @@ void Translator::EmitVectorAlu(const GcnInst& inst) {
return V_MUL_HI_U32(true, inst);
case Opcode::V_MAD_U64_U32:
return V_MAD_U64_U32(inst);
case Opcode::V_ADD3_U32:
return V_ADD3_U32(inst);
case Opcode::V_OR3_B32:
return V_OR3_B32(inst);
case Opcode::V_NOP:
return;
default:
@ -1548,6 +1552,24 @@ void Translator::V_MAD_U64_U32(const GcnInst& inst) {
ir.SetVcc(did_overflow);
}
void Translator::V_ADD3_U32(const GcnInst& inst) {
const auto src0 = GetSrc<IR::U32>(inst.src[0]);
const auto src1 = GetSrc<IR::U32>(inst.src[1]);
const auto src2 = GetSrc<IR::U32>(inst.src[2]);
SetDst(inst.dst[0], ir.IAdd(src0, ir.IAdd(src1, src2)));
}
void Translator::V_OR3_B32(const GcnInst& inst) {
const auto src0 = GetSrc<IR::U32>(inst.src[0]);
const auto src1 = GetSrc<IR::U32>(inst.src[1]);
const auto src2 = GetSrc<IR::U32>(inst.src[2]);
const auto result = ir.BitwiseOr(ir.BitwiseOr(src0, src1), src2);
SetDst(inst.dst[0], result);
}
IR::U32 Translator::GetCarryIn(const GcnInst& inst) {
IR::U1 carry;
if (inst.src_count == 3) { // VOP3

View File

@ -161,3 +161,86 @@ TEST_F(GcnTest, min_nan) {
EXPECT_TRUE(result.has_value());
EXPECT_EQ(*result, 0);
}
TEST_F(GcnTest, add3_u32_1) {
auto runner = gcn_test::Runner::instance().value();
auto spirv = TranslateToSpirv(VOP3A(OpcodeVOP3::V_ADD3_U32, VOperand8::V0, SOperand9::V0, SOperand9::V1, SOperand9::V2).Get());
auto result = runner->run<u32>(spirv, std::array{0, 1, 2});
EXPECT_TRUE(result.has_value());
EXPECT_EQ(*result, 3);
}
TEST_F(GcnTest, add3_u32_2) {
auto runner = gcn_test::Runner::instance().value();
auto big = 2000000000;
auto spirv = TranslateToSpirv(VOP3A(OpcodeVOP3::V_ADD3_U32, VOperand8::V0, SOperand9::V0, SOperand9::V1, SOperand9::V2).Get());
auto result = runner->run<u32>(spirv, std::array{big, big, big});
EXPECT_TRUE(result.has_value());
EXPECT_EQ(*result, 0x65A0BC00);
}
TEST_F(GcnTest, add3_u32_3) {
auto runner = gcn_test::Runner::instance().value();
auto big = 2000000000;
auto spirv = TranslateToSpirv(VOP3A(OpcodeVOP3::V_ADD3_U32, VOperand8::V0, SOperand9::V0, SOperand9::V1, SOperand9::V2).SetClamp(true).Get());
auto result = runner->run<u32>(spirv, std::array{big, big, big});
EXPECT_TRUE(result.has_value());
EXPECT_EQ(*result, 0x65A0BC00);
}
TEST_F(GcnTest, add3_u32_4) {
auto runner = gcn_test::Runner::instance().value();
auto spirv = TranslateToSpirv(VOP3A(OpcodeVOP3::V_ADD3_U32, VOperand8::V0, SOperand9::V0, SOperand9::V1, SOperand9::V2).SetNeg({1,0,0}).Get());
auto result = runner->run<u32>(spirv, std::array{0, 1, 2});
EXPECT_TRUE(result.has_value());
EXPECT_EQ(*result, 0x80000003);
}
TEST_F(GcnTest, or3_u32_1) {
auto runner = gcn_test::Runner::instance().value();
auto spirv = TranslateToSpirv(VOP3A(OpcodeVOP3::V_OR3_B32, VOperand8::V0, SOperand9::V0, SOperand9::V1, SOperand9::V2).Get());
auto result = runner->run<u32>(spirv, std::array<u32,3>{0xF0F0F0F0, 0x07070707, 0x11111111});
EXPECT_TRUE(result.has_value());
EXPECT_EQ(*result, 0xF7F7F7F7);
}
TEST_F(GcnTest, or3_u32_2) {
auto runner = gcn_test::Runner::instance().value();
auto spirv = TranslateToSpirv(VOP3A(OpcodeVOP3::V_OR3_B32, VOperand8::V0, SOperand9::V0, SOperand9::V1, SOperand9::V2).Get());
auto result = runner->run<u32>(spirv, std::array{0x07070707, 0x11111111, 0x40404040});
EXPECT_TRUE(result.has_value());
EXPECT_EQ(*result, 0x57575757);
}
TEST_F(GcnTest, or3_u32_3) {
auto runner = gcn_test::Runner::instance().value();
auto big = 2000000000;
auto spirv = TranslateToSpirv(VOP3A(OpcodeVOP3::V_OR3_B32, VOperand8::V0, SOperand9::V0, SOperand9::V1, SOperand9::V2).SetClamp(true).Get());
auto result = runner->run<u32>(spirv, std::array{0x07070707, 0x11111111, 0x40404040});
EXPECT_TRUE(result.has_value());
EXPECT_EQ(*result, 0x57575757);
}
TEST_F(GcnTest, or3_u32_4) {
auto runner = gcn_test::Runner::instance().value();
auto spirv = TranslateToSpirv(VOP3A(OpcodeVOP3::V_OR3_B32, VOperand8::V0, SOperand9::V0, SOperand9::V1, SOperand9::V2).SetNeg({0,0,1}).Get());
auto result = runner->run<u32>(spirv, std::array{0x07070707, 0x11111111, 0x40404040});
EXPECT_TRUE(result.has_value());
EXPECT_EQ(*result, 0xD7575757);
}