[bug] Properly use vpternlog write-only cases (x86::Compiler)

This commit is contained in:
kobalicek
2024-12-15 18:50:15 +01:00
parent 7bed2b0e14
commit 976f8ed35a
4 changed files with 75 additions and 0 deletions

View File

@@ -895,8 +895,10 @@ Error queryRWInfo(Arch arch, const BaseInst& inst, const Operand_* operands, siz
case Inst::kIdVpternlogq: {
if (opCount == 4 && operands[3].isImm()) {
uint32_t predicate = operands[3].as<Imm>().valueAs<uint8_t>();
if ((predicate >> 4) == (predicate & 0xF)) {
out->_operands[0].clearOpFlags(OpRWFlags::kRead);
out->_operands[0].setReadByteMask(0);
}
}
break;

View File

@@ -477,6 +477,20 @@ Error RACFGBuilder::onInst(InstNode* inst, InstControlFlow& cf, RAInstBuilder& i
}
}
}
else if (opCount == 4 && inst->op(3).isImm()) {
const Imm& imm = inst->op(3).as<Imm>();
switch (inst->id()) {
case Inst::kIdVpternlogd:
case Inst::kIdVpternlogq: {
uint32_t predicate = uint32_t(imm.value() & 0xFFu);
if (predicate == 0x00u || predicate == 0xFFu) {
ib[0]->makeWriteOnly();
}
break;
}
}
}
switch (sameRegHint) {
case InstSameRegHint::kNone:

View File

@@ -2463,6 +2463,60 @@ public:
}
};
// x86::Compiler - X86Test_AVX512_TernLog
// ======================================
class X86Test_AVX512_TernLog : public X86TestCase {
public:
X86Test_AVX512_TernLog() : X86TestCase("AVX512_TernLog") {}
static void add(TestApp& app) {
const CpuInfo& cpuInfo = CpuInfo::host();
if (cpuInfo.features().x86().hasAVX512_F()) {
app.add(new X86Test_AVX512_TernLog());
}
}
virtual void compile(x86::Compiler& cc) {
FuncNode* funcNode = cc.addFunc(FuncSignature::build<void, void*>());
x86::Gp out = cc.newIntPtr("outPtr");
x86::Vec vec = cc.newZmm("vec");
funcNode->setArg(0, out);
cc.vpternlogd(vec, vec, vec, 0xFFu);
cc.vmovdqu8(x86::ptr(out), vec);
cc.endFunc();
}
virtual bool run(void* _func, String& result, String& expect) {
typedef void (*Func)(void*);
Func func = ptr_as_func<Func>(_func);
uint32_t out[16];
func(out);
result.assign("{");
expect.assign("{");
for (uint32_t i = 0; i < 16; i++) {
if (i) {
result.append(", ");
expect.append(", ");
}
result.appendFormat("0x%08X", out[i]);
expect.appendFormat("0x%08X", 0xFFFFFFFFu);
}
result.append("}");
expect.append("}");
return result == expect;
}
};
// x86::Compiler - X86Test_FuncArgInt8
// ===================================
@@ -4590,6 +4644,7 @@ void compiler_add_x86_tests(TestApp& app) {
app.addT<X86Test_ExtraBlock>();
app.addT<X86Test_AlphaBlend>();
app.addT<X86Test_AVX512_KK>();
app.addT<X86Test_AVX512_TernLog>();
// Function arguments handling tests.
app.addT<X86Test_FuncArgInt8>();

View File

@@ -151,6 +151,7 @@ static void testX86Arch() {
Arch arch = Arch::kX64;
printInfoSimple(arch, Inst::kIdAdd, InstOptions::kNone, eax, ebx);
printInfoSimple(arch, Inst::kIdXor, InstOptions::kNone, eax, eax);
printInfoSimple(arch, Inst::kIdLods, InstOptions::kNone, eax, dword_ptr(rsi));
printInfoSimple(arch, Inst::kIdPshufd, InstOptions::kNone, xmm0, xmm1, imm(0));
@@ -167,6 +168,9 @@ static void testX86Arch() {
printInfoSimple(arch, Inst::kIdVaddpd, InstOptions::kNone, ymm0, ymm30, ymm31);
printInfoSimple(arch, Inst::kIdVaddpd, InstOptions::kNone, zmm0, zmm1, zmm2);
printInfoSimple(arch, Inst::kIdVpternlogd, InstOptions::kNone, zmm0, zmm0, zmm0, imm(0xFF));
printInfoSimple(arch, Inst::kIdVpternlogq, InstOptions::kNone, zmm0, zmm1, zmm2, imm(0x33));
printInfoExtra(arch, Inst::kIdVaddpd, InstOptions::kNone, k1, zmm0, zmm1, zmm2);
printInfoExtra(arch, Inst::kIdVaddpd, InstOptions::kX86_ZMask, k1, zmm0, zmm1, zmm2);
#endif // !ASMJIT_NO_X86