1
0
Fork 0
mirror of https://github.com/VSadov/Satori.git synced 2025-06-10 01:50:53 +09:00

JIT: Add out-of-bounds fallback for AdvSimd.ShiftRightLogical (#105777)

Fixes #105621. When its immediate is out-of-bounds, AdvSimd.ShiftRightLogical can be transformed into AdvSimd.ShiftLogical, which takes the immediate in a register. This means AdvSimd.ShiftRightLogical will no longer throw ArgumentOutOfRangeException in Debug or Release; when optimizing, we'd previously fold the intrinsic away, thus creating behavioral discrepancies.
This commit is contained in:
Aman Khalid 2024-08-01 13:39:57 +00:00 committed by GitHub
parent 71d8ae6843
commit 74c608d67d
Signed by: github
GPG key ID: B5690EEEBB952194
4 changed files with 84 additions and 2 deletions

View file

@ -1660,7 +1660,24 @@ bool Compiler::CheckHWIntrinsicImmRange(NamedIntrinsic intrinsic,
{
assert(!mustExpand);
// The imm-HWintrinsics that do not accept all imm8 values may throw
// ArgumentOutOfRangeException when the imm argument is not in the valid range
// ArgumentOutOfRangeException when the imm argument is not in the valid range,
// unless the intrinsic can be transformed into one that does accept all imm8 values
#ifdef TARGET_ARM64
switch (intrinsic)
{
case NI_AdvSimd_ShiftRightLogical:
*useFallback = true;
break;
// TODO: Implement more AdvSimd fallbacks in Compiler::impNonConstFallback
default:
assert(*useFallback == false);
break;
}
#endif // TARGET_ARM64
return false;
}
}

View file

@ -564,8 +564,27 @@ void HWIntrinsicInfo::lookupImmBounds(
//
GenTree* Compiler::impNonConstFallback(NamedIntrinsic intrinsic, var_types simdType, CorInfoType simdBaseJitType)
{
switch (intrinsic)
{
case NI_AdvSimd_ShiftRightLogical:
{
// AdvSimd.ShiftRightLogical be replaced with AdvSimd.ShiftLogical, which takes op2 in a simd register
GenTree* op2 = impPopStack().val;
GenTree* op1 = impSIMDPopStack();
// AdvSimd.ShiftLogical does right-shifts with negative immediates, hence the negation
GenTree* tmpOp =
gtNewSimdCreateBroadcastNode(simdType, gtNewOperNode(GT_NEG, genActualType(op2->TypeGet()), op2),
simdBaseJitType, genTypeSize(simdType));
return gtNewSimdHWIntrinsicNode(simdType, op1, tmpOp, NI_AdvSimd_ShiftLogical, simdBaseJitType,
genTypeSize(simdType));
}
default:
return nullptr;
}
}
//------------------------------------------------------------------------
// impSpecialIntrinsic: Import a hardware intrinsic that requires special handling as a GT_HWINTRINSIC node if possible

View file

@ -0,0 +1,38 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// Generated by Fuzzlyn v2.1 on 2024-07-28 20:49:49
// Run on Arm64 Linux
// Seed: 14204794442367797079-vectort,vector64,vector128,armadvsimd,armadvsimdarm64,armaes,armarmbase,armarmbasearm64,armcrc32,armcrc32arm64,armdp,armrdm,armrdmarm64,armsha1,armsha256
// Reduced from 12.6 KiB to 0.4 KiB in 00:00:17
// Debug: Throws 'System.ArgumentOutOfRangeException'
// Release: Runs successfully
using System;
using System.Runtime.Intrinsics;
using System.Runtime.Intrinsics.Arm;
using Xunit;
public class Runtime_105621
{
[Fact]
public static void TestShiftByZero()
{
if (AdvSimd.IsSupported)
{
var vr3 = Vector64.Create<byte>(0);
var vr4 = AdvSimd.ShiftRightLogical(vr3, 0);
Assert.Equal(vr3, vr4);
}
}
[Fact]
public static void TestShiftToZero()
{
if (AdvSimd.IsSupported)
{
var vr3 = Vector64.Create<byte>(128);
var vr4 = AdvSimd.ShiftRightLogical(vr3, 9);
Assert.Equal(vr4, Vector64<byte>.Zero);
}
}
}

View file

@ -0,0 +1,8 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<Optimize>False</Optimize>
</PropertyGroup>
<ItemGroup>
<Compile Include="$(MSBuildProjectName).cs" />
</ItemGroup>
</Project>