diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,9 @@
 # Changelog for the [`ghc-typelits-natnormalise`](http://hackage.haskell.org/package/ghc-typelits-natnormalise) package
 
+## 0.7.5 *June 17th 2021*
+* Fixes [#52](https://github.com/clash-lang/ghc-typelits-natnormalise/issues/50) Plugin doesn't solve inside arbitrary class constraints
+* Build on GHC 9.2.0.20210422
+
 ## 0.7.4 *February 12th 2021*
 * Fixes [#50](https://github.com/clash-lang/ghc-typelits-natnormalise/issues/50) `x ^ C ~ y` erroneously deemed hard insoluable, a contradiction, when `C` is some type family other than +,-,*,^
 
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
 # ghc-typelits-natnormalise
 
-[![Build Status](https://secure.travis-ci.org/clash-lang/ghc-typelits-natnormalise.svg?branch=master)](http://travis-ci.org/clash-lang/ghc-typelits-natnormalise)
+[![Build Status](https://github.com/clash-lang/ghc-typelits-natnormalise/actions/workflows/haskell-ci.yml/badge.svg?branch=master)](https://github.com/clash-lang/ghc-typelits-natnormalise/actions)
 [![Hackage](https://img.shields.io/hackage/v/ghc-typelits-natnormalise.svg)](https://hackage.haskell.org/package/ghc-typelits-natnormalise)
 [![Hackage Dependencies](https://img.shields.io/hackage-deps/v/ghc-typelits-natnormalise.svg?style=flat)](http://packdeps.haskellers.com/feed?needle=exact%3Aghc-typelits-natnormalise)
 
diff --git a/ghc-typelits-natnormalise.cabal b/ghc-typelits-natnormalise.cabal
--- a/ghc-typelits-natnormalise.cabal
+++ b/ghc-typelits-natnormalise.cabal
@@ -1,5 +1,5 @@
 name:                ghc-typelits-natnormalise
-version:             0.7.4
+version:             0.7.5
 synopsis:            GHC typechecker plugin for types of kind GHC.TypeLits.Nat
 description:
   A type checker plugin for GHC that can solve /equalities/ and /inequalities/
@@ -49,7 +49,7 @@
                      CHANGELOG.md
 cabal-version:       >=1.10
 tested-with:         GHC == 8.0.2, GHC == 8.2.2, GHC == 8.4.4, GHC == 8.6.5,
-                     GHC == 8.8.4, GHC == 8.10.3, GHC == 9.0.1
+                     GHC == 8.8.4, GHC == 8.10.4, GHC == 9.0.1
 
 source-repository head
   type: git
@@ -67,7 +67,7 @@
                        GHC.TypeLits.Normalise.Unify
   build-depends:       base                >=4.9   && <5,
                        containers          >=0.5.7.1 && <0.7,
-                       ghc                 >=8.0.1 && <9.2,
+                       ghc                 >=8.0.1 && <9.4,
                        ghc-tcplugins-extra >=0.3.1,
                        transformers        >=0.5.2.0 && < 0.6
   if impl(ghc >= 9.0.0)
diff --git a/src/GHC/TypeLits/Normalise.hs b/src/GHC/TypeLits/Normalise.hs
--- a/src/GHC/TypeLits/Normalise.hs
+++ b/src/GHC/TypeLits/Normalise.hs
@@ -169,6 +169,9 @@
 import Data.Maybe          (mapMaybe, catMaybes)
 import Data.Set            (Set, empty, toList, notMember, fromList, union)
 import GHC.TcPluginM.Extra (tracePlugin, newGiven, newWanted)
+#if MIN_VERSION_ghc(9,2,0)
+import GHC.TcPluginM.Extra (lookupModule, lookupName)
+#endif
 import qualified GHC.TcPluginM.Extra as TcPluginM
 #if MIN_VERSION_ghc(8,4,0)
 import GHC.TcPluginM.Extra (flattenGivens)
@@ -178,27 +181,43 @@
 -- GHC API
 #if MIN_VERSION_ghc(9,0,0)
 import GHC.Builtin.Names (knownNatClassName, eqTyConKey, heqTyConKey, hasKey)
-import GHC.Builtin.Types (promotedFalseDataCon, promotedTrueDataCon, typeNatKind)
+import GHC.Builtin.Types (promotedFalseDataCon, promotedTrueDataCon)
 import GHC.Builtin.Types.Literals
-  (typeNatAddTyCon, typeNatExpTyCon, typeNatLeqTyCon, typeNatMulTyCon,
-   typeNatSubTyCon)
+  (typeNatAddTyCon, typeNatExpTyCon, typeNatMulTyCon, typeNatSubTyCon)
+#if MIN_VERSION_ghc(9,2,0)
+import GHC.Builtin.Types (naturalTy)
+import GHC.Builtin.Types.Literals (typeNatCmpTyCon)
+#else
+import GHC.Builtin.Types (typeNatKind)
+import GHC.Builtin.Types.Literals (typeNatLeqTyCon)
+#endif
 import GHC.Core (Expr (..))
 import GHC.Core.Coercion (CoercionHole, Role (..), mkUnivCo)
 import GHC.Core.Predicate
   (EqRel (NomEq), Pred (EqPred), classifyPredType, getEqPredTys, mkClassPred,
-   mkPrimEqPred, isEqPred, isEqPrimPred)
+   mkPrimEqPred, isEqPred, isEqPrimPred, getClassPredTys_maybe)
 import GHC.Core.TyCo.Rep (Type (..), UnivCoProvenance (..))
+import GHC.Core.TyCon (TyCon)
 import GHC.Core.Type
   (Kind, PredType, eqType, mkTyVarTy, tyConAppTyCon_maybe, typeKind)
 import GHC.Driver.Plugins (Plugin (..), defaultPlugin, purePlugin)
 import GHC.Tc.Plugin
-  (TcPluginM, newCoercionHole, tcLookupClass, tcPluginTrace, tcPluginIO)
+  (TcPluginM, newCoercionHole, tcLookupClass, tcPluginTrace, tcPluginIO,
+   newEvVar)
+#if MIN_VERSION_ghc(9,2,0)
+import GHC.Tc.Plugin (tcLookupTyCon)
+#endif
 import GHC.Tc.Types (TcPlugin (..), TcPluginResult (..))
 import GHC.Tc.Types.Constraint
   (Ct, CtEvidence (..), CtLoc, TcEvDest (..), ShadowInfo (WDeriv), ctEvidence,
    ctLoc, ctLocSpan, isGiven, isWanted, mkNonCanonical, setCtLoc, setCtLocSpan,
    isWantedCt, ctEvLoc, ctEvPred, ctEvExpr)
-import GHC.Tc.Types.Evidence (EvTerm (..), evCast)
+import GHC.Tc.Types.Evidence (EvTerm (..), evCast, evId)
+#if MIN_VERSION_ghc(9,2,0)
+import GHC.Data.FastString (fsLit)
+import GHC.Types.Name.Occurrence (mkTcOcc)
+import GHC.Unit.Module (mkModuleName)
+#endif
 import GHC.Utils.Outputable (Outputable (..), (<+>), ($$), text)
 #else
 #if MIN_VERSION_ghc(8,5,0)
@@ -213,20 +232,22 @@
 import PrelNames  (eqTyConKey, heqTyConKey)
 import TcEvidence (EvTerm (..))
 #if MIN_VERSION_ghc(8,6,0)
-import TcEvidence (evCast)
+import TcEvidence (evCast, evId)
 #endif
 #if !MIN_VERSION_ghc(8,4,0)
 import TcPluginM  (zonkCt)
 #endif
 import TcPluginM  (TcPluginM, tcPluginTrace, tcPluginIO)
-import Type       (Kind, PredType, eqType, mkTyVarTy, tyConAppTyCon_maybe)
+import Type
+  (Kind, PredType, eqType, mkTyVarTy, tyConAppTyCon_maybe)
 import TysWiredIn (typeNatKind)
 
 import Coercion   (CoercionHole, Role (..), mkUnivCo)
-import TcPluginM  (newCoercionHole, tcLookupClass)
+import TcPluginM  (newCoercionHole, tcLookupClass, newEvVar)
 import TcRnTypes  (TcPlugin (..), TcPluginResult(..))
 import TyCoRep    (UnivCoProvenance (..))
 import TcType     (isEqPred)
+import TyCon      (TyCon)
 import TyCoRep    (Type (..))
 import TcTypeNats (typeNatAddTyCon, typeNatExpTyCon, typeNatMulTyCon,
                    typeNatSubTyCon)
@@ -241,7 +262,7 @@
    isWantedCt)
 import Predicate
   (EqRel (NomEq), Pred (EqPred), classifyPredType, getEqPredTys, mkClassPred,
-   mkPrimEqPred)
+   mkPrimEqPred, getClassPredTys_maybe)
 import Type (typeKind)
 #else
 import TcRnTypes
@@ -250,9 +271,12 @@
    isWantedCt)
 import TcType (typeKind)
 import Type
-  (EqRel (NomEq), PredTree (EqPred), classifyPredType, getEqPredTys, mkClassPred,
-   mkPrimEqPred)
+  (EqRel (NomEq), PredTree (EqPred), classifyPredType, mkClassPred, mkPrimEqPred,
+   getClassPredTys_maybe)
+#if MIN_VERSION_ghc(8,4,0)
+import Type (getEqPredTys)
 #endif
+#endif
 
 #if MIN_VERSION_ghc(8,10,0)
 import Constraint (ctEvExpr)
@@ -279,6 +303,11 @@
 import GHC.TypeLits.Normalise.SOP
 import GHC.TypeLits.Normalise.Unify
 
+#if MIN_VERSION_ghc(9,2,0)
+typeNatKind :: Type
+typeNatKind = naturalTy
+#endif
+
 #if !MIN_VERSION_ghc(8,10,0)
 isEqPrimPred :: PredType -> Bool
 isEqPrimPred = isEqPred
@@ -314,18 +343,39 @@
 
 normalisePlugin :: Opts -> TcPlugin
 normalisePlugin opts = tracePlugin "ghc-typelits-natnormalise"
-  TcPlugin { tcPluginInit  = tcPluginIO $ newIORef empty
+  TcPlugin { tcPluginInit  = lookupExtraDefs
            , tcPluginSolve = decideEqualSOP opts
            , tcPluginStop  = const (return ())
            }
 newtype OrigCt = OrigCt { runOrigCt :: Ct }
 
+type ExtraDefs = (IORef (Set CType), TyCon)
+
+lookupExtraDefs :: TcPluginM ExtraDefs
+lookupExtraDefs = do
+    ref <- tcPluginIO (newIORef empty)
+#if !MIN_VERSION_ghc(9,2,0)
+    return (ref, typeNatLeqTyCon)
+#else
+    md <- lookupModule myModule myPackage
+    ordCond <- look md "OrdCond"
+    return (ref, ordCond)
+  where
+    look md s = tcLookupTyCon =<< lookupName md (mkTcOcc s)
+    myModule  = mkModuleName "Data.Type.Ord"
+    myPackage = fsLit "base"
+#endif
+
 decideEqualSOP
   :: Opts
-  -> IORef (Set CType)
-      -- ^ Givens that is already generated.
+  -> ExtraDefs
+      -- ^ 1. Givens that is already generated.
       --   We have to generate new givens at most once;
       --   otherwise GHC will loop indefinitely.
+      --
+      --
+      --   2. For GHc 9.2: TyCon of Data.Type.Ord.OrdCond
+      --      For older: TyCon of GHC.TypeLits.<=?
   -> [Ct]
   -> [Ct]
   -> [Ct]
@@ -340,7 +390,7 @@
 -- without this phase, we cannot derive, e.g.,
 -- @IsVector UVector (Fin (n + 1))@ from
 -- @Unbox (1 + n)@!
-decideEqualSOP opts gen'd givens _deriveds [] = do
+decideEqualSOP opts (gen'd,ordCond) givens _deriveds [] = do
     done <- tcPluginIO $ readIORef gen'd
 #if MIN_VERSION_ghc(8,4,0)
     let simplGivens = flattenGivens givens
@@ -349,7 +399,7 @@
 #endif
     let reds =
           filter (\(_,(_,_,v)) -> null v || negNumbers opts) $
-          reduceGivens opts done simplGivens
+          reduceGivens opts ordCond done simplGivens
         newlyDone = map (\(_,(prd, _,_)) -> CType prd) reds
     tcPluginIO $
       modifyIORef' gen'd $ union (fromList newlyDone)
@@ -360,7 +410,7 @@
 -- Solving phase.
 -- Solves in/equalities on Nats and simplifiable constraints
 -- containing naturals.
-decideEqualSOP opts gen'd givens  _deriveds wanteds = do
+decideEqualSOP opts (gen'd,ordCond) givens deriveds wanteds = do
     -- GHC 7.10.1 puts deriveds with the wanteds, so filter them out
 #if MIN_VERSION_ghc(8,4,0)
     let simplGivens = givens ++ flattenGivens givens
@@ -373,12 +423,16 @@
     let wanteds0 = map (\ct -> (OrigCt ct, ct)) wanteds
     simplGivens <- mapM zonkCt givens
 #endif
-    let wanteds' = filter (isWanted . ctEvidence) wanteds
-        unit_wanteds = mapMaybe toNatEquality wanteds'
+    let wanteds1 = filter (isWanted . ctEvidence) wanteds
+        -- only return solve deriveds when there are wanteds to solve
+        wanteds2 = case wanteds1 of
+                     [] -> []
+                     w  -> w ++ deriveds
+        unit_wanteds = mapMaybe (toNatEquality ordCond) wanteds2
         nonEqs = filter (not . (\p -> isEqPred p || isEqPrimPred p) . ctEvPred . ctEvidence.snd)
                  $ filter (isWanted. ctEvidence.snd) wanteds0
     done <- tcPluginIO $ readIORef gen'd
-    let redGs = reduceGivens opts done simplGivens
+    let redGs = reduceGivens opts ordCond done simplGivens
         newlyDone = map (\(_,(prd, _,_)) -> CType prd) redGs
     redGivens <- forM redGs $ \(origCt, (pred', evTerm, _)) ->
       mkNonCanonical' (ctLoc origCt) <$> newGiven (ctLoc origCt) pred' evTerm
@@ -400,24 +454,28 @@
           fmap (mkNonCanonical' (ctLoc ct)) . newWanted (ctLoc ct)
         tcPluginIO $
           modifyIORef' gen'd $ union (fromList newlyDone)
-        let unit_givens = mapMaybe toNatEquality simplGivens
-        sr <- simplifyNats opts unit_givens unit_wanteds
+        let unit_givens = mapMaybe (toNatEquality ordCond) simplGivens
+        sr <- simplifyNats opts ordCond unit_givens unit_wanteds
         tcPluginTrace "normalised" (ppr sr)
-        reds <- forM reducible_wanteds $ \(origCt,(term, ws)) -> do
-          wants <- evSubtPreds origCt $ subToPred opts ws
-          return ((term, origCt), wants)
+        reds <- forM reducible_wanteds $ \(origCt,(term, ws, wDicts)) -> do
+          wants <- evSubtPreds origCt $ subToPred opts ordCond ws
+          return ((term, origCt), wDicts ++ wants)
         case sr of
           Simplified evs -> do
-            let simpld = filter (isWanted . ctEvidence . (\((_,x),_) -> x)) evs
-                (solved',newWanteds) = second concat (unzip $ simpld ++ reds)
+            let simpld = filter (not . isGiven . ctEvidence . (\((_,x),_) -> x)) evs
+                -- Only solve derived when we solved a wanted
+                simpld1 = case filter (isWanted . ctEvidence . (\((_,x),_) -> x)) evs ++ reds of
+                            [] -> []
+                            _  -> simpld
+                (solved',newWanteds) = second concat (unzip $ simpld1 ++ reds)
             return (TcPluginOk solved' $ newWanteds ++ ineqForRedWants)
           Impossible eq -> return (TcPluginContradiction [fromNatEquality eq])
 
 type NatEquality   = (Ct,CoreSOP,CoreSOP)
 type NatInEquality = (Ct,(CoreSOP,CoreSOP,Bool))
 
-reduceGivens :: Opts -> Set CType -> [Ct] -> [(Ct, (Type, EvTerm, [PredType]))]
-reduceGivens opts done givens =
+reduceGivens :: Opts -> TyCon -> Set CType -> [Ct] -> [(Ct, (Type, EvTerm, [PredType]))]
+reduceGivens opts ordCond done givens =
   let nonEqs =
         [ ct
         | ct <- givens
@@ -431,18 +489,18 @@
         notMember (CType prd) done
       )
     $ mapMaybe
-      (\ct -> (ct,) <$> tryReduceGiven opts givens ct)
+      (\ct -> (ct,) <$> tryReduceGiven opts ordCond givens ct)
       nonEqs
 
 tryReduceGiven
-  :: Opts -> [Ct] -> Ct
+  :: Opts -> TyCon -> [Ct] -> Ct
   -> Maybe (PredType, EvTerm, [PredType])
-tryReduceGiven opts simplGivens ct = do
+tryReduceGiven opts ordCond simplGivens ct = do
     let (mans, ws) =
           runWriter $ normaliseNatEverywhere $
           ctEvPred $ ctEvidence ct
         ws' = [ p
-              | (p, _) <- subToPred opts ws
+              | (p, _) <- subToPred opts ordCond ws
               , all (not . (`eqType` p). ctEvPred . ctEvidence) simplGivens
               ]
     pred' <- mans
@@ -452,7 +510,7 @@
 fromNatEquality (Left  (ct, _, _)) = ct
 fromNatEquality (Right (ct, _))    = ct
 
-reduceNatConstr :: [Ct] -> Ct -> TcPluginM (Maybe (EvTerm, [(Type, Type)]))
+reduceNatConstr :: [Ct] -> Ct -> TcPluginM (Maybe (EvTerm, [(Type, Type)], [Ct]))
 reduceNatConstr givens ct =  do
   let pred0 = ctEvPred $ ctEvidence ct
       (mans, tests) = runWriter $ normaliseNatEverywhere pred0
@@ -460,8 +518,35 @@
     Nothing -> return Nothing
     Just pred' -> do
       case find ((`eqType` pred') .ctEvPred . ctEvidence) givens of
-        Nothing -> return Nothing
-        Just c  -> return (Just (toReducedDict (ctEvidence c) pred0, tests))
+        -- No existing evidence found
+        Nothing -> case getClassPredTys_maybe pred' of
+          -- Are we trying to solve a class instance?
+          Just _ -> do
+            -- Create new evidence binding for normalized class constraint
+            evVar <- newEvVar pred'
+            -- Bind the evidence to a new wanted normalized class constraint
+            let wDict = mkNonCanonical
+                          (CtWanted pred' (EvVarDest evVar)
+#if MIN_VERSION_ghc(8,2,0)
+                          WDeriv
+#endif
+                          (ctLoc ct))
+            -- Evidence for current wanted is simply the coerced binding for
+            -- the new binding
+                evCo = mkUnivCo (PluginProv "ghc-typelits-natnormalise")
+                         Representational
+                         pred' pred0
+#if MIN_VERSION_ghc(8,6,0)
+                ev = evId evVar `evCast` evCo
+#else
+                ev = EvId evVar `EvCast` evCo
+#endif
+            -- Use newly created coerced wanted as evidence, and emit the
+            -- normalized wanted as a new constraint to solve.
+            return (Just (ev, tests, [wDict]))
+          _ -> return Nothing
+        -- Use existing evidence
+        Just c  -> return (Just (toReducedDict (ctEvidence c) pred0, tests, []))
 
 toReducedDict :: CtEvidence -> PredType -> EvTerm
 toReducedDict ct pred' =
@@ -488,12 +573,15 @@
 simplifyNats
   :: Opts
   -- ^ Allow negated numbers (potentially unsound!)
+  -> TyCon
+  -- ^ For GHc 9.2: TyCon of Data.Type.Ord.OrdCond
+  --   For older: TyCon of GHC.TypeLits.<=?
   -> [(Either NatEquality NatInEquality,[(Type,Type)])]
   -- ^ Given constraints
   -> [(Either NatEquality NatInEquality,[(Type,Type)])]
   -- ^ Wanted constraints
   -> TcPluginM SimplifyResult
-simplifyNats opts@Opts {..} eqsG eqsW = do
+simplifyNats opts@Opts {..} ordCond eqsG eqsW = do
     let eqsG1 = map (second (const ([] :: [(Type,Type)]))) eqsG
         (varEqs,otherEqs) = partition isVarEqs eqsG1
         fancyGivens = concatMap (makeGivensSet otherEqs) varEqs
@@ -527,7 +615,7 @@
       tcPluginTrace "unifyNats result" (ppr ur)
       case ur of
         Win -> do
-          evs' <- maybe evs (:evs) <$> evMagic ct empty (subToPred opts k)
+          evs' <- maybe evs (:evs) <$> evMagic ct empty (subToPred opts ordCond k)
           simples subst evs' leqsG [] (xs ++ eqs')
         Lose -> if null evs && null eqs'
                    then return (Impossible (fst eq))
@@ -535,7 +623,7 @@
         Draw [] -> simples subst evs [] (eq:xs) eqs'
         Draw subst' -> do
           evM <- evMagic ct empty (map unifyItemToPredType subst' ++
-                                   subToPred opts k)
+                                   subToPred opts ordCond k)
           let leqsG' | isGiven (ctEvidence ct) = eqToLeq u' v' ++ leqsG
                      | otherwise  = leqsG
           case evM of
@@ -557,7 +645,7 @@
       tcPluginTrace "unifyNats(ineq) results" (ppr (ct,u,u',ineqs))
       case runWriterT (isNatural u') of
         Just (True,knW)  -> do
-          evs' <- maybe evs (:evs) <$> evMagic ct knW (subToPred opts k)
+          evs' <- maybe evs (:evs) <$> evMagic ct knW (subToPred opts ordCond k)
           simples subst evs' leqsG' xs eqs'
 
         Just (False,_) | null k -> return (Impossible (fst eq))
@@ -577,7 +665,7 @@
               smallest = solvedInEqSmallestConstraint solvedIneq
           case smallest of
             (True,kW) -> do
-              evs' <- maybe evs (:evs) <$> evMagic ct kW (subToPred opts k)
+              evs' <- maybe evs (:evs) <$> evMagic ct kW (subToPred opts ordCond k)
               simples subst evs' leqsG' xs eqs'
             _ -> simples subst evs leqsG (eq:xs) eqs'
 
@@ -632,14 +720,14 @@
 -- If we allow negated numbers we simply do not emit the inequalities
 -- derived from the subtractions that are converted to additions with a
 -- negated operand
-subToPred :: Opts -> [(Type, Type)] -> [(PredType, Kind)]
-subToPred Opts{..}
+subToPred :: Opts -> TyCon -> [(Type, Type)] -> [(PredType, Kind)]
+subToPred Opts{..} ordCond
   | negNumbers = const []
-  | otherwise  = map subtractionToPred
+  | otherwise  = map (subtractionToPred ordCond)
 
 -- Extract the Nat equality constraints
-toNatEquality :: Ct -> Maybe (Either NatEquality NatInEquality,[(Type,Type)])
-toNatEquality ct = case classifyPredType $ ctEvPred $ ctEvidence ct of
+toNatEquality :: TyCon -> Ct -> Maybe (Either NatEquality NatInEquality,[(Type,Type)])
+toNatEquality ordCond ct = case classifyPredType $ ctEvPred $ ctEvidence ct of
     EqPred NomEq t1 t2
       -> go t1 t2
     _ -> Nothing
@@ -656,7 +744,28 @@
             , let (y',k2) = runWriter (normaliseNat y)
             -> Just (Left (ct, x', y'),k1 ++ k2)
           _ -> Nothing
-      | tc == typeNatLeqTyCon
+#if MIN_VERSION_ghc(9,2,0)
+      | tc == ordCond
+      , [_,cmp,lt,eq,gt] <- xs
+      , TyConApp tcCmpNat [x,y] <- cmp
+      , tcCmpNat == typeNatCmpTyCon
+      , TyConApp ltTc [] <- lt
+      , ltTc == promotedTrueDataCon
+      , TyConApp eqTc [] <- eq
+      , eqTc == promotedTrueDataCon
+      , TyConApp gtTc [] <- gt
+      , gtTc == promotedFalseDataCon
+      , let (x',k1) = runWriter (normaliseNat x)
+      , let (y',k2) = runWriter (normaliseNat y)
+      , let ks      = k1 ++ k2
+      = case tc' of
+         _ | tc' == promotedTrueDataCon
+           -> Just (Right (ct, (x', y', True)), ks)
+         _ | tc' == promotedFalseDataCon
+           -> Just (Right (ct, (x', y', False)), ks)
+         _ -> Nothing
+#else
+      | tc == ordCond
       , [x,y] <- xs
       , let (x',k1) = runWriter (normaliseNat x)
       , let (y',k2) = runWriter (normaliseNat y)
@@ -667,6 +776,7 @@
          _ | tc' == promotedFalseDataCon
            -> Just (Right (ct, (x', y', False)), ks)
          _ -> Nothing
+#endif
 
     go x y
       | isNatKind (typeKind x)
diff --git a/src/GHC/TypeLits/Normalise/Unify.hs b/src/GHC/TypeLits/Normalise/Unify.hs
--- a/src/GHC/TypeLits/Normalise/Unify.hs
+++ b/src/GHC/TypeLits/Normalise/Unify.hs
@@ -61,9 +61,16 @@
 
 -- GHC API
 #if MIN_VERSION_ghc(9,0,0)
-import GHC.Builtin.Types (boolTy, promotedTrueDataCon, typeNatKind)
+import GHC.Builtin.Types (boolTy, promotedTrueDataCon)
 import GHC.Builtin.Types.Literals
-  (typeNatAddTyCon, typeNatExpTyCon, typeNatLeqTyCon, typeNatMulTyCon, typeNatSubTyCon)
+  (typeNatAddTyCon, typeNatExpTyCon, typeNatMulTyCon, typeNatSubTyCon)
+#if MIN_VERSION_ghc(9,2,0)
+import GHC.Builtin.Types (naturalTy, promotedFalseDataCon)
+import GHC.Builtin.Types.Literals (typeNatCmpTyCon)
+#else
+import GHC.Builtin.Types (typeNatKind)
+import GHC.Builtin.Types.Literals (typeNatLeqTyCon)
+#endif
 import GHC.Core.Predicate (EqRel (NomEq), Pred (EqPred), classifyPredType, mkPrimEqPred)
 import GHC.Core.TyCon (TyCon)
 import GHC.Core.Type
@@ -104,6 +111,11 @@
 -- Used for haddock
 import GHC.TypeLits (Nat)
 
+#if MIN_VERSION_ghc(9,2,0)
+typeNatKind :: Type
+typeNatKind = naturalTy
+#endif
+
 newtype CType = CType { unCType :: Type }
   deriving Outputable
 
@@ -304,12 +316,23 @@
   = Nothing
 
 subtractionToPred
-  :: (Type,Type)
+  :: TyCon
+  -> (Type,Type)
   -> (PredType, Kind)
-subtractionToPred (x,y) =
-  (mkPrimEqPred (mkTyConApp typeNatLeqTyCon [y,x])
+subtractionToPred ordCond (x,y) =
+#if MIN_VERSION_ghc(9,2,0)
+  let cmpNat = mkTyConApp typeNatCmpTyCon [y,x]
+      trueTc = mkTyConApp promotedTrueDataCon []
+      falseTc = mkTyConApp promotedFalseDataCon []
+      ordCmp = mkTyConApp ordCond
+                [boolTy,cmpNat,trueTc,trueTc,falseTc]
+      predTy = mkPrimEqPred ordCmp trueTc
+   in (predTy,boolTy)
+#else
+  (mkPrimEqPred (mkTyConApp ordCond [y,x])
                 (mkTyConApp promotedTrueDataCon [])
   ,boolTy)
+#endif
 
 -- | A substitution is essentially a list of (variable, 'SOP') pairs,
 -- but we keep the original 'Ct' that lead to the substitution being
diff --git a/tests/ErrorTests.hs b/tests/ErrorTests.hs
--- a/tests/ErrorTests.hs
+++ b/tests/ErrorTests.hs
@@ -112,7 +112,11 @@
 testProxy6 = proxyFun6 (Proxy :: Proxy 7)
 
 testProxy6Errors =
-#if __GLASGOW_HASKELL__ >= 900
+#if __GLASGOW_HASKELL__ >= 902
+  ["Expected: Proxy 7"
+  ,"  Actual: Proxy (2 ^ k0)"
+  ]
+#elif __GLASGOW_HASKELL__ >= 900
   ["Expected: Proxy (2 ^ k0)"
   ,"  Actual: Proxy 7"
   ]
@@ -139,31 +143,69 @@
   ]
 #endif
 
-proxyInEq :: (a <= b) => Proxy a -> Proxy b -> ()
+proxyInEq :: (a <= b) => Proxy (a :: Nat) -> Proxy b -> ()
 proxyInEq _ _ = ()
 
-proxyInEq' :: ((a <=? b) ~ 'False) => Proxy a -> Proxy b -> ()
+proxyInEq' :: ((a <=? b) ~ 'False) => Proxy (a :: Nat) -> Proxy b -> ()
 proxyInEq' _ _ = ()
 
 testProxy9 :: Proxy (a + 1) -> Proxy a -> ()
 testProxy9 = proxyInEq
 
 testProxy9Errors =
+#if __GLASGOW_HASKELL__ >= 902
   [$(do localeEncoding <- runIO (getLocaleEncoding)
         if textEncodingName localeEncoding == textEncodingName utf8
+          then litE $ stringL "Couldn't match type ‘Data.Type.Ord.OrdCond"
+          else litE $ stringL "Couldn't match type `Data.Type.Ord.OrdCond"
+    )
+  ,$(do localeEncoding <- runIO (getLocaleEncoding)
+        if textEncodingName localeEncoding == textEncodingName utf8
+          then litE $ stringL "(CmpNat (a + 1) a) 'True 'True 'False’"
+          else litE $ stringL "(CmpNat (a + 1) a) 'True 'True 'False'"
+    )
+  ,$(do localeEncoding <- runIO (getLocaleEncoding)
+        if textEncodingName localeEncoding == textEncodingName utf8
+          then litE $ stringL "with ‘'True’"
+          else litE $ stringL "with 'True"
+    )
+  ]
+#else
+  [$(do localeEncoding <- runIO (getLocaleEncoding)
+        if textEncodingName localeEncoding == textEncodingName utf8
           then litE $ stringL "Couldn't match type ‘(a + 1) <=? a’ with ‘'True’"
           else litE $ stringL "Couldn't match type `(a + 1) <=? a' with 'True"
     )]
+#endif
 
 testProxy10 :: Proxy (a :: Nat) -> Proxy (a + 2) -> ()
 testProxy10 = proxyInEq'
 
 testProxy10Errors =
+#if __GLASGOW_HASKELL__ >= 902
   [$(do localeEncoding <- runIO (getLocaleEncoding)
         if textEncodingName localeEncoding == textEncodingName utf8
+          then litE $ stringL "Couldn't match type ‘Data.Type.Ord.OrdCond"
+          else litE $ stringL "Couldn't match type `Data.Type.Ord.OrdCond"
+    )
+  ,$(do localeEncoding <- runIO (getLocaleEncoding)
+        if textEncodingName localeEncoding == textEncodingName utf8
+          then litE $ stringL "(CmpNat a (a + 2)) 'True 'True 'False’"
+          else litE $ stringL "(CmpNat a (a + 2)) 'True 'True 'False'"
+    )
+  ,$(do localeEncoding <- runIO (getLocaleEncoding)
+        if textEncodingName localeEncoding == textEncodingName utf8
+          then litE $ stringL "with ‘'False"
+          else litE $ stringL "with 'False"
+    )
+  ]
+#else
+  [$(do localeEncoding <- runIO (getLocaleEncoding)
+        if textEncodingName localeEncoding == textEncodingName utf8
           then litE $ stringL "Couldn't match type ‘a <=? (a + 2)’ with ‘'False’"
           else litE $ stringL "Couldn't match type `a <=? (a + 2)' with 'False"
     )]
+#endif
 
 testProxy11 :: Proxy (a :: Nat) -> Proxy a -> ()
 testProxy11 = proxyInEq'
@@ -179,31 +221,88 @@
 testProxy12 = proxyInEq
 
 testProxy12Errors =
+#if __GLASGOW_HASKELL__ >= 902
   [$(do localeEncoding <- runIO (getLocaleEncoding)
         if textEncodingName localeEncoding == textEncodingName utf8
+          then litE $ stringL "Couldn't match type ‘Data.Type.Ord.OrdCond"
+          else litE $ stringL "Couldn't match type `Data.Type.Ord.OrdCond"
+    )
+  ,$(do localeEncoding <- runIO (getLocaleEncoding)
+        if textEncodingName localeEncoding == textEncodingName utf8
+          then litE $ stringL "(CmpNat (a + b) (a + c)) 'True 'True 'False’"
+          else litE $ stringL "(CmpNat (a + b) (a + c)) 'True 'True 'False'"
+    )
+  ,$(do localeEncoding <- runIO (getLocaleEncoding)
+        if textEncodingName localeEncoding == textEncodingName utf8
+          then litE $ stringL "with ‘'True’"
+          else litE $ stringL "with 'True"
+    )
+  ]
+#else
+  [$(do localeEncoding <- runIO (getLocaleEncoding)
+        if textEncodingName localeEncoding == textEncodingName utf8
           then litE $ stringL "Couldn't match type ‘(a + b) <=? (a + c)’ with ‘'True’"
           else litE $ stringL "Couldn't match type `(a + b) <=? (a + c)' with 'True"
     )]
+#endif
 
 testProxy13 :: Proxy (4*a) -> Proxy (2*a) ->()
 testProxy13 = proxyInEq
 
 testProxy13Errors =
+#if __GLASGOW_HASKELL__ >= 902
   [$(do localeEncoding <- runIO (getLocaleEncoding)
         if textEncodingName localeEncoding == textEncodingName utf8
+          then litE $ stringL "Couldn't match type ‘Data.Type.Ord.OrdCond"
+          else litE $ stringL "Couldn't match type `Data.Type.Ord.OrdCond"
+    )
+  ,$(do localeEncoding <- runIO (getLocaleEncoding)
+        if textEncodingName localeEncoding == textEncodingName utf8
+          then litE $ stringL "(CmpNat (4 * a) (2 * a)) 'True 'True 'False’"
+          else litE $ stringL "(CmpNat (4 * a) (2 * a)) 'True 'True 'False'"
+    )
+  ,$(do localeEncoding <- runIO (getLocaleEncoding)
+        if textEncodingName localeEncoding == textEncodingName utf8
+          then litE $ stringL "with ‘'True’"
+          else litE $ stringL "with 'True"
+    )
+  ]
+#else
+  [$(do localeEncoding <- runIO (getLocaleEncoding)
+        if textEncodingName localeEncoding == textEncodingName utf8
           then litE $ stringL "Couldn't match type ‘(4 * a) <=? (2 * a)’ with ‘'True’"
           else litE $ stringL "Couldn't match type `(4 * a) <=? (2 * a)' with 'True"
     )]
+#endif
 
 testProxy14 :: Proxy (2*a) -> Proxy (4*a) -> ()
 testProxy14 = proxyInEq'
 
 testProxy14Errors =
+#if __GLASGOW_HASKELL__ >= 902
   [$(do localeEncoding <- runIO (getLocaleEncoding)
         if textEncodingName localeEncoding == textEncodingName utf8
+          then litE $ stringL "Couldn't match type ‘Data.Type.Ord.OrdCond"
+          else litE $ stringL "Couldn't match type `Data.Type.Ord.OrdCond"
+    )
+  ,$(do localeEncoding <- runIO (getLocaleEncoding)
+        if textEncodingName localeEncoding == textEncodingName utf8
+          then litE $ stringL "(CmpNat (2 * a) (4 * a)) 'True 'True 'False’"
+          else litE $ stringL "(CmpNat (2 * a) (4 * a)) 'True 'True 'False'"
+    )
+  ,$(do localeEncoding <- runIO (getLocaleEncoding)
+        if textEncodingName localeEncoding == textEncodingName utf8
+          then litE $ stringL "with ‘'False"
+          else litE $ stringL "with 'False"
+    )
+  ]
+#else
+  [$(do localeEncoding <- runIO (getLocaleEncoding)
+        if textEncodingName localeEncoding == textEncodingName utf8
           then litE $ stringL "Couldn't match type ‘(2 * a) <=? (4 * a)’ with ‘'False’"
           else litE $ stringL "Couldn't match type `(2 * a) <=? (4 * a)' with 'False"
     )]
+#endif
 
 type family CLog (b :: Nat) (x :: Nat) :: Nat
 type instance CLog 2 2 = 1
@@ -232,11 +331,30 @@
   x -> FS (test16 @(n-1) (x-1))
 
 test16Errors =
+#if __GLASGOW_HASKELL__ >= 902
   [$(do localeEncoding <- runIO (getLocaleEncoding)
         if textEncodingName localeEncoding == textEncodingName utf8
+          then litE $ stringL "Couldn't match type ‘Data.Type.Ord.OrdCond"
+          else litE $ stringL "Couldn't match type `Data.Type.Ord.OrdCond"
+    )
+  ,$(do localeEncoding <- runIO (getLocaleEncoding)
+        if textEncodingName localeEncoding == textEncodingName utf8
+          then litE $ stringL "(CmpNat 1 n) 'True 'True 'False’"
+          else litE $ stringL "(CmpNat 1 n) 'True 'True 'False'"
+    )
+  ,$(do localeEncoding <- runIO (getLocaleEncoding)
+        if textEncodingName localeEncoding == textEncodingName utf8
+          then litE $ stringL "with ‘'True’"
+          else litE $ stringL "with 'True"
+    )
+  ]
+#else
+  [$(do localeEncoding <- runIO (getLocaleEncoding)
+        if textEncodingName localeEncoding == textEncodingName utf8
           then litE $ stringL "Couldn't match type ‘1 <=? n’ with ‘'True’"
           else litE $ stringL "Couldn't match type `1 <=? n' with 'True"
     )]
+#endif
 
 data Dict c where
   Dict :: c => Dict c
@@ -249,12 +367,7 @@
 testProxy17 :: String
 
 testProxy17 = test17 (Proxy :: Proxy 17) Boo
-test17Errors =
-  [$(do localeEncoding <- runIO (getLocaleEncoding)
-        if textEncodingName localeEncoding == textEncodingName utf8
-          then litE $ stringL "Couldn't match type ‘1 <=? n’ with ‘'True’"
-          else litE $ stringL "Couldn't match type `1 <=? n' with 'True"
-    )]
+test17Errors = test16Errors
 
 test19f :: (1 <= n)
   => Proxy n -> Proxy n
@@ -268,4 +381,11 @@
 testProxy19 _ _ = test19f
 
 test19Errors =
+#if __GLASGOW_HASKELL__ >= 902
+  [ "Could not deduce: Data.Type.Ord.OrdCond"
+  , "(CmpNat 1 (rp - m)) 'True 'True 'False"
+  , "~ 'True"
+  ]
+#else
   ["Could not deduce: (1 <=? (rp - m)) ~ 'True"]
+#endif
diff --git a/tests/Tests.hs b/tests/Tests.hs
--- a/tests/Tests.hs
+++ b/tests/Tests.hs
@@ -4,10 +4,12 @@
 {-# LANGUAGE ExistentialQuantification #-}
 {-# LANGUAGE FlexibleContexts          #-}
 {-# LANGUAGE FlexibleInstances         #-}
+{-# LANGUAGE FunctionalDependencies    #-}
 {-# LANGUAGE GADTs                     #-}
 {-# LANGUAGE MultiParamTypeClasses     #-}
 {-# LANGUAGE NoImplicitPrelude         #-}
 {-# LANGUAGE PolyKinds                 #-}
+{-# LANGUAGE RoleAnnotations           #-}
 {-# LANGUAGE Rank2Types                #-}
 {-# LANGUAGE ScopedTypeVariables       #-}
 {-# LANGUAGE TypeApplications          #-}
@@ -297,6 +299,23 @@
   BT -> BT
   a' -> B0 a'
 predBNat (B0 x)  = B1 (predBNat x)
+
+-- issue 52 begin
+type role Signal nominal representational
+data Signal (dom :: Symbol) a = a :- Signal dom a
+
+type role BitVector nominal
+newtype BitVector (n :: Nat) = BV { unsafeToNatural :: Integer }
+
+class Bundle (f :: Type -> Type) a res | f a -> res, f res -> a, a res -> f
+bundle :: Bundle f a res => res -> f a
+bundle = bundle
+
+instance Bundle (Signal dom) (a,b) (Signal dom a, Signal dom b)
+
+issue52 :: (1 <= n, KnownNat n) => (Signal dom (),Signal dom (BitVector (n-1+1))) -> Signal dom ((),BitVector n)
+issue52 = bundle
+-- issue 52 end
 
 proxyInEq1 :: Proxy a -> Proxy (a+1) -> ()
 proxyInEq1 = proxyInEq
