Skip to content

Commit

Permalink
[JIT] Enable EGPRs in JIT by adding REX2 encoding to the backend. (#1…
Browse files Browse the repository at this point in the history
…06557)

* Ruihan: POC with REX2

Update comments.

Merge the REX2 changes into the original legacy emit path

bug fix: Set REX2.W with correct mask code.

register encoding and prefix emitting logics.

Add REX2 prefix emit logic

bug fixes

Add Stress mode for REX2 encoding and some bug fixes

resolve comments:
1. add assertion check for UD opcodes.
2. add checks for EGPRs.

Add REX2 to emitOutputAM, and let LEA to be REX2 compatible.

Add REX2.X encoding for SIB byte

But fixes: add REX2 prefix on the path in RI where MOV is specially handled.

Enable REX2 encoding for `movups`

fixed bugs in REX2 prefix emitting logic when working with map 1 instructions, and enabled REX2 for POPCNT

legacy map index-er

bug fixes

some clean-up

Adding initial APX unit testing path.

Adding a coredistools dll that has LLVM APX disasm capability.

It must be coppied into a CORE_ROOT manually.

clean up work for REX2

narrow the REX2 scope to `sub` only

some clean up based on the comments.

bug fix

resolve comment

* resolve comments

* refactor register encoding for REX2

* merge REX2 path to legacy path

* Enable REX2 in more instructions.

* Avoid repeatedly estimate the size of REX2 prefix

* Enable REX2 encoding on RI and SV path
 - SV path is mostly for debugging purposes

Added encoding unit tests for instructions with immediates

* Add rex2 support to rotate and shift.

* CR session.

* Testing infra updates: assert REX2 is enabled.
Code refactoring: AddX86PrefixIfNeeded.

* revert rcl_N and rcr_N, tp and latency data for these instructions is missing in JIT, may indicate these instructions are not being used in JIT, drop them for now.

* partially enable REX2 on emitOutputAM, case covered: R_AR and AR_R.

* Adding unit tests.

* push, pop, inc, dec, neg, not, xadd, shld, shrd, cmpxchg, setcc, bswap.

* bug fix for bswap

* bt

* xchg, idiv

* Make sure add REX2 prefix if register encoding for EGPRs are being called before adding any prefix.

* Ensure code size is correctly computed in R_R_I path.

* clean up

* Change all AddSimdPrefix to AddX86Prefix
Refactor REX2 encoding stress logics.

* div, mulEAX

* filter out test from REX2 encoding when using ACC form.
(this will have side effect that the estimated code will go up and mismatch with actual code size.)

* Make sure REX prefix will not be added when emitting with REX2.

* resolve comments.

* make sure the APX debug knob is only available under debug build.

* clean up some out-dated code.

* enable movsxd

* Enable "Call"

* Enable "JMP"

* resolve merge errors

* formatting

* remote coredistools.dll for internal tests only

* bug fix

* resolve comments

* add more emitter tests.

* resolve comments.

* clean up some comments and tweak the REX2 stress logic

* clean up

* formatting.

* resolve comments.
  • Loading branch information
Ruihan-Yin authored Dec 17, 2024
1 parent d108be1 commit 3410c76
Show file tree
Hide file tree
Showing 11 changed files with 974 additions and 161 deletions.
1 change: 1 addition & 0 deletions src/coreclr/jit/codegen.h
Original file line number Diff line number Diff line change
Expand Up @@ -648,6 +648,7 @@ class CodeGen final : public CodeGenInterface

#if defined(TARGET_AMD64)
void genAmd64EmitterUnitTestsSse2();
void genAmd64EmitterUnitTestsApx();
#endif

#endif // defined(DEBUG)
Expand Down
4 changes: 4 additions & 0 deletions src/coreclr/jit/codegenlinear.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2698,6 +2698,10 @@ void CodeGen::genEmitterUnitTests()
{
genAmd64EmitterUnitTestsSse2();
}
if (unitTestSectionAll || (strstr(unitTestSection, "apx") != nullptr))
{
genAmd64EmitterUnitTestsApx();
}

#elif defined(TARGET_ARM64)
if (unitTestSectionAll || (strstr(unitTestSection, "general") != nullptr))
Expand Down
219 changes: 219 additions & 0 deletions src/coreclr/jit/codegenxarch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9053,6 +9053,225 @@ void CodeGen::genAmd64EmitterUnitTestsSse2()
GetEmitter()->emitIns_R_R_R(INS_cvtsd2ss, EA_8BYTE, REG_XMM0, REG_XMM1, REG_XMM2);
}

