
[Git][ghc/ghc][master] Fix bytecode generation for `tagToEnum# <LITERAL>`
by Marge Bot (@marge-bot) 20 Apr '25
by Marge Bot (@marge-bot) 20 Apr '25
20 Apr '25
Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC
Commits:
a00eeaec by Matthew Craven at 2025-04-20T10:55:03-04:00
Fix bytecode generation for `tagToEnum# <LITERAL>`
Fixes #25975.
- - - - -
4 changed files:
- compiler/GHC/StgToByteCode.hs
- + testsuite/tests/bytecode/T25975.hs
- + testsuite/tests/bytecode/T25975.stdout
- testsuite/tests/bytecode/all.T
Changes:
=====================================
compiler/GHC/StgToByteCode.hs
=====================================
@@ -1801,10 +1801,14 @@ maybe_getCCallReturnRep fn_ty
_ -> pprPanic "maybe_getCCallReturn: can't handle:"
(pprType fn_ty)
-maybe_is_tagToEnum_call :: CgStgExpr -> Maybe (Id, [Name])
+maybe_is_tagToEnum_call :: CgStgExpr -> Maybe (StgArg, [Name])
-- Detect and extract relevant info for the tagToEnum kludge.
-maybe_is_tagToEnum_call (StgOpApp (StgPrimOp TagToEnumOp) [StgVarArg v] t)
+maybe_is_tagToEnum_call (StgOpApp (StgPrimOp TagToEnumOp) args t)
+ | [v] <- args
= Just (v, extract_constr_Names t)
+ | otherwise
+ = pprPanic "StgToByteCode: tagToEnum#"
+ $ text "Expected exactly one arg, but actual args are:" <+> ppr args
where
extract_constr_Names ty
| rep_ty <- unwrapType ty
@@ -1851,13 +1855,13 @@ implement_tagToId
:: StackDepth
-> Sequel
-> BCEnv
- -> Id
+ -> StgArg
-> [Name]
-> BcM BCInstrList
-- See Note [Implementing tagToEnum#]
implement_tagToId d s p arg names
= assert (notNull names) $
- do (push_arg, arg_bytes) <- pushAtom d p (StgVarArg arg)
+ do (push_arg, arg_bytes) <- pushAtom d p arg
labels <- getLabelsBc (strictGenericLength names)
label_fail <- getLabelBc
label_exit <- getLabelBc
=====================================
testsuite/tests/bytecode/T25975.hs
=====================================
@@ -0,0 +1,27 @@
+-- Tests bytecode generation for tagToEnum# applied to literals
+{-# LANGUAGE MagicHash #-}
+module Main (main) where
+
+import GHC.Exts
+
+f1 :: Int# -> Bool
+{-# OPAQUE f1 #-}
+f1 v = case v of
+ 4# -> tagToEnum# v
+ _ -> False
+
+f2 :: Int# -> Bool
+{-# OPAQUE f2 #-}
+f2 v = case v of
+ 5# -> tagToEnum# 6#
+ _ -> True
+
+f3 :: Ordering
+f3 = tagToEnum# (noinline runRW# (\_ -> 1#))
+
+
+main :: IO ()
+main = do
+ print $ f1 2#
+ print $ f2 3#
+ print f3
=====================================
testsuite/tests/bytecode/T25975.stdout
=====================================
@@ -0,0 +1,3 @@
+False
+True
+EQ
=====================================
testsuite/tests/bytecode/all.T
=====================================
@@ -1,3 +1,7 @@
ghci_dump_bcos = [only_ways(['ghci']), extra_run_opts('-dno-typeable-binds -dsuppress-uniques -ddump-bcos')]
test('T23068', ghci_dump_bcos + [filter_stdout_lines(r'.*bitmap: .*')], ghci_script, ['T23068.script'])
+
+test('T25975', extra_ways(ghci_ways), compile_and_run,
+ # Some of the examples work more robustly with these flags
+ ['-fno-break-points -fno-full-laziness'])
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a00eeaec8f0b98ec2b8c4630f359fde…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a00eeaec8f0b98ec2b8c4630f359fde…
You're receiving this email because of your account on gitlab.haskell.org.
1
0

[Git][ghc/ghc][master] 3 commits: Fix specialisation of incoherent instances (fixes #25883)
by Marge Bot (@marge-bot) 20 Apr '25
by Marge Bot (@marge-bot) 20 Apr '25
20 Apr '25
Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC
Commits:
6caa6508 by Adam Gundry at 2025-04-20T10:54:22-04:00
Fix specialisation of incoherent instances (fixes #25883)
GHC normally assumes that class constraints are canonical, meaning that
the specialiser is allowed to replace one dictionary argument with another
provided that they have the same type. The `-fno-specialise-incoherents`
flag alters INCOHERENT instance definitions so that they will prevent
specialisation in some cases, by inserting `nospec`.
This commit fixes a bug in 7124e4ad76d98f1fc246ada4fd7bf64413ff2f2e, which
treated some INCOHERENT instance matches as if `-fno-specialise-incoherents`
was in effect, thereby unnecessarily preventing specialisation. In addition
it updates the relevant `Note [Rules for instance lookup]` and adds a new
`Note [Canonicity for incoherent matches]`.
- - - - -
0426fd6c by Adam Gundry at 2025-04-20T10:54:23-04:00
Add regression test for #23429
- - - - -
eec96527 by Adam Gundry at 2025-04-20T10:54:23-04:00
user's guide: update specification of overlapping/incoherent instances
The description of the instance resolution algorithm in the user's
guide was slightly out of date, because it mentioned in-scope given
constraints only at the end, whereas the implementation checks for
their presence before any of the other steps.
This also adds a warning to the user's guide about the impact of
incoherent instances on specialisation, and more clearly documents
some of the other effects of `-XIncoherentInstances`.
- - - - -
16 changed files:
- compiler/GHC/Core/InstEnv.hs
- compiler/GHC/Tc/Solver/Dict.hs
- docs/users_guide/exts/instances.rst
- + testsuite/tests/simplCore/should_compile/T25883.hs
- + testsuite/tests/simplCore/should_compile/T25883.substr-simpl
- + testsuite/tests/simplCore/should_compile/T25883b.hs
- + testsuite/tests/simplCore/should_compile/T25883b.substr-simpl
- + testsuite/tests/simplCore/should_compile/T25883c.hs
- + testsuite/tests/simplCore/should_compile/T25883c.substr-simpl
- + testsuite/tests/simplCore/should_compile/T25883d.hs
- + testsuite/tests/simplCore/should_compile/T25883d.stderr
- + testsuite/tests/simplCore/should_compile/T25883d_import.hs
- testsuite/tests/simplCore/should_compile/all.T
- + testsuite/tests/simplCore/should_run/T23429.hs
- + testsuite/tests/simplCore/should_run/T23429.stdout
- testsuite/tests/simplCore/should_run/all.T
Changes:
=====================================
compiler/GHC/Core/InstEnv.hs
=====================================
@@ -599,7 +599,7 @@ These functions implement the carefully-written rules in the user
manual section on "overlapping instances". At risk of duplication,
here are the rules. If the rules change, change this text and the
user manual simultaneously. The link may be this:
-http://www.haskell.org/ghc/docs/latest/html/users_guide/glasgow_exts.html#instance-overlap
+https://downloads.haskell.org/ghc/latest/docs/users_guide/exts/instances.html#instance-overlap
The willingness to be overlapped or incoherent is a property of the
instance declaration itself, controlled by its `OverlapMode`, as follows
@@ -627,14 +627,22 @@ of the target constraint (C ty1 .. tyn). The search works like this.
(IL0) If there are any local Givens that match (potentially unifying
any metavariables, even untouchable ones) the target constraint,
- the search fails. See Note [Instance and Given overlap] in
- GHC.Tc.Solver.Dict.
-
-(IL1) Find all instances `I` that *match* the target constraint; that is, the target
- constraint is a substitution instance of `I`. These instance declarations are
- the /candidates/.
-
-(IL2) If there are no candidates, the search fails.
+ the search fails unless -XIncoherentInstances is enabled. See
+ Note [Instance and Given overlap] in GHC.Tc.Solver.Dict. This is
+ implemented by the first guard in matchClassInst.
+
+(IL1) Find `all_matches` and `all_unifs` in `lookupInstEnv`:
+ - all_matches: all instances `I` that *match* the target constraint (that
+ is, the target constraint is a substitution instance of `I`). These
+ instance declarations are the /candidates/.
+ - all_unifs: all non-incoherent instances that *unify with but do not match*
+ the target constraint. These are not candidates, but might match later if
+ the target constraint is furhter instantiated. See
+ `data PotentialUnifiers` for more precise details.
+
+(IL2) If there are no candidates, the search fails
+ (lookupInstEnv returns no final_matches). The PotentialUnifiers are returned
+ by lookupInstEnv for use in error message generation (mkDictErr).
(IL3) Eliminate any candidate `IX` for which there is another candidate `IY` such
that both of the following hold:
@@ -644,29 +652,39 @@ of the target constraint (C ty1 .. tyn). The search works like this.
"either/or" design, rather than a "both/and" design, allow a
client to deliberately override an instance from a library,
without requiring a change to the library.)
- This is done by `pruneOverlappingMatches`
-(IL4) If all the remaining candidates are *incoherent*, the search succeeds,
- returning an arbitrary surviving candidate.
+ In addition, provided there is at least one candidate, eliminate any other
+ candidates that are *incoherent*. (In particular, if all remaining candidates
+ are incoherent, all except an arbitrarily chosen one will be eliminated.)
+
+ This is implemented by `pruneOverlappedMatches`, producing final_matches in
+ lookupInstEnv. See Note [Instance overlap and guards] and
+ Note [Incoherent instances].
+
+(IL4) If exactly one *incoherent* candidate remains, the search succeeds.
+ (By the previous step, there cannot be more than one incoherent candidate
+ remaining.)
- If any coherent or non-canonical incoherent unifiers were discarded,
- return NoUnifiers EvNonCanonical; if only canonical incoherent unifiers
- were discarded, return NoUnifiers EvCanonical
+ In this case, lookupInstEnv returns the successful match, and it returns
+ NoUnifiers as the final_unifs, which amounts to skipping the following
+ steps.
-(IL5) If more than one non-*incoherent* candidate remains, the search
- fails. Otherwise there is exactly one non-*incoherent*
- candidate; call it the "prime candidate".
+(IL5) If more than one candidate remains, the search fails. (We have already
+ eliminated the incoherent candidates, and we have no way to select
+ between non-incoherent candidates.)
-(IL6) Now find all instances that unify with the target constraint,
- but do not match it. Such non-candidate instances might match
- when the target constraint is further instantiated.
+(IL6) Otherwise there is exactly one candidate remaining. The all_unifs
+ computed at step (IL1) are returned from lookupInstEnv as final_unifs.
- If any are *coherent* (not incoherent) return them
- as PotentialUnifiers.
+ If there are no potential unifiers, the search succeeds (in matchInstEnv).
+ If there is at least one (non-incoherent) potential unifier, matchInstEnv
+ returns a NotSure result and refrains from committing to the instance.
+
+ Incoherent instances are not returned as part of the potential unifiers. This
+ affects error messages: they will not be listed as "potentially matching instances"
+ in an "Overlapping instances" or "Ambiguous type variable" error.
+ See also Note [Recording coherence information in `PotentialUnifiers`].
- If all are *incoherent* (OverlapFlag = Incoherent or NonCanonical)
- return (NoUnifiers nc), where nc is EvNonCanonical if any of the discarded
- unifiers are NonCanonical.
Notice that these rules are not influenced by flag settings in the
client module, where the instances are *used*. These rules make it
@@ -894,8 +912,8 @@ instances, i.e. with `-fno-specialise-incoherents`.
To avoid this incoherence breaking the specialiser,
-* We label as "non-canonical" the dictionary constructed by a (potentially)
- incoherent use of an ClsInst whose `OverlapFlag` is `NonCanonical`.
+* We label as "non-canonical" any dictionary constructed by a (potentially)
+ incoherent use of an ClsInst.
* We do not specialise a function if there is a non-canonical
dictionary in the /transistive dependencies/ of its dictionary
@@ -922,7 +940,9 @@ So `d2` is incoherent, and hence (transitively) so is `d1`.
Here are the moving parts:
* GHC.Core.InstEnv.lookupInstEnv tells if any incoherent unifiers were discarded
- in step (IL6) of the instance lookup.
+ in step (IL4) or (IL6) of the instance lookup: see
+ Note [Recording coherence information in `PotentialUnifiers`] and
+ Note [Canonicity for incoherent matches].
* That info is recorded in the `cir_is_coherent` field of `OneInst`, and thence
transferred to the `ep_is_coherent` field of the `EvBind` for the dictionary.
@@ -930,6 +950,47 @@ Here are the moving parts:
* In the desugarer we exploit this info:
see Note [Desugaring non-canonical evidence] in GHC.HsToCore.Expr.
See also Note [nospecId magic] in GHC.Types.Id.Make.
+
+
+Note [Canonicity for incoherent matches]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+When the selected instance is INCOHERENT at step (IL4) of
+Note [Rules for instance lookup], we ignore all unifiers,
+whether or not they are marked with INCOHERENT pragmas.
+This is implemented by returning NoUnifiers in final_unifs.
+NoUnifiers takes an argument indicating whether the match was canonical
+as described in Note [Coherence and specialisation: overview] and
+Note [Recording coherence information in `PotentialUnifiers`].
+
+To determine whether an incoherent match was canonical, we look *only*
+at the OverlapFlag of the instance being matched. For example:
+
+ class C a
+ instance {-# INCOHERENT #-} C a -- (1)
+ instance C Int -- (2)
+
+ [W] C tau
+
+Here we match instance (1) and discard instance (2). If (1) is Incoherent
+(under -fspecialise-incoherents), it is important that we treat the match
+as EvCanonical so that we do not block specialisation (see #25883).
+
+What about the following situation:
+
+ instance {-# INCOHERENT #-} C a -- (1), in a module with -fspecialise-incoherents (Incoherent)
+ instance {-# INCOHERENT #-} C Int -- (2), in a module with -fno-specialise-incoherents (NonCanonical)
+
+ [W] C tau
+
+Again we match instance (1) and discard instance (2). It is not obvious
+whether Incoherent or NonCanonical should "win" here, but it seems more
+consistent with the previous example to look only at the flag on instance (1).
+
+What about if the only instance that can match is marked as NonCanonical?
+In this case are no unifiers at all, so all_unifs = NoUnifiers EvCanonical.
+It is not obvious what -fno-specialise-incoherents should do here, but
+currently it returns NoUnifiers EvCanonical.
+
-}
type DFunInstType = Maybe Type
@@ -1070,8 +1131,8 @@ data PotentialUnifiers
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
When we find a matching instance, there might be other instances that
could potentially unify with the goal. For `INCOHERENT` instances, we
-don't care (see steps IL4 and IL6 in Note [Rules for instance
-lookup]). But if we have potentially unifying coherent instance, we
+don't care (see step (IL6) in Note [Rules for instance lookup]).
+But if we have potentially unifying coherent instance, we
report these `OneOrMoreUnifiers` so that `matchInstEnv` can go down
the `NotSure` route.
@@ -1081,6 +1142,21 @@ solution is canonical or not (see Note [Coherence and specialisation:
overview] for why we care at all). So when the set of potential
unifiers is empty, we record in `NoUnifiers` if the one solution is
`Canonical`.
+
+For example, suppose we have:
+
+ class C x y
+ instance C a Bool -- (1)
+ instance {-# INCOHERENT #-} C Int a -- (2)
+
+ [W] C x Bool
+
+Here instance (1) matches the Wanted, and since instance (2) is INCOHERENT
+we want to succeed with the match rather than getting stick at step (IL6).
+But if -fno-specialise-incoherents was enabled for (2), the specialiser is
+not permitted to specialise this dictionary later, so lookupInstEnv reports
+the PotentialUnifiers as NoUnifiers EvNonCanonical.
+
-}
instance Outputable CanonicalEvidence where
@@ -1101,10 +1177,18 @@ getCoherentUnifiers :: PotentialUnifiers -> [ClsInst]
getCoherentUnifiers NoUnifiers{} = []
getCoherentUnifiers (OneOrMoreUnifiers cls) = NE.toList cls
+-- | Are there no *coherent* unifiers?
nullUnifiers :: PotentialUnifiers -> Bool
nullUnifiers NoUnifiers{} = True
nullUnifiers _ = False
+-- | Are there any unifiers, ignoring those marked Incoherent (but including any
+-- marked NonCanonical)?
+someUnifiers :: PotentialUnifiers -> Bool
+someUnifiers (NoUnifiers EvCanonical) = False
+someUnifiers _ = True
+
+
instEnvMatchesAndUnifiers
:: InstEnv -- InstEnv to look in
-> VisibleOrphanModules -- But filter against this
@@ -1209,10 +1293,13 @@ lookupInstEnv check_overlap_safe
tys
= (final_matches, final_unifs, unsafe_overlapped)
where
+ -- (IL1): Find all instances that match the target constraint
(home_matches, home_unifs) = instEnvMatchesAndUnifiers home_ie vis_mods cls tys
(pkg_matches, pkg_unifs) = instEnvMatchesAndUnifiers pkg_ie vis_mods cls tys
all_matches = home_matches <> pkg_matches
all_unifs = home_unifs <> pkg_unifs
+
+ -- (IL3): Eliminate candidates that are overlapped or incoherent
final_matches = pruneOverlappedMatches all_matches
-- Even if the unifs is non-empty (an error situation)
-- we still prune the matches, so that the error message isn't
@@ -1230,10 +1317,13 @@ lookupInstEnv check_overlap_safe
(m:ms) | isIncoherent (fst m)
-- Incoherent match, so discard all unifiers, but
-- keep track of dropping coherent or non-canonical ones
+ -- if the match is non-canonical.
+ -- See Note [Canonicity for incoherent matches]
-> assertPpr (null ms) (ppr final_matches) $
- case all_unifs of
- OneOrMoreUnifiers{} -> NoUnifiers EvNonCanonical
- NoUnifiers{} -> all_unifs
+ NoUnifiers $
+ if isNonCanonical (fst m) && someUnifiers all_unifs
+ then EvNonCanonical
+ else EvCanonical
_ -> all_unifs
-- Note [Safe Haskell isSafeOverlap]
=====================================
compiler/GHC/Tc/Solver/Dict.hs
=====================================
@@ -926,7 +926,8 @@ matchClassInst dflags inerts clas tys loc
-- First check whether there is an in-scope Given that could
-- match this constraint. In that case, do not use any instance
-- whether top level, or local quantified constraints.
--- See Note [Instance and Given overlap]
+-- See Note [Instance and Given overlap] and see
+-- (IL0) in Note [Rules for instance lookup] in GHC.Core.InstEnv
| not (xopt LangExt.IncoherentInstances dflags)
, not (isCTupleClass clas)
-- It is always safe to unpack constraint tuples
=====================================
docs/users_guide/exts/instances.rst
=====================================
@@ -417,7 +417,7 @@ Overlapping instances
:status: Deprecated
Deprecated extension to weaken checks intended to ensure instance resolution
- termination.
+ termination. Use ``OVERLAPPING``, ``OVERLAPPABLE`` or ``OVERLAPS`` pragmas instead.
.. extension:: IncoherentInstances
:shortdesc: Allow definitions of instances that may result in incoherence.
@@ -429,7 +429,9 @@ Overlapping instances
:status: Deprecated
Deprecated extension to weaken checks intended to ensure instance resolution
- termination.
+ termination. Use ``INCOHERENT`` pragmas instead. Also permits classes to
+ have non-nominal roles, and affects the instance resolution algorithm for
+ in-scope given constraints.
In general, as discussed in :ref:`instance-resolution`, *GHC requires
that it be unambiguous which instance declaration should be used to
@@ -473,11 +475,15 @@ Now suppose that, in some client module, we are searching for an
instance of the *target constraint* ``(C ty1 .. tyn)``. The search works
like this:
+- If there are any in-scope given constraints that might match the target
+ constraint (after unifying any metavariables), and
+ :extension:`IncoherentInstances` is not enabled, the search fails.
+
- Find all instances :math:`I` that *match* the target constraint; that is, the
target constraint is a substitution instance of :math:`I`. These instance
declarations are the *candidates*.
-- If no candidates remain, the search fails
+- If there are no candidates, the search fails.
- Eliminate any candidate :math:`IX` for which there is another candidate
:math:`IY` such that both of the following hold:
@@ -498,7 +504,7 @@ like this:
- Otherwise there is exactly one non-incoherent candidate; call it the
"prime candidate".
-- Now find all instances, or in-scope given constraints, that *unify* with
+- Now find all instances that *unify* with
the target constraint,
but do not *match* it. Such non-candidate instances might match when
the target constraint is further instantiated. If all of them are
@@ -596,8 +602,8 @@ declaration, thus: ::
(You need :extension:`FlexibleContexts` to do this.)
-In the unification check in the final bullet, GHC also uses the
-"in-scope given constraints". Consider for example ::
+As an example of the "in-scope given constraints" in the first bullet,
+consider ::
instance C a Int
@@ -609,7 +615,7 @@ top-level instance, because a particular call of ``g`` might
instantiate both ``b`` and ``c`` to the same type, which would
allow the constraint to be solved in a different way. This latter
restriction is principally to make the constraint-solver complete.
-(Interested folk can read ``Note [Instance and Given overlap]`` in ``TcInteract``.)
+(Interested folk can read ``Note [Instance and Given overlap]`` in ``GHC.Tc.Solver.Dict``.)
It is easy to avoid: in a type signature avoid a constraint that
matches a top-level instance. The flag :ghc-flag:`-Wsimplifiable-class-constraints` warns about such signatures.
@@ -660,6 +666,22 @@ matches a top-level instance. The flag :ghc-flag:`-Wsimplifiable-class-constrai
to reject module ``Help`` on the grounds that a later instance
declaration might overlap the local one.)
+.. warning::
+ GHC's optimiser (in particular, the :ghc-flag:`-fspecialise` option)
+ assumes that type-classes are coherent, and hence it may replace
+ any type-class dictionary argument with another dictionary of the same
+ type.
+
+ This may cause unexpected results if incoherence occurs due to incoherent
+ or overlapping instances, and there is an observable difference between the
+ instances (see :ghc-ticket:`22448` and :ghc-ticket:`24924` for examples).
+
+ The :ghc-flag:`-fno-specialise-incoherents <-fspecialise-incoherents>` will
+ inhibit specialisation in the presence of some incoherent instance matches,
+ which may help avoid this issue at the cost of runtime performance.
+ Alternatively, specialisation can be disabled entirely with
+ :ghc-flag:`-fno-specialise <-fspecialise>`.
+
.. _instance-sigs:
Instance signatures: type signatures in instance declarations
=====================================
testsuite/tests/simplCore/should_compile/T25883.hs
=====================================
@@ -0,0 +1,20 @@
+-- By default -fspecialise-incoherents is in effect, so the call to m in f
+-- should get specialised even though there is another potential instance.
+
+{-# LANGUAGE UndecidableInstances #-}
+module T25833 (y) where
+
+class C a where
+ m :: a -> a
+
+instance {-# INCOHERENT #-} Num a => C a where
+ m = (* 3)
+
+instance C () where
+ m = id
+
+f :: Num a => a -> a
+f = m
+
+y :: Int
+y = f 2
=====================================
testsuite/tests/simplCore/should_compile/T25883.substr-simpl
=====================================
@@ -0,0 +1 @@
+y = I# 6#
\ No newline at end of file
=====================================
testsuite/tests/simplCore/should_compile/T25883b.hs
=====================================
@@ -0,0 +1,21 @@
+-- Under -fno-specialise-incoherents, the call to m in f should not be
+-- specialised, because there is another possible (though unused) instance.
+
+{-# OPTIONS_GHC -fno-specialise-incoherents #-}
+{-# LANGUAGE UndecidableInstances #-}
+module T25833b (y) where
+
+class C a where
+ m :: a -> a
+
+instance {-# INCOHERENT #-} Num a => C a where
+ m = (* 3)
+
+instance C () where
+ m = id
+
+f :: Num a => a -> a
+f = m
+
+y :: Int
+y = f 2
=====================================
testsuite/tests/simplCore/should_compile/T25883b.substr-simpl
=====================================
@@ -0,0 +1 @@
+y = nospec m
\ No newline at end of file
=====================================
testsuite/tests/simplCore/should_compile/T25883c.hs
=====================================
@@ -0,0 +1,18 @@
+-- Here -fno-specialise-incoherents is in effect, but f refers unambiguously to
+-- a single instance (because there are no others), so it should be specialised.
+
+{-# OPTIONS_GHC -fno-specialise-incoherents #-}
+{-# LANGUAGE UndecidableInstances #-}
+module T25833c (y) where
+
+class C a where
+ m :: a -> a
+
+instance {-# INCOHERENT #-} Num a => C a where
+ m = (* 3)
+
+f :: Num a => a -> a
+f = m
+
+y :: Int
+y = f 2
=====================================
testsuite/tests/simplCore/should_compile/T25883c.substr-simpl
=====================================
@@ -0,0 +1 @@
+y = I# 6#
\ No newline at end of file
=====================================
testsuite/tests/simplCore/should_compile/T25883d.hs
=====================================
@@ -0,0 +1,14 @@
+{-# OPTIONS_GHC -fno-specialise-incoherents #-}
+
+module T25883d (y) where
+
+import T25883d_import
+
+instance {-# INCOHERENT #-} C () where
+ m = id
+
+f :: Num a => a -> a
+f = m
+
+y :: Int
+y = f 2
\ No newline at end of file
=====================================
testsuite/tests/simplCore/should_compile/T25883d.stderr
=====================================
@@ -0,0 +1 @@
+y = I# 6#
=====================================
testsuite/tests/simplCore/should_compile/T25883d_import.hs
=====================================
@@ -0,0 +1,11 @@
+-- This module defines an instance with -fspecialise-incoherents in effect,
+-- then it will be imported by a module that uses -fno-specialise-incoherents.
+
+{-# LANGUAGE UndecidableInstances #-}
+module T25883d_import where
+
+class C a where
+ m :: a -> a
+
+instance {-# INCOHERENT #-} Num a => C a where
+ m = (* 3)
=====================================
testsuite/tests/simplCore/should_compile/all.T
=====================================
@@ -536,3 +536,8 @@ test('T25197', [req_th, extra_files(["T25197_TH.hs"]), only_ways(['optasm'])], m
test('T25389', normal, compile, ['-O -ddump-simpl -dsuppress-uniques -dno-typeable-binds'])
test('T24359a', normal, compile, ['-O -ddump-rules'])
test('T25713', [grep_errmsg('W:::')], compile, ['-O -ddump-simpl'])
+
+test('T25883', normal, compile_grep_core, [''])
+test('T25883b', normal, compile_grep_core, [''])
+test('T25883c', normal, compile_grep_core, [''])
+test('T25883d', [extra_files(['T25883d_import.hs'])], multimod_compile_filter, ['T25883d', '-O -ddump-simpl -dno-typeable-binds -dsuppress-all -dsuppress-uniques', r'grep -e "y ="'])
=====================================
testsuite/tests/simplCore/should_run/T23429.hs
=====================================
@@ -0,0 +1,39 @@
+{-# OPTIONS_GHC -fno-specialise-incoherents #-}
+{-# LANGUAGE MonoLocalBinds #-}
+class C a where
+ op :: a -> String
+
+instance {-# OVERLAPPABLE #-} C a where
+ op _ = "C a"
+ {-# NOINLINE op #-}
+
+instance {-# INCOHERENT #-} C (Maybe a) where
+ op _ = "C (Maybe a)"
+ {-# NOINLINE op #-}
+
+instance {-# INCOHERENT #-} C (Maybe ()) where
+ op _ = "C (Maybe ())"
+ {-# NOINLINE op #-}
+
+-- | Inhibit inlining, but keep specialize-ability
+large :: a -> a
+large x = x
+{-# NOINLINE large #-}
+
+bar :: C a => a -> String
+bar x = large (large (large (large (large (large (large (large (large (large (large (large (large (large (op x))))))))))))))
+
+gen :: a -> String -- No C a constraint, has to choose the incoherent generic instance
+gen = bar
+
+specMaybe :: Maybe a -> String -- C () constraint is resolved to the specialized instance for Maybe a
+specMaybe = bar
+
+specMaybeUnit :: Maybe () -> String -- C () constraint is resolved to the specialized instance for Maybe ()
+specMaybeUnit = bar
+
+main :: IO ()
+main = do
+ putStrLn $ "gen () == " <> gen (Just ())
+ putStrLn $ "specMaybe () == " <> specMaybe (Just ())
+ putStrLn $ "specMaybeUnit () == " <> specMaybeUnit (Just ())
=====================================
testsuite/tests/simplCore/should_run/T23429.stdout
=====================================
@@ -0,0 +1,3 @@
+gen () == C a
+specMaybe () == C (Maybe a)
+specMaybeUnit () == C (Maybe ())
=====================================
testsuite/tests/simplCore/should_run/all.T
=====================================
@@ -119,3 +119,4 @@ test('T24725', normal, compile_and_run, ['-O -dcore-lint'])
test('T25096', normal, compile_and_run, ['-O -dcore-lint'])
test('AppIsHNF', normal, compile_and_run, ['-O'])
test('T24359b', normal, compile_and_run, ['-O'])
+test('T23429', normal, compile_and_run, ['-O'])
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/e2f2f9d08274c90e775a35dc5b776f…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/e2f2f9d08274c90e775a35dc5b776f…
You're receiving this email because of your account on gitlab.haskell.org.
1
0

20 Apr '25
Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC
Commits:
e2f2f9d0 by Vladislav Zavialov at 2025-04-20T10:53:39-04:00
Add name for -Wunusable-unpack-pragmas
This warning had no name or flag and was triggered unconditionally.
Now it is part of -Wdefault.
In GHC.Tc.TyCl.tcTyClGroupsPass's strict mode, we now have to
force-enable this warning to ensure that detection of flawed groups
continues to work even if the user disables the warning with the
-Wno-unusable-unpack-pragmas option. Test case: T3990c
Also, the misnamed BackpackUnpackAbstractType is now called
UnusableUnpackPragma.
- - - - -
21 changed files:
- compiler/GHC/Driver/Flags.hs
- compiler/GHC/Driver/Session.hs
- compiler/GHC/Tc/Errors/Ppr.hs
- compiler/GHC/Tc/Errors/Types.hs
- compiler/GHC/Tc/TyCl.hs
- compiler/GHC/Tc/Utils/Monad.hs
- compiler/GHC/Types/Error/Codes.hs
- docs/users_guide/9.14.1-notes.rst
- docs/users_guide/using-warnings.rst
- testsuite/tests/simplCore/should_compile/Makefile
- testsuite/tests/simplCore/should_compile/T23307c.stderr
- + testsuite/tests/simplCore/should_compile/T3990c.hs
- + testsuite/tests/simplCore/should_compile/T3990c.stdout
- testsuite/tests/simplCore/should_compile/all.T
- testsuite/tests/simplCore/should_fail/T25672.stderr
- testsuite/tests/typecheck/should_compile/T7050.stderr
- testsuite/tests/typecheck/should_fail/T3966.stderr
- + testsuite/tests/typecheck/should_fail/T3966b.hs
- + testsuite/tests/typecheck/should_fail/T3966b.stderr
- testsuite/tests/typecheck/should_fail/all.T
- testsuite/tests/unboxedsums/unpack_sums_5.stderr
Changes:
=====================================
compiler/GHC/Driver/Flags.hs
=====================================
@@ -1098,6 +1098,7 @@ data WarningFlag =
-- ^ @since 9.14, scheduled to be removed in 9.18
--
-- See Note [Quantifying over equalities in RULES] in GHC.Tc.Gen.Sig
+ | Opt_WarnUnusableUnpackPragmas -- Since 9.14
deriving (Eq, Ord, Show, Enum, Bounded)
-- | Return the names of a WarningFlag
@@ -1217,6 +1218,7 @@ warnFlagNames wflag = case wflag of
Opt_WarnUselessSpecialisations -> "useless-specialisations" :| ["useless-specializations"]
Opt_WarnDeprecatedPragmas -> "deprecated-pragmas" :| []
Opt_WarnRuleLhsEqualities -> "rule-lhs-equalities" :| []
+ Opt_WarnUnusableUnpackPragmas -> "unusable-unpack-pragmas" :| []
-- -----------------------------------------------------------------------------
-- Standard sets of warning options
@@ -1362,7 +1364,8 @@ standardWarnings -- see Note [Documenting warning flags]
Opt_WarnViewPatternSignatures,
Opt_WarnUselessSpecialisations,
Opt_WarnDeprecatedPragmas,
- Opt_WarnRuleLhsEqualities
+ Opt_WarnRuleLhsEqualities,
+ Opt_WarnUnusableUnpackPragmas
]
-- | Things you get with @-W@.
=====================================
compiler/GHC/Driver/Session.hs
=====================================
@@ -2385,6 +2385,7 @@ wWarningFlagsDeps = [minBound..maxBound] >>= \x -> case x of
Opt_WarnUselessSpecialisations -> warnSpec x
Opt_WarnDeprecatedPragmas -> warnSpec x
Opt_WarnRuleLhsEqualities -> warnSpec x
+ Opt_WarnUnusableUnpackPragmas -> warnSpec x
warningGroupsDeps :: [(Deprecation, FlagSpec WarningGroup)]
warningGroupsDeps = map mk warningGroups
=====================================
compiler/GHC/Tc/Errors/Ppr.hs
=====================================
@@ -2521,6 +2521,8 @@ instance Diagnostic TcRnMessage where
-> WarningWithFlag Opt_WarnIncompleteRecordSelectors
TcRnBadFieldAnnotation _ _ LazyFieldsDisabled
-> ErrorWithoutFlag
+ TcRnBadFieldAnnotation _ _ UnusableUnpackPragma
+ -> WarningWithFlag Opt_WarnUnusableUnpackPragmas
TcRnBadFieldAnnotation{}
-> WarningWithoutFlag
TcRnSuperclassCycle{}
@@ -5814,7 +5816,7 @@ pprBadFieldAnnotationReason = \case
text "Lazy field annotations (~) are disabled"
UnpackWithoutStrictness ->
text "UNPACK pragma lacks '!'"
- BackpackUnpackAbstractType ->
+ UnusableUnpackPragma ->
text "Ignoring unusable UNPACK pragma"
pprSuperclassCycleDetail :: SuperclassCycleDetail -> SDoc
=====================================
compiler/GHC/Tc/Errors/Types.hs
=====================================
@@ -6275,13 +6275,28 @@ data BadFieldAnnotationReason where
T14761a, T7562
-}
UnpackWithoutStrictness :: BadFieldAnnotationReason
- {-| An UNPACK pragma was applied to an abstract type in an indefinite package
- in Backpack.
+ {-| An UNPACK pragma is unusable.
+
+ A possible reason for this warning is that the UNPACK pragma was applied to
+ one of the following:
+
+ * a function type @a -> b@
+ * a recursive use of the data type being defined
+ * a sum type that cannot be unpacked, see @Note [UNPACK for sum types]@
+ * a type/data family application with no matching instance in the environment
+
+ However, it is deliberately /not/ emitted if:
+
+ * the failure occurs in an indefinite package in Backpack
+ * the pragma is usable, but unpacking is disabled by @-O0@
Test cases:
- unpack_sums_5, T3966, T7050
+ unpack_sums_5, T3966, T7050, T25672, T23307c
+
+ Negative test cases (must not trigger this warning):
+ T3990
-}
- BackpackUnpackAbstractType :: BadFieldAnnotationReason
+ UnusableUnpackPragma :: BadFieldAnnotationReason
deriving (Generic)
data SuperclassCycle =
=====================================
compiler/GHC/Tc/TyCl.hs
=====================================
@@ -322,7 +322,7 @@ splice to separate the module and force the desired order of kind-checking:
data D1 = MkD1 !(F Int) -- now (F Int) surely gets unpacked
The current version of GHC is more predictable. Neither the (Complex Double) nor
-the (F Int) example gets unpacking, the type/data instance is put into a
+the (F Int) example gets unpacking unless the type/data instance is put into a
separate HsGroup, either with $(return []) or by placing it in another module
altogether. This is a direct result of placing instances after the other SCCs,
as described in Note [Put instances at the end] in GHC.Rename.Module
@@ -449,11 +449,20 @@ tcTyClGroupsPass all_gs thing_inside = go True ttcgs_zero mempty nilOL all_gs
-- pass, the current group's lexical dependencies must have been
-- satisfied by the preceding groups; no need for the ready check,
-- this avoids some lookups in tcg_env
+
+ -- See Note [Expedient use of diagnostics in tcTyClGroupsPass]
+ set_opts action
+ | strict = setWOptM Opt_WarnUnusableUnpackPragmas action
+ | otherwise = action
+ validate _ msgs _
+ | strict = not (unpackErrorsFound msgs)
+ | otherwise = True
+
if not ready then return on_blocked else
- tryTcDiscardingErrs' (\_ msgs _ -> not (strict && unpackErrorsFound msgs))
+ tryTcDiscardingErrs' validate
(return on_flawed)
(return on_failed)
- (on_success <$> tcTyClGroup g)
+ (on_success <$> set_opts (tcTyClGroup g))
data TcTyClGroupsStats =
TcTyClGroupsStats
@@ -479,15 +488,36 @@ instance Outputable TcTyClGroupsStats where
, text "n_failed =" <+> ppr (ttcgs_n_failed stats)
, text "n_flawed =" <+> ppr (ttcgs_n_flawed stats) ]
+-- See Note [Expedient use of diagnostics in tcTyClGroupsPass]
unpackErrorsFound :: Messages TcRnMessage -> Bool
unpackErrorsFound = any is_unpack_error
where
is_unpack_error :: TcRnMessage -> Bool
is_unpack_error (TcRnMessageWithInfo _ (TcRnMessageDetailed _ msg)) = is_unpack_error msg
is_unpack_error (TcRnWithHsDocContext _ msg) = is_unpack_error msg
- is_unpack_error (TcRnBadFieldAnnotation _ _ BackpackUnpackAbstractType) = True
+ is_unpack_error (TcRnBadFieldAnnotation _ _ UnusableUnpackPragma) = True
is_unpack_error _ = False
+{- Note [Expedient use of diagnostics in tcTyClGroupsPass]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+In tcTyClGroupsPass.go with strict=True, we want to skip "flawed" groups, i.e.
+groups with unusable unpack pragmas, as explained in Note [Retrying TyClGroups].
+To detect these unusable {-# UNPACK #-} pragmas, we currently piggy-back on the
+diagnostics infrastructure:
+
+ 1. (setWOptM Opt_WarnUnusableUnpackPragmas) to enable the warning.
+ The warning is on by default, but the user may have disabled it with
+ -Wno-unusable-unpack-pragmas, in which case we need to turn it back on.
+
+ 2. (unpackErrorsFound msgs) to check if UnusableUnpackPragma is one of the
+ collected diagnostics. This is somewhat unpleasant because of the need to
+ recurse into TcRnMessageWithInfo and TcRnWithHsDocContext.
+
+Arguably, this is not a principled solution, because diagnostics are meant for
+the user and here we inspect them to determine the order of type-checking. The
+only reason for the current setup is that it was the easy thing to do.
+-}
+
isReadyTyClGroup :: TcGblEnv -> TyClGroup GhcRn -> Bool
isReadyTyClGroup tcg_env TyClGroup{group_ext = deps} =
nameSetAll (\n -> n `elemNameEnv` tcg_type_env tcg_env) deps
@@ -5123,7 +5153,7 @@ checkValidDataCon dflags existential_ok tc con
-- warn in this case (it gives users the wrong idea about whether
-- or not UNPACK on abstract types is supported; it is!)
, isHomeUnitDefinite (hsc_home_unit hsc_env)
- = addDiagnosticTc (bad_bang n BackpackUnpackAbstractType)
+ = addDiagnosticTc (bad_bang n UnusableUnpackPragma)
| otherwise
= return ()
=====================================
compiler/GHC/Tc/Utils/Monad.hs
=====================================
@@ -20,7 +20,8 @@ module GHC.Tc.Utils.Monad(
updTopFlags,
getEnvs, setEnvs, updEnvs, restoreEnvs,
xoptM, doptM, goptM, woptM,
- setXOptM, unsetXOptM, unsetGOptM, unsetWOptM,
+ setXOptM, setWOptM,
+ unsetXOptM, unsetGOptM, unsetWOptM,
whenDOptM, whenGOptM, whenWOptM,
whenXOptM, unlessXOptM,
getGhcMode,
@@ -579,6 +580,9 @@ woptM flag = wopt flag <$> getDynFlags
setXOptM :: LangExt.Extension -> TcRnIf gbl lcl a -> TcRnIf gbl lcl a
setXOptM flag = updTopFlags (\dflags -> xopt_set dflags flag)
+setWOptM :: WarningFlag -> TcRnIf gbl lcl a -> TcRnIf gbl lcl a
+setWOptM flag = updTopFlags (\dflags -> wopt_set dflags flag)
+
unsetXOptM :: LangExt.Extension -> TcRnIf gbl lcl a -> TcRnIf gbl lcl a
unsetXOptM flag = updTopFlags (\dflags -> xopt_unset dflags flag)
=====================================
compiler/GHC/Types/Error/Codes.hs
=====================================
@@ -711,7 +711,7 @@ type family GhcDiagnosticCode c = n | n -> c where
-- TcRnBadFieldAnnotation/BadFieldAnnotationReason
GhcDiagnosticCode "LazyFieldsDisabled" = 81601
GhcDiagnosticCode "UnpackWithoutStrictness" = 10107
- GhcDiagnosticCode "BackpackUnpackAbstractType" = 40091
+ GhcDiagnosticCode "UnusableUnpackPragma" = 40091
-- TcRnRoleValidationFailed/RoleInferenceFailedReason
GhcDiagnosticCode "TyVarRoleMismatch" = 22221
=====================================
docs/users_guide/9.14.1-notes.rst
=====================================
@@ -25,17 +25,6 @@ Language
This deprecation is controlled by the newly introduced ``-Wdeprecated-pragmas``
flag in ``-Wdefault``.
-* A new flag, ``-Wuseless-specialisations``, controls warnings emitted when GHC
- determines that a SPECIALISE pragma would have no effect.
-
-* A new flag, ``-Wrule-lhs-equalities``, controls warnings emitted for RULES
- whose left-hand side attempts to quantify over equality constraints that
- previous GHC versions accepted quantifying over. GHC will now drop such RULES,
- emitting a warning message controlled by this flag.
-
- This warning is intended to give visibility to the fact that the RULES that
- previous GHC versions generated in such circumstances could never fire.
-
* ``-Wincomplete-record-selectors`` is now part of `-Wall`, as specified
by `GHC Proposal 516: add warning for incomplete record selectors <https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0516-i…>`_.
Hence, if a library is compiled with ``-Werror``, compilation may now fail. Solution: fix the library.
@@ -93,6 +82,25 @@ Compiler
:ghc-ticket:`20875`, :ghc-ticket:`21172`, :ghc-ticket:`22257`, :ghc-ticket:`25238`,
:ghc-ticket:`25834`.
+- A new flag, :ghc-flag:`-Wuseless-specialisations`, controls warnings emitted when GHC
+ determines that a SPECIALISE pragma would have no effect.
+
+- A new flag, :ghc-flag:`-Wrule-lhs-equalities`, controls warnings emitted for RULES
+ whose left-hand side attempts to quantify over equality constraints that
+ previous GHC versions accepted quantifying over. GHC will now drop such RULES,
+ emitting a warning message controlled by this flag.
+
+ This warning is intended to give visibility to the fact that the RULES that
+ previous GHC versions generated in such circumstances could never fire.
+
+- A new flag, :ghc-flag:`-Wunusable-unpack-pragmas`, controls warnings emitted
+ when GHC is unable to unpack a data constructor field annotated by the
+ ``{-# UNPACK #-}`` pragma.
+
+ Previous GHC versions issued this warning unconditionally. Now it is possible
+ to disable it with ``-Wno-unusable-unpack-pragmas`` or turn it into an error
+ with ``-Werror=unusable-unpack-pragmas``.
+
GHCi
~~~~
=====================================
docs/users_guide/using-warnings.rst
=====================================
@@ -84,6 +84,7 @@ as ``-Wno-...`` for every individual warning in the group.
* :ghc-flag:`-Wnoncanonical-monad-instances`
* :ghc-flag:`-Wdata-kinds-tc`
* :ghc-flag:`-Wimplicit-rhs-quantification`
+ * :ghc-flag:`-Wunusable-unpack-pragmas`
.. ghc-flag:: -W
:shortdesc: enable normal warnings
@@ -2646,6 +2647,40 @@ of ``-W(no-)*``.
To make the code forwards-compatible and silence the warning, users are
advised to add parentheses manually.
+.. ghc-flag:: -Wunusable-unpack-pragmas
+ :shortdesc: warn when an ``{-# UNPACK #-}`` pragma is unusable
+ :type: dynamic
+ :reverse: -Wno-unusable-unpack-pragmas
+
+ :since: 9.14.1
+ :default: on
+
+ Warn on unusable ``{-# UNPACK #-}`` pragmas in data type declarations.
+ Examples::
+
+ data T = MkT {-# UNPACK #-} !(Int -> Bool)
+
+ data G where
+ MkG :: {-# UNPACK #-} !G -> G
+
+ type family F a where {}
+ data R a = MkR { fld :: {-# UNPACK #-} !(F a) }
+
+ A possible reason for this warning is that the ``{-# UNPACK #-}`` pragma was
+ applied to one of the following:
+
+ * a function type ``a -> b``
+ * a recursive use of the data type being defined
+ * a sum type that cannot be unpacked
+ * a type/data family application with no matching instance in the environment
+
+ However, it is deliberately **not** emitted if:
+
+ * the failure occurs in an indefinite package in Backpack
+ * the pragma is usable, but unpacking is disabled by :ghc-flag:`-O0`
+
+----
+
If you're feeling really paranoid, the :ghc-flag:`-dcore-lint` option is a good choice.
It turns on heavyweight intra-pass sanity-checking within GHC. (It checks GHC's
sanity, not yours.)
=====================================
testsuite/tests/simplCore/should_compile/Makefile
=====================================
@@ -43,6 +43,11 @@ T3990b:
'$(TEST_HC)' $(TEST_HC_OPTS) -O -c -ddump-simpl T3990b.hs | grep 'test_case'
# Grep output should show an unpacked constructor
+T3990c:
+ $(RM) -f T3990c.o T3990c.hi
+ '$(TEST_HC)' $(TEST_HC_OPTS) -O -c -ddump-simpl T3990c.hs | grep 'test_case'
+ # Grep output should show an unpacked constructor
+
T8848:
$(RM) -f T8848.o T8848.hi
'$(TEST_HC)' $(TEST_HC_OPTS) -O -c -ddump-rule-firings T8848.hs | grep 'SPEC map2'
=====================================
testsuite/tests/simplCore/should_compile/T23307c.stderr
=====================================
@@ -1,5 +1,5 @@
-
-T23307c.hs:7:13: warning: [GHC-40091]
+T23307c.hs:7:13: warning: [GHC-40091] [-Wunusable-unpack-pragmas (in -Wdefault)]
• Ignoring unusable UNPACK pragma on the first argument of ‘LCon’
• In the definition of data constructor ‘LCon’
In the data type declaration for ‘Loop’
+
=====================================
testsuite/tests/simplCore/should_compile/T3990c.hs
=====================================
@@ -0,0 +1,18 @@
+{-# OPTIONS -Wno-unusable-unpack-pragmas #-}
+ -- The warning is disabled, but this should not affect unpacking
+
+{-# LANGUAGE TypeFamilies #-}
+module T3990c where
+
+type family F a
+
+data D1 = MkD1 {-# UNPACK #-} !(F Int)
+ -- This should actually get unpacked
+
+data D2 = MkD2 {-# UNPACK #-} !Int
+ {-# UNPACK #-} !Int
+
+type instance F Int = D2
+
+test_case :: D1
+test_case = MkD1 (MkD2 1 1)
=====================================
testsuite/tests/simplCore/should_compile/T3990c.stdout
=====================================
@@ -0,0 +1,2 @@
+test_case :: D1
+test_case = T3990c.MkD1 1# 1#
=====================================
testsuite/tests/simplCore/should_compile/all.T
=====================================
@@ -211,6 +211,7 @@ test('T11742', normal, compile, ['-O2'])
test('T11644', normal, compile, ['-O2'])
test('T3990', normal, makefile_test, ['T3990'])
test('T3990b', normal, makefile_test, ['T3990b'])
+test('T3990c', normal, makefile_test, ['T3990c'])
test('T12076', [], multimod_compile, ['T12076', '-v0'])
test('T12076lit', normal, compile, ['-O'])
=====================================
testsuite/tests/simplCore/should_fail/T25672.stderr
=====================================
@@ -1,4 +1,4 @@
-T25672.hs:12:7: warning: [GHC-40091]
+T25672.hs:12:7: warning: [GHC-40091] [-Wunusable-unpack-pragmas (in -Wdefault)]
• Ignoring unusable UNPACK pragma
on the first argument of ‘WrapIntOrWord’
• In the definition of data constructor ‘WrapIntOrWord’
=====================================
testsuite/tests/typecheck/should_compile/T7050.stderr
=====================================
@@ -1,5 +1,5 @@
-
-T7050.hs:3:14: warning: [GHC-40091]
+T7050.hs:3:14: warning: [GHC-40091] [-Wunusable-unpack-pragmas (in -Wdefault)]
• Ignoring unusable UNPACK pragma on the first argument of ‘Foo’
• In the definition of data constructor ‘Foo’
In the data type declaration for ‘Foo’
+
=====================================
testsuite/tests/typecheck/should_fail/T3966.stderr
=====================================
@@ -1,5 +1,5 @@
-
-T3966.hs:5:16: error: [GHC-40091] [-Werror]
+T3966.hs:5:16: error: [GHC-40091] [-Wunusable-unpack-pragmas (in -Wdefault), Werror=unusable-unpack-pragmas]
• Ignoring unusable UNPACK pragma on the first argument of ‘Foo’
• In the definition of data constructor ‘Foo’
In the data type declaration for ‘Foo’
+
=====================================
testsuite/tests/typecheck/should_fail/T3966b.hs
=====================================
@@ -0,0 +1,12 @@
+{-# OPTIONS -Werror=unusable-unpack-pragmas #-}
+{-# LANGUAGE TypeFamilies #-}
+
+module T3966b where
+
+data T = MkT {-# UNPACK #-} !(Int -> Bool)
+
+data G where
+ MkG :: {-# UNPACK #-} !G -> G
+
+type family F a where {}
+data R a = MkR { fld :: {-# UNPACK #-} !(F a) }
=====================================
testsuite/tests/typecheck/should_fail/T3966b.stderr
=====================================
@@ -0,0 +1,15 @@
+T3966b.hs:6:10: error: [GHC-40091] [-Wunusable-unpack-pragmas (in -Wdefault), Werror=unusable-unpack-pragmas]
+ • Ignoring unusable UNPACK pragma on the first argument of ‘MkT’
+ • In the definition of data constructor ‘MkT’
+ In the data type declaration for ‘T’
+
+T3966b.hs:9:3: error: [GHC-40091] [-Wunusable-unpack-pragmas (in -Wdefault), Werror=unusable-unpack-pragmas]
+ • Ignoring unusable UNPACK pragma on the first argument of ‘MkG’
+ • In the definition of data constructor ‘MkG’
+ In the data type declaration for ‘G’
+
+T3966b.hs:12:12: error: [GHC-40091] [-Wunusable-unpack-pragmas (in -Wdefault), Werror=unusable-unpack-pragmas]
+ • Ignoring unusable UNPACK pragma on the first argument of ‘MkR’
+ • In the definition of data constructor ‘MkR’
+ In the data type declaration for ‘R’
+
=====================================
testsuite/tests/typecheck/should_fail/all.T
=====================================
@@ -213,6 +213,7 @@ test('T3613', normal, compile_fail, [''])
test('fd-loop', normal, compile_fail, [''])
test('T3950', normal, compile_fail, [''])
test('T3966', normal, compile_fail, [''])
+test('T3966b', normal, compile_fail, [''])
test('IPFail', normal, compile_fail, [''])
test('T3468', [], multimod_compile_fail, ['T3468', '-v0'])
=====================================
testsuite/tests/unboxedsums/unpack_sums_5.stderr
=====================================
@@ -1,10 +1,10 @@
-
-unpack_sums_5.hs:4:22: warning: [GHC-40091]
+unpack_sums_5.hs:4:22: warning: [GHC-40091] [-Wunusable-unpack-pragmas (in -Wdefault)]
• Ignoring unusable UNPACK pragma on the first argument of ‘JustT’
• In the definition of data constructor ‘JustT’
In the data type declaration for ‘SMaybeT’
-unpack_sums_5.hs:7:10: warning: [GHC-40091]
+unpack_sums_5.hs:7:10: warning: [GHC-40091] [-Wunusable-unpack-pragmas (in -Wdefault)]
• Ignoring unusable UNPACK pragma on the first argument of ‘MkT’
• In the definition of data constructor ‘MkT’
In the data type declaration for ‘T’
+
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e2f2f9d08274c90e775a35dc5b776f7…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e2f2f9d08274c90e775a35dc5b776f7…
You're receiving this email because of your account on gitlab.haskell.org.
1
0

[Git][ghc/ghc][wip/marge_bot_batch_merge_job] 5 commits: Add name for -Wunusable-unpack-pragmas
by Marge Bot (@marge-bot) 20 Apr '25
by Marge Bot (@marge-bot) 20 Apr '25
20 Apr '25
Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC
Commits:
bed38773 by Vladislav Zavialov at 2025-04-20T06:23:15-04:00
Add name for -Wunusable-unpack-pragmas
This warning had no name or flag and was triggered unconditionally.
Now it is part of -Wdefault.
In GHC.Tc.TyCl.tcTyClGroupsPass's strict mode, we now have to
force-enable this warning to ensure that detection of flawed groups
continues to work even if the user disables the warning with the
-Wno-unusable-unpack-pragmas option. Test case: T3990c
Also, the misnamed BackpackUnpackAbstractType is now called
UnusableUnpackPragma.
- - - - -
47aaf40c by Adam Gundry at 2025-04-20T06:23:17-04:00
Fix specialisation of incoherent instances (fixes #25883)
GHC normally assumes that class constraints are canonical, meaning that
the specialiser is allowed to replace one dictionary argument with another
provided that they have the same type. The `-fno-specialise-incoherents`
flag alters INCOHERENT instance definitions so that they will prevent
specialisation in some cases, by inserting `nospec`.
This commit fixes a bug in 7124e4ad76d98f1fc246ada4fd7bf64413ff2f2e, which
treated some INCOHERENT instance matches as if `-fno-specialise-incoherents`
was in effect, thereby unnecessarily preventing specialisation. In addition
it updates the relevant `Note [Rules for instance lookup]` and adds a new
`Note [Canonicity for incoherent matches]`.
- - - - -
e8878442 by Adam Gundry at 2025-04-20T06:23:18-04:00
Add regression test for #23429
- - - - -
b8f2a43e by Adam Gundry at 2025-04-20T06:23:18-04:00
user's guide: update specification of overlapping/incoherent instances
The description of the instance resolution algorithm in the user's
guide was slightly out of date, because it mentioned in-scope given
constraints only at the end, whereas the implementation checks for
their presence before any of the other steps.
This also adds a warning to the user's guide about the impact of
incoherent instances on specialisation, and more clearly documents
some of the other effects of `-XIncoherentInstances`.
- - - - -
aece199c by Matthew Craven at 2025-04-20T06:23:18-04:00
Fix bytecode generation for `tagToEnum# <LITERAL>`
Fixes #25975.
- - - - -
40 changed files:
- compiler/GHC/Core/InstEnv.hs
- compiler/GHC/Driver/Flags.hs
- compiler/GHC/Driver/Session.hs
- compiler/GHC/StgToByteCode.hs
- compiler/GHC/Tc/Errors/Ppr.hs
- compiler/GHC/Tc/Errors/Types.hs
- compiler/GHC/Tc/Solver/Dict.hs
- compiler/GHC/Tc/TyCl.hs
- compiler/GHC/Tc/Utils/Monad.hs
- compiler/GHC/Types/Error/Codes.hs
- docs/users_guide/9.14.1-notes.rst
- docs/users_guide/exts/instances.rst
- docs/users_guide/using-warnings.rst
- + testsuite/tests/bytecode/T25975.hs
- + testsuite/tests/bytecode/T25975.stdout
- testsuite/tests/bytecode/all.T
- testsuite/tests/simplCore/should_compile/Makefile
- testsuite/tests/simplCore/should_compile/T23307c.stderr
- + testsuite/tests/simplCore/should_compile/T25883.hs
- + testsuite/tests/simplCore/should_compile/T25883.substr-simpl
- + testsuite/tests/simplCore/should_compile/T25883b.hs
- + testsuite/tests/simplCore/should_compile/T25883b.substr-simpl
- + testsuite/tests/simplCore/should_compile/T25883c.hs
- + testsuite/tests/simplCore/should_compile/T25883c.substr-simpl
- + testsuite/tests/simplCore/should_compile/T25883d.hs
- + testsuite/tests/simplCore/should_compile/T25883d.stderr
- + testsuite/tests/simplCore/should_compile/T25883d_import.hs
- + testsuite/tests/simplCore/should_compile/T3990c.hs
- + testsuite/tests/simplCore/should_compile/T3990c.stdout
- testsuite/tests/simplCore/should_compile/all.T
- testsuite/tests/simplCore/should_fail/T25672.stderr
- + testsuite/tests/simplCore/should_run/T23429.hs
- + testsuite/tests/simplCore/should_run/T23429.stdout
- testsuite/tests/simplCore/should_run/all.T
- testsuite/tests/typecheck/should_compile/T7050.stderr
- testsuite/tests/typecheck/should_fail/T3966.stderr
- + testsuite/tests/typecheck/should_fail/T3966b.hs
- + testsuite/tests/typecheck/should_fail/T3966b.stderr
- testsuite/tests/typecheck/should_fail/all.T
- testsuite/tests/unboxedsums/unpack_sums_5.stderr
The diff was not included because it is too large.
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/f0206e27434bfdd8151666d39417cb…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/f0206e27434bfdd8151666d39417cb…
You're receiving this email because of your account on gitlab.haskell.org.
1
0

[Git][ghc/ghc][wip/T24603] 4 commits: RTS: remove target info and fix host info (#24058)
by Serge S. Gulin (@gulin.serge) 20 Apr '25
by Serge S. Gulin (@gulin.serge) 20 Apr '25
20 Apr '25
Serge S. Gulin pushed to branch wip/T24603 at Glasgow Haskell Compiler / GHC
Commits:
b96e2f77 by Sylvain Henry at 2025-04-18T20:46:33-04:00
RTS: remove target info and fix host info (#24058)
The RTS isn't a compiler, hence it doesn't have a target and we remove
the reported target info displayed by "+RTS --info". We also fix the
host info displayed by "+RTS --info": the host of the RTS is the
RTS-building compiler's target, not the compiler's host (wrong when
doing cross-compilation).
- - - - -
6d9965f4 by Sylvain Henry at 2025-04-18T20:46:33-04:00
RTS: remove build info
As per the discussion in !13967, there is no reason to tag the RTS with
information about the build platform.
- - - - -
d52e9b3f by Vladislav Zavialov at 2025-04-18T20:47:15-04:00
Diagnostics: remove the KindMismatch constructor (#25957)
The KindMismatch constructor was only used as an intermediate
representation in pretty-printing.
Its removal addresses a problem detected by the "codes" test case:
[GHC-89223] is untested (constructor = KindMismatch)
In a concious deviation from the usual procedure, the error code
GHC-89223 is removed entirely rather than marked as Outdated.
The reason is that it never was user-facing in the first place.
- - - - -
b6424e48 by Serge S. Gulin at 2025-04-20T09:31:47+03:00
Support for ARM64 Windows (LLVM-enabled) (fixes #24603)
submodule
Co-authored-by: Cheng Shao <terrorjack(a)type.dance>
Co-authored-by: Dmitrii Egorov <egorov.d.i(a)icloud.com>
Co-authored-by: Andrei Borzenkov <root(a)sandwitch.dev>
- - - - -
40 changed files:
- .gitlab-ci.yml
- .gitlab/ci.sh
- .gitlab/generate-ci/gen_ci.hs
- .gitlab/hello.hs
- .gitlab/jobs.yaml
- compiler/CodeGen.Platform.h
- compiler/GHC/CmmToAsm/AArch64/CodeGen.hs
- compiler/GHC/CmmToAsm/AArch64/Instr.hs
- compiler/GHC/CmmToAsm/AArch64/Ppr.hs
- compiler/GHC/CmmToAsm/Reg/Linear/AArch64.hs
- compiler/GHC/Driver/Session.hs
- compiler/GHC/Platform/Regs.hs
- compiler/GHC/Tc/Errors/Ppr.hs
- compiler/GHC/Tc/Errors/Types.hs
- compiler/GHC/Types/Error/Codes.hs
- configure.ac
- hadrian/src/Oracles/Setting.hs
- hadrian/src/Rules/BinaryDist.hs
- hadrian/src/Settings/Packages.hs
- libraries/Cabal
- libraries/Win32
- libraries/base/src/System/CPUTime/Windows.hsc
- libraries/base/tests/perf/encodingAllocations.hs
- libraries/directory
- libraries/haskeline
- libraries/process
- libraries/unix
- llvm-targets
- m4/fp_cc_supports_target.m4
- m4/fptools_set_platform_vars.m4
- m4/ghc_tables_next_to_code.m4
- rts/RtsUtils.c
- rts/StgCRun.c
- rts/linker/PEi386.c
- rts/win32/veh_excn.c
- testsuite/ghc-config/ghc-config.hs
- testsuite/tests/diagnostic-codes/codes.stdout
- utils/ghc-toolchain/exe/Main.hs
- utils/hsc2hs
- utils/llvm-targets/gen-data-layout.sh
The diff was not included because it is too large.
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/aca81c371f72ad910c1b6501a0631d…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/aca81c371f72ad910c1b6501a0631d…
You're receiving this email because of your account on gitlab.haskell.org.
1
0

[Git][ghc/ghc][wip/marge_bot_batch_merge_job] 6 commits: Support for ARM64 Windows (LLVM-enabled) (fixes #24603)
by Marge Bot (@marge-bot) 20 Apr '25
by Marge Bot (@marge-bot) 20 Apr '25
20 Apr '25
Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC
Commits:
cb5fcc24 by Serge S. Gulin at 2025-04-20T00:11:47-04:00
Support for ARM64 Windows (LLVM-enabled) (fixes #24603)
submodule
Co-authored-by: Cheng Shao <terrorjack(a)type.dance>
Co-authored-by: Dmitrii Egorov <egorov.d.i(a)icloud.com>
Co-authored-by: Andrei Borzenkov <root(a)sandwitch.dev>
- - - - -
90c1e7a6 by Vladislav Zavialov at 2025-04-20T00:11:48-04:00
Add name for -Wunusable-unpack-pragmas
This warning had no name or flag and was triggered unconditionally.
Now it is part of -Wdefault.
In GHC.Tc.TyCl.tcTyClGroupsPass's strict mode, we now have to
force-enable this warning to ensure that detection of flawed groups
continues to work even if the user disables the warning with the
-Wno-unusable-unpack-pragmas option. Test case: T3990c
Also, the misnamed BackpackUnpackAbstractType is now called
UnusableUnpackPragma.
- - - - -
b975fdfe by Adam Gundry at 2025-04-20T00:11:49-04:00
Fix specialisation of incoherent instances (fixes #25883)
GHC normally assumes that class constraints are canonical, meaning that
the specialiser is allowed to replace one dictionary argument with another
provided that they have the same type. The `-fno-specialise-incoherents`
flag alters INCOHERENT instance definitions so that they will prevent
specialisation in some cases, by inserting `nospec`.
This commit fixes a bug in 7124e4ad76d98f1fc246ada4fd7bf64413ff2f2e, which
treated some INCOHERENT instance matches as if `-fno-specialise-incoherents`
was in effect, thereby unnecessarily preventing specialisation. In addition
it updates the relevant `Note [Rules for instance lookup]` and adds a new
`Note [Canonicity for incoherent matches]`.
- - - - -
3fbf3433 by Adam Gundry at 2025-04-20T00:11:49-04:00
Add regression test for #23429
- - - - -
06784c1d by Adam Gundry at 2025-04-20T00:11:49-04:00
user's guide: update specification of overlapping/incoherent instances
The description of the instance resolution algorithm in the user's
guide was slightly out of date, because it mentioned in-scope given
constraints only at the end, whereas the implementation checks for
their presence before any of the other steps.
This also adds a warning to the user's guide about the impact of
incoherent instances on specialisation, and more clearly documents
some of the other effects of `-XIncoherentInstances`.
- - - - -
f0206e27 by Matthew Craven at 2025-04-20T00:11:50-04:00
Fix bytecode generation for `tagToEnum# <LITERAL>`
Fixes #25975.
- - - - -
71 changed files:
- .gitlab-ci.yml
- .gitlab/ci.sh
- .gitlab/generate-ci/gen_ci.hs
- .gitlab/hello.hs
- .gitlab/jobs.yaml
- compiler/CodeGen.Platform.h
- compiler/GHC/CmmToAsm/AArch64/CodeGen.hs
- compiler/GHC/CmmToAsm/AArch64/Instr.hs
- compiler/GHC/CmmToAsm/AArch64/Ppr.hs
- compiler/GHC/CmmToAsm/Reg/Linear/AArch64.hs
- compiler/GHC/Core/InstEnv.hs
- compiler/GHC/Driver/Flags.hs
- compiler/GHC/Driver/Session.hs
- compiler/GHC/Platform/Regs.hs
- compiler/GHC/StgToByteCode.hs
- compiler/GHC/Tc/Errors/Ppr.hs
- compiler/GHC/Tc/Errors/Types.hs
- compiler/GHC/Tc/Solver/Dict.hs
- compiler/GHC/Tc/TyCl.hs
- compiler/GHC/Tc/Utils/Monad.hs
- compiler/GHC/Types/Error/Codes.hs
- docs/users_guide/9.14.1-notes.rst
- docs/users_guide/exts/instances.rst
- docs/users_guide/using-warnings.rst
- hadrian/src/Oracles/Setting.hs
- hadrian/src/Rules/BinaryDist.hs
- libraries/Cabal
- libraries/Win32
- libraries/base/src/System/CPUTime/Windows.hsc
- libraries/base/tests/perf/encodingAllocations.hs
- libraries/directory
- libraries/haskeline
- libraries/process
- libraries/unix
- llvm-targets
- m4/fp_cc_supports_target.m4
- m4/fptools_set_platform_vars.m4
- m4/ghc_tables_next_to_code.m4
- rts/StgCRun.c
- rts/linker/PEi386.c
- rts/win32/veh_excn.c
- + testsuite/tests/bytecode/T25975.hs
- + testsuite/tests/bytecode/T25975.stdout
- testsuite/tests/bytecode/all.T
- testsuite/tests/simplCore/should_compile/Makefile
- testsuite/tests/simplCore/should_compile/T23307c.stderr
- + testsuite/tests/simplCore/should_compile/T25883.hs
- + testsuite/tests/simplCore/should_compile/T25883.substr-simpl
- + testsuite/tests/simplCore/should_compile/T25883b.hs
- + testsuite/tests/simplCore/should_compile/T25883b.substr-simpl
- + testsuite/tests/simplCore/should_compile/T25883c.hs
- + testsuite/tests/simplCore/should_compile/T25883c.substr-simpl
- + testsuite/tests/simplCore/should_compile/T25883d.hs
- + testsuite/tests/simplCore/should_compile/T25883d.stderr
- + testsuite/tests/simplCore/should_compile/T25883d_import.hs
- + testsuite/tests/simplCore/should_compile/T3990c.hs
- + testsuite/tests/simplCore/should_compile/T3990c.stdout
- testsuite/tests/simplCore/should_compile/all.T
- testsuite/tests/simplCore/should_fail/T25672.stderr
- + testsuite/tests/simplCore/should_run/T23429.hs
- + testsuite/tests/simplCore/should_run/T23429.stdout
- testsuite/tests/simplCore/should_run/all.T
- testsuite/tests/typecheck/should_compile/T7050.stderr
- testsuite/tests/typecheck/should_fail/T3966.stderr
- + testsuite/tests/typecheck/should_fail/T3966b.hs
- + testsuite/tests/typecheck/should_fail/T3966b.stderr
- testsuite/tests/typecheck/should_fail/all.T
- testsuite/tests/unboxedsums/unpack_sums_5.stderr
- utils/ghc-toolchain/exe/Main.hs
- utils/hsc2hs
- utils/llvm-targets/gen-data-layout.sh
The diff was not included because it is too large.
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/21f0194fd38c233844c4621e50d12a…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/21f0194fd38c233844c4621e50d12a…
You're receiving this email because of your account on gitlab.haskell.org.
1
0

[Git][ghc/ghc][wip/marge_bot_batch_merge_job] 6 commits: Support for ARM64 Windows (LLVM-enabled) (fixes #24603)
by Marge Bot (@marge-bot) 19 Apr '25
by Marge Bot (@marge-bot) 19 Apr '25
19 Apr '25
Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC
Commits:
d2a6d6d5 by Serge S. Gulin at 2025-04-19T19:10:00-04:00
Support for ARM64 Windows (LLVM-enabled) (fixes #24603)
submodule
Co-authored-by: Cheng Shao <terrorjack(a)type.dance>
Co-authored-by: Dmitrii Egorov <egorov.d.i(a)icloud.com>
Co-authored-by: Andrei Borzenkov <root(a)sandwitch.dev>
- - - - -
979d292f by Vladislav Zavialov at 2025-04-19T19:10:01-04:00
Add name for -Wunusable-unpack-pragmas
This warning had no name or flag and was triggered unconditionally.
Now it is part of -Wdefault.
In GHC.Tc.TyCl.tcTyClGroupsPass's strict mode, we now have to
force-enable this warning to ensure that detection of flawed groups
continues to work even if the user disables the warning with the
-Wno-unusable-unpack-pragmas option. Test case: T3990c
Also, the misnamed BackpackUnpackAbstractType is now called
UnusableUnpackPragma.
- - - - -
241031c2 by Adam Gundry at 2025-04-19T19:10:03-04:00
Fix specialisation of incoherent instances (fixes #25883)
GHC normally assumes that class constraints are canonical, meaning that
the specialiser is allowed to replace one dictionary argument with another
provided that they have the same type. The `-fno-specialise-incoherents`
flag alters INCOHERENT instance definitions so that they will prevent
specialisation in some cases, by inserting `nospec`.
This commit fixes a bug in 7124e4ad76d98f1fc246ada4fd7bf64413ff2f2e, which
treated some INCOHERENT instance matches as if `-fno-specialise-incoherents`
was in effect, thereby unnecessarily preventing specialisation. In addition
it updates the relevant `Note [Rules for instance lookup]` and adds a new
`Note [Canonicity for incoherent matches]`.
- - - - -
ded9afca by Adam Gundry at 2025-04-19T19:10:03-04:00
Add regression test for #23429
- - - - -
5d38130a by Adam Gundry at 2025-04-19T19:10:03-04:00
user's guide: update specification of overlapping/incoherent instances
The description of the instance resolution algorithm in the user's
guide was slightly out of date, because it mentioned in-scope given
constraints only at the end, whereas the implementation checks for
their presence before any of the other steps.
This also adds a warning to the user's guide about the impact of
incoherent instances on specialisation, and more clearly documents
some of the other effects of `-XIncoherentInstances`.
- - - - -
21f0194f by Matthew Craven at 2025-04-19T19:10:03-04:00
Fix bytecode generation for `tagToEnum# <LITERAL>`
Fixes #25975.
- - - - -
71 changed files:
- .gitlab-ci.yml
- .gitlab/ci.sh
- .gitlab/generate-ci/gen_ci.hs
- .gitlab/hello.hs
- .gitlab/jobs.yaml
- compiler/CodeGen.Platform.h
- compiler/GHC/CmmToAsm/AArch64/CodeGen.hs
- compiler/GHC/CmmToAsm/AArch64/Instr.hs
- compiler/GHC/CmmToAsm/AArch64/Ppr.hs
- compiler/GHC/CmmToAsm/Reg/Linear/AArch64.hs
- compiler/GHC/Core/InstEnv.hs
- compiler/GHC/Driver/Flags.hs
- compiler/GHC/Driver/Session.hs
- compiler/GHC/Platform/Regs.hs
- compiler/GHC/StgToByteCode.hs
- compiler/GHC/Tc/Errors/Ppr.hs
- compiler/GHC/Tc/Errors/Types.hs
- compiler/GHC/Tc/Solver/Dict.hs
- compiler/GHC/Tc/TyCl.hs
- compiler/GHC/Tc/Utils/Monad.hs
- compiler/GHC/Types/Error/Codes.hs
- docs/users_guide/9.14.1-notes.rst
- docs/users_guide/exts/instances.rst
- docs/users_guide/using-warnings.rst
- hadrian/src/Oracles/Setting.hs
- hadrian/src/Rules/BinaryDist.hs
- libraries/Cabal
- libraries/Win32
- libraries/base/src/System/CPUTime/Windows.hsc
- libraries/base/tests/perf/encodingAllocations.hs
- libraries/directory
- libraries/haskeline
- libraries/process
- libraries/unix
- llvm-targets
- m4/fp_cc_supports_target.m4
- m4/fptools_set_platform_vars.m4
- m4/ghc_tables_next_to_code.m4
- rts/StgCRun.c
- rts/linker/PEi386.c
- rts/win32/veh_excn.c
- + testsuite/tests/bytecode/T25975.hs
- + testsuite/tests/bytecode/T25975.stdout
- testsuite/tests/bytecode/all.T
- testsuite/tests/simplCore/should_compile/Makefile
- testsuite/tests/simplCore/should_compile/T23307c.stderr
- + testsuite/tests/simplCore/should_compile/T25883.hs
- + testsuite/tests/simplCore/should_compile/T25883.substr-simpl
- + testsuite/tests/simplCore/should_compile/T25883b.hs
- + testsuite/tests/simplCore/should_compile/T25883b.substr-simpl
- + testsuite/tests/simplCore/should_compile/T25883c.hs
- + testsuite/tests/simplCore/should_compile/T25883c.substr-simpl
- + testsuite/tests/simplCore/should_compile/T25883d.hs
- + testsuite/tests/simplCore/should_compile/T25883d.stderr
- + testsuite/tests/simplCore/should_compile/T25883d_import.hs
- + testsuite/tests/simplCore/should_compile/T3990c.hs
- + testsuite/tests/simplCore/should_compile/T3990c.stdout
- testsuite/tests/simplCore/should_compile/all.T
- testsuite/tests/simplCore/should_fail/T25672.stderr
- + testsuite/tests/simplCore/should_run/T23429.hs
- + testsuite/tests/simplCore/should_run/T23429.stdout
- testsuite/tests/simplCore/should_run/all.T
- testsuite/tests/typecheck/should_compile/T7050.stderr
- testsuite/tests/typecheck/should_fail/T3966.stderr
- + testsuite/tests/typecheck/should_fail/T3966b.hs
- + testsuite/tests/typecheck/should_fail/T3966b.stderr
- testsuite/tests/typecheck/should_fail/all.T
- testsuite/tests/unboxedsums/unpack_sums_5.stderr
- utils/ghc-toolchain/exe/Main.hs
- utils/hsc2hs
- utils/llvm-targets/gen-data-layout.sh
The diff was not included because it is too large.
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/5d761a4e0d13c4afd650b2a741207c…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/5d761a4e0d13c4afd650b2a741207c…
You're receiving this email because of your account on gitlab.haskell.org.
1
0

[Git][ghc/ghc][wip/supersven/riscv-vectors] 11 commits: Document assertVectorRegWidth
by Sven Tennie (@supersven) 19 Apr '25
by Sven Tennie (@supersven) 19 Apr '25
19 Apr '25
Sven Tennie pushed to branch wip/supersven/riscv-vectors at Glasgow Haskell Compiler / GHC
Commits:
44974798 by Sven Tennie at 2025-04-19T09:51:18+02:00
Document assertVectorRegWidth
- - - - -
9e5c3af3 by Sven Tennie at 2025-04-19T10:01:05+02:00
Cleanup assignReg
- - - - -
aa715e3f by Sven Tennie at 2025-04-19T10:07:48+02:00
Cleanup assignMem
- - - - -
2c5e6db8 by Sven Tennie at 2025-04-19T14:24:51+02:00
Add TODO
- - - - -
2cc90143 by Sven Tennie at 2025-04-19T15:29:24+02:00
Align code with similar occurences
- - - - -
f88897ab by Sven Tennie at 2025-04-19T16:08:29+02:00
Broadcast with VMV.V.I
- - - - -
b59eb306 by Sven Tennie at 2025-04-19T16:42:50+02:00
Implement MO_VS_Neg
- - - - -
06ecb88e by Sven Tennie at 2025-04-19T16:47:15+02:00
Cleanup old TODO
- - - - -
f7657f22 by Sven Tennie at 2025-04-19T17:17:59+02:00
Cleanup
- - - - -
348b54d9 by Sven Tennie at 2025-04-19T19:04:09+02:00
Implement more MachOps
- - - - -
5a31e90c by Sven Tennie at 2025-04-19T20:45:06+02:00
Implement VREM
- - - - -
3 changed files:
- compiler/GHC/CmmToAsm/RV64/CodeGen.hs
- compiler/GHC/CmmToAsm/RV64/Instr.hs
- compiler/GHC/CmmToAsm/RV64/Ppr.hs
Changes:
=====================================
compiler/GHC/CmmToAsm/RV64/CodeGen.hs
=====================================
@@ -364,10 +364,7 @@ stmtToInstrs stmt = do
genCCall target result_regs args
CmmComment s -> pure (unitOL (COMMENT (ftext s)))
CmmTick {} -> pure nilOL
- CmmAssign reg src -> assignReg format reg src
- where
- ty = cmmRegType reg
- format = cmmTypeFormat ty
+ CmmAssign reg src -> assignReg reg src
CmmStore addr src _alignment -> assignMem format addr src
where
ty = cmmExprType platform src
@@ -475,23 +472,27 @@ getRegister e = do
assertVectorRegWidth e
getRegister' config (ncgPlatform config) e
+-- | Assert that `CmmExpr` vector expression types fit into the configured VLEN
assertVectorRegWidth :: CmmExpr -> NatM ()
assertVectorRegWidth expr = do
config <- getConfig
let platform = ncgPlatform config
mbRegMinBits :: Maybe Int = fromIntegral <$> ncgVectorMinBits config
format = cmmTypeFormat $ cmmExprType platform expr
- if isVecFormat format then
- case mbRegMinBits of
- Nothing -> pprPanic
- "CmmExpr results in vector format, but no vector register configured (see -mriscv-vlen in docs)"
- (pdoc platform expr)
- Just regMinBits | (formatInBytes format) * 8 <= regMinBits -> pure ()
- | otherwise -> pprPanic
- "CmmExpr results in vector format which is bigger than the configured vector register size (see -mriscv-vlen in docs)"
- (pdoc platform expr)
- else
- pure ()
+ if isVecFormat format
+ then case mbRegMinBits of
+ Nothing ->
+ pprPanic
+ "CmmExpr results in vector format, but no vector register configured (see -mriscv-vlen in docs)"
+ (pdoc platform expr)
+ Just regMinBits
+ | (formatInBytes format) * 8 <= regMinBits -> pure ()
+ | otherwise ->
+ pprPanic
+ "CmmExpr results in vector format which is bigger than the configured vector register size (see -mriscv-vlen in docs)"
+ (pdoc platform expr)
+ else
+ pure ()
-- | The register width to be used for an operation on the given width
-- operand.
@@ -602,14 +603,13 @@ getRegister' config plat expr =
format = floatFormat w
pure $ Any format (\dst -> unitOL $ annExpr expr (MOV (OpReg format dst) op))
CmmFloat f w -> do
- let
- toWord :: Rational -> Integer
+ let toWord :: Rational -> Integer
toWord r = case w of
- W8 -> pprPanic "getRegister' (CmmLit:CmmFloat), no support for bytes" (pdoc plat expr)
- W16 -> pprPanic "getRegister' (CmmLit:CmmFloat), no support for halfs" (pdoc plat expr)
- W32 -> fromIntegral $ castFloatToWord32 (fromRational r)
- W64 -> fromIntegral $ castDoubleToWord64 (fromRational r)
- w -> pprPanic ("getRegister' (CmmLit:CmmFloat), no support for width " ++ show w) (pdoc plat expr)
+ W8 -> pprPanic "getRegister' (CmmLit:CmmFloat), no support for bytes" (pdoc plat expr)
+ W16 -> pprPanic "getRegister' (CmmLit:CmmFloat), no support for halfs" (pdoc plat expr)
+ W32 -> fromIntegral $ castFloatToWord32 (fromRational r)
+ W64 -> fromIntegral $ castDoubleToWord64 (fromRational r)
+ w -> pprPanic ("getRegister' (CmmLit:CmmFloat), no support for width " ++ show w) (pdoc plat expr)
format_int = intFormat w
format_dst = floatFormat w
intReg <- getNewRegNat format_int
@@ -645,6 +645,7 @@ getRegister' config plat expr =
expr
(MOV (OpReg fmt dst) (OpReg format reg))
)
+ -- TODO: After issue #25977 has been fixed / merged, load the literal from memory.
CmmVec _lits -> pprPanic "getRegister' (CmmLit:CmmVec): " (pdoc plat expr)
CmmLabel lbl -> do
let op = OpImm (ImmCLbl lbl)
@@ -685,8 +686,9 @@ getRegister' config plat expr =
( Any
format
( \dst ->
- addr_code `snocOL`
- annExpr expr
+ addr_code
+ `snocOL` annExpr
+ expr
-- We pattern match on the format in the pretty-printer.
-- So, we can here simply emit LDRU for all vectors.
(LDRU format (OpReg format dst) (OpAddr addr))
@@ -765,14 +767,15 @@ getRegister' config plat expr =
MO_SF_Round from to | from < W32 -> do
-- extend to the smallest available representation
(reg_x, code_x) <- signExtendReg from W32 e_reg
- let format = floatFormat to
+ let toFormat = floatFormat to
+ fromFormat = intFormat from
pure
$ Any
- format
+ toFormat
( \dst ->
e_code
`appOL` code_x
- `snocOL` annExpr expr (FCVT IntToFloat (OpReg format dst) (OpReg (intFormat from) reg_x)) -- (Signed ConVerT Float)
+ `snocOL` annExpr expr (FCVT IntToFloat (OpReg toFormat dst) (OpReg fromFormat reg_x)) -- (Signed ConVerT Float)
)
MO_SF_Round from to ->
let toFmt = floatFormat to
@@ -853,7 +856,7 @@ getRegister' config plat expr =
fromFmt = intFormat from
in pure
$ Any
- toFmt
+ toFmt
( \dst ->
e_code
`snocOL` annExpr e (MOV (OpReg fromFmt dst) (OpReg fromFmt e_reg))
@@ -864,20 +867,12 @@ getRegister' config plat expr =
reg <- getRegister' config plat e
addAlignmentCheck align wordWidth reg
- -- TODO: MO_V_Broadcast with immediate: If the right value is a literal,
- -- it may use vmv.v.i (simpler)
- MO_V_Broadcast length w ->vectorBroadcast (intVecFormat length w)
- MO_VF_Broadcast length w -> vectorBroadcast (floatVecFormat length w)
+ MO_V_Broadcast length w -> vectorBroadcast (intVecFormat length w) e
+ MO_VF_Broadcast length w -> vectorBroadcast (floatVecFormat length w) e
+
+ MO_VS_Neg length w -> vectorNegation (intVecFormat length w)
+ MO_VF_Neg length w -> vectorNegation (floatVecFormat length w)
- -- TODO: NO MO_V_Neg? Why?
- MO_VF_Neg length w -> do
- (reg_v, format_v, code_v) <- getSomeReg e
- let toFmt = VecFormat length (floatScalarFormat w)
- pure $ Any toFmt $ \dst ->
- code_v
- `snocOL` annExpr
- expr
- (VNEG (OpReg toFmt dst) (OpReg format_v reg_v))
x -> pprPanic ("getRegister' (monadic CmmMachOp): " ++ show x) (pdoc plat expr)
where
-- In the case of 16- or 8-bit values we need to sign-extend to 32-bits
@@ -919,15 +914,32 @@ getRegister' config plat expr =
where
shift = 64 - (widthInBits from - widthInBits to)
- vectorBroadcast :: Format -> NatM Register
- vectorBroadcast targetFormat = do
- (reg_val, format_val, code_val) <- getSomeReg e
+ vectorBroadcast :: Format -> CmmExpr -> NatM Register
+ vectorBroadcast targetFormat (CmmLit (CmmInt n _w)) | fitsIn5bitImm n =
+ -- Go for `vmv.v.i`
+ pure $ Any targetFormat $ \dst ->
+ unitOL
+ $ annExpr
+ expr
+ (VMV (OpReg targetFormat dst) (OpImm (ImmInteger n)))
+ vectorBroadcast targetFormat expr = do
+ -- Go for `vmv.v.x`
+ (reg_val, format_val, code_val) <- getSomeReg expr
pure $ Any targetFormat $ \dst ->
code_val
`snocOL` annExpr
expr
(VMV (OpReg targetFormat dst) (OpReg format_val reg_val))
+ vectorNegation :: Format -> NatM Register
+ vectorNegation targetFormat = do
+ (reg_v, format_v, code_v) <- getSomeReg e
+ pure $ Any targetFormat $ \dst ->
+ code_v
+ `snocOL` annExpr
+ expr
+ (VNEG (OpReg targetFormat dst) (OpReg format_v reg_v))
+
-- Dyadic machops:
--
-- The general idea is:
@@ -1277,8 +1289,11 @@ getRegister' config plat expr =
MO_V_Extract _length w -> vecExtract ((scalarFormatFormat . intScalarFormat) w)
MO_VF_Add length w -> vecOp (floatVecFormat length w) VADD
+ MO_V_Add length w -> vecOp (intVecFormat length w) VADD
MO_VF_Sub length w -> vecOp (floatVecFormat length w) VSUB
+ MO_V_Sub length w -> vecOp (intVecFormat length w) VSUB
MO_VF_Mul length w -> vecOp (floatVecFormat length w) VMUL
+ MO_V_Mul length w -> vecOp (intVecFormat length w) VMUL
MO_VF_Quot length w -> vecOp (floatVecFormat length w) VQUOT
-- See https://godbolt.org/z/PvcWKMKoW
MO_VS_Min length w -> vecOp (intVecFormat length w) VSMIN
@@ -1289,32 +1304,6 @@ getRegister' config plat expr =
MO_VF_Max length w -> vecOp (floatVecFormat length w) VFMAX
_e -> panic $ "Missing operation " ++ show expr
- -- Vectors
-
- --TODO: MO_V_Broadcast with immediate: If the right value is a literal,
- -- it may use vmv.v.i (simpler)
--- MO_V_Broadcast _length w -> do
--- (reg_v, format_v, code_v) <- getSomeReg x
--- (reg_idx, format_idx, code_idx) <- getSomeReg y
--- let w_v = formatToWidth format_v
--- w_idx = formatToWidth format_idx
--- pure $ Any (intFormat w) $ \dst ->
--- code_v `appOL`
--- code_idx `snocOL`
--- annExpr expr (VMV (OpReg w_v reg_v) (OpReg w_idx reg_idx)) `snocOL`
--- MOV (OpReg w dst) (OpReg w_v reg_v)
---
--- MO_VF_Broadcast _length w -> do
--- (reg_v, format_v, code_v) <- getSomeReg x
--- (reg_idx, format_idx, code_idx) <- getSomeReg y
--- let w_v = formatToWidth format_v
--- w_idx = formatToWidth format_idx
--- pure $ Any (intFormat w) $ \dst ->
--- code_v `appOL`
--- code_idx `snocOL`
--- annExpr expr (VMV (OpReg w_v reg_v) (OpReg w_idx reg_idx)) `snocOL`
--- MOV (OpReg w dst) (OpReg w_v reg_v)
-
-- Generic ternary case.
CmmMachOp op [x, y, z] ->
case op of
@@ -1343,17 +1332,6 @@ getRegister' config plat expr =
(VMV (OpReg targetFormat dst) (OpReg format_x reg_x))
`snocOL` VFMA var (OpReg targetFormat dst) (OpReg format_y reg_y) (OpReg format_z reg_z)
- -- TODO: Implement length as immediate
-
- -- insert_float_into_vector:
- -- vsetivli zero, 4, e32, m1, ta, ma
- -- vid.v v8
- -- vmseq.vi v0, v8, 2
- -- vfmv.v.f v8, fa0
- -- vmerge.vvm v8, v8, v8, v0
- -- ret
- --
- -- https://godbolt.org/z/sEG8MrM8P
MO_VF_Insert length width -> vecInsert floatVecFormat length width
MO_V_Insert length width -> vecInsert intVecFormat length width
_ ->
@@ -1380,12 +1358,14 @@ getRegister' config plat expr =
`snocOL` annExpr
expr
-- 1. fill elements with index numbers
- -- TODO: The Width is made up
- -- TODO: Is it safe to use v0 (default mask register) here? Instructions may be shuffled around...
- -- Can we use an explicitly fetched register as mask (depends on instructions)?
(VID (OpReg format_vid vidReg))
`snocOL`
- -- 2. Build mask
+ -- 2. Build mask (N.B. using v0 as mask could cause trouble
+ -- when the register allocator decides to move instructions.
+ -- However, VMERGE requires the mask to be in v0. If this
+ -- issue ever comes up, we could squeese the
+ -- pseudo-instructions below into a single one. Taking the
+ -- register allocator the chance to get between them.)
VMSEQ (OpReg format_mask v0Reg) (OpReg format_vid vidReg) (OpReg format_idx reg_idx)
`snocOL`
-- 3. Splat value into tmp vector
@@ -1699,21 +1679,25 @@ getAmode _platform _ expr =
-- fails when the right hand side is forced into a fixed register
-- (e.g. the result of a call).
+-- | Store the result of a `CmmExpr` to an address determined by a `CmmExpr`
assignMem :: Format -> CmmExpr -> CmmExpr -> NatM InstrBlock
-assignMem rep addrE srcE =
+assignMem rep addrExpr srcExpr =
do
- (src_reg, src_format, code) <- getSomeReg srcE
+ (src_reg, src_format, code) <- getSomeReg srcExpr
platform <- getPlatform
let w = formatToWidth rep
- Amode addr addr_code <- getAmode platform w addrE
- return $ COMMENT (text "CmmStore" <+> parens (text (show addrE)) <+> parens (text (show srcE)))
+ Amode addr addr_code <- getAmode platform w addrExpr
+ return $ COMMENT (text "CmmStore" <+> parens (text (show addrExpr)) <+> parens (text (show srcExpr)))
`consOL` ( code
`appOL` addr_code
`snocOL` STR rep (OpReg src_format src_reg) (OpAddr addr)
)
-assignReg :: Format -> CmmReg -> CmmExpr -> NatM InstrBlock
-assignReg _ reg src =
+-- | Assign the result of `CmmExpr` to `CmmReg`
+--
+-- The register can be a virtual or real register.
+assignReg :: CmmReg -> CmmExpr -> NatM InstrBlock
+assignReg reg src =
do
platform <- getPlatform
let dst = getRegisterReg platform reg
@@ -2159,8 +2143,14 @@ genCCall (PrimTarget mop) dest_regs arg_regs = do
MO_SubIntC _w -> unsupported mop
MO_U_Mul2 _w -> unsupported mop
MO_VS_Quot {} -> unsupported mop
- MO_VS_Rem {} -> unsupported mop
MO_VU_Quot {} -> unsupported mop
+ MO_VS_Rem length w
+ | [x, y] <- arg_regs,
+ [dst_reg] <- dest_regs -> vrem mop length w dst_reg x y Signed
+ MO_VS_Rem {} -> unsupported mop
+ MO_VU_Rem length w
+ | [x, y] <- arg_regs,
+ [dst_reg] <- dest_regs -> vrem mop length w dst_reg x y Unsigned
MO_VU_Rem {} -> unsupported mop
MO_I64X2_Min -> unsupported mop
MO_I64X2_Max -> unsupported mop
@@ -2285,6 +2275,25 @@ genCCall (PrimTarget mop) dest_regs arg_regs = do
let code = code_fx `appOL` op (OpReg fmt dst) (OpReg format_x reg_fx)
pure code
+ vrem :: CallishMachOp -> Int -> Width -> LocalReg -> CmmExpr -> CmmExpr -> Signage -> NatM InstrBlock
+ vrem mop length w dst_reg x y s = do
+ platform <- getPlatform
+ let dst = getRegisterReg platform (CmmLocal dst_reg)
+ format = intVecFormat length w
+ moDescr = pprCallishMachOp mop
+ (reg_x, format_x, code_x) <- getSomeReg x
+ (reg_y, format_y, code_y) <- getSomeReg y
+ massertPpr (isVecFormat format_x && isVecFormat format_y)
+ $ text "vecOp: non-vector operand. operands: "
+ <+> ppr format_x
+ <+> ppr format_y
+ pure
+ $ code_x
+ `appOL` code_y
+ `snocOL`
+ ann moDescr
+ (VREM s (OpReg format dst) (OpReg format_x reg_x) (OpReg format_y reg_y))
+
{- Note [RISCV64 far jumps]
~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -2524,6 +2533,7 @@ makeFarBranches {- only used when debugging -} _platform statics basic_blocks =
VSUB {} -> 2
VMUL {} -> 2
VQUOT {} -> 2
+ VREM {} -> 2
VSMIN {} -> 2
VSMAX {} -> 2
VUMIN {} -> 2
=====================================
compiler/GHC/CmmToAsm/RV64/Instr.hs
=====================================
@@ -114,12 +114,13 @@ regUsageOfInstr platform instr = case instr of
VMERGE dst op1 op2 opm -> usage (regOp op1 ++ regOp op2 ++ regOp opm, regOp dst)
VSLIDEDOWN dst op1 op2 -> usage (regOp op1 ++ regOp op2, regOp dst)
-- WARNING: VSETIVLI is a special case. It changes the interpretation of all vector registers!
- VSETIVLI (OpReg fmt reg) _ _ _ _ _ -> usage ([], [(reg, fmt)])
+ VSETIVLI (OpReg fmt reg) _ _ _ _ _ -> usage ([], [(reg, fmt)])
VNEG dst src1 -> usage (regOp src1, regOp dst)
VADD dst src1 src2 -> usage (regOp src1 ++ regOp src2, regOp dst)
VSUB dst src1 src2 -> usage (regOp src1 ++ regOp src2, regOp dst)
VMUL dst src1 src2 -> usage (regOp src1 ++ regOp src2, regOp dst)
VQUOT dst src1 src2 -> usage (regOp src1 ++ regOp src2, regOp dst)
+ VREM s dst src1 src2 -> usage (regOp src1 ++ regOp src2, regOp dst)
VSMIN dst src1 src2 -> usage (regOp src1 ++ regOp src2, regOp dst)
VSMAX dst src1 src2 -> usage (regOp src1 ++ regOp src2, regOp dst)
VUMIN dst src1 src2 -> usage (regOp src1 ++ regOp src2, regOp dst)
@@ -175,9 +176,10 @@ callerSavedRegisters =
where
toTuple :: Reg -> (Reg, Format)
toTuple r = (r, format r)
- format r | isIntReg r = II64
- | isFloatReg r = FF64
- | otherwise = panic $ "Unexpected register: " ++ show r
+ format r
+ | isIntReg r = II64
+ | isFloatReg r = FF64
+ | otherwise = panic $ "Unexpected register: " ++ show r
-- | Apply a given mapping to all the register references in this instruction.
patchRegsOfInstr :: Instr -> (Reg -> Reg) -> Instr
@@ -232,6 +234,7 @@ patchRegsOfInstr instr env = case instr of
VSUB o1 o2 o3 -> VSUB (patchOp o1) (patchOp o2) (patchOp o3)
VMUL o1 o2 o3 -> VMUL (patchOp o1) (patchOp o2) (patchOp o3)
VQUOT o1 o2 o3 -> VQUOT (patchOp o1) (patchOp o2) (patchOp o3)
+ VREM s o1 o2 o3 -> VREM s (patchOp o1) (patchOp o2) (patchOp o3)
VSMIN o1 o2 o3 -> VSMIN (patchOp o1) (patchOp o2) (patchOp o3)
VSMAX o1 o2 o3 -> VSMAX (patchOp o1) (patchOp o2) (patchOp o3)
VUMIN o1 o2 o3 -> VUMIN (patchOp o1) (patchOp o2) (patchOp o3)
@@ -386,10 +389,10 @@ mkLoadInstr _config (RegWithFormat reg fmt) delta slot =
]
where
fmt'
- | isVecFormat fmt
- = fmt
- | otherwise
- = scalarMoveFormat fmt
+ | isVecFormat fmt =
+ fmt
+ | otherwise =
+ scalarMoveFormat fmt
mkLdrSpImm imm =
ANN (text "Reload@" <> int (off - delta))
$ LDR fmt' (OpReg fmt' reg) (OpAddr (AddrRegImm spMachReg (ImmInt imm)))
@@ -410,7 +413,6 @@ scalarMoveFormat fmt
| isFloatFormat fmt = FF64
| otherwise = II64
-
-- | See if this instruction is telling us the current C stack delta
takeDeltaInstr :: Instr -> Maybe Int
takeDeltaInstr (ANN _ i) = takeDeltaInstr i
@@ -651,13 +653,11 @@ data Instr
FCVT FcvtVariant Operand Operand
| -- | Floating point ABSolute value
FABS Operand Operand
-
| -- | Min
-- dest = min(r1)
FMIN Operand Operand Operand
| -- | Max
FMAX Operand Operand Operand
-
| -- | Floating-point fused multiply-add instructions
--
-- - fmadd : d = r1 * r2 + r3
@@ -665,7 +665,6 @@ data Instr
-- - fmsub : d = - r1 * r2 + r3
-- - fnmadd: d = - r1 * r2 - r3
FMA FMASign Operand Operand Operand Operand
-
| -- TODO: Care about the variants (<instr>.x.y) -> sum type
VMV Operand Operand
| VID Operand
@@ -678,6 +677,7 @@ data Instr
| VSUB Operand Operand Operand
| VMUL Operand Operand Operand
| VQUOT Operand Operand Operand
+ | VREM Signage Operand Operand Operand
| VSMIN Operand Operand Operand
| VSMAX Operand Operand Operand
| VUMIN Operand Operand Operand
@@ -686,6 +686,9 @@ data Instr
| VFMAX Operand Operand Operand
| VFMA FMASign Operand Operand Operand
+data Signage = Signed | Unsigned
+ deriving (Eq, Show)
+
-- | Operand of a FENCE instruction (@r@, @w@ or @rw@)
data FenceType = FenceRead | FenceWrite | FenceReadWrite
@@ -757,6 +760,7 @@ instrCon i =
VSETIVLI {} -> "VSETIVLI"
VNEG {} -> "VNEG"
VADD {} -> "VADD"
+ VREM {} -> "VREM"
VSUB {} -> "VSUB"
VMUL {} -> "VMUL"
VQUOT {} -> "VQUOT"
@@ -910,17 +914,19 @@ d30 = operandFromRegNo FF64 62
d31 = operandFromRegNo FF64 d31RegNo
-fitsIn12bitImm :: (Num a, Ord a) => a -> Bool
-fitsIn12bitImm off = off >= intMin12bit && off <= intMax12bit
+fitsIn12bitImm :: (Num a, Ord a, Bits a) => a -> Bool
+fitsIn12bitImm = fitsInBits 12
-intMin12bit :: (Num a) => a
-intMin12bit = -2048
-
-intMax12bit :: (Num a) => a
-intMax12bit = 2047
+fitsIn5bitImm :: (Num a, Ord a, Bits a) => a -> Bool
+fitsIn5bitImm = fitsInBits 5
fitsIn32bits :: (Num a, Ord a, Bits a) => a -> Bool
-fitsIn32bits i = (-1 `shiftL` 31) <= i && i <= (1 `shiftL` 31 - 1)
+fitsIn32bits = fitsInBits 32
+
+fitsInBits :: (Num a, Ord a, Bits a) => Int -> a -> Bool
+fitsInBits n i = (-1 `shiftL` n') <= i && i <= (1 `shiftL` n' - 1)
+ where
+ n' = n - 1
isNbitEncodeable :: Int -> Integer -> Bool
isNbitEncodeable n i = let shift = n - 1 in (-1 `shiftL` shift) <= i && i < (1 `shiftL` shift)
@@ -952,7 +958,6 @@ isFloatImmOp _ = False
isFloatOp :: Operand -> Bool
isFloatOp op = isFloatRegOp op || isFloatImmOp op
--- TODO: Hide OpReg (Operand) constructor and use this guard to ensure only sane fmt/reg combinations can be used
assertFmtReg :: (HasCallStack) => Format -> Reg -> a -> a
assertFmtReg fmt reg | fmtRegCombinationIsSane fmt reg = id
assertFmtReg fmt reg =
@@ -987,3 +992,13 @@ isVectorReg _ = False
allVectorRegOps :: [Operand] -> Bool
allVectorRegOps = all isVectorRegOp
+
+allIntVectorRegOps :: [Operand] -> Bool
+allIntVectorRegOps = all $ isVectorFmtRegOp isIntScalarFormat
+
+isVectorFmtRegOp :: (ScalarFormat -> Bool) -> Operand -> Bool
+isVectorFmtRegOp p (OpReg (VecFormat _ sFmt) _r) | p sFmt = True
+isVectorFmtRegOp _ _ = False
+
+allFloatVectorRegOps :: [Operand] -> Bool
+allFloatVectorRegOps = all $ isVectorFmtRegOp isFloatScalarFormat
=====================================
compiler/GHC/CmmToAsm/RV64/Ppr.hs
=====================================
@@ -812,6 +812,7 @@ pprInstr platform instr = case instr of
| isFloatOp o1 && isVectorRegOp o2 -> op2 (text "\tvfmv" <> dot <> text "f" <> dot <> text "s") o1 o2
| isVectorRegOp o1 && isFloatOp o2 -> op2 (text "\tvfmv" <> dot <> opToVInstrSuffix o1 <> dot <> text "f") o1 o2
| isIntRegOp o1 && isVectorRegOp o2 -> op2 (text "\tvmv" <> dot <> text "x" <> dot <> text "s") o1 o2
+ | isVectorRegOp o1 && isIntImmOp o2 -> op2 (text "\tvmv" <> dot <> opToVInstrSuffix o1 <> dot <> text "i") o1 o2
| isVectorRegOp o1 && isIntRegOp o2 -> op2 (text "\tvmv" <> dot <> opToVInstrSuffix o1 <> dot <> text "x") o1 o2
| isVectorRegOp o1 && isVectorRegOp o2 -> op2 (text "\tvmv" <> dot <> opToVInstrSuffix o1 <> dot <> text "v") o1 o2
| True -> pprPanic "RV64.pprInstr - impossible vector move (VMV)" (pprOp platform o1 <+> pprOp platform o2 <+> text "fmt" <> colon <> (text . show) fmt)
@@ -840,16 +841,23 @@ pprInstr platform instr = case instr of
<> comma
<+> pprMasking ma
VSETIVLI o1 _ _ _ _ _ -> pprPanic "RV64.pprInstr - VSETIVLI wrong operands." (pprOp platform o1)
- VNEG o1 o2 | allVectorRegOps [o1, o2] -> op2 (text "\tvfneg.v") o1 o2
+ VNEG o1 o2 | allIntVectorRegOps [o1, o2] -> op2 (text "\tvneg.v") o1 o2
+ VNEG o1 o2 | allFloatVectorRegOps [o1, o2] -> op2 (text "\tvfneg.v") o1 o2
VNEG o1 o2 -> pprPanic "RV64.pprInstr - VNEG wrong operands." (pprOps platform [o1, o2])
- VADD o1 o2 o3 | allVectorRegOps [o1, o2, o3] -> op3 (text "\tvfadd.vv") o1 o2 o3
+ VADD o1 o2 o3 | allIntVectorRegOps [o1, o2, o3] -> op3 (text "\tvadd.vv") o1 o2 o3
+ VADD o1 o2 o3 | allFloatVectorRegOps [o1, o2, o3] -> op3 (text "\tvfadd.vv") o1 o2 o3
VADD o1 o2 o3 -> pprPanic "RV64.pprInstr - VADD wrong operands." (pprOps platform [o1, o2, o3])
- VSUB o1 o2 o3 | allVectorRegOps [o1, o2, o3] -> op3 (text "\tvfsub.vv") o1 o2 o3
+ VSUB o1 o2 o3 | allIntVectorRegOps [o1, o2, o3] -> op3 (text "\tvsub.vv") o1 o2 o3
+ VSUB o1 o2 o3 | allFloatVectorRegOps [o1, o2, o3] -> op3 (text "\tvfsub.vv") o1 o2 o3
VSUB o1 o2 o3 -> pprPanic "RV64.pprInstr - VSUB wrong operands." (pprOps platform [o1, o2, o3])
- VMUL o1 o2 o3 | allVectorRegOps [o1, o2, o3] -> op3 (text "\tvfmul.vv") o1 o2 o3
+ VMUL o1 o2 o3 | allIntVectorRegOps [o1, o2, o3] -> op3 (text "\tvmul.vv") o1 o2 o3
+ VMUL o1 o2 o3 | allFloatVectorRegOps [o1, o2, o3] -> op3 (text "\tvfmul.vv") o1 o2 o3
VMUL o1 o2 o3 -> pprPanic "RV64.pprInstr - VMUL wrong operands." (pprOps platform [o1, o2, o3])
VQUOT o1 o2 o3 | allVectorRegOps [o1, o2, o3] -> op3 (text "\tvfdiv.vv") o1 o2 o3
VQUOT o1 o2 o3 -> pprPanic "RV64.pprInstr - VQUOT wrong operands." (pprOps platform [o1, o2, o3])
+ VREM Signed o1 o2 o3 | allIntVectorRegOps [o1, o2, o3] -> op3 (text "\tvrem.vv") o1 o2 o3
+ VREM Unsigned o1 o2 o3 | allIntVectorRegOps [o1, o2, o3] -> op3 (text "\tvremu.vv") o1 o2 o3
+ VREM s o1 o2 o3 -> pprPanic ("RV64.pprInstr - VREM wrong operands. " ++ show s) (pprOps platform [o1, o2, o3])
VSMIN o1 o2 o3 | allVectorRegOps [o1, o2, o3] -> op3 (text "\tvmin.vv") o1 o2 o3
VSMIN o1 o2 o3 -> pprPanic "RV64.pprInstr - VSMIN wrong operands." (pprOps platform [o1, o2, o3])
VSMAX o1 o2 o3 | allVectorRegOps [o1, o2, o3] -> op3 (text "\tvmax.vv") o1 o2 o3
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/242564bdfe880c26228324e8ff9786…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/242564bdfe880c26228324e8ff9786…
You're receiving this email because of your account on gitlab.haskell.org.
1
0

[Git][ghc/ghc][wip/marge_bot_batch_merge_job] 5 commits: RTS: remove target info and fix host info (#24058)
by Marge Bot (@marge-bot) 19 Apr '25
by Marge Bot (@marge-bot) 19 Apr '25
19 Apr '25
Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC
Commits:
b96e2f77 by Sylvain Henry at 2025-04-18T20:46:33-04:00
RTS: remove target info and fix host info (#24058)
The RTS isn't a compiler, hence it doesn't have a target and we remove
the reported target info displayed by "+RTS --info". We also fix the
host info displayed by "+RTS --info": the host of the RTS is the
RTS-building compiler's target, not the compiler's host (wrong when
doing cross-compilation).
- - - - -
6d9965f4 by Sylvain Henry at 2025-04-18T20:46:33-04:00
RTS: remove build info
As per the discussion in !13967, there is no reason to tag the RTS with
information about the build platform.
- - - - -
d52e9b3f by Vladislav Zavialov at 2025-04-18T20:47:15-04:00
Diagnostics: remove the KindMismatch constructor (#25957)
The KindMismatch constructor was only used as an intermediate
representation in pretty-printing.
Its removal addresses a problem detected by the "codes" test case:
[GHC-89223] is untested (constructor = KindMismatch)
In a concious deviation from the usual procedure, the error code
GHC-89223 is removed entirely rather than marked as Outdated.
The reason is that it never was user-facing in the first place.
- - - - -
d5badca1 by Serge S. Gulin at 2025-04-19T13:37:38-04:00
Support for ARM64 Windows (LLVM-enabled) (fixes #24603)
submodule
Co-authored-by: Cheng Shao <terrorjack(a)type.dance>
Co-authored-by: Dmitrii Egorov <egorov.d.i(a)icloud.com>
Co-authored-by: Andrei Borzenkov <root(a)sandwitch.dev>
- - - - -
5d761a4e by Vladislav Zavialov at 2025-04-19T13:37:39-04:00
Add name for -Wunusable-unpack-pragmas
This warning had no name or flag and was triggered unconditionally.
Now it is part of -Wdefault.
In GHC.Tc.TyCl.tcTyClGroupsPass's strict mode, we now have to
force-enable this warning to ensure that detection of flawed groups
continues to work even if the user disables the warning with the
-Wno-unusable-unpack-pragmas option. Test case: T3990c
Also, the misnamed BackpackUnpackAbstractType is now called
UnusableUnpackPragma.
- - - - -
57 changed files:
- .gitlab-ci.yml
- .gitlab/ci.sh
- .gitlab/generate-ci/gen_ci.hs
- .gitlab/hello.hs
- .gitlab/jobs.yaml
- compiler/CodeGen.Platform.h
- compiler/GHC/CmmToAsm/AArch64/CodeGen.hs
- compiler/GHC/CmmToAsm/AArch64/Instr.hs
- compiler/GHC/CmmToAsm/AArch64/Ppr.hs
- compiler/GHC/CmmToAsm/Reg/Linear/AArch64.hs
- compiler/GHC/Driver/Flags.hs
- compiler/GHC/Driver/Session.hs
- compiler/GHC/Platform/Regs.hs
- compiler/GHC/Tc/Errors/Ppr.hs
- compiler/GHC/Tc/Errors/Types.hs
- compiler/GHC/Tc/TyCl.hs
- compiler/GHC/Tc/Utils/Monad.hs
- compiler/GHC/Types/Error/Codes.hs
- configure.ac
- docs/users_guide/9.14.1-notes.rst
- docs/users_guide/using-warnings.rst
- hadrian/src/Oracles/Setting.hs
- hadrian/src/Rules/BinaryDist.hs
- hadrian/src/Settings/Packages.hs
- libraries/Cabal
- libraries/Win32
- libraries/base/src/System/CPUTime/Windows.hsc
- libraries/base/tests/perf/encodingAllocations.hs
- libraries/directory
- libraries/haskeline
- libraries/process
- libraries/unix
- llvm-targets
- m4/fp_cc_supports_target.m4
- m4/fptools_set_platform_vars.m4
- m4/ghc_tables_next_to_code.m4
- rts/RtsUtils.c
- rts/StgCRun.c
- rts/linker/PEi386.c
- rts/win32/veh_excn.c
- testsuite/ghc-config/ghc-config.hs
- testsuite/tests/diagnostic-codes/codes.stdout
- testsuite/tests/simplCore/should_compile/Makefile
- testsuite/tests/simplCore/should_compile/T23307c.stderr
- + testsuite/tests/simplCore/should_compile/T3990c.hs
- + testsuite/tests/simplCore/should_compile/T3990c.stdout
- testsuite/tests/simplCore/should_compile/all.T
- testsuite/tests/simplCore/should_fail/T25672.stderr
- testsuite/tests/typecheck/should_compile/T7050.stderr
- testsuite/tests/typecheck/should_fail/T3966.stderr
- + testsuite/tests/typecheck/should_fail/T3966b.hs
- + testsuite/tests/typecheck/should_fail/T3966b.stderr
- testsuite/tests/typecheck/should_fail/all.T
- testsuite/tests/unboxedsums/unpack_sums_5.stderr
- utils/ghc-toolchain/exe/Main.hs
- utils/hsc2hs
- utils/llvm-targets/gen-data-layout.sh
The diff was not included because it is too large.
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/9c42eba1b6304cf66d29bf8bf172d5…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/9c42eba1b6304cf66d29bf8bf172d5…
You're receiving this email because of your account on gitlab.haskell.org.
1
0

[Git][ghc/ghc][wip/int-index/unusable-unpack-pragma-flag] Add name for -Wunusable-unpack-pragmas
by Vladislav Zavialov (@int-index) 19 Apr '25
by Vladislav Zavialov (@int-index) 19 Apr '25
19 Apr '25
Vladislav Zavialov pushed to branch wip/int-index/unusable-unpack-pragma-flag at Glasgow Haskell Compiler / GHC
Commits:
a83bbd11 by Vladislav Zavialov at 2025-04-19T17:27:34+03:00
Add name for -Wunusable-unpack-pragmas
This warning had no name or flag and was triggered unconditionally.
Now it is part of -Wdefault.
In GHC.Tc.TyCl.tcTyClGroupsPass's strict mode, we now have to
force-enable this warning to ensure that detection of flawed groups
continues to work even if the user disables the warning with the
-Wno-unusable-unpack-pragmas option. Test case: T3990c
Also, the misnamed BackpackUnpackAbstractType is now called
UnusableUnpackPragma.
- - - - -
21 changed files:
- compiler/GHC/Driver/Flags.hs
- compiler/GHC/Driver/Session.hs
- compiler/GHC/Tc/Errors/Ppr.hs
- compiler/GHC/Tc/Errors/Types.hs
- compiler/GHC/Tc/TyCl.hs
- compiler/GHC/Tc/Utils/Monad.hs
- compiler/GHC/Types/Error/Codes.hs
- docs/users_guide/9.14.1-notes.rst
- docs/users_guide/using-warnings.rst
- testsuite/tests/simplCore/should_compile/Makefile
- testsuite/tests/simplCore/should_compile/T23307c.stderr
- + testsuite/tests/simplCore/should_compile/T3990c.hs
- + testsuite/tests/simplCore/should_compile/T3990c.stdout
- testsuite/tests/simplCore/should_compile/all.T
- testsuite/tests/simplCore/should_fail/T25672.stderr
- testsuite/tests/typecheck/should_compile/T7050.stderr
- testsuite/tests/typecheck/should_fail/T3966.stderr
- + testsuite/tests/typecheck/should_fail/T3966b.hs
- + testsuite/tests/typecheck/should_fail/T3966b.stderr
- testsuite/tests/typecheck/should_fail/all.T
- testsuite/tests/unboxedsums/unpack_sums_5.stderr
Changes:
=====================================
compiler/GHC/Driver/Flags.hs
=====================================
@@ -1098,6 +1098,7 @@ data WarningFlag =
-- ^ @since 9.14, scheduled to be removed in 9.18
--
-- See Note [Quantifying over equalities in RULES] in GHC.Tc.Gen.Sig
+ | Opt_WarnUnusableUnpackPragmas -- Since 9.14
deriving (Eq, Ord, Show, Enum, Bounded)
-- | Return the names of a WarningFlag
@@ -1217,6 +1218,7 @@ warnFlagNames wflag = case wflag of
Opt_WarnUselessSpecialisations -> "useless-specialisations" :| ["useless-specializations"]
Opt_WarnDeprecatedPragmas -> "deprecated-pragmas" :| []
Opt_WarnRuleLhsEqualities -> "rule-lhs-equalities" :| []
+ Opt_WarnUnusableUnpackPragmas -> "unusable-unpack-pragmas" :| []
-- -----------------------------------------------------------------------------
-- Standard sets of warning options
@@ -1362,7 +1364,8 @@ standardWarnings -- see Note [Documenting warning flags]
Opt_WarnViewPatternSignatures,
Opt_WarnUselessSpecialisations,
Opt_WarnDeprecatedPragmas,
- Opt_WarnRuleLhsEqualities
+ Opt_WarnRuleLhsEqualities,
+ Opt_WarnUnusableUnpackPragmas
]
-- | Things you get with @-W@.
=====================================
compiler/GHC/Driver/Session.hs
=====================================
@@ -2384,6 +2384,7 @@ wWarningFlagsDeps = [minBound..maxBound] >>= \x -> case x of
Opt_WarnUselessSpecialisations -> warnSpec x
Opt_WarnDeprecatedPragmas -> warnSpec x
Opt_WarnRuleLhsEqualities -> warnSpec x
+ Opt_WarnUnusableUnpackPragmas -> warnSpec x
warningGroupsDeps :: [(Deprecation, FlagSpec WarningGroup)]
warningGroupsDeps = map mk warningGroups
=====================================
compiler/GHC/Tc/Errors/Ppr.hs
=====================================
@@ -2504,6 +2504,8 @@ instance Diagnostic TcRnMessage where
-> WarningWithFlag Opt_WarnIncompleteRecordSelectors
TcRnBadFieldAnnotation _ _ LazyFieldsDisabled
-> ErrorWithoutFlag
+ TcRnBadFieldAnnotation _ _ UnusableUnpackPragma
+ -> WarningWithFlag Opt_WarnUnusableUnpackPragmas
TcRnBadFieldAnnotation{}
-> WarningWithoutFlag
TcRnSuperclassCycle{}
@@ -5802,7 +5804,7 @@ pprBadFieldAnnotationReason = \case
text "Lazy field annotations (~) are disabled"
UnpackWithoutStrictness ->
text "UNPACK pragma lacks '!'"
- BackpackUnpackAbstractType ->
+ UnusableUnpackPragma ->
text "Ignoring unusable UNPACK pragma"
pprSuperclassCycleDetail :: SuperclassCycleDetail -> SDoc
=====================================
compiler/GHC/Tc/Errors/Types.hs
=====================================
@@ -6257,13 +6257,28 @@ data BadFieldAnnotationReason where
T14761a, T7562
-}
UnpackWithoutStrictness :: BadFieldAnnotationReason
- {-| An UNPACK pragma was applied to an abstract type in an indefinite package
- in Backpack.
+ {-| An UNPACK pragma is unusable.
+
+ A possible reason for this warning is that the UNPACK pragma was applied to
+ one of the following:
+
+ * a function type @a -> b@
+ * a recursive use of the data type being defined
+ * a sum type that cannot be unpacked, see @Note [UNPACK for sum types]@
+ * a type/data family application with no matching instance in the environment
+
+ However, it is deliberately /not/ emitted if:
+
+ * the failure occurs in an indefinite package in Backpack
+ * the pragma is usable, but unpacking is disabled by @-O0@
Test cases:
- unpack_sums_5, T3966, T7050
+ unpack_sums_5, T3966, T7050, T25672, T23307c
+
+ Negative test cases (must not trigger this warning):
+ T3990
-}
- BackpackUnpackAbstractType :: BadFieldAnnotationReason
+ UnusableUnpackPragma :: BadFieldAnnotationReason
deriving (Generic)
data SuperclassCycle =
=====================================
compiler/GHC/Tc/TyCl.hs
=====================================
@@ -322,7 +322,7 @@ splice to separate the module and force the desired order of kind-checking:
data D1 = MkD1 !(F Int) -- now (F Int) surely gets unpacked
The current version of GHC is more predictable. Neither the (Complex Double) nor
-the (F Int) example gets unpacking, the type/data instance is put into a
+the (F Int) example gets unpacking unless the type/data instance is put into a
separate HsGroup, either with $(return []) or by placing it in another module
altogether. This is a direct result of placing instances after the other SCCs,
as described in Note [Put instances at the end] in GHC.Rename.Module
@@ -449,11 +449,20 @@ tcTyClGroupsPass all_gs thing_inside = go True ttcgs_zero mempty nilOL all_gs
-- pass, the current group's lexical dependencies must have been
-- satisfied by the preceding groups; no need for the ready check,
-- this avoids some lookups in tcg_env
+
+ -- See Note [Expedient use of diagnostics in tcTyClGroupsPass]
+ set_opts action
+ | strict = setWOptM Opt_WarnUnusableUnpackPragmas action
+ | otherwise = action
+ validate _ msgs _
+ | strict = not (unpackErrorsFound msgs)
+ | otherwise = True
+
if not ready then return on_blocked else
- tryTcDiscardingErrs' (\_ msgs _ -> not (strict && unpackErrorsFound msgs))
+ tryTcDiscardingErrs' validate
(return on_flawed)
(return on_failed)
- (on_success <$> tcTyClGroup g)
+ (on_success <$> set_opts (tcTyClGroup g))
data TcTyClGroupsStats =
TcTyClGroupsStats
@@ -479,15 +488,36 @@ instance Outputable TcTyClGroupsStats where
, text "n_failed =" <+> ppr (ttcgs_n_failed stats)
, text "n_flawed =" <+> ppr (ttcgs_n_flawed stats) ]
+-- See Note [Expedient use of diagnostics in tcTyClGroupsPass]
unpackErrorsFound :: Messages TcRnMessage -> Bool
unpackErrorsFound = any is_unpack_error
where
is_unpack_error :: TcRnMessage -> Bool
is_unpack_error (TcRnMessageWithInfo _ (TcRnMessageDetailed _ msg)) = is_unpack_error msg
is_unpack_error (TcRnWithHsDocContext _ msg) = is_unpack_error msg
- is_unpack_error (TcRnBadFieldAnnotation _ _ BackpackUnpackAbstractType) = True
+ is_unpack_error (TcRnBadFieldAnnotation _ _ UnusableUnpackPragma) = True
is_unpack_error _ = False
+{- Note [Expedient use of diagnostics in tcTyClGroupsPass]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+In tcTyClGroupsPass.go with strict=True, we want to skip "flawed" groups, i.e.
+groups with unusable unpack pragmas, as explained in Note [Retrying TyClGroups].
+To detect these unusable {-# UNPACK #-} pragmas, we currently piggy-back on the
+diagnostics infrastructure:
+
+ 1. (setWOptM Opt_WarnUnusableUnpackPragmas) to enable the warning.
+ The warning is on by default, but the user may have disabled it with
+ -Wno-unusable-unpack-pragmas, in which case we need to turn it back on.
+
+ 2. (unpackErrorsFound msgs) to check if UnusableUnpackPragma is one of the
+ collected diagnostics. This is somewhat unpleasant because of the need to
+ recurse into TcRnMessageWithInfo and TcRnWithHsDocContext.
+
+Arguably, this is not a principled solution, because diagnostics are meant for
+the user and here we inspect them to determine the order of type-checking. The
+only reason for the current setup is that it was the easy thing to do.
+-}
+
isReadyTyClGroup :: TcGblEnv -> TyClGroup GhcRn -> Bool
isReadyTyClGroup tcg_env TyClGroup{group_ext = deps} =
nameSetAll (\n -> n `elemNameEnv` tcg_type_env tcg_env) deps
@@ -5123,7 +5153,7 @@ checkValidDataCon dflags existential_ok tc con
-- warn in this case (it gives users the wrong idea about whether
-- or not UNPACK on abstract types is supported; it is!)
, isHomeUnitDefinite (hsc_home_unit hsc_env)
- = addDiagnosticTc (bad_bang n BackpackUnpackAbstractType)
+ = addDiagnosticTc (bad_bang n UnusableUnpackPragma)
| otherwise
= return ()
=====================================
compiler/GHC/Tc/Utils/Monad.hs
=====================================
@@ -20,7 +20,8 @@ module GHC.Tc.Utils.Monad(
updTopFlags,
getEnvs, setEnvs, updEnvs, restoreEnvs,
xoptM, doptM, goptM, woptM,
- setXOptM, unsetXOptM, unsetGOptM, unsetWOptM,
+ setXOptM, setWOptM,
+ unsetXOptM, unsetGOptM, unsetWOptM,
whenDOptM, whenGOptM, whenWOptM,
whenXOptM, unlessXOptM,
getGhcMode,
@@ -579,6 +580,9 @@ woptM flag = wopt flag <$> getDynFlags
setXOptM :: LangExt.Extension -> TcRnIf gbl lcl a -> TcRnIf gbl lcl a
setXOptM flag = updTopFlags (\dflags -> xopt_set dflags flag)
+setWOptM :: WarningFlag -> TcRnIf gbl lcl a -> TcRnIf gbl lcl a
+setWOptM flag = updTopFlags (\dflags -> wopt_set dflags flag)
+
unsetXOptM :: LangExt.Extension -> TcRnIf gbl lcl a -> TcRnIf gbl lcl a
unsetXOptM flag = updTopFlags (\dflags -> xopt_unset dflags flag)
=====================================
compiler/GHC/Types/Error/Codes.hs
=====================================
@@ -711,7 +711,7 @@ type family GhcDiagnosticCode c = n | n -> c where
-- TcRnBadFieldAnnotation/BadFieldAnnotationReason
GhcDiagnosticCode "LazyFieldsDisabled" = 81601
GhcDiagnosticCode "UnpackWithoutStrictness" = 10107
- GhcDiagnosticCode "BackpackUnpackAbstractType" = 40091
+ GhcDiagnosticCode "UnusableUnpackPragma" = 40091
-- TcRnRoleValidationFailed/RoleInferenceFailedReason
GhcDiagnosticCode "TyVarRoleMismatch" = 22221
=====================================
docs/users_guide/9.14.1-notes.rst
=====================================
@@ -25,17 +25,6 @@ Language
This deprecation is controlled by the newly introduced ``-Wdeprecated-pragmas``
flag in ``-Wdefault``.
-* A new flag, ``-Wuseless-specialisations``, controls warnings emitted when GHC
- determines that a SPECIALISE pragma would have no effect.
-
-* A new flag, ``-Wrule-lhs-equalities``, controls warnings emitted for RULES
- whose left-hand side attempts to quantify over equality constraints that
- previous GHC versions accepted quantifying over. GHC will now drop such RULES,
- emitting a warning message controlled by this flag.
-
- This warning is intended to give visibility to the fact that the RULES that
- previous GHC versions generated in such circumstances could never fire.
-
* ``-Wincomplete-record-selectors`` is now part of `-Wall`, as specified
by `GHC Proposal 516: add warning for incomplete record selectors <https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0516-i…>`_.
Hence, if a library is compiled with ``-Werror``, compilation may now fail. Solution: fix the library.
@@ -93,6 +82,25 @@ Compiler
:ghc-ticket:`20875`, :ghc-ticket:`21172`, :ghc-ticket:`22257`, :ghc-ticket:`25238`,
:ghc-ticket:`25834`.
+- A new flag, :ghc-flag:`-Wuseless-specialisations`, controls warnings emitted when GHC
+ determines that a SPECIALISE pragma would have no effect.
+
+- A new flag, :ghc-flag:`-Wrule-lhs-equalities`, controls warnings emitted for RULES
+ whose left-hand side attempts to quantify over equality constraints that
+ previous GHC versions accepted quantifying over. GHC will now drop such RULES,
+ emitting a warning message controlled by this flag.
+
+ This warning is intended to give visibility to the fact that the RULES that
+ previous GHC versions generated in such circumstances could never fire.
+
+- A new flag, :ghc-flag:`-Wunusable-unpack-pragmas`, controls warnings emitted
+ when GHC is unable to unpack a data constructor field annotated by the
+ ``{-# UNPACK #-}`` pragma.
+
+ Previous GHC versions issued this warning unconditionally. Now it is possible
+ to disable it with ``-Wno-unusable-unpack-pragmas`` or turn it into an error
+ with ``-Werror=unusable-unpack-pragmas``.
+
GHCi
~~~~
=====================================
docs/users_guide/using-warnings.rst
=====================================
@@ -84,6 +84,7 @@ as ``-Wno-...`` for every individual warning in the group.
* :ghc-flag:`-Wnoncanonical-monad-instances`
* :ghc-flag:`-Wdata-kinds-tc`
* :ghc-flag:`-Wimplicit-rhs-quantification`
+ * :ghc-flag:`-Wunusable-unpack-pragmas`
.. ghc-flag:: -W
:shortdesc: enable normal warnings
@@ -2646,6 +2647,40 @@ of ``-W(no-)*``.
To make the code forwards-compatible and silence the warning, users are
advised to add parentheses manually.
+.. ghc-flag:: -Wunusable-unpack-pragmas
+ :shortdesc: warn when an ``{-# UNPACK #-}`` pragma is unusable
+ :type: dynamic
+ :reverse: -Wno-unusable-unpack-pragmas
+
+ :since: 9.14.1
+ :default: on
+
+ Warn on unusable ``{-# UNPACK #-}`` pragmas in data type declarations.
+ Examples::
+
+ data T = MkT {-# UNPACK #-} !(Int -> Bool)
+
+ data G where
+ MkG :: {-# UNPACK #-} !G -> G
+
+ type family F a where {}
+ data R a = MkR { fld :: {-# UNPACK #-} !(F a) }
+
+ A possible reason for this warning is that the ``{-# UNPACK #-}`` pragma was
+ applied to one of the following:
+
+ * a function type ``a -> b``
+ * a recursive use of the data type being defined
+ * a sum type that cannot be unpacked
+ * a type/data family application with no matching instance in the environment
+
+ However, it is deliberately **not** emitted if:
+
+ * the failure occurs in an indefinite package in Backpack
+ * the pragma is usable, but unpacking is disabled by :ghc-flag:`-O0`
+
+----
+
If you're feeling really paranoid, the :ghc-flag:`-dcore-lint` option is a good choice.
It turns on heavyweight intra-pass sanity-checking within GHC. (It checks GHC's
sanity, not yours.)
=====================================
testsuite/tests/simplCore/should_compile/Makefile
=====================================
@@ -43,6 +43,11 @@ T3990b:
'$(TEST_HC)' $(TEST_HC_OPTS) -O -c -ddump-simpl T3990b.hs | grep 'test_case'
# Grep output should show an unpacked constructor
+T3990c:
+ $(RM) -f T3990c.o T3990c.hi
+ '$(TEST_HC)' $(TEST_HC_OPTS) -O -c -ddump-simpl T3990c.hs | grep 'test_case'
+ # Grep output should show an unpacked constructor
+
T8848:
$(RM) -f T8848.o T8848.hi
'$(TEST_HC)' $(TEST_HC_OPTS) -O -c -ddump-rule-firings T8848.hs | grep 'SPEC map2'
=====================================
testsuite/tests/simplCore/should_compile/T23307c.stderr
=====================================
@@ -1,5 +1,5 @@
-
-T23307c.hs:7:13: warning: [GHC-40091]
+T23307c.hs:7:13: warning: [GHC-40091] [-Wunusable-unpack-pragmas (in -Wdefault)]
• Ignoring unusable UNPACK pragma on the first argument of ‘LCon’
• In the definition of data constructor ‘LCon’
In the data type declaration for ‘Loop’
+
=====================================
testsuite/tests/simplCore/should_compile/T3990c.hs
=====================================
@@ -0,0 +1,18 @@
+{-# OPTIONS -Wno-unusable-unpack-pragmas #-}
+ -- The warning is disabled, but this should not affect unpacking
+
+{-# LANGUAGE TypeFamilies #-}
+module T3990c where
+
+type family F a
+
+data D1 = MkD1 {-# UNPACK #-} !(F Int)
+ -- This should actually get unpacked
+
+data D2 = MkD2 {-# UNPACK #-} !Int
+ {-# UNPACK #-} !Int
+
+type instance F Int = D2
+
+test_case :: D1
+test_case = MkD1 (MkD2 1 1)
=====================================
testsuite/tests/simplCore/should_compile/T3990c.stdout
=====================================
@@ -0,0 +1,2 @@
+test_case :: D1
+test_case = T3990c.MkD1 1# 1#
=====================================
testsuite/tests/simplCore/should_compile/all.T
=====================================
@@ -211,6 +211,7 @@ test('T11742', normal, compile, ['-O2'])
test('T11644', normal, compile, ['-O2'])
test('T3990', normal, makefile_test, ['T3990'])
test('T3990b', normal, makefile_test, ['T3990b'])
+test('T3990c', normal, makefile_test, ['T3990c'])
test('T12076', [], multimod_compile, ['T12076', '-v0'])
test('T12076lit', normal, compile, ['-O'])
=====================================
testsuite/tests/simplCore/should_fail/T25672.stderr
=====================================
@@ -1,4 +1,4 @@
-T25672.hs:12:7: warning: [GHC-40091]
+T25672.hs:12:7: warning: [GHC-40091] [-Wunusable-unpack-pragmas (in -Wdefault)]
• Ignoring unusable UNPACK pragma
on the first argument of ‘WrapIntOrWord’
• In the definition of data constructor ‘WrapIntOrWord’
=====================================
testsuite/tests/typecheck/should_compile/T7050.stderr
=====================================
@@ -1,5 +1,5 @@
-
-T7050.hs:3:14: warning: [GHC-40091]
+T7050.hs:3:14: warning: [GHC-40091] [-Wunusable-unpack-pragmas (in -Wdefault)]
• Ignoring unusable UNPACK pragma on the first argument of ‘Foo’
• In the definition of data constructor ‘Foo’
In the data type declaration for ‘Foo’
+
=====================================
testsuite/tests/typecheck/should_fail/T3966.stderr
=====================================
@@ -1,5 +1,5 @@
-
-T3966.hs:5:16: error: [GHC-40091] [-Werror]
+T3966.hs:5:16: error: [GHC-40091] [-Wunusable-unpack-pragmas (in -Wdefault), Werror=unusable-unpack-pragmas]
• Ignoring unusable UNPACK pragma on the first argument of ‘Foo’
• In the definition of data constructor ‘Foo’
In the data type declaration for ‘Foo’
+
=====================================
testsuite/tests/typecheck/should_fail/T3966b.hs
=====================================
@@ -0,0 +1,12 @@
+{-# OPTIONS -Werror=unusable-unpack-pragmas #-}
+{-# LANGUAGE TypeFamilies #-}
+
+module T3966b where
+
+data T = MkT {-# UNPACK #-} !(Int -> Bool)
+
+data G where
+ MkG :: {-# UNPACK #-} !G -> G
+
+type family F a where {}
+data R a = MkR { fld :: {-# UNPACK #-} !(F a) }
=====================================
testsuite/tests/typecheck/should_fail/T3966b.stderr
=====================================
@@ -0,0 +1,15 @@
+T3966b.hs:6:10: error: [GHC-40091] [-Wunusable-unpack-pragmas (in -Wdefault), Werror=unusable-unpack-pragmas]
+ • Ignoring unusable UNPACK pragma on the first argument of ‘MkT’
+ • In the definition of data constructor ‘MkT’
+ In the data type declaration for ‘T’
+
+T3966b.hs:9:3: error: [GHC-40091] [-Wunusable-unpack-pragmas (in -Wdefault), Werror=unusable-unpack-pragmas]
+ • Ignoring unusable UNPACK pragma on the first argument of ‘MkG’
+ • In the definition of data constructor ‘MkG’
+ In the data type declaration for ‘G’
+
+T3966b.hs:12:12: error: [GHC-40091] [-Wunusable-unpack-pragmas (in -Wdefault), Werror=unusable-unpack-pragmas]
+ • Ignoring unusable UNPACK pragma on the first argument of ‘MkR’
+ • In the definition of data constructor ‘MkR’
+ In the data type declaration for ‘R’
+
=====================================
testsuite/tests/typecheck/should_fail/all.T
=====================================
@@ -213,6 +213,7 @@ test('T3613', normal, compile_fail, [''])
test('fd-loop', normal, compile_fail, [''])
test('T3950', normal, compile_fail, [''])
test('T3966', normal, compile_fail, [''])
+test('T3966b', normal, compile_fail, [''])
test('IPFail', normal, compile_fail, [''])
test('T3468', [], multimod_compile_fail, ['T3468', '-v0'])
=====================================
testsuite/tests/unboxedsums/unpack_sums_5.stderr
=====================================
@@ -1,10 +1,10 @@
-
-unpack_sums_5.hs:4:22: warning: [GHC-40091]
+unpack_sums_5.hs:4:22: warning: [GHC-40091] [-Wunusable-unpack-pragmas (in -Wdefault)]
• Ignoring unusable UNPACK pragma on the first argument of ‘JustT’
• In the definition of data constructor ‘JustT’
In the data type declaration for ‘SMaybeT’
-unpack_sums_5.hs:7:10: warning: [GHC-40091]
+unpack_sums_5.hs:7:10: warning: [GHC-40091] [-Wunusable-unpack-pragmas (in -Wdefault)]
• Ignoring unusable UNPACK pragma on the first argument of ‘MkT’
• In the definition of data constructor ‘MkT’
In the data type declaration for ‘T’
+
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a83bbd1152bf3eb76c21ab60c2a1631…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a83bbd1152bf3eb76c21ab60c2a1631…
You're receiving this email because of your account on gitlab.haskell.org.
1
0