Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix #105969 #106218

Merged
merged 13 commits into from
Aug 15, 2024
16 changes: 16 additions & 0 deletions src/coreclr/jit/gentree.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20931,6 +20931,13 @@ GenTree* Compiler::gtNewSimdBinOpNode(
std::swap(op1, op2);
#endif // TARGET_XARCH
}
#ifdef TARGET_XARCH
if (HWIntrinsicInfo::NeedsNormalizeSmallTypeToInt(intrinsic) && varTypeIsSmall(simdBaseType))
{
simdBaseJitType = varTypeIsUnsigned(simdBaseType) ? CORINFO_TYPE_UINT : CORINFO_TYPE_INT;
simdBaseType = JitType2PreciseVarType(simdBaseJitType);
}
#endif // TARGET_XARCH
return gtNewSimdHWIntrinsicNode(type, op1, op2, intrinsic, simdBaseJitType, simdSize);
}

Expand Down Expand Up @@ -25689,6 +25696,15 @@ GenTree* Compiler::gtNewSimdTernaryLogicNode(var_types type,
intrinsic = NI_AVX512F_VL_TernaryLogic;
}

#ifdef TARGET_XARCH
assert(HWIntrinsicInfo::NeedsNormalizeSmallTypeToInt(intrinsic));
if (varTypeIsSmall(simdBaseType))
{
simdBaseJitType = varTypeIsUnsigned(simdBaseType) ? CORINFO_TYPE_UINT : CORINFO_TYPE_INT;
simdBaseType = JitType2PreciseVarType(simdBaseJitType);
}
#endif // TARGET_XARCH

return gtNewSimdHWIntrinsicNode(type, op1, op2, op3, op4, intrinsic, simdBaseJitType, simdSize);
}
#endif // TARGET_XARCH
Expand Down
14 changes: 14 additions & 0 deletions src/coreclr/jit/gentree.h
Original file line number Diff line number Diff line change
Expand Up @@ -6667,6 +6667,20 @@ struct GenTreeHWIntrinsic : public GenTreeJitIntrinsic

bool ShouldConstantProp(GenTree* operand, GenTreeVecCon* vecCon);

void NormalizeJitBaseTypeToInt(NamedIntrinsic id, var_types simdBaseType)
{
assert(varTypeIsSmall(simdBaseType));

if (varTypeIsUnsigned(simdBaseType))
{
SetSimdBaseJitType(CORINFO_TYPE_UINT);
}
else
{
SetSimdBaseJitType(CORINFO_TYPE_UINT);
}
}

private:
void SetHWIntrinsicId(NamedIntrinsic intrinsicId);

Expand Down
7 changes: 7 additions & 0 deletions src/coreclr/jit/hwintrinsic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1818,6 +1818,13 @@ GenTree* Compiler::impHWIntrinsic(NamedIntrinsic intrinsic,
if (simdBaseJitType != CORINFO_TYPE_UNDEF)
{
simdBaseType = JitType2PreciseVarType(simdBaseJitType);
#ifdef TARGET_XARCH
if (HWIntrinsicInfo::NeedsNormalizeSmallTypeToInt(intrinsic) && varTypeIsSmall(simdBaseType))
{
simdBaseJitType = varTypeIsUnsigned(simdBaseType) ? CORINFO_TYPE_UINT : CORINFO_TYPE_INT;
simdBaseType = JitType2PreciseVarType(simdBaseJitType);
}
tannergooding marked this conversation as resolved.
Show resolved Hide resolved
#endif // TARGET_XARCH
}

const unsigned simdSize = HWIntrinsicInfo::lookupSimdSize(this, intrinsic, sig);
Expand Down
9 changes: 9 additions & 0 deletions src/coreclr/jit/hwintrinsic.h
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,9 @@ enum HWIntrinsicFlag : unsigned int

// The intrinsic is an embedded masking compatible intrinsic
HW_Flag_EmbMaskingCompatible = 0x10000000,

// The base type of this intrinsic needs to be normalized to int/uint unless it is long/ulong.
HW_Flag_NormalizeSmallTypeToInt = 0x20000000,
#elif defined(TARGET_ARM64)

// The intrinsic has an enum operand. Using this implies HW_Flag_HasImmediateOperand.
Expand Down Expand Up @@ -755,6 +758,12 @@ struct HWIntrinsicInfo
HWIntrinsicFlag flags = lookupFlags(id);
return (flags & HW_Flag_MaybeMemoryStore) != 0;
}

static bool NeedsNormalizeSmallTypeToInt(NamedIntrinsic id)
{
HWIntrinsicFlag flags = lookupFlags(id);
return (flags & HW_Flag_NormalizeSmallTypeToInt) != 0;
}
#endif

static bool NoJmpTableImm(NamedIntrinsic id)
Expand Down
1 change: 1 addition & 0 deletions src/coreclr/jit/hwintrinsiccodegenxarch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,7 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node)
// We need to validate that other phases of the compiler haven't introduced unsupported intrinsics
assert(compiler->compIsaSupportedDebugOnly(isa));
assert(HWIntrinsicInfo::RequiresCodegen(intrinsicId));
assert(!HWIntrinsicInfo::NeedsNormalizeSmallTypeToInt(intrinsicId) || !varTypeIsSmall(node->GetSimdBaseType()));

bool isTableDriven = genIsTableDrivenHWIntrinsic(intrinsicId, category);
insOpts instOptions = INS_OPTS_NONE;
Expand Down
34 changes: 17 additions & 17 deletions src/coreclr/jit/hwintrinsiclistxarch.h

