From ceed5cc2c7ef0f4c2c39885011eaa18c736bea49 Mon Sep 17 00:00:00 2001 From: Tanner Gooding Date: Sat, 29 Aug 2026 10:01:30 -0700 Subject: [PATCH] Preserve side effects in SIMD classification helpers Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- src/coreclr/jit/gentree.cpp | 18 ++-- .../JitBlue/Runtime_132902/Runtime_132902.cs | 90 +++++++++++++++++++ .../JIT/Regression/Regression_ro_2.csproj | 1 + 3 files changed, 100 insertions(+), 9 deletions(-) create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_132902/Runtime_132902.cs diff --git a/src/coreclr/jit/gentree.cpp b/src/coreclr/jit/gentree.cpp index f55f7d6c05b8a5..397b5f4350e45e 100644 --- a/src/coreclr/jit/gentree.cpp +++ b/src/coreclr/jit/gentree.cpp @@ -25772,7 +25772,7 @@ GenTree* Compiler::gtNewSimdIsFiniteNode(var_types type, GenTree* op1, var_types } assert(varTypeIsIntegral(simdBaseType)); - return gtNewAllBitsSetConNode(type); + return gtWrapWithSideEffects(gtNewAllBitsSetConNode(type), op1, GTF_ALL_EFFECT); } //---------------------------------------------------------------------------------------------- @@ -25802,7 +25802,7 @@ GenTree* Compiler::gtNewSimdIsInfinityNode(var_types type, GenTree* op1, var_typ op1 = gtNewSimdAbsNode(type, op1, simdBaseType, simdSize); return gtNewSimdIsPositiveInfinityNode(type, op1, simdBaseType, simdSize); } - return gtNewZeroConNode(type); + return gtWrapWithSideEffects(gtNewZeroConNode(type), op1, GTF_ALL_EFFECT); } //---------------------------------------------------------------------------------------------- @@ -25841,7 +25841,7 @@ GenTree* Compiler::gtNewSimdIsIntegerNode(var_types type, GenTree* op1, var_type } assert(varTypeIsIntegral(simdBaseType)); - return gtNewAllBitsSetConNode(type); + return gtWrapWithSideEffects(gtNewAllBitsSetConNode(type), op1, GTF_ALL_EFFECT); } //---------------------------------------------------------------------------------------------- @@ -25871,7 +25871,7 @@ GenTree* Compiler::gtNewSimdIsNaNNode(var_types type, GenTree* op1, var_types si GenTree* op1Dup = fgMakeMultiUse(&op1); return gtNewSimdCmpOpNode(GT_NE, type, op1, op1Dup, simdBaseType, simdSize); } - return gtNewZeroConNode(type); + return gtWrapWithSideEffects(gtNewZeroConNode(type), op1, GTF_ALL_EFFECT); } //---------------------------------------------------------------------------------------------- @@ -25907,7 +25907,7 @@ GenTree* Compiler::gtNewSimdIsNegativeNode(var_types type, GenTree* op1, var_typ if (varTypeIsUnsigned(simdBaseType)) { - return gtNewZeroConNode(type); + return gtWrapWithSideEffects(gtNewZeroConNode(type), op1, GTF_ALL_EFFECT); } return gtNewSimdCmpOpNode(GT_LT, type, op1, gtNewZeroConNode(type), simdBaseType, simdSize); } @@ -25957,7 +25957,7 @@ GenTree* Compiler::gtNewSimdIsNegativeInfinityNode(var_types type, return gtNewSimdCmpOpNode(GT_EQ, type, op1, cnsNode, simdBaseType, simdSize); } - return gtNewZeroConNode(type); + return gtWrapWithSideEffects(gtNewZeroConNode(type), op1, GTF_ALL_EFFECT); } //---------------------------------------------------------------------------------------------- @@ -26076,7 +26076,7 @@ GenTree* Compiler::gtNewSimdIsPositiveNode(var_types type, GenTree* op1, var_typ if (varTypeIsUnsigned(simdBaseType)) { - return gtNewAllBitsSetConNode(type); + return gtWrapWithSideEffects(gtNewAllBitsSetConNode(type), op1, GTF_ALL_EFFECT); } return gtNewSimdCmpOpNode(GT_GE, type, op1, gtNewZeroConNode(type), simdBaseType, simdSize); } @@ -26126,7 +26126,7 @@ GenTree* Compiler::gtNewSimdIsPositiveInfinityNode(var_types type, return gtNewSimdCmpOpNode(GT_EQ, type, op1, cnsNode, simdBaseType, simdSize); } - return gtNewZeroConNode(type); + return gtWrapWithSideEffects(gtNewZeroConNode(type), op1, GTF_ALL_EFFECT); } //---------------------------------------------------------------------------------------------- @@ -26180,7 +26180,7 @@ GenTree* Compiler::gtNewSimdIsSubnormalNode(var_types type, GenTree* op1, var_ty return gtNewSimdCmpOpNode(GT_LT, type, op1, cnsNode2, simdBaseType, simdSize); } - return gtNewZeroConNode(type); + return gtWrapWithSideEffects(gtNewZeroConNode(type), op1, GTF_ALL_EFFECT); } //---------------------------------------------------------------------------------------------- diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_132902/Runtime_132902.cs b/src/tests/JIT/Regression/JitBlue/Runtime_132902/Runtime_132902.cs new file mode 100644 index 00000000000000..c537adbe4e0576 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_132902/Runtime_132902.cs @@ -0,0 +1,90 @@ +// 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.Runtime.Intrinsics; +using Xunit; + +namespace Runtime_132902; + +public class Runtime_132902 +{ + public enum Classification + { + IsFinite, + IsInfinity, + IsInteger, + IsNaN, + IsNegative, + IsNegativeInfinity, + IsPositive, + IsPositiveInfinity, + IsSubnormal, + } + + [Theory] + [InlineData(Classification.IsFinite)] + [InlineData(Classification.IsInfinity)] + [InlineData(Classification.IsInteger)] + [InlineData(Classification.IsNaN)] + [InlineData(Classification.IsNegative)] + [InlineData(Classification.IsNegativeInfinity)] + [InlineData(Classification.IsPositive)] + [InlineData(Classification.IsPositiveInfinity)] + [InlineData(Classification.IsSubnormal)] + public static void TestEntryPoint(Classification classification) + { + Action action = classification switch + { + Classification.IsFinite => () => IsFinite(Vector128.Count), + Classification.IsInfinity => () => IsInfinity(Vector128.Count), + Classification.IsInteger => () => IsInteger(Vector128.Count), + Classification.IsNaN => () => IsNaN(Vector128.Count), + Classification.IsNegative => () => IsNegative(Vector128.Count), + Classification.IsNegativeInfinity => () => IsNegativeInfinity(Vector128.Count), + Classification.IsPositive => () => IsPositive(Vector128.Count), + Classification.IsPositiveInfinity => () => IsPositiveInfinity(Vector128.Count), + Classification.IsSubnormal => () => IsSubnormal(Vector128.Count), + _ => throw new ArgumentOutOfRangeException(nameof(classification)), + }; + + Assert.Throws(action); + } + + [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.AggressiveOptimization)] + private static Vector128 IsFinite(int index) => + Vector128.IsFinite(Vector128.WithElement(Vector128.Zero, index, 0)); + + [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.AggressiveOptimization)] + private static Vector128 IsInfinity(int index) => + Vector128.IsInfinity(Vector128.WithElement(Vector128.Zero, index, 0)); + + [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.AggressiveOptimization)] + private static Vector128 IsInteger(int index) => + Vector128.IsInteger(Vector128.WithElement(Vector128.Zero, index, 0)); + + [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.AggressiveOptimization)] + private static Vector128 IsNaN(int index) => + Vector128.IsNaN(Vector128.WithElement(Vector128.Zero, index, 0)); + + [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.AggressiveOptimization)] + private static Vector128 IsNegative(int index) => + Vector128.IsNegative(Vector128.WithElement(Vector128.Zero, index, 0u)); + + [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.AggressiveOptimization)] + private static Vector128 IsNegativeInfinity(int index) => + Vector128.IsNegativeInfinity(Vector128.WithElement(Vector128.Zero, index, 0)); + + [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.AggressiveOptimization)] + private static Vector128 IsPositive(int index) => + Vector128.IsPositive(Vector128.WithElement(Vector128.Zero, index, 0u)); + + [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.AggressiveOptimization)] + private static Vector128 IsPositiveInfinity(int index) => + Vector128.IsPositiveInfinity(Vector128.WithElement(Vector128.Zero, index, 0)); + + [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.AggressiveOptimization)] + private static Vector128 IsSubnormal(int index) => + Vector128.IsSubnormal(Vector128.WithElement(Vector128.Zero, index, 0)); +} diff --git a/src/tests/JIT/Regression/Regression_ro_2.csproj b/src/tests/JIT/Regression/Regression_ro_2.csproj index f45592f1d391a5..71e278a4be983d 100644 --- a/src/tests/JIT/Regression/Regression_ro_2.csproj +++ b/src/tests/JIT/Regression/Regression_ro_2.csproj @@ -133,6 +133,7 @@ +