diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,7 @@
+# 1.2.3
+
+* Added `Semigroup` instances for some types (h/t Herbert Valerio Riedel).
+
 # 1.2.2
 
 * New maintainer.
diff --git a/Data/IntMap/CharMap2.hs b/Data/IntMap/CharMap2.hs
--- a/Data/IntMap/CharMap2.hs
+++ b/Data/IntMap/CharMap2.hs
@@ -10,7 +10,7 @@
 import Data.List as L (map)
 import qualified Data.IntMap as M
 import qualified Data.IntSet as S(IntSet)
-import Data.Monoid(Monoid(..))
+import Data.Semigroup as Sem
 
 #ifndef __GLASGOW_HASKELL__
 unsafeChr = chr
@@ -18,9 +18,12 @@
 
 newtype CharMap a = CharMap {unCharMap :: M.IntMap a} deriving (Eq,Ord,Read,Show)
 
+instance Sem.Semigroup (CharMap a) where
+  CharMap x <> CharMap y = CharMap (x `mappend` y)
+
 instance Monoid (CharMap a) where
   mempty = CharMap mempty
-  CharMap x `mappend` CharMap y = CharMap (x `mappend` y)
+  mappend = (<>)
 
 instance Functor CharMap where
   fmap f (CharMap m) = CharMap (fmap f m)
diff --git a/Data/IntMap/EnumMap2.hs b/Data/IntMap/EnumMap2.hs
--- a/Data/IntMap/EnumMap2.hs
+++ b/Data/IntMap/EnumMap2.hs
@@ -3,16 +3,19 @@
 import Data.Foldable(Foldable(..))
 import qualified Data.IntMap as M
 import qualified Data.IntSet.EnumSet2 as S (EnumSet(..))
-import Data.Monoid(Monoid(..))
+import Data.Semigroup as Sem
 import Prelude
 import qualified Prelude as L (map)
 
 newtype EnumMap k a = EnumMap {unEnumMap :: M.IntMap a}
   deriving (Eq,Ord,Read,Show)
 
+instance Ord k => Sem.Semigroup (EnumMap k a) where
+  EnumMap x <> EnumMap y = EnumMap (x `mappend` y)
+
 instance Ord k => Monoid (EnumMap k a) where
   mempty = EnumMap mempty
-  EnumMap x `mappend` EnumMap y = EnumMap (x `mappend` y)
+  mappend = (<>)
 
 instance Ord k => Functor (EnumMap k) where
   fmap f (EnumMap m) = EnumMap (fmap f m)
diff --git a/Data/IntSet/EnumSet2.hs b/Data/IntSet/EnumSet2.hs
--- a/Data/IntSet/EnumSet2.hs
+++ b/Data/IntSet/EnumSet2.hs
@@ -2,14 +2,17 @@
 
 import qualified Data.IntSet as S
 import qualified Data.List as L (map)
-import Data.Monoid(Monoid(..))
+import Data.Semigroup as Sem
 
 newtype EnumSet e = EnumSet {unEnumSet :: S.IntSet}
   deriving (Eq,Ord,Read,Show)
 
+instance Sem.Semigroup (EnumSet e) where
+  EnumSet x <> EnumSet y = EnumSet (x `mappend` y)
+
 instance Monoid (EnumSet e) where
   mempty = EnumSet mempty
-  EnumSet x `mappend` EnumSet y = EnumSet (x `mappend` y)
+  mappend = (<>)
 
 (\\) :: (Enum e) => EnumSet e -> EnumSet e -> EnumSet e
 (\\) (EnumSet s1) (EnumSet s2) = EnumSet ((S.\\) s1 s2)
diff --git a/Text/Regex/TDFA/CorePattern.hs b/Text/Regex/TDFA/CorePattern.hs
--- a/Text/Regex/TDFA/CorePattern.hs
+++ b/Text/Regex/TDFA/CorePattern.hs
@@ -42,6 +42,7 @@
 --import Data.Maybe(isNothing)
 import Data.IntSet.EnumSet2(EnumSet)
 import qualified Data.IntSet.EnumSet2 as Set(singleton,toList,isSubsetOf)
