From 11316daf88d84108d4cce857b258d0de092769ba Mon Sep 17 00:00:00 2001 From: Brian Rourke Boll Date: Mon, 2 Dec 2024 06:40:12 -0500 Subject: [PATCH] Support `ldelem.u8`, `ldelem.u` opcode aliases (#18081) --- .../.FSharp.Compiler.Service/9.0.200.md | 1 + src/Compiler/AbstractIL/ilwrite.fs | 4 +- .../ForXInArray_ToArray.fs | 15 + .../ForXInArray_ToArray.fs.il.bsl | 533 ++++++++++++++++++ 4 files changed, 551 insertions(+), 2 deletions(-) diff --git a/docs/release-notes/.FSharp.Compiler.Service/9.0.200.md b/docs/release-notes/.FSharp.Compiler.Service/9.0.200.md index 8c19083bb74..22b160629f3 100644 --- a/docs/release-notes/.FSharp.Compiler.Service/9.0.200.md +++ b/docs/release-notes/.FSharp.Compiler.Service/9.0.200.md @@ -13,6 +13,7 @@ * Fix missing nullness warning in case of method resolution multiple candidates ([PR #17917](https://github.com/dotnet/fsharp/pull/17918)) * Fix failure to use bound values in `when` clauses of `try-with` in `seq` expressions ([PR #17990](https://github.com/dotnet/fsharp/pull/17990)) * Fix locals allocating for the special `copyOfStruct` defensive copy ([PR #18025](https://github.com/dotnet/fsharp/pull/18025)) +* Fix lowering of computed array expressions when the expression consists of a simple mapping from a `uint64` or `unativeint` array. [PR #18081](https://github.com/dotnet/fsharp/pull/18081) ### Added diff --git a/src/Compiler/AbstractIL/ilwrite.fs b/src/Compiler/AbstractIL/ilwrite.fs index 3cbdd3c752b..e5183809e1a 100644 --- a/src/Compiler/AbstractIL/ilwrite.fs +++ b/src/Compiler/AbstractIL/ilwrite.fs @@ -2026,11 +2026,11 @@ module Codebuf = | I_ldelem dt -> emitInstrCode codebuf (match dt with - | DT_I -> i_ldelem_i + | DT_I | DT_U -> i_ldelem_i | DT_I1 -> i_ldelem_i1 | DT_I2 -> i_ldelem_i2 | DT_I4 -> i_ldelem_i4 - | DT_I8 -> i_ldelem_i8 + | DT_I8 | DT_U8 -> i_ldelem_i8 | DT_U1 -> i_ldelem_u1 | DT_U2 -> i_ldelem_u2 | DT_U4 -> i_ldelem_u4 diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/ComputedCollections/ForXInArray_ToArray.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/ComputedCollections/ForXInArray_ToArray.fs index 1f55bc40d91..4d1e3e8c879 100644 --- a/tests/FSharp.Compiler.ComponentTests/EmittedIL/ComputedCollections/ForXInArray_ToArray.fs +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/ComputedCollections/ForXInArray_ToArray.fs @@ -35,3 +35,18 @@ let ``for Failure _ | _ in ...`` () = [|for Failure _ | _ in [||] do 0|] let ``for true | false in ...`` () = [|for true | false in [||] do 0|] let ``for true | _ in ...`` () = [|for true | _ in [||] do 0|] let ``for _ | true in ...`` () = [|for _ | true in [||] do 0|] + +// https://github.com/dotnet/fsharp/issues/18066 +let ``[|for x in sbyteArray -> x|]`` (xs : sbyte array) = [|for x in xs -> x|] +let ``[|for x in byteArray -> x|]`` (xs : byte array) = [|for x in xs -> x|] +let ``[|for x in int16Array -> x|]`` (xs : int16 array) = [|for x in xs -> x|] +let ``[|for x in uint16Array -> x|]`` (xs : uint16 array) = [|for x in xs -> x|] +let ``[|for x in charArray -> x|]`` (xs : char array) = [|for x in xs -> x|] +let ``[|for x in intArray -> x|]`` (xs : int array) = [|for x in xs -> x|] +let ``[|for x in uintArray -> x|]`` (xs : uint array) = [|for x in xs -> x|] +let ``[|for x in int64Array -> x|]`` (xs : int64 array) = [|for x in xs -> x|] +let ``[|for x in uint64Array -> x|]`` (xs : uint64 array) = [|for x in xs -> x|] +let ``[|for x in nativeintArray -> x|]`` (xs : nativeint array) = [|for x in xs -> x|] +let ``[|for x in unativeintArray -> x|]`` (xs : unativeint array) = [|for x in xs -> x|] +let ``[|for x in floatArray -> x|]`` (xs : float array) = [|for x in xs -> x|] +let ``[|for x in float32Array -> x|]`` (xs : float32 array) = [|for x in xs -> x|] diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/ComputedCollections/ForXInArray_ToArray.fs.il.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/ComputedCollections/ForXInArray_ToArray.fs.il.bsl index 2e1eeb67e45..7cfc61c36b6 100644 --- a/tests/FSharp.Compiler.ComponentTests/EmittedIL/ComputedCollections/ForXInArray_ToArray.fs.il.bsl +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/ComputedCollections/ForXInArray_ToArray.fs.il.bsl @@ -1798,6 +1798,539 @@ IL_0022: ret } + .method public static int8[] '[|for x in sbyteArray -> x|]'(int8[] xs) cil managed + { + + .maxstack 6 + .locals init (int8[] V_0, + int8[] V_1, + int32 V_2, + int8 V_3) + IL_0000: ldarg.0 + IL_0001: stloc.0 + IL_0002: ldloc.0 + IL_0003: ldlen + IL_0004: conv.i4 + IL_0005: newarr [runtime]System.SByte + IL_000a: stloc.1 + IL_000b: ldc.i4.0 + IL_000c: stloc.2 + IL_000d: br.s IL_001b + + IL_000f: ldloc.1 + IL_0010: ldloc.2 + IL_0011: ldloc.0 + IL_0012: ldloc.2 + IL_0013: ldelem.i1 + IL_0014: stloc.3 + IL_0015: ldloc.3 + IL_0016: stelem.i1 + IL_0017: ldloc.2 + IL_0018: ldc.i4.1 + IL_0019: add + IL_001a: stloc.2 + IL_001b: ldloc.2 + IL_001c: ldloc.1 + IL_001d: ldlen + IL_001e: conv.i4 + IL_001f: blt.s IL_000f + + IL_0021: ldloc.1 + IL_0022: ret + } + + .method public static uint8[] '[|for x in byteArray -> x|]'(uint8[] xs) cil managed + { + + .maxstack 6 + .locals init (uint8[] V_0, + uint8[] V_1, + int32 V_2, + uint8 V_3) + IL_0000: ldarg.0 + IL_0001: stloc.0 + IL_0002: ldloc.0 + IL_0003: ldlen + IL_0004: conv.i4 + IL_0005: newarr [runtime]System.Byte + IL_000a: stloc.1 + IL_000b: ldc.i4.0 + IL_000c: stloc.2 + IL_000d: br.s IL_001b + + IL_000f: ldloc.1 + IL_0010: ldloc.2 + IL_0011: ldloc.0 + IL_0012: ldloc.2 + IL_0013: ldelem.u1 + IL_0014: stloc.3 + IL_0015: ldloc.3 + IL_0016: stelem.i1 + IL_0017: ldloc.2 + IL_0018: ldc.i4.1 + IL_0019: add + IL_001a: stloc.2 + IL_001b: ldloc.2 + IL_001c: ldloc.1 + IL_001d: ldlen + IL_001e: conv.i4 + IL_001f: blt.s IL_000f + + IL_0021: ldloc.1 + IL_0022: ret + } + + .method public static int16[] '[|for x in int16Array -> x|]'(int16[] xs) cil managed + { + + .maxstack 6 + .locals init (int16[] V_0, + int16[] V_1, + int32 V_2, + int16 V_3) + IL_0000: ldarg.0 + IL_0001: stloc.0 + IL_0002: ldloc.0 + IL_0003: ldlen + IL_0004: conv.i4 + IL_0005: newarr [runtime]System.Int16 + IL_000a: stloc.1 + IL_000b: ldc.i4.0 + IL_000c: stloc.2 + IL_000d: br.s IL_001b + + IL_000f: ldloc.1 + IL_0010: ldloc.2 + IL_0011: ldloc.0 + IL_0012: ldloc.2 + IL_0013: ldelem.i2 + IL_0014: stloc.3 + IL_0015: ldloc.3 + IL_0016: stelem.i2 + IL_0017: ldloc.2 + IL_0018: ldc.i4.1 + IL_0019: add + IL_001a: stloc.2 + IL_001b: ldloc.2 + IL_001c: ldloc.1 + IL_001d: ldlen + IL_001e: conv.i4 + IL_001f: blt.s IL_000f + + IL_0021: ldloc.1 + IL_0022: ret + } + + .method public static uint16[] '[|for x in uint16Array -> x|]'(uint16[] xs) cil managed + { + + .maxstack 6 + .locals init (uint16[] V_0, + uint16[] V_1, + int32 V_2, + uint16 V_3) + IL_0000: ldarg.0 + IL_0001: stloc.0 + IL_0002: ldloc.0 + IL_0003: ldlen + IL_0004: conv.i4 + IL_0005: newarr [runtime]System.UInt16 + IL_000a: stloc.1 + IL_000b: ldc.i4.0 + IL_000c: stloc.2 + IL_000d: br.s IL_001b + + IL_000f: ldloc.1 + IL_0010: ldloc.2 + IL_0011: ldloc.0 + IL_0012: ldloc.2 + IL_0013: ldelem.u2 + IL_0014: stloc.3 + IL_0015: ldloc.3 + IL_0016: stelem.i2 + IL_0017: ldloc.2 + IL_0018: ldc.i4.1 + IL_0019: add + IL_001a: stloc.2 + IL_001b: ldloc.2 + IL_001c: ldloc.1 + IL_001d: ldlen + IL_001e: conv.i4 + IL_001f: blt.s IL_000f + + IL_0021: ldloc.1 + IL_0022: ret + } + + .method public static char[] '[|for x in charArray -> x|]'(char[] xs) cil managed + { + + .maxstack 6 + .locals init (char[] V_0, + char[] V_1, + int32 V_2, + char V_3) + IL_0000: ldarg.0 + IL_0001: stloc.0 + IL_0002: ldloc.0 + IL_0003: ldlen + IL_0004: conv.i4 + IL_0005: newarr [runtime]System.Char + IL_000a: stloc.1 + IL_000b: ldc.i4.0 + IL_000c: stloc.2 + IL_000d: br.s IL_001b + + IL_000f: ldloc.1 + IL_0010: ldloc.2 + IL_0011: ldloc.0 + IL_0012: ldloc.2 + IL_0013: ldelem.u2 + IL_0014: stloc.3 + IL_0015: ldloc.3 + IL_0016: stelem.i2 + IL_0017: ldloc.2 + IL_0018: ldc.i4.1 + IL_0019: add + IL_001a: stloc.2 + IL_001b: ldloc.2 + IL_001c: ldloc.1 + IL_001d: ldlen + IL_001e: conv.i4 + IL_001f: blt.s IL_000f + + IL_0021: ldloc.1 + IL_0022: ret + } + + .method public static int32[] '[|for x in intArray -> x|]'(int32[] xs) cil managed + { + + .maxstack 6 + .locals init (int32[] V_0, + int32[] V_1, + int32 V_2, + int32 V_3) + IL_0000: ldarg.0 + IL_0001: stloc.0 + IL_0002: ldloc.0 + IL_0003: ldlen + IL_0004: conv.i4 + IL_0005: newarr [runtime]System.Int32 + IL_000a: stloc.1 + IL_000b: ldc.i4.0 + IL_000c: stloc.2 + IL_000d: br.s IL_001b + + IL_000f: ldloc.1 + IL_0010: ldloc.2 + IL_0011: ldloc.0 + IL_0012: ldloc.2 + IL_0013: ldelem.i4 + IL_0014: stloc.3 + IL_0015: ldloc.3 + IL_0016: stelem.i4 + IL_0017: ldloc.2 + IL_0018: ldc.i4.1 + IL_0019: add + IL_001a: stloc.2 + IL_001b: ldloc.2 + IL_001c: ldloc.1 + IL_001d: ldlen + IL_001e: conv.i4 + IL_001f: blt.s IL_000f + + IL_0021: ldloc.1 + IL_0022: ret + } + + .method public static uint32[] '[|for x in uintArray -> x|]'(uint32[] xs) cil managed + { + + .maxstack 6 + .locals init (uint32[] V_0, + uint32[] V_1, + int32 V_2, + uint32 V_3) + IL_0000: ldarg.0 + IL_0001: stloc.0 + IL_0002: ldloc.0 + IL_0003: ldlen + IL_0004: conv.i4 + IL_0005: newarr [runtime]System.UInt32 + IL_000a: stloc.1 + IL_000b: ldc.i4.0 + IL_000c: stloc.2 + IL_000d: br.s IL_001b + + IL_000f: ldloc.1 + IL_0010: ldloc.2 + IL_0011: ldloc.0 + IL_0012: ldloc.2 + IL_0013: ldelem.u4 + IL_0014: stloc.3 + IL_0015: ldloc.3 + IL_0016: stelem.i4 + IL_0017: ldloc.2 + IL_0018: ldc.i4.1 + IL_0019: add + IL_001a: stloc.2 + IL_001b: ldloc.2 + IL_001c: ldloc.1 + IL_001d: ldlen + IL_001e: conv.i4 + IL_001f: blt.s IL_000f + + IL_0021: ldloc.1 + IL_0022: ret + } + + .method public static int64[] '[|for x in int64Array -> x|]'(int64[] xs) cil managed + { + + .maxstack 6 + .locals init (int64[] V_0, + int64[] V_1, + int32 V_2, + int64 V_3) + IL_0000: ldarg.0 + IL_0001: stloc.0 + IL_0002: ldloc.0 + IL_0003: ldlen + IL_0004: conv.i4 + IL_0005: newarr [runtime]System.Int64 + IL_000a: stloc.1 + IL_000b: ldc.i4.0 + IL_000c: stloc.2 + IL_000d: br.s IL_001b + + IL_000f: ldloc.1 + IL_0010: ldloc.2 + IL_0011: ldloc.0 + IL_0012: ldloc.2 + IL_0013: ldelem.i8 + IL_0014: stloc.3 + IL_0015: ldloc.3 + IL_0016: stelem.i8 + IL_0017: ldloc.2 + IL_0018: ldc.i4.1 + IL_0019: add + IL_001a: stloc.2 + IL_001b: ldloc.2 + IL_001c: ldloc.1 + IL_001d: ldlen + IL_001e: conv.i4 + IL_001f: blt.s IL_000f + + IL_0021: ldloc.1 + IL_0022: ret + } + + .method public static uint64[] '[|for x in uint64Array -> x|]'(uint64[] xs) cil managed + { + + .maxstack 6 + .locals init (uint64[] V_0, + uint64[] V_1, + int32 V_2, + uint64 V_3) + IL_0000: ldarg.0 + IL_0001: stloc.0 + IL_0002: ldloc.0 + IL_0003: ldlen + IL_0004: conv.i4 + IL_0005: newarr [runtime]System.UInt64 + IL_000a: stloc.1 + IL_000b: ldc.i4.0 + IL_000c: stloc.2 + IL_000d: br.s IL_001b + + IL_000f: ldloc.1 + IL_0010: ldloc.2 + IL_0011: ldloc.0 + IL_0012: ldloc.2 + IL_0013: ldelem.i8 + IL_0014: stloc.3 + IL_0015: ldloc.3 + IL_0016: stelem.i8 + IL_0017: ldloc.2 + IL_0018: ldc.i4.1 + IL_0019: add + IL_001a: stloc.2 + IL_001b: ldloc.2 + IL_001c: ldloc.1 + IL_001d: ldlen + IL_001e: conv.i4 + IL_001f: blt.s IL_000f + + IL_0021: ldloc.1 + IL_0022: ret + } + + .method public static native int[] '[|for x in nativeintArray -> x|]'(native int[] xs) cil managed + { + + .maxstack 6 + .locals init (native int[] V_0, + native int[] V_1, + int32 V_2, + native int V_3) + IL_0000: ldarg.0 + IL_0001: stloc.0 + IL_0002: ldloc.0 + IL_0003: ldlen + IL_0004: conv.i4 + IL_0005: newarr [runtime]System.IntPtr + IL_000a: stloc.1 + IL_000b: ldc.i4.0 + IL_000c: stloc.2 + IL_000d: br.s IL_001b + + IL_000f: ldloc.1 + IL_0010: ldloc.2 + IL_0011: ldloc.0 + IL_0012: ldloc.2 + IL_0013: ldelem.i + IL_0014: stloc.3 + IL_0015: ldloc.3 + IL_0016: stelem.i + IL_0017: ldloc.2 + IL_0018: ldc.i4.1 + IL_0019: add + IL_001a: stloc.2 + IL_001b: ldloc.2 + IL_001c: ldloc.1 + IL_001d: ldlen + IL_001e: conv.i4 + IL_001f: blt.s IL_000f + + IL_0021: ldloc.1 + IL_0022: ret + } + + .method public static native uint[] '[|for x in unativeintArray -> x|]'(native uint[] xs) cil managed + { + + .maxstack 6 + .locals init (native uint[] V_0, + native uint[] V_1, + int32 V_2, + native uint V_3) + IL_0000: ldarg.0 + IL_0001: stloc.0 + IL_0002: ldloc.0 + IL_0003: ldlen + IL_0004: conv.i4 + IL_0005: newarr [runtime]System.UIntPtr + IL_000a: stloc.1 + IL_000b: ldc.i4.0 + IL_000c: stloc.2 + IL_000d: br.s IL_001b + + IL_000f: ldloc.1 + IL_0010: ldloc.2 + IL_0011: ldloc.0 + IL_0012: ldloc.2 + IL_0013: ldelem.i + IL_0014: stloc.3 + IL_0015: ldloc.3 + IL_0016: stelem.i + IL_0017: ldloc.2 + IL_0018: ldc.i4.1 + IL_0019: add + IL_001a: stloc.2 + IL_001b: ldloc.2 + IL_001c: ldloc.1 + IL_001d: ldlen + IL_001e: conv.i4 + IL_001f: blt.s IL_000f + + IL_0021: ldloc.1 + IL_0022: ret + } + + .method public static float64[] '[|for x in floatArray -> x|]'(float64[] xs) cil managed + { + + .maxstack 6 + .locals init (float64[] V_0, + float64[] V_1, + int32 V_2, + float64 V_3) + IL_0000: ldarg.0 + IL_0001: stloc.0 + IL_0002: ldloc.0 + IL_0003: ldlen + IL_0004: conv.i4 + IL_0005: newarr [runtime]System.Double + IL_000a: stloc.1 + IL_000b: ldc.i4.0 + IL_000c: stloc.2 + IL_000d: br.s IL_001b + + IL_000f: ldloc.1 + IL_0010: ldloc.2 + IL_0011: ldloc.0 + IL_0012: ldloc.2 + IL_0013: ldelem.r8 + IL_0014: stloc.3 + IL_0015: ldloc.3 + IL_0016: stelem.r8 + IL_0017: ldloc.2 + IL_0018: ldc.i4.1 + IL_0019: add + IL_001a: stloc.2 + IL_001b: ldloc.2 + IL_001c: ldloc.1 + IL_001d: ldlen + IL_001e: conv.i4 + IL_001f: blt.s IL_000f + + IL_0021: ldloc.1 + IL_0022: ret + } + + .method public static float32[] '[|for x in float32Array -> x|]'(float32[] xs) cil managed + { + + .maxstack 6 + .locals init (float32[] V_0, + float32[] V_1, + int32 V_2, + float32 V_3) + IL_0000: ldarg.0 + IL_0001: stloc.0 + IL_0002: ldloc.0 + IL_0003: ldlen + IL_0004: conv.i4 + IL_0005: newarr [runtime]System.Single + IL_000a: stloc.1 + IL_000b: ldc.i4.0 + IL_000c: stloc.2 + IL_000d: br.s IL_001b + + IL_000f: ldloc.1 + IL_0010: ldloc.2 + IL_0011: ldloc.0 + IL_0012: ldloc.2 + IL_0013: ldelem.r4 + IL_0014: stloc.3 + IL_0015: ldloc.3 + IL_0016: stelem.r4 + IL_0017: ldloc.2 + IL_0018: ldc.i4.1 + IL_0019: add + IL_001a: stloc.2 + IL_001b: ldloc.2 + IL_001c: ldloc.1 + IL_001d: ldlen + IL_001e: conv.i4 + IL_001f: blt.s IL_000f + + IL_0021: ldloc.1 + IL_0022: ret + } + } .class private abstract auto ansi sealed ''.$assembly