Johan
Johan

Reputation: 76703

Does AVX support imply BMI1 support?

I have some code that relies on AVX.
In the same code base I also use TZCNT.
The latter is part of BMI1. I know I can test for this instruction using CPUID, but I'm lazy so I did not actually implement that.

To test for support I simply perform an AVX instruction. If I get a #UD undefined instruction exception back I know the CPU does not support AVX.
However tzcnt is backwards compatible (kind of) with the bsf (or bsr - I always forget which is which), so that will not trigger an exception.

If I have AVX support, does that imply BMI1 support?
For the record, I do not have AVX2 on the CPU that I'm testing with right now.

Upvotes: 3

Views: 1388

Answers (1)

Johan
Johan

Reputation: 76703

No, AVX support does not imply BMI1 support.

See the following table for details:

          Intel          AMD                  Year
---------------------------------------------------
AVX      Sandy Bridge    Bulldozer           2011
---------------------------------------------------
BMI1     Haswell         Piledriver/Jaguar   2013
---------------------------------------------------
ABM                      Barcelona           2007
         Haswell                             2013
---------------------------------------------------
AVX2     Haswell                             2013
                         Carrizo             2015
                         Ryzen               2017
---------------------------------------------------
BMI2     Haswell                             2013
                         Excavator           2015
                         Ryzen               2017

Most processors support both, but AVX predates BMI1 by two years.
Add to this the fact that tzcnt and bsf have different semantics with regards to the flags.
If you want to force a #UD exception, you can use a andn.

Source: Wikipedia: BMI, AVX

If you want to use CPUID:

BMI1 -> CPUID.(EAX=07H, ECX=0H):EBX.BMI1[bit 3]
(ANDN, BEXTR, BLSI, BLSMSK, BLSR, TZCNT)

BMI2  -> CPUID.(EAX=07H, ECX=0H):EBX.BMI2[bit 8]
(BZHI, MULX, PDEP, PEXT, RORX, SARX, SHLX, SHRX)

LZCNT -> CPUID.(EAX=80000001H) ECX.LZCNT[bit 5]  

POPCNT -> CPUID.(EAX=01H) :ECX.POPCNT [Bit 23]

Note that even if CPUID indicates that a (Intel) processor does not support popcnt it often does.

Upvotes: 4

Related Questions