/*****************************************************************************
* Unit tests for the APX instructions.
*/

void CodeGen::genAmd64EmitterUnitTestsApx()
{
emitter* theEmitter = GetEmitter();

genDefineTempLabel(genCreateTempLabel());

// This test suite needs REX2 enabled.
if (!theEmitter->UseRex2Encoding() && !theEmitter->emitComp->DoJitStressRex2Encoding())
{
return;
}

theEmitter->emitIns_R_R(INS_add, EA_1BYTE, REG_EAX, REG_ECX);
theEmitter->emitIns_R_R(INS_add, EA_2BYTE, REG_EAX, REG_ECX);
theEmitter->emitIns_R_R(INS_add, EA_4BYTE, REG_EAX, REG_ECX);
theEmitter->emitIns_R_R(INS_add, EA_8BYTE, REG_EAX, REG_ECX);
theEmitter->emitIns_R_R(INS_or, EA_4BYTE, REG_EAX, REG_ECX);
theEmitter->emitIns_R_R(INS_adc, EA_4BYTE, REG_EAX, REG_ECX);
theEmitter->emitIns_R_R(INS_sbb, EA_4BYTE, REG_EAX, REG_ECX);
theEmitter->emitIns_R_R(INS_and, EA_4BYTE, REG_EAX, REG_ECX);
theEmitter->emitIns_R_R(INS_sub, EA_4BYTE, REG_EAX, REG_ECX);
theEmitter->emitIns_R_R(INS_xor, EA_4BYTE, REG_EAX, REG_ECX);
theEmitter->emitIns_R_R(INS_cmp, EA_4BYTE, REG_EAX, REG_ECX);
theEmitter->emitIns_R_R(INS_test, EA_4BYTE, REG_EAX, REG_ECX);
theEmitter->emitIns_R_R(INS_bsf, EA_4BYTE, REG_EAX, REG_ECX);
theEmitter->emitIns_R_R(INS_bsr, EA_4BYTE, REG_EAX, REG_ECX);

theEmitter->emitIns_R_R(INS_cmovo, EA_4BYTE, REG_EAX, REG_ECX);

theEmitter->emitIns_Mov(INS_mov, EA_4BYTE, REG_EAX, REG_ECX, false);
theEmitter->emitIns_Mov(INS_movsx, EA_2BYTE, REG_EAX, REG_ECX, false);
theEmitter->emitIns_Mov(INS_movzx, EA_2BYTE, REG_EAX, REG_ECX, false);

theEmitter->emitIns_R_R(INS_popcnt, EA_4BYTE, REG_EAX, REG_ECX);
theEmitter->emitIns_R_R(INS_lzcnt, EA_4BYTE, REG_EAX, REG_ECX);
theEmitter->emitIns_R_R(INS_tzcnt, EA_4BYTE, REG_EAX, REG_ECX);

theEmitter->emitIns_R_I(INS_add, EA_4BYTE, REG_ECX, 0x05);
theEmitter->emitIns_R_I(INS_add, EA_2BYTE, REG_ECX, 0x05);
theEmitter->emitIns_R_I(INS_or, EA_4BYTE, REG_EAX, 0x05);
theEmitter->emitIns_R_I(INS_adc, EA_4BYTE, REG_EAX, 0x05);
theEmitter->emitIns_R_I(INS_sbb, EA_4BYTE, REG_EAX, 0x05);
theEmitter->emitIns_R_I(INS_and, EA_4BYTE, REG_EAX, 0x05);
theEmitter->emitIns_R_I(INS_sub, EA_4BYTE, REG_EAX, 0x05);
theEmitter->emitIns_R_I(INS_xor, EA_4BYTE, REG_EAX, 0x05);
theEmitter->emitIns_R_I(INS_cmp, EA_4BYTE, REG_EAX, 0x05);
theEmitter->emitIns_R_I(INS_test, EA_4BYTE, REG_EAX, 0x05);

theEmitter->emitIns_R_I(INS_mov, EA_4BYTE, REG_EAX, 0xE0);

// JIT tend to compress imm64 to imm32 if higher half is all-zero, make sure this test checks the path for imm64.
theEmitter->emitIns_R_I(INS_mov, EA_8BYTE, REG_RAX, 0xFFFF000000000000);

// shf reg, cl
theEmitter->emitIns_R(INS_rol, EA_4BYTE, REG_EAX);
theEmitter->emitIns_R(INS_ror, EA_4BYTE, REG_EAX);
theEmitter->emitIns_R(INS_rcl, EA_4BYTE, REG_EAX);
theEmitter->emitIns_R(INS_rcr, EA_4BYTE, REG_EAX);
theEmitter->emitIns_R(INS_shl, EA_4BYTE, REG_EAX);
theEmitter->emitIns_R(INS_shr, EA_4BYTE, REG_EAX);
theEmitter->emitIns_R(INS_sar, EA_4BYTE, REG_EAX);

// shf reg, 1
theEmitter->emitIns_R(INS_rol_1, EA_4BYTE, REG_EAX);
theEmitter->emitIns_R(INS_ror_1, EA_4BYTE, REG_EAX);
theEmitter->emitIns_R(INS_rcl_1, EA_4BYTE, REG_EAX);
theEmitter->emitIns_R(INS_rcr_1, EA_4BYTE, REG_EAX);
theEmitter->emitIns_R(INS_shl_1, EA_4BYTE, REG_EAX);
theEmitter->emitIns_R(INS_shr_1, EA_4BYTE, REG_EAX);
theEmitter->emitIns_R(INS_sar_1, EA_4BYTE, REG_EAX);

// shf reg, imm8
theEmitter->emitIns_R_I(INS_shl_N, EA_4BYTE, REG_ECX, 0x05);
theEmitter->emitIns_R_I(INS_shr_N, EA_4BYTE, REG_ECX, 0x05);
theEmitter->emitIns_R_I(INS_sar_N, EA_4BYTE, REG_ECX, 0x05);
theEmitter->emitIns_R_I(INS_rol_N, EA_4BYTE, REG_ECX, 0x05);
theEmitter->emitIns_R_I(INS_ror_N, EA_4BYTE, REG_ECX, 0x05);
// TODO-xarch-apx: not enable these 2 for now.
// theEmitter->emitIns_R_I(INS_rcl_N, EA_4BYTE, REG_ECX, 0x05);
// theEmitter->emitIns_R_I(INS_rcr_N, EA_4BYTE, REG_ECX, 0x05);

theEmitter->emitIns_R(INS_neg, EA_2BYTE, REG_EAX);
theEmitter->emitIns_R(INS_not, EA_2BYTE, REG_EAX);

theEmitter->emitIns_R_AR(INS_lea, EA_4BYTE, REG_ECX, REG_EAX, 4);

theEmitter->emitIns_R_AR(INS_mov, EA_1BYTE, REG_ECX, REG_EAX, 4);
theEmitter->emitIns_R_AR(INS_mov, EA_2BYTE, REG_ECX, REG_EAX, 4);
theEmitter->emitIns_R_AR(INS_mov, EA_4BYTE, REG_ECX, REG_EAX, 4);
theEmitter->emitIns_R_AR(INS_mov, EA_8BYTE, REG_ECX, REG_EAX, 4);

theEmitter->emitIns_R_AR(INS_add, EA_1BYTE, REG_EAX, REG_ECX, 4);
theEmitter->emitIns_R_AR(INS_add, EA_2BYTE, REG_EAX, REG_ECX, 4);
theEmitter->emitIns_R_AR(INS_add, EA_4BYTE, REG_EAX, REG_ECX, 4);
theEmitter->emitIns_R_AR(INS_add, EA_8BYTE, REG_EAX, REG_ECX, 4);
theEmitter->emitIns_R_AR(INS_or, EA_4BYTE, REG_EAX, REG_ECX, 4);
theEmitter->emitIns_R_AR(INS_adc, EA_4BYTE, REG_EAX, REG_ECX, 4);
theEmitter->emitIns_R_AR(INS_sbb, EA_4BYTE, REG_EAX, REG_ECX, 4);
theEmitter->emitIns_R_AR(INS_and, EA_4BYTE, REG_EAX, REG_ECX, 4);
theEmitter->emitIns_R_AR(INS_sub, EA_4BYTE, REG_EAX, REG_ECX, 4);
theEmitter->emitIns_R_AR(INS_xor, EA_4BYTE, REG_EAX, REG_ECX, 4);
theEmitter->emitIns_R_AR(INS_cmp, EA_4BYTE, REG_EAX, REG_ECX, 4);
theEmitter->emitIns_R_AR(INS_test, EA_4BYTE, REG_EAX, REG_ECX, 4);
theEmitter->emitIns_R_AR(INS_bsf, EA_4BYTE, REG_EAX, REG_ECX, 4);
theEmitter->emitIns_R_AR(INS_bsr, EA_4BYTE, REG_EAX, REG_ECX, 4);
theEmitter->emitIns_R_AR(INS_popcnt, EA_4BYTE, REG_EAX, REG_ECX, 4);
theEmitter->emitIns_R_AR(INS_lzcnt, EA_4BYTE, REG_EAX, REG_ECX, 4);
theEmitter->emitIns_R_AR(INS_tzcnt, EA_4BYTE, REG_EAX, REG_ECX, 4);

theEmitter->emitIns_AR_R(INS_add, EA_1BYTE, REG_EAX, REG_ECX, 4);
theEmitter->emitIns_AR_R(INS_add, EA_2BYTE, REG_EAX, REG_ECX, 4);
theEmitter->emitIns_AR_R(INS_add, EA_4BYTE, REG_EAX, REG_ECX, 4);
theEmitter->emitIns_AR_R(INS_add, EA_8BYTE, REG_EAX, REG_ECX, 4);
theEmitter->emitIns_AR_R(INS_or, EA_4BYTE, REG_EAX, REG_ECX, 4);
theEmitter->emitIns_AR_R(INS_adc, EA_4BYTE, REG_EAX, REG_ECX, 4);
theEmitter->emitIns_AR_R(INS_sbb, EA_4BYTE, REG_EAX, REG_ECX, 4);
theEmitter->emitIns_AR_R(INS_and, EA_4BYTE, REG_EAX, REG_ECX, 4);
theEmitter->emitIns_AR_R(INS_sub, EA_4BYTE, REG_EAX, REG_ECX, 4);
theEmitter->emitIns_AR_R(INS_xor, EA_4BYTE, REG_EAX, REG_ECX, 4);
theEmitter->emitIns_AR_R(INS_cmp, EA_4BYTE, REG_EAX, REG_ECX, 4);
theEmitter->emitIns_AR_R(INS_test, EA_4BYTE, REG_EAX, REG_ECX, 4);

theEmitter->emitIns_R_AR(INS_movsx, EA_2BYTE, REG_ECX, REG_EAX, 4);
theEmitter->emitIns_R_AR(INS_movzx, EA_2BYTE, REG_EAX, REG_ECX, 4);
theEmitter->emitIns_R_AR(INS_cmovo, EA_4BYTE, REG_EAX, REG_ECX, 4);

theEmitter->emitIns_AR_R(INS_xadd, EA_4BYTE, REG_EAX, REG_EDX, 2);

theEmitter->emitIns_R_R_I(INS_shld, EA_4BYTE, REG_EAX, REG_ECX, 5);
theEmitter->emitIns_R_R_I(INS_shrd, EA_2BYTE, REG_EAX, REG_ECX, 5);
// TODO-XArch-apx: S_R_I path only accepts SEE or VEX instructions,
// so I assuem shld/shrd will not be taking the first argument from stack.
// theEmitter->emitIns_S_R_I(INS_shld, EA_2BYTE, 1, 2, REG_EAX, 5);
// theEmitter->emitIns_S_R_I(INS_shrd, EA_2BYTE, 1, 2, REG_EAX, 5);

theEmitter->emitIns_AR_R(INS_cmpxchg, EA_2BYTE, REG_EAX, REG_EDX, 2);

theEmitter->emitIns_R(INS_seto, EA_1BYTE, REG_EDX);

theEmitter->emitIns_R(INS_bswap, EA_8BYTE, REG_EDX);

// INS_bt only has reg-to-reg form.
theEmitter->emitIns_R_R(INS_bt, EA_2BYTE, REG_EAX, REG_EDX);

theEmitter->emitIns_R(INS_idiv, EA_8BYTE, REG_EDX);

theEmitter->emitIns_R_R(INS_xchg, EA_8BYTE, REG_EAX, REG_EDX);

theEmitter->emitIns_R(INS_div, EA_8BYTE, REG_EDX);
theEmitter->emitIns_R(INS_mulEAX, EA_8BYTE, REG_EDX);

GenTreePhysReg physReg(REG_EDX);
physReg.SetRegNum(REG_EDX);
GenTreeIndir load = indirForm(TYP_INT, &physReg);

theEmitter->emitIns_R_A(INS_add, EA_1BYTE, REG_EAX, &load);
theEmitter->emitIns_R_A(INS_add, EA_2BYTE, REG_EAX, &load);
theEmitter->emitIns_R_A(INS_add, EA_4BYTE, REG_EAX, &load);
theEmitter->emitIns_R_A(INS_add, EA_8BYTE, REG_EAX, &load);
theEmitter->emitIns_R_A(INS_or, EA_4BYTE, REG_EAX, &load);
theEmitter->emitIns_R_A(INS_adc, EA_4BYTE, REG_EAX, &load);
theEmitter->emitIns_R_A(INS_sbb, EA_4BYTE, REG_EAX, &load);
theEmitter->emitIns_R_A(INS_and, EA_4BYTE, REG_EAX, &load);
theEmitter->emitIns_R_A(INS_sub, EA_4BYTE, REG_EAX, &load);
theEmitter->emitIns_R_A(INS_xor, EA_4BYTE, REG_EAX, &load);
theEmitter->emitIns_R_A(INS_cmp, EA_4BYTE, REG_EAX, &load);
theEmitter->emitIns_R_A(INS_test, EA_4BYTE, REG_EAX, &load);
theEmitter->emitIns_R_A(INS_bsf, EA_4BYTE, REG_EAX, &load);
theEmitter->emitIns_R_A(INS_bsr, EA_4BYTE, REG_EAX, &load);

// Note:
// All the tests below rely on the runtime status of the stack this unit tests attaching to,
// it might fail due to stack value unavailable/mismatch, since these tests are mainly for
// encoding correctness check, this kind of failures may be considered as not harmful.

theEmitter->emitIns_R_S(INS_add, EA_1BYTE, REG_EAX, 0, 0);
theEmitter->emitIns_R_S(INS_add, EA_2BYTE, REG_EAX, 0, 0);
theEmitter->emitIns_R_S(INS_add, EA_4BYTE, REG_EAX, 0, 0);
theEmitter->emitIns_R_S(INS_add, EA_8BYTE, REG_EAX, 0, 0);
theEmitter->emitIns_R_S(INS_or, EA_4BYTE, REG_EAX, 0, 0);
theEmitter->emitIns_R_S(INS_adc, EA_4BYTE, REG_EAX, 0, 0);
theEmitter->emitIns_R_S(INS_sbb, EA_4BYTE, REG_EAX, 0, 0);
theEmitter->emitIns_R_S(INS_and, EA_4BYTE, REG_EAX, 0, 0);
theEmitter->emitIns_R_S(INS_sub, EA_4BYTE, REG_EAX, 0, 0);
theEmitter->emitIns_R_S(INS_xor, EA_4BYTE, REG_EAX, 0, 0);
theEmitter->emitIns_R_S(INS_cmp, EA_4BYTE, REG_EAX, 0, 0);
theEmitter->emitIns_R_S(INS_test, EA_4BYTE, REG_EAX, 0, 0);
theEmitter->emitIns_S_R(INS_xadd, EA_2BYTE, REG_EAX, 0, 0);

theEmitter->emitIns_S_I(INS_shl_N, EA_4BYTE, 0, 0, 4);
theEmitter->emitIns_S(INS_shl_1, EA_4BYTE, 0, 4);

theEmitter->emitIns_R_S(INS_movsx, EA_2BYTE, REG_ECX, 0, 0);
theEmitter->emitIns_R_S(INS_movzx, EA_2BYTE, REG_EAX, 0, 0);
theEmitter->emitIns_R_S(INS_cmovo, EA_4BYTE, REG_EAX, 0, 0);

theEmitter->emitIns_R(INS_pop, EA_PTRSIZE, REG_EAX);
theEmitter->emitIns_R(INS_push, EA_PTRSIZE, REG_EAX);
theEmitter->emitIns_R(INS_pop_hide, EA_PTRSIZE, REG_EAX);
theEmitter->emitIns_R(INS_push_hide, EA_PTRSIZE, REG_EAX);

theEmitter->emitIns_S(INS_pop, EA_PTRSIZE, 0, 0);
theEmitter->emitIns_I(INS_push, EA_PTRSIZE, 50);

theEmitter->emitIns_R(INS_inc, EA_4BYTE, REG_EAX);
theEmitter->emitIns_AR(INS_inc, EA_2BYTE, REG_EAX, 2);
theEmitter->emitIns_S(INS_inc, EA_2BYTE, 0, 0);
theEmitter->emitIns_R(INS_dec, EA_4BYTE, REG_EAX);
theEmitter->emitIns_AR(INS_dec, EA_2BYTE, REG_EAX, 2);
theEmitter->emitIns_S(INS_dec, EA_2BYTE, 0, 0);

theEmitter->emitIns_S(INS_neg, EA_2BYTE, 0, 0);
theEmitter->emitIns_S(INS_not, EA_2BYTE, 0, 0);
}