Large diffs are not rendered by default.

23 changes: 23 additions & 0 deletions src/coreclr/jit/lowerxarch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1672,6 +1672,11 @@ GenTree* Lowering::LowerHWIntrinsic(GenTreeHWIntrinsic* node)
BlockRange().InsertBefore(userIntrin, op4);

userIntrin->ResetHWIntrinsicId(ternaryLogicId, comp, op1, op2, op3, op4);
if (varTypeIsSmall(simdBaseType))
{
assert(HWIntrinsicInfo::NeedsNormalizeSmallTypeToInt(ternaryLogicId));
userIntrin->NormalizeJitBaseTypeToInt(ternaryLogicId, simdBaseType);
}
return nextNode;
}
}
Expand Down Expand Up @@ -1737,6 +1742,11 @@ GenTree* Lowering::LowerHWIntrinsic(GenTreeHWIntrinsic* node)
BlockRange().InsertBefore(node, control);

node->ResetHWIntrinsicId(ternaryLogicId, comp, op1, op2, op3, control);
if (varTypeIsSmall(simdBaseType))
{
assert(HWIntrinsicInfo::NeedsNormalizeSmallTypeToInt(ternaryLogicId));
node->NormalizeJitBaseTypeToInt(ternaryLogicId, simdBaseType);
}
return LowerNode(node);
}
}
Expand Down Expand Up @@ -1823,6 +1833,10 @@ GenTree* Lowering::LowerHWIntrinsic(GenTreeHWIntrinsic* node)
LowerNode(op2);

node->ResetHWIntrinsicId(intrinsicId, comp, op1, op2);
if (HWIntrinsicInfo::NeedsNormalizeSmallTypeToInt(intrinsicId) && varTypeIsSmall(simdBaseType))
{
node->NormalizeJitBaseTypeToInt(intrinsicId, simdBaseType);
}
break;
}

Expand Down Expand Up @@ -1882,6 +1896,10 @@ GenTree* Lowering::LowerHWIntrinsic(GenTreeHWIntrinsic* node)
LowerNode(op3);

node->ResetHWIntrinsicId(intrinsicId, comp, op1, op2, op3);
if (HWIntrinsicInfo::NeedsNormalizeSmallTypeToInt(intrinsicId) && varTypeIsSmall(simdBaseType))
{
node->NormalizeJitBaseTypeToInt(intrinsicId, simdBaseType);
}
break;
}

Expand Down Expand Up @@ -3455,6 +3473,11 @@ GenTree* Lowering::LowerHWIntrinsicCndSel(GenTreeHWIntrinsic* node)
BlockRange().InsertBefore(node, control);

node->ResetHWIntrinsicId(ternaryLogicId, comp, op1, op2, op3, control);
if (varTypeIsSmall(simdBaseType))
{
assert(HWIntrinsicInfo::NeedsNormalizeSmallTypeToInt(ternaryLogicId));
node->NormalizeJitBaseTypeToInt(ternaryLogicId, simdBaseType);
}
return LowerNode(node);
}

Expand Down
43 changes: 43 additions & 0 deletions src/tests/JIT/Regression/JitBlue/Runtime_105969/Runtime_105969.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System;
using System.Runtime.CompilerServices;
using System.Numerics;
using System.Runtime.Intrinsics;
using System.Runtime.Intrinsics.X86;
using Xunit;

// Generated by Fuzzlyn v2.2 on 2024-08-04 15:50:11
// Run on X64 Linux
// Seed: 9513455124659677293-vectort,vector128,vector256,vector512,x86aes,x86avx,x86avx2,x86avx512bw,x86avx512bwvl,x86avx512cd,x86avx512cdvl,x86avx512dq,x86avx512dqvl,x86avx512f,x86avx512fvl,x86avx512fx64,x86avx512vbmi,x86avx512vbmivl,x86bmi1,x86bmi1x64,x86bmi2,x86bmi2x64,x86fma,x86lzcnt,x86lzcntx64,x86pclmulqdq,x86popcnt,x86popcntx64,x86sse,x86ssex64,x86sse2,x86sse2x64,x86sse3,x86sse41,x86sse41x64,x86sse42,x86sse42x64,x86ssse3,x86x86base
// Reduced from 26.0 KiB to 1.1 KiB in 00:00:56
// Debug: Outputs <0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0>
// Release: Outputs <0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0>

public class Runtime_105969
{
public static byte s_5;

[Fact]
public static void TestEntryPoint()
{
if (Avx512BW.IsSupported)
{
var vr16 = Vector512.CreateScalar(s_5);
var vr17 = Vector512.Create<byte>(1);
var vr18 = (byte)0;
var vr19 = Vector512.CreateScalar(vr18);
var vr20 = Vector128.Create<byte>(0);
var vr21 = Avx512BW.BroadcastScalarToVector512(vr20);
var vr22 = Vector256.Create<byte>(1);
var vr23 = Avx512F.InsertVector256(vr21, vr22, 0);
var vr24 = Vector512.Create(249, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0);
var vr25 = Avx512BW.BlendVariable(vr19, vr23, vr24);
var vr26 = Avx512BW.Min(vr17, vr25);
Vector512<byte> vr27 = Avx512BW.UnpackLow(vr16, vr26);
Vector512<byte> expected = Vector512.Create(0, (byte)1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
Assert.Equal(expected, vr27);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<Optimize>True</Optimize>
</PropertyGroup>
<ItemGroup>
<Compile Include="$(MSBuildProjectName).cs" />
</ItemGroup>
</Project>
Loading