diff --git a/src/coreclr/jit/gentree.cpp b/src/coreclr/jit/gentree.cpp index adb85ddda13a7..0142eb9481b03 100644 --- a/src/coreclr/jit/gentree.cpp +++ b/src/coreclr/jit/gentree.cpp @@ -20818,6 +20818,16 @@ GenTree* Compiler::gtNewSimdBinOpNode( if (op2->IsCnsIntOrI()) { op2->AsIntCon()->gtIconVal &= shiftCountMask; +#ifdef TARGET_ARM64 + // On ARM64, ShiftRight* intrinsics cannot encode a shift value of zero, + // so use the generic Shift* fallback intrinsic. + // GenTreeHWIntrinsic::GetHWIntrinsicIdForBinOp will see that the immediate node is not const, + // and return the correct fallback intrinsic. + if ((op != GT_LSH) && (op2->AsIntCon()->IconValue() == 0)) + { + op2 = gtNewZeroConNode(type); + } +#endif // TARGET_ARM64 } else { diff --git a/src/coreclr/jit/hwintrinsiccodegenarm64.cpp b/src/coreclr/jit/hwintrinsiccodegenarm64.cpp index 5bf021ac90b55..32492363d548a 100644 --- a/src/coreclr/jit/hwintrinsiccodegenarm64.cpp +++ b/src/coreclr/jit/hwintrinsiccodegenarm64.cpp @@ -443,18 +443,8 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node) for (helper.EmitBegin(); !helper.Done(); helper.EmitCaseEnd()) { const int shiftAmount = helper.ImmValue(); - - if (shiftAmount == 0) - { - // TODO: Use emitIns_Mov instead. - // We do not use it currently because it will still elide the 'mov' - // even if 'canSkip' is false. We cannot elide the 'mov' here. - GetEmitter()->emitIns_R_R_R(INS_mov, emitTypeSize(node), targetReg, reg, reg); - } - else - { - GetEmitter()->emitIns_R_R_I(ins, emitSize, targetReg, reg, shiftAmount, opt); - } + assert((shiftAmount != 0) || (intrin.category == HW_Category_ShiftLeftByImmediate)); + GetEmitter()->emitIns_R_R_I(ins, emitSize, targetReg, reg, shiftAmount, opt); } }; diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_107173/Runtime_107173.cs b/src/tests/JIT/Regression/JitBlue/Runtime_107173/Runtime_107173.cs new file mode 100644 index 0000000000000..147b25e47c49d --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_107173/Runtime_107173.cs @@ -0,0 +1,45 @@ +// 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.4 on 2024-08-26 23:38:13 +// Run on Arm64 Linux +// Seed: 8716802894387291290-vectort,vector64,vector128,armadvsimd,armadvsimdarm64,armaes,armarmbase,armarmbasearm64,armcrc32,armcrc32arm64,armdp,armrdm,armrdmarm64,armsha1,armsha256 +// Reduced from 19.5 KiB to 0.5 KiB in 00:00:27 +// Debug: Outputs <0, 0, 0, 0> +// Release: Outputs <0, 0, 4457472, 0> +using System; +using System.Numerics; +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.Arm; +using Xunit; + +public class C0 +{ + public ushort F2; + public ushort F8; +} + +public class Runtime_107173 +{ + public static C0 s_8 = new C0(); + + [Fact] + public static void TestLeftShift() + { + if (AdvSimd.IsSupported) + { + var vr6 = s_8.F8; + var vr7 = s_8.F2; + var vr8 = Vector64.Create(vr6, vr7, 0, 0); + Vector128 vr9 = AdvSimd.ShiftLeftLogicalWideningLower(vr8, 0); + Assert.Equal(vr9, Vector128.Zero); + } + } + + [Fact] + public static void TestRightShift() + { + var result = Vector128.AllBitsSet >> 8; + Assert.Equal(result, Vector128.AllBitsSet); + } +} \ No newline at end of file diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_107173/Runtime_107173.csproj b/src/tests/JIT/Regression/JitBlue/Runtime_107173/Runtime_107173.csproj new file mode 100644 index 0000000000000..de6d5e08882e8 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_107173/Runtime_107173.csproj @@ -0,0 +1,8 @@ + + + True + + + + +