#endif // defined(DEBUG) && defined(TARGET_AMD64)

#ifdef PROFILING_SUPPORTED
Expand Down
5 changes: 4 additions & 1 deletion src/coreclr/jit/compiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2295,7 +2295,10 @@ void Compiler::compSetProcessor()
if (canUseEvexEncoding())
{
codeGen->GetEmitter()->SetUseEvexEncoding(true);
// TODO-XArch-AVX512 : Revisit other flags to be set once avx512 instructions are added.
}
if (canUseApxEncoding())
{
codeGen->GetEmitter()->SetUseRex2Encoding(true);
}
}
#endif // TARGET_XARCH
Expand Down
50 changes: 48 additions & 2 deletions src/coreclr/jit/compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -9921,6 +9921,17 @@ class Compiler
return (compOpportunisticallyDependsOn(InstructionSet_EVEX));
}

//------------------------------------------------------------------------
// canUseRex2Encoding - Answer the question: Is Rex2 encoding supported on this target.
//
// Returns:
// `true` if Rex2 encoding is supported, `false` if not.
//
bool canUseApxEncoding() const
{
return compOpportunisticallyDependsOn(InstructionSet_APX);
}

private:
//------------------------------------------------------------------------
// DoJitStressEvexEncoding- Answer the question: Do we force EVEX encoding.
Expand All @@ -9935,7 +9946,7 @@ class Compiler
// otherwise use VEX encoding but can be EVEX encoded to use EVEX encoding
// This requires AVX512F, AVX512BW, AVX512CD, AVX512DQ, and AVX512VL support

