https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109081
Bug ID: 109081
Summary: Confusion between FEATURE_LZCNT and FEATURE_ABM in
i386 cpuinfo
Product: gcc
Version: 12.2.1
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: libgcc
Assignee: unassigned at gcc dot gnu.org
Reporter: [email protected]
Target Milestone: ---
For detecting the x86_64 microarchitecture level in RPM I tried to reuse parts
from libgcc to avoid mistakes:
https://github.com/rpm-software-management/rpm/pull/2315
I did stumble upon some oddities around the LZCNT identification:
gcc/config/i386/cpuid.h puts bit_LZCNT among other bits for CPUID %eax == 1:
/* %ecx */
#define bit_SSE3 (1 << 0)
#define bit_PCLMUL (1 << 1)
#define bit_LZCNT (1 << 5)
#define bit_SSSE3 (1 << 9)
#define bit_FMA (1 << 12)
However, bit 5 there actually stands for VMX.
Presence of LZCNT is indicated (according to Intel and AMD docs) in CPUID %eax
== 0x80000001. The corresponding bit is also defined by cpuid.h, just called
ABM (technically correct as well):
/* Extended Features (%eax == 0x80000001) */
/* %ecx */
#define bit_LAHF_LM (1 << 0)
#define bit_ABM (1 << 5)
#define bit_SSE4a (1 << 6)
While the cpuid.h header defines bit_LZCNT in the wrong section, the detection
code in gcc/common/config/i386/cpuinfo.h actually uses it correctly:
__cpuid (0x80000001, eax, ebx, ecx, edx);
if (ecx & bit_SSE4a)
set_feature (FEATURE_SSE4_A);
if (ecx & bit_LAHF_LM)
set_feature (FEATURE_LAHF_LM);
if (ecx & bit_ABM)
set_feature (FEATURE_ABM);
if (ecx & bit_LWP)
set_feature (FEATURE_LWP);
if (ecx & bit_TBM)
set_feature (FEATURE_TBM);
if (ecx & bit_LZCNT)
set_feature (FEATURE_LZCNT);
However, because both bit_ABM and bit_LZCNT are (1 << 5), this means
FEATURE_ABM == FEATURE_LZCNT.
Is it intentional that this is the case? Is it intentional that bit_LZCNT is
declared in the wrong section as well?