BMI support in Skylake

BMI support in Skylake

The erratum SKD002 in http://www.intel.com/content/dam/www/public/us/en/documents/specification-updates/desktop-6th-gen-core-family-spec-update.pdf makes the reader think that BMI extensions aren't supported in Skylake.

It is said that CPUID is "incorrectly indicating the presence of BMI1 or BMI2 instruction set extensions" and that "Attempting to use instructions from the BMI1 or BMI2 instruction set extensions will result in a #UD exception."

I use BMI instructions in some highly optimized part of my software so I wonder what the BIOS workaround is doing:

1) Returns correctly that BMI isn't supported

2) Fix BMI with trap handlers

3) Other TBD

I'll be glad to have detailed explanations from people in the know.

12 posts / 0 new
Last post
For more complete information about compiler optimizations, see our Optimization Notice.

Certainly I'm not a person in the know, but I can't imagine that Intel has just silently dropped support for one of their newest instruction set extensions and then only mentioned that indirectly via an errata.

I'm guessing the errata applies to some unusual case e.g., the chip running in 16-bit mode where these extensions probably were not ever supported. The documentation unfortunately is not clear on the matter.

Quote:

Travis D. wrote:
I can't imagine that Intel has just silently dropped support for one of their newest instruction set extensions and then only mentioned that indirectly via an errata.

indeed, neither me, I must confess I was playing the fool when asking the question this way since I was already aware that BMI is well supported at top speed, based on the results here: http://users.atw.hu/instlatx64/GenuineIntel00506E3_Skylake_InstLatX64.txt, see timings for TZCNT etc. 

Quote:

Travis D. wrote:
I'm guessing the errata applies to some unusual case e.g., the chip running in 16-bit mode where these extensions probably were not ever ported.

this looks like a good explanation, still curious to see the official one

Usually this means a microcode update that fixes the problem.

Sorry, the errata is badly written.To be clear, Skylake is completely consistent with Haswell/Broadwell in terms of BMI support.

BMI is available in products  i3 and above and not available in Pentium/Celeron processors based on core. This was true in HSW/BDW and continues to be true in SKL.. The errata is that SKL Pentium/Celerron CPUID incorrectly reports that the instructions are present. The BIOS patch can fix it so that the CPUID matches the processor behavior.

Bob,
Is it possible to use other CPUID functions to correct BMI flags?

First, the documentation will be corrected so that the errata isn't even mentioned in Skylake based Core/Xeon products i3 and above. Such products have BMI enabled hence the CPUID bits are consistent with the uarch.

"Is it possible to use other CPUID functions to correct BMI flags". If you can determine  that you are on a 'sixth generation Core(tm) based Pentium/Celeron' then you will know that if BMI is indicated as present then it is incorrect.

I don't know whether structured exception handling can be used to check the presence of undefined opcodes.

With both suggestions, is  invasive. I don't want to say much more than that because the point of CPUID is so you DON'T have to do 'tricks' to figure out where you are running. My hope is that the majority of Petium/Celeron BUIOS will have the gotten the update.

Quote:

Bob V. wrote:

Sorry, the errata is badly written.To be clear, Skylake is completely consistent with Haswell/Broadwell in terms of BMI support.

BMI is available in products  i3 and above and not available in Pentium/Celeron processors based on core. This was true in HSW/BDW and continues to be true in SKL.. The errata is that SKL Pentium/Celerron CPUID incorrectly reports that the instructions are present. The BIOS patch can fix it so that the CPUID matches the processor behavior.

thank you for the clarification

in my case BMI is used only in the AVX2 and AVX-512 code paths which can't be entered on low end parts anyway

if not all BIOS are with the fix, it will make sense that the compiler team add a workaround to _may_i_use_cpu_feature() so that it works OK with _FEATURE_BMI in the input set

 

 

Not everyone is using Intel compiler. If the cpuid instruction itself is not fixed by BIOS, I expect a lot of valid software to be broken.

Hopefully this code solves the problem:

if ((cpu.family == 6) && ((cpu.model & 0xF0) == 0x50) &&    //Skylake
    !AVX)   //Pentium/Celeron
{
    no BMI1 / BMI2
}

I suspect checking the cpu.model is redundant. As well as checking cpu.family :)

 

Using exception handler to test for #UD in this specific case is not a good idea, especially if you pick TZCNT as a test instruction due to annother errata:

SDK037 - Opcode bytes F3 0F BC May Execute as TZCNT Even When TZCNT Not Enumerated by CPUID

 

I think it may be easiest to read and save the processor features flags. Then preset the result register to, perhaps, -1 then issue the TZCNT and see if you get the correct value. Depending on returned value you either set/reset the saved processor feature flag. Then later when your code tests for features it tests the saved (and corrected) feature flags.

Jim Dempsey

Leave a Comment

Please sign in to add a comment. Not a member? Join today