Skip to content

Commit dd7a848

Browse files
authored
[APX] Enable APX-EVEX.ZU for SETcc instructions (#117258)
1 parent c0f4c7d commit dd7a848

File tree

10 files changed

+270
-67
lines changed

10 files changed

+270
-67
lines changed

src/coreclr/jit/codegen.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1338,7 +1338,7 @@ class CodeGen final : public CodeGenInterface
13381338
void inst_JMP(emitJumpKind jmp, BasicBlock* tgtBlock);
13391339
#endif
13401340

1341-
void inst_SET(emitJumpKind condition, regNumber reg);
1341+
void inst_SET(emitJumpKind condition, regNumber reg, insOpts instOptions = INS_OPTS_NONE);
13421342

13431343
void inst_RV(instruction ins, regNumber reg, var_types type, emitAttr size = EA_UNKNOWN);
13441344

src/coreclr/jit/codegenxarch.cpp

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1807,19 +1807,29 @@ void CodeGen::inst_SETCC(GenCondition condition, var_types type, regNumber dstRe
18071807
assert(varTypeIsIntegral(type));
18081808
assert(genIsValidIntReg(dstReg) && isByteReg(dstReg));
18091809

1810-
const GenConditionDesc& desc = GenConditionDesc::Get(condition);
1810+
const GenConditionDesc& desc = GenConditionDesc::Get(condition);
1811+
insOpts instOptions = INS_OPTS_NONE;
18111812

1812-
inst_SET(desc.jumpKind1, dstReg);
1813+
bool needsMovzx = !varTypeIsByte(type);
1814+
if (needsMovzx && compiler->canUseApxEvexEncoding() && JitConfig.EnableApxZU())
1815+
{
1816+
instOptions = INS_OPTS_EVEX_zu;
1817+
needsMovzx = false;
1818+
}
1819+
1820+
inst_SET(desc.jumpKind1, dstReg, instOptions);
18131821

18141822
if (desc.oper != GT_NONE)
18151823
{
18161824
BasicBlock* labelNext = genCreateTempLabel();
18171825
inst_JMP((desc.oper == GT_OR) ? desc.jumpKind1 : emitter::emitReverseJumpKind(desc.jumpKind1), labelNext);
1818-
inst_SET(desc.jumpKind2, dstReg);
1826+
inst_SET(desc.jumpKind2, dstReg, instOptions);
18191827
genDefineTempLabel(labelNext);
18201828
}
18211829

1822-
if (!varTypeIsByte(type))
1830+
// we can apply EVEX.ZU to avoid this movzx.
1831+
// TODO-XArch-apx: evaluate setcc + movzx and xor + set
1832+
if (needsMovzx)
18231833
{
18241834
GetEmitter()->emitIns_Mov(INS_movzx, EA_1BYTE, dstReg, dstReg, /* canSkip */ false);
18251835
}
@@ -9478,6 +9488,8 @@ void CodeGen::genAmd64EmitterUnitTestsApx()
94789488

94799489
theEmitter->emitIns_Mov(INS_movd32, EA_4BYTE, REG_R16, REG_XMM0, false);
94809490
theEmitter->emitIns_Mov(INS_movd32, EA_4BYTE, REG_R16, REG_XMM16, false);
9491+
9492+
theEmitter->emitIns_R(INS_seto_apx, EA_1BYTE, REG_R11, INS_OPTS_EVEX_zu);
94819493
}
94829494

94839495
void CodeGen::genAmd64EmitterUnitTestsAvx10v2()
@@ -10379,7 +10391,7 @@ void CodeGen::genPushCalleeSavedRegisters()
1037910391
#endif // DEBUG
1038010392

1038110393
#ifdef TARGET_AMD64
10382-
if (compiler->canUseApxEncoding() && compiler->canUseEvexEncoding() && JitConfig.EnableApxPPX())
10394+
if (compiler->canUseApxEvexEncoding() && JitConfig.EnableApxPPX())
1038310395
{
1038410396
genPushCalleeSavedRegistersFromMaskAPX(rsPushRegs);
1038510397
return;
@@ -10505,7 +10517,7 @@ void CodeGen::genPopCalleeSavedRegisters(bool jmpEpilog)
1050510517
return;
1050610518
}
1050710519

10508-
if (compiler->canUseApxEncoding() && compiler->canUseEvexEncoding() && JitConfig.EnableApxPPX())
10520+
if (compiler->canUseApxEvexEncoding() && JitConfig.EnableApxPPX())
1050910521
{
1051010522
regMaskTP rsPopRegs = regSet.rsGetModifiedIntCalleeSavedRegsMask();
1051110523
const unsigned popCount = genPopCalleeSavedRegistersFromMaskAPX(rsPopRegs);

src/coreclr/jit/compiler.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9673,6 +9673,17 @@ class Compiler
96739673
return compOpportunisticallyDependsOn(InstructionSet_APX);
96749674
}
96759675

9676+
//------------------------------------------------------------------------
9677+
// canUseApxEvexEncoding - Answer the question: Are APX-EVEX encodings supported on this target.
9678+
//
9679+
// Returns:
9680+
// `true` if APX-EVEX encoding is supported, `false` if not.
9681+
//
9682+
bool canUseApxEvexEncoding() const
9683+
{
9684+
return canUseApxEncoding() && canUseEvexEncoding();
9685+
}
9686+
96769687
private:
96779688
//------------------------------------------------------------------------
96789689
// DoJitStressEvexEncoding- Answer the question: Do we force EVEX encoding.

src/coreclr/jit/emit.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -846,6 +846,8 @@ class emitter
846846

847847
#define _idEvexbContext (_idCustom6 << 1) | _idCustom5 /* Evex.b: embedded broadcast, rounding, SAE */
848848
#define _idEvexNdContext _idCustom5 /* bits used for the APX-EVEX.nd context for promoted legacy instructions */
849+
#define _idEvexZuContext _idCustom5 /* bits used for the APX-EVEX.zu context for promoted legacy instructions */
850+
849851
#define _idEvexNfContext _idCustom6 /* bits used for the APX-EVEX.nf context for promoted legacy/vex instructions */
850852

851853
// We repurpose 4 bits for the default flag value bits for ccmp instructions.
@@ -1793,15 +1795,28 @@ class emitter
17931795

17941796
bool idIsEvexNdContextSet() const
17951797
{
1798+
assert(IsApxNddCompatibleInstruction(_idIns));
17961799
return _idEvexNdContext != 0;
17971800
}
17981801

1802+
bool idIsEvexZuContextSet() const
1803+
{
1804+
assert(IsApxZuCompatibleInstruction(_idIns));
1805+
return (_idEvexZuContext != 0);
1806+
}
1807+
17991808
void idSetEvexNdContext()
18001809
{
18011810
assert(!idIsEvexNdContextSet());
18021811
_idEvexNdContext = 1;
18031812
}
18041813

1814+
void idSetEvexZuContext()
1815+
{
1816+
assert(!idIsEvexZuContextSet());
1817+
_idEvexZuContext = 1;
1818+
}
1819+
18051820
bool idIsEvexNfContextSet() const
18061821
{
18071822
return _idEvexNfContext != 0;

0 commit comments

Comments
 (0)