diff --git a/runtime/compiler/env/ProcessorDetection.cpp b/runtime/compiler/env/ProcessorDetection.cpp index 2142ed43560..c028fc6cabf 100644 --- a/runtime/compiler/env/ProcessorDetection.cpp +++ b/runtime/compiler/env/ProcessorDetection.cpp @@ -116,6 +116,17 @@ #include #endif +#if defined(OMR_OS_WINDOWS) && defined(TR_TARGET_X86) +#include +#elif defined(TR_TARGET_X86) +inline unsigned long long _xgetbv(unsigned int ecx) + { + unsigned int eax, edx; + __asm__ __volatile__("xgetbv" : "=a"(eax), "=d"(edx) : "c"(ecx)); + return ((unsigned long long)edx << 32) | eax; + } +#endif + #if defined(J9ZOS390) extern "C" bool _isPSWInProblemState(); /* 390 asm stub */ #endif @@ -296,7 +307,7 @@ void TR_J9VM::initializeProcessorType() { TR_ASSERT(_compInfo,"compInfo not defined"); - + if (TR::Compiler->target.cpu.isZ()) { OMRProcessorDesc processorDescription = TR::Compiler->target.cpu.getProcessorDescription(); @@ -333,12 +344,42 @@ TR_J9VM::initializeProcessorType() { OMRProcessorDesc processorDescription = TR::Compiler->target.cpu.getProcessorDescription(); OMRPORT_ACCESS_FROM_OMRPORT(TR::Compiler->omrPortLib); - static const bool disableAVX = feGetEnv("TR_DisableAVX") != NULL; - if (disableAVX) + + bool disableAVX = true; + bool disableAVX512 = true; + + // Check XCRO register for OS support of xmm/ymm/zmm + if (TRUE == omrsysinfo_processor_has_feature(&processorDescription, OMR_FEATURE_X86_OSXSAVE)) { - omrsysinfo_processor_set_feature(&processorDescription, OMR_FEATURE_X86_OSXSAVE, FALSE); + // '6' = mask for XCR0[2:1]='11b' (XMM state and YMM state are enabled) + disableAVX = ((6 & _xgetbv(0)) != 6); + // 'e6' = (mask for XCR0[7:5]='111b' (Opmask, ZMM_Hi256, Hi16_ZMM) + XCR0[2:1]='11b' (XMM/YMM)) + disableAVX512 = ((0xe6 & _xgetbv(0)) != 0xe6); } - + + if(disableAVX) + { + // Unset AVX/AVX2 if not enabled via CR0 or otherwise disabled + omrsysinfo_processor_set_feature(&processorDescription, OMR_FEATURE_X86_AVX, FALSE); + omrsysinfo_processor_set_feature(&processorDescription, OMR_FEATURE_X86_AVX2, FALSE); + } + + if (disableAVX512) + { + // Unset AVX-512 if not enabled via CR0 or otherwise disabled + // If other AVX-512 extensions are supported in the port library, they need to be disabled here + omrsysinfo_processor_set_feature(&processorDescription, OMR_FEATURE_X86_AVX512F, FALSE); + omrsysinfo_processor_set_feature(&processorDescription, OMR_FEATURE_X86_AVX512VL, FALSE); + omrsysinfo_processor_set_feature(&processorDescription, OMR_FEATURE_X86_AVX512BW, FALSE); + omrsysinfo_processor_set_feature(&processorDescription, OMR_FEATURE_X86_AVX512CD, FALSE); + omrsysinfo_processor_set_feature(&processorDescription, OMR_FEATURE_X86_AVX512DQ, FALSE); + omrsysinfo_processor_set_feature(&processorDescription, OMR_FEATURE_X86_AVX512_BITALG, FALSE); + omrsysinfo_processor_set_feature(&processorDescription, OMR_FEATURE_X86_AVX512_VBMI, FALSE); + omrsysinfo_processor_set_feature(&processorDescription, OMR_FEATURE_X86_AVX512_VBMI2, FALSE); + omrsysinfo_processor_set_feature(&processorDescription, OMR_FEATURE_X86_AVX512_VNNI, FALSE); + omrsysinfo_processor_set_feature(&processorDescription, OMR_FEATURE_X86_AVX512_VPOPCNTDQ, FALSE); + } + TR::Compiler->target.cpu = TR::CPU::customize(processorDescription); const char *vendor = TR::Compiler->target.cpu.getProcessorVendorId(); diff --git a/runtime/compiler/x/codegen/J9CodeGenerator.cpp b/runtime/compiler/x/codegen/J9CodeGenerator.cpp index 23c33ef97dd..6a9804b6965 100644 --- a/runtime/compiler/x/codegen/J9CodeGenerator.cpp +++ b/runtime/compiler/x/codegen/J9CodeGenerator.cpp @@ -99,9 +99,6 @@ J9::X86::CodeGenerator::initialize() cg->setSupportsInliningOfTypeCoersionMethods(); cg->setSupportsNewInstanceImplOpt(); - TR_ASSERT_FATAL(comp->compileRelocatableCode() || comp->isOutOfProcessCompilation() || comp->compilePortableCode() || comp->target().cpu.supportsFeature(OMR_FEATURE_X86_SSE4_1) == cg->getX86ProcessorInfo().supportsSSE4_1(), "supportsSSE4_1() failed\n"); - TR_ASSERT_FATAL(comp->compileRelocatableCode() || comp->isOutOfProcessCompilation() || comp->compilePortableCode() || comp->target().cpu.supportsFeature(OMR_FEATURE_X86_SSSE3) == cg->getX86ProcessorInfo().supportsSSSE3(), "supportsSSSE3() failed\n"); - if (comp->target().cpu.supportsFeature(OMR_FEATURE_X86_SSE4_1) && !comp->getOption(TR_DisableSIMDStringCaseConv) && !TR::Compiler->om.canGenerateArraylets() && !TR::Compiler->om.isOffHeapAllocationEnabled()) diff --git a/runtime/compiler/x/env/J9CPU.cpp b/runtime/compiler/x/env/J9CPU.cpp index 40af5779d04..9e8145a25c3 100644 --- a/runtime/compiler/x/env/J9CPU.cpp +++ b/runtime/compiler/x/env/J9CPU.cpp @@ -139,6 +139,9 @@ J9::X86::CPU::supportsFeature(uint32_t feature) { OMRPORT_ACCESS_FROM_OMRPORT(TR::Compiler->omrPortLib); + if (is_feature_disabled(feature)) + return false; + static bool disableCPUDetectionTest = feGetEnv("TR_DisableCPUDetectionTest"); if (!disableCPUDetectionTest) { @@ -146,29 +149,6 @@ J9::X86::CPU::supportsFeature(uint32_t feature) TR_ASSERT_FATAL(TRUE == omrsysinfo_processor_has_feature(&_supportedFeatureMasks, feature), "New processor feature usage detected, please add feature %d to _supportedFeatureMasks via TR::CPU::enableFeatureMasks()\n", feature); } - static bool disableAVX512 = feGetEnv("TR_DisableAVX512"); - - if (disableAVX512) - { - switch (feature) - { - case OMR_FEATURE_X86_AVX512F: - case OMR_FEATURE_X86_AVX512VL: - case OMR_FEATURE_X86_AVX512BW: - case OMR_FEATURE_X86_AVX512DQ: - case OMR_FEATURE_X86_AVX512CD: - case OMR_FEATURE_X86_AVX512ER: - case OMR_FEATURE_X86_AVX512PF: - case OMR_FEATURE_X86_AVX512_BITALG: - case OMR_FEATURE_X86_AVX512_IFMA: - case OMR_FEATURE_X86_AVX512_VBMI: - case OMR_FEATURE_X86_AVX512_VBMI2: - case OMR_FEATURE_X86_AVX512_VNNI: - case OMR_FEATURE_X86_AVX512_VPOPCNTDQ: - return false; - } - } - return TRUE == omrsysinfo_processor_has_feature(&_processorDescription, feature); }