if (JitConfig.JitStressEvexEncoding() && IsBaselineVector512IsaSupportedOpportunistically())
if (JitStressEvexEncoding() && IsBaselineVector512IsaSupportedOpportunistically())
{
assert(compIsaSupportedDebugOnly(InstructionSet_AVX512F));
assert(compIsaSupportedDebugOnly(InstructionSet_AVX512F_VL));
Expand All @@ -9948,14 +9959,49 @@ class Compiler

return true;
}
else if (JitConfig.JitStressEvexEncoding() && compOpportunisticallyDependsOn(InstructionSet_AVX10v1))
else if (JitStressEvexEncoding() && compOpportunisticallyDependsOn(InstructionSet_AVX10v1))
{
return true;
}
#endif // DEBUG

return false;
}

//------------------------------------------------------------------------
// DoJitStressRex2Encoding- Answer the question: Do we force REX2 encoding.
//
// Returns:
// `true` if user requests REX2 encoding.
//
bool DoJitStressRex2Encoding() const
{
#ifdef DEBUG
if (JitConfig.JitStressRex2Encoding() && compOpportunisticallyDependsOn(InstructionSet_APX))
{
// we should make sure EVEX is also stressed when REX2 is stressed, as we will need to guarantee EGPR
// functionality is properly turned on for every instructions when REX2 is stress.
return true;
}
#endif // DEBUG

return false;
}

//------------------------------------------------------------------------
// JitStressEvexEncoding- Answer the question: Is Evex stress knob set
//
// Returns:
// `true` if user requests REX2 encoding.
//
bool JitStressEvexEncoding() const
{
#ifdef DEBUG
return JitConfig.JitStressEvexEncoding() || JitConfig.JitStressRex2Encoding();
#endif // DEBUG

return false;
}
#endif // TARGET_XARCH

/*
Expand Down
1 change: 1 addition & 0 deletions src/coreclr/jit/emit.h
Original file line number Diff line number Diff line change
Expand Up @@ -470,6 +470,7 @@ class emitter
#ifdef TARGET_XARCH
SetUseVEXEncoding(false);
SetUseEvexEncoding(false);
SetUseRex2Encoding(false);
#endif // TARGET_XARCH

emitDataSecCur = nullptr;
Expand Down
Loading

0 comments on commit 3410c76

Please sign in to comment.