+import Data.Semigroup as Sem
 import Text.Regex.TDFA.Common {- all -}
 import Text.Regex.TDFA.Pattern(Pattern(..),starTrans)
 -- import Debug.Trace
@@ -87,9 +88,12 @@
 -- This is a set of WhichTest where each test has associated pattern location information
 newtype SetTestInfo = SetTestInfo {getTests :: EnumMap WhichTest (EnumSet DoPa)} deriving (Eq)
 
+instance Semigroup SetTestInfo where
+  SetTestInfo x <> SetTestInfo y = SetTestInfo (x Sem.<> y)
+
 instance Monoid SetTestInfo where
   mempty = SetTestInfo mempty
-  SetTestInfo x `mappend` SetTestInfo y = SetTestInfo (x `mappend` y)
+  mappend = (Sem.<>)
 
 instance Show SetTestInfo where
   show (SetTestInfo sti) = "SetTestInfo "++show (mapSnd (Set.toList) $ Map.assocs sti)
diff --git a/Text/Regex/TDFA/NewDFA/Engine.hs b/Text/Regex/TDFA/NewDFA/Engine.hs
--- a/Text/Regex/TDFA/NewDFA/Engine.hs
+++ b/Text/Regex/TDFA/NewDFA/Engine.hs
@@ -122,6 +122,7 @@
     let obtainNext = join (readSTRef storeNext)
     return obtainNext
 
+  goNext :: STRef s (ST s [MatchArray]) -> ST s [MatchArray]
   goNext storeNext = {-# SCC "goNext" #-} do
     (SScratch s1In s2In (winQ,blank,which)) <- newScratch b_index b_tags
     _ <- spawnStart b_tags blank startState s1In offsetIn
diff --git a/Text/Regex/TDFA/NewDFA/Engine_FA.hs b/Text/Regex/TDFA/NewDFA/Engine_FA.hs
--- a/Text/Regex/TDFA/NewDFA/Engine_FA.hs
+++ b/Text/Regex/TDFA/NewDFA/Engine_FA.hs
@@ -86,6 +86,7 @@
   comp :: C s
   comp = {-# SCC "matchHere.comp" #-} ditzyComp'3 aTags
 
+  goNext :: ST s [MatchArray]
   goNext = {-# SCC "goNext" #-} do
     (SScratch s1In s2In (winQ,blank,which)) <- newScratch b_index b_tags
     spawnAt b_tags blank startState s1In offsetIn
diff --git a/regex-tdfa.cabal b/regex-tdfa.cabal
--- a/regex-tdfa.cabal
+++ b/regex-tdfa.cabal
@@ -1,5 +1,5 @@
 Name:                   regex-tdfa
-Version:                1.2.2
+Version:                1.2.3
 License:                BSD3
 License-File:           LICENSE
 Copyright:              Copyright (c) 2007, Christopher Kuklewicz
@@ -11,7 +11,7 @@
 Synopsis:               Replaces/Enhances Text.Regex
 Description:            A new all Haskell "tagged" DFA regex engine, inspired by libtre
 Category:               Text
-Tested-With:            GHC == 7.6.3, GHC == 7.8.4, GHC == 7.10.3, GHC == 8.0.1
+Tested-With:            GHC == 7.6.3, GHC == 7.8.4, GHC == 7.10.3, GHC == 8.0.1, GHC == 8.2.2, GHC == 8.4.1
 Build-Type:             Simple
 extra-source-files:
   CHANGELOG.md
@@ -35,6 +35,17 @@
                       , mtl
                       , parsec
                       , regex-base >= 0.93.1
+
+  -- Support Semigroup instances uniformly
+  --
+  -- See also
+  --  https://prime.haskell.org/wiki/Libraries/Proposals/SemigroupMonoid#RecommendedVariant
+  --
+  -- NB: This is the same logic `parsec.cabal` uses, so this doesn't
+  -- add any new dependency that isn't already incurred by
+  -- `regex-tdfa`'s transitive deps
+  if !impl(ghc >= 8.0)
+    build-depends:      semigroups == 0.18.*
 
   other-modules:          Paths_regex_tdfa
   Exposed-Modules:        Data.IntMap.CharMap2
