diff --git a/src/coreclr/jit/gentree.cpp b/src/coreclr/jit/gentree.cpp index d111ae7ed3f4f2..d2341d16568a3a 100644 --- a/src/coreclr/jit/gentree.cpp +++ b/src/coreclr/jit/gentree.cpp @@ -13434,15 +13434,14 @@ GenTree* Compiler::gtFoldExprConst(GenTree* tree) i1 = -i1; break; + // Note: BSWAP16 is considered to leave upper 16 bits + // undefined as it differs by platform, so we cannot + // constant fold it. case GT_BSWAP: i1 = ((i1 >> 24) & 0xFF) | ((i1 >> 8) & 0xFF00) | ((i1 << 8) & 0xFF0000) | ((i1 << 24) & 0xFF000000); break; - case GT_BSWAP16: - i1 = ((i1 >> 8) & 0xFF) | ((i1 << 8) & 0xFF00); - break; - case GT_CAST: // assert (genActualType(tree->CastToType()) == tree->TypeGet()); diff --git a/src/coreclr/jit/gtlist.h b/src/coreclr/jit/gtlist.h index c902b21ec72f47..2b52b81aa841fe 100644 --- a/src/coreclr/jit/gtlist.h +++ b/src/coreclr/jit/gtlist.h @@ -104,7 +104,7 @@ GTNODE(RUNTIMELOOKUP , GenTreeRuntimeLookup, 0,GTK_UNOP|GTK_EXOP|DBK_NOTLIR) GTNODE(ARR_ADDR , GenTreeArrAddr ,0,GTK_UNOP|GTK_EXOP|DBK_NOTLIR) // Wraps an array address expression GTNODE(BSWAP , GenTreeOp ,0,GTK_UNOP) // Byte swap (32-bit or 64-bit) -GTNODE(BSWAP16 , GenTreeOp ,0,GTK_UNOP) // Byte swap (16-bit) +GTNODE(BSWAP16 , GenTreeOp ,0,GTK_UNOP) // Byte swap lower 16 bits. The upper 16 bits are undefined. //----------------------------------------------------------------------------- // Binary operators (2 operands): diff --git a/src/coreclr/jit/valuenum.cpp b/src/coreclr/jit/valuenum.cpp index 27d00595522416..c7f3200a5435ac 100644 --- a/src/coreclr/jit/valuenum.cpp +++ b/src/coreclr/jit/valuenum.cpp @@ -557,14 +557,9 @@ T ValueNumStore::EvalOpSpecialized(VNFunc vnf, T v0) case GT_NOT: return ~v0; - case GT_BSWAP16: - { - UINT16 v0_unsigned = UINT16(v0); - - v0_unsigned = ((v0_unsigned >> 8) & 0xFF) | ((v0_unsigned << 8) & 0xFF00); - return T(v0_unsigned); - } - + // Note: BSWAP16 is considered to leave upper 16 bits + // undefined as it differs by platform, so we cannot + // constant fold it. case GT_BSWAP: if (sizeof(T) == 4) { @@ -3355,7 +3350,7 @@ bool ValueNumStore::CanEvalForConstantArgs(VNFunc vnf) // Unary Ops case GT_NEG: case GT_NOT: - case GT_BSWAP16: + // Cannot constant fold BSWAP16 as upper bits are undefined. case GT_BSWAP: // Binary Ops diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_67723/Runtime_67723.cs b/src/tests/JIT/Regression/JitBlue/Runtime_67723/Runtime_67723.cs new file mode 100644 index 00000000000000..24e3ecf0e311f8 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_67723/Runtime_67723.cs @@ -0,0 +1,15 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Buffers.Binary; + +public class Runtime_67223 +{ + public static int Main() + { + short[] foo = { short.MinValue }; + int test = BinaryPrimitives.ReverseEndianness(foo[0]); + return test == 0x80 ? 100 : -1; + } +} + diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_67723/Runtime_67723.csproj b/src/tests/JIT/Regression/JitBlue/Runtime_67723/Runtime_67723.csproj new file mode 100644 index 00000000000000..f492aeac9d056b --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_67723/Runtime_67723.csproj @@ -0,0 +1,9 @@ + + + Exe + True + + + + + \ No newline at end of file