Skip to content

Commit a9037f4

Browse files
Use alternative way of ignoring measures when detecting integral types (#17040)
* Use alternative way of ignoring measures * Use `typeEquivAux EraseMeasures` instead of calling `stripMeasuresFromTy` and passing the result into `typeEquiv` when determining whether the range operator's type argument is an integral type. I would have expected the outcome to be the same for both approaches, but that appears not always to be the case (though it often is). * Update release notes * Typo
1 parent b4bf40c commit a9037f4

File tree

8 files changed

+1430
-30
lines changed

8 files changed

+1430
-30
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
### Fixed
22

33
Various parenthesization API fixes. ([PR #16977](https://github.com/dotnet/fsharp/pull/16977))
4+
* Fix bug in optimization of for-loops over integral ranges with steps and units of measure. ([Issue #17025](https://github.com/dotnet/fsharp/issues/17025), [PR #17040](https://github.com/dotnet/fsharp/pull/17040))

src/Compiler/TypedTree/TypedTreeOps.fs

Lines changed: 28 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -7417,39 +7417,37 @@ let mkTwo g m = mkInt g m 2
74177417
let mkMinusOne g m = mkInt g m -1
74187418

74197419
let mkTypedZero g m ty =
7420-
let underlyingTy = stripMeasuresFromTy g ty
7421-
if typeEquiv g underlyingTy g.int32_ty then Expr.Const (Const.Int32 0, m, ty)
7422-
elif typeEquiv g underlyingTy g.int64_ty then Expr.Const (Const.Int64 0L, m, ty)
7423-
elif typeEquiv g underlyingTy g.uint64_ty then Expr.Const (Const.UInt64 0UL, m, ty)
7424-
elif typeEquiv g underlyingTy g.uint32_ty then Expr.Const (Const.UInt32 0u, m, ty)
7425-
elif typeEquiv g underlyingTy g.nativeint_ty then Expr.Const (Const.IntPtr 0L, m, ty)
7426-
elif typeEquiv g underlyingTy g.unativeint_ty then Expr.Const (Const.UIntPtr 0UL, m, ty)
7427-
elif typeEquiv g underlyingTy g.int16_ty then Expr.Const (Const.Int16 0s, m, ty)
7428-
elif typeEquiv g underlyingTy g.uint16_ty then Expr.Const (Const.UInt16 0us, m, ty)
7429-
elif typeEquiv g underlyingTy g.sbyte_ty then Expr.Const (Const.SByte 0y, m, ty)
7430-
elif typeEquiv g underlyingTy g.byte_ty then Expr.Const (Const.Byte 0uy, m, ty)
7431-
elif typeEquiv g underlyingTy g.char_ty then Expr.Const (Const.Char '\000', m, ty)
7432-
elif typeEquiv g underlyingTy g.float32_ty then Expr.Const (Const.Single 0.0f, m, ty)
7433-
elif typeEquiv g underlyingTy g.float_ty then Expr.Const (Const.Double 0.0, m, ty)
7434-
elif typeEquiv g underlyingTy g.decimal_ty then Expr.Const (Const.Decimal 0m, m, ty)
7420+
if typeEquivAux EraseMeasures g ty g.int32_ty then Expr.Const (Const.Int32 0, m, ty)
7421+
elif typeEquivAux EraseMeasures g ty g.int64_ty then Expr.Const (Const.Int64 0L, m, ty)
7422+
elif typeEquivAux EraseMeasures g ty g.uint64_ty then Expr.Const (Const.UInt64 0UL, m, ty)
7423+
elif typeEquivAux EraseMeasures g ty g.uint32_ty then Expr.Const (Const.UInt32 0u, m, ty)
7424+
elif typeEquivAux EraseMeasures g ty g.nativeint_ty then Expr.Const (Const.IntPtr 0L, m, ty)
7425+
elif typeEquivAux EraseMeasures g ty g.unativeint_ty then Expr.Const (Const.UIntPtr 0UL, m, ty)
7426+
elif typeEquivAux EraseMeasures g ty g.int16_ty then Expr.Const (Const.Int16 0s, m, ty)
7427+
elif typeEquivAux EraseMeasures g ty g.uint16_ty then Expr.Const (Const.UInt16 0us, m, ty)
7428+
elif typeEquivAux EraseMeasures g ty g.sbyte_ty then Expr.Const (Const.SByte 0y, m, ty)
7429+
elif typeEquivAux EraseMeasures g ty g.byte_ty then Expr.Const (Const.Byte 0uy, m, ty)
7430+
elif typeEquivAux EraseMeasures g ty g.char_ty then Expr.Const (Const.Char '\000', m, ty)
7431+
elif typeEquivAux EraseMeasures g ty g.float32_ty then Expr.Const (Const.Single 0.0f, m, ty)
7432+
elif typeEquivAux EraseMeasures g ty g.float_ty then Expr.Const (Const.Double 0.0, m, ty)
7433+
elif typeEquivAux EraseMeasures g ty g.decimal_ty then Expr.Const (Const.Decimal 0m, m, ty)
74357434
else error (InternalError ($"Unrecognized numeric type '{ty}'.", m))
74367435

74377436
let mkTypedOne g m ty =
7438-
let underlyingTy = stripMeasuresFromTy g ty
7439-
if typeEquiv g underlyingTy g.int32_ty then Expr.Const (Const.Int32 1, m, ty)
7440-
elif typeEquiv g underlyingTy g.int64_ty then Expr.Const (Const.Int64 1L, m, ty)
7441-
elif typeEquiv g underlyingTy g.uint64_ty then Expr.Const (Const.UInt64 1UL, m, ty)
7442-
elif typeEquiv g underlyingTy g.uint32_ty then Expr.Const (Const.UInt32 1u, m, ty)
7443-
elif typeEquiv g underlyingTy g.nativeint_ty then Expr.Const (Const.IntPtr 1L, m, ty)
7444-
elif typeEquiv g underlyingTy g.unativeint_ty then Expr.Const (Const.UIntPtr 1UL, m, ty)
7445-
elif typeEquiv g underlyingTy g.int16_ty then Expr.Const (Const.Int16 1s, m, ty)
7446-
elif typeEquiv g underlyingTy g.uint16_ty then Expr.Const (Const.UInt16 1us, m, ty)
7447-
elif typeEquiv g underlyingTy g.sbyte_ty then Expr.Const (Const.SByte 1y, m, ty)
7448-
elif typeEquiv g underlyingTy g.byte_ty then Expr.Const (Const.Byte 1uy, m, ty)
7449-
elif typeEquiv g underlyingTy g.char_ty then Expr.Const (Const.Char '\001', m, ty)
7450-
elif typeEquiv g underlyingTy g.float32_ty then Expr.Const (Const.Single 1.0f, m, ty)
7451-
elif typeEquiv g underlyingTy g.float_ty then Expr.Const (Const.Double 1.0, m, ty)
7452-
elif typeEquiv g underlyingTy g.decimal_ty then Expr.Const (Const.Decimal 1m, m, ty)
7437+
if typeEquivAux EraseMeasures g ty g.int32_ty then Expr.Const (Const.Int32 1, m, ty)
7438+
elif typeEquivAux EraseMeasures g ty g.int64_ty then Expr.Const (Const.Int64 1L, m, ty)
7439+
elif typeEquivAux EraseMeasures g ty g.uint64_ty then Expr.Const (Const.UInt64 1UL, m, ty)
7440+
elif typeEquivAux EraseMeasures g ty g.uint32_ty then Expr.Const (Const.UInt32 1u, m, ty)
7441+
elif typeEquivAux EraseMeasures g ty g.nativeint_ty then Expr.Const (Const.IntPtr 1L, m, ty)
7442+
elif typeEquivAux EraseMeasures g ty g.unativeint_ty then Expr.Const (Const.UIntPtr 1UL, m, ty)
7443+
elif typeEquivAux EraseMeasures g ty g.int16_ty then Expr.Const (Const.Int16 1s, m, ty)
7444+
elif typeEquivAux EraseMeasures g ty g.uint16_ty then Expr.Const (Const.UInt16 1us, m, ty)
7445+
elif typeEquivAux EraseMeasures g ty g.sbyte_ty then Expr.Const (Const.SByte 1y, m, ty)
7446+
elif typeEquivAux EraseMeasures g ty g.byte_ty then Expr.Const (Const.Byte 1uy, m, ty)
7447+
elif typeEquivAux EraseMeasures g ty g.char_ty then Expr.Const (Const.Char '\001', m, ty)
7448+
elif typeEquivAux EraseMeasures g ty g.float32_ty then Expr.Const (Const.Single 1.0f, m, ty)
7449+
elif typeEquivAux EraseMeasures g ty g.float_ty then Expr.Const (Const.Double 1.0, m, ty)
7450+
elif typeEquivAux EraseMeasures g ty g.decimal_ty then Expr.Const (Const.Decimal 1m, m, ty)
74537451
else error (InternalError ($"Unrecognized numeric type '{ty}'.", m))
74547452

74557453
let destInt32 = function Expr.Const (Const.Int32 n, _, _) -> Some n | _ -> None
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
open FSharp.Data.UnitSystems.SI.UnitSymbols
2+
3+
let mutable c = 0L<m>
4+
5+
let f1 () =
6+
for n in 10L<m>..1L<m>..1L<m> do
7+
c <- n
8+
9+
let f2 () =
10+
for n in 1L<m>..1L<m>..10L<m> do
11+
c <- n
12+
13+
let f3 () =
14+
for n in 1L<m>..2L<m>..10L<m> do
15+
c <- n
16+
17+
let f4 start =
18+
for n in start..2L<m>..10L<m> do
19+
c <- n
20+
21+
let f5 step =
22+
for n in 1L<m>..step..10L<m> do
23+
c <- n
24+
25+
let f6 finish =
26+
for n in 1L<m>..2L<m>..finish do
27+
c <- n
28+
29+
let f7 start step finish =
30+
for n in start..step..finish do
31+
c <- n
32+
33+
let f8 start finish =
34+
for n in start..0L<m>..finish do
35+
c <- n
36+
37+
let f9 () =
38+
for n in 1L<m>..0L<m>..10L<m> do
39+
c <- n
40+
41+
let f10 () =
42+
for n in 10L<m> .. -1L<m>..1L<m> do
43+
c <- n
44+
45+
let f11 () =
46+
for n in 10L<m> .. -2L<m>..1L<m> do
47+
c <- n

0 commit comments

Comments
 (0)