-
Notifications
You must be signed in to change notification settings - Fork 5.3k
Description
Description
On a machine without AVX2 but with AVX (Sandy Bridge / Ivy Bridge), Vector256<IntegralType>.AllBitsSet will emit illegal instructions and cause the program to crash.
In particular, this method:
public static Vector256<byte> Problem() => Vector256<byte>.AllBitsSet;Will emit the following:
vzeroupper
G_M65241_IG02:
vpcmpeqd ymm0, ymm0, ymm0
vmovupd ymmword ptr[rcx], ymm0
mov rax, rcx
G_M65241_IG03:
vzeroupper
retAccording to https://www.felixcloutier.com/x86/pcmpeqb:pcmpeqw:pcmpeqd, vpcmpeqd with ymm operands is only available when AVX2 is.
This is also a problem for Vector256.Create(-1).
Configuration
This applies to .NET 5 and .NET 6, tested on an Ivy Bridge machine running Windows 10 x64.
Regression?
This is not a regression in case of AllBitsSet (the API was introduced in .NET 5), but it is a regression from .NET Core 3.1 for the Create(-1) call (lowering now folds it to the same get_AllBitsSet node, see also #47385).
Other information
During importation, Vector256<byte>.AllBitsSet depends on the Vector256 ISA, presumably because it is declared like so:
HARDWARE_INTRINSIC(Vector256, get_AllBitsSet, 32, 0, {INS_pcmpeqd, INS_pcmpeqd, INS_pcmpeqd, INS_pcmpeqd, INS_pcmpeqd, INS_pcmpeqd, INS_pcmpeqd, INS_pcmpeqd, INS_cmpps, INS_cmppd}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoContainment|HW_Flag_NoRMWSemantics)
This ISA is available when AVX is available, and the intrinsic is recognized:
Named Intrinsic System.Runtime.Intrinsics.Vector256`1.get_AllBitsSet: Notify VM instruction set (Vector256) must be supported.
And the node is later emitted as vpcmpeqd:
runtime/src/coreclr/jit/hwintrinsiccodegenxarch.cpp
Lines 1254 to 1269 in 7e681c1
| case NI_Vector128_get_AllBitsSet: | |
| case NI_Vector256_get_AllBitsSet: | |
| { | |
| assert(op1 == nullptr); | |
| if (varTypeIsFloating(baseType) && compiler->compOpportunisticallyDependsOn(InstructionSet_AVX)) | |
| { | |
| // The immediate 8 means Equal (unordered, non-signaling) | |
| // This is not available without VEX prefix. | |
| emit->emitIns_SIMD_R_R_R_I(ins, attr, targetReg, targetReg, targetReg, 8); | |
| } | |
| else | |
| { | |
| assert(varTypeIsIntegral(baseType) || !compiler->compIsaSupportedDebugOnly(InstructionSet_AVX)); | |
| emit->emitIns_SIMD_R_R_R(INS_pcmpeqd, attr, targetReg, targetReg, targetReg); | |
| } | |
| break; |
Metadata
Metadata
Assignees
Labels
Type
Projects
Status