diff --git a/gnu/packages/haskell.scm b/gnu/packages/haskell.scm
index 62815efbb1..88826fb31f 100644
--- a/gnu/packages/haskell.scm
+++ b/gnu/packages/haskell.scm
@@ -1437,14 +1437,14 @@ (define ghc-happy-bootstrap-for-9.4
   (hidden-package
     (package
      (name "ghc-happy")
-     (version "1.20.0")
+     (version "1.20.1.1")
      (source
       (origin
         (method url-fetch)
         (uri (hackage-uri "happy" version))
         (sha256
          (base32
-          "1346r2x5ravs5fqma65bzjragqbb2g6v41wz9maknwm2jf7kl79v"))))
+          "06w8g3lfk2ynrfhqznhp1mnp8a5b64lj6qviixpndzf5lv2psklb"))))
      (build-system haskell-build-system)
      (arguments
        (list #:haskell ghc-bootstrap-for-9.4
@@ -1462,14 +1462,14 @@ (define-public ghc-9.4
     (package
       (inherit base)
       (name "ghc-next")
-      (version "9.4.4")
+      (version "9.4.8")
       (source (origin
                 (method url-fetch)
                 (uri (string-append "https://www.haskell.org/ghc/dist/" version
                                     "/ghc-" version "-src.tar.xz"))
                 (sha256
                  (base32
-                  "1qk7rlqf02s3b6m6sqqngmjq1mxnrz88h159lz6k25gddmdg5kp8"))))
+                  "0pmqg9846lanb0hcyxhgr9ipzq33rfldxj7ln0j3qgpyczmhgx0b"))))
       (arguments
        (substitute-keyword-arguments (package-arguments base)
          ((#:phases phases '%standard-phases)
@@ -1487,7 +1487,8 @@ (define-public ghc-9.4
                     version "/ghc-" version "-testsuite.tar.xz"))
              (sha256
               (base32
-               "04p2lawxxg3nyv6frzhyjyh3arhqqyh5ka3alxa2pxhcd2hdcja3"))))
+               "159wsqnqpqb0pxa3zyhvyg07wxr2zz7v52h52wkplw4pn12dsidc"))
+             (patches (search-patches "ghc-9.4-testsuite-fixes.patch"))))
          ("ghc-alex" ,ghc-alex-bootstrap-for-9.4)
          ("ghc-happy" ,ghc-happy-bootstrap-for-9.4)
          ,@(filter (match-lambda
diff --git a/gnu/packages/patches/ghc-9.4-testsuite-fixes.patch b/gnu/packages/patches/ghc-9.4-testsuite-fixes.patch
new file mode 100644
index 0000000000..f394632add
--- /dev/null
+++ b/gnu/packages/patches/ghc-9.4-testsuite-fixes.patch
@@ -0,0 +1,119 @@
+From 3acd8aa948a27465cffc8e2ab56229485e2a5b98 Mon Sep 17 00:00:00 2001
+From: Saku Laesvuori <saku@laesvuori.fi>
+Date: Tue, 5 Dec 2023 22:49:45 +0200
+Subject: [PATCH] Fix tests
+
+* replaces egrep with grep -E
+* removes unnecessary escaping in some grep regular expressions
+* adds a missing include header to a makefile
+---
+ testsuite/tests/cabal/cabal01/Makefile                | 2 +-
+ testsuite/tests/ghci/should_run/GHCiPrimCall/Makefile | 4 ++++
+ testsuite/tests/haddock/perf/Makefile                 | 8 ++++----
+ testsuite/tests/hsc2hs/Makefile                       | 4 ++--
+ testsuite/tests/numeric/should_run/T7014.primops      | 4 ++--
+ testsuite/tests/simplCore/should_compile/Makefile     | 4 ++--
+ 6 files changed, 15 insertions(+), 11 deletions(-)
+
+diff --git a/testsuite/tests/cabal/cabal01/Makefile b/testsuite/tests/cabal/cabal01/Makefile
+index 004e4c75..6ec499c9 100644
+--- a/testsuite/tests/cabal/cabal01/Makefile
++++ b/testsuite/tests/cabal/cabal01/Makefile
+@@ -5,7 +5,7 @@ include $(TOP)/mk/test.mk
+ # Find all the env variables starting with CI_ to unset them.
+ # Otherwise, we might run into environment length limitations on Windows.
+ # (See `xargs --show-limits`.)
+-VARS_TO_UNSET := $(shell env | grep ^CI_ | egrep -o '^[^=]+')
++VARS_TO_UNSET := $(shell env | grep ^CI_ | grep -E -o '^[^=]+')
+ unexport $(VARS_TO_UNSET)
+ 
+ clean:
+diff --git a/testsuite/tests/ghci/should_run/GHCiPrimCall/Makefile b/testsuite/tests/ghci/should_run/GHCiPrimCall/Makefile
+index fd64d23f..cb669db3 100644
+--- a/testsuite/tests/ghci/should_run/GHCiPrimCall/Makefile
++++ b/testsuite/tests/ghci/should_run/GHCiPrimCall/Makefile
+@@ -1,3 +1,7 @@
++TOP=../../../..
++include $(TOP)/mk/boilerplate.mk
++include $(TOP)/mk/test.mk
++
+ .PHONY: GHCiPrimCall
+ GHCiPrimCall:
+ 	'$(TEST_HC)' $(TEST_HC_OPTS) -fPIC -v0 -c GHCiPrimCall_cmm.cmm
+diff --git a/testsuite/tests/haddock/perf/Makefile b/testsuite/tests/haddock/perf/Makefile
+index b67b52f2..ff2f7ebb 100644
+--- a/testsuite/tests/haddock/perf/Makefile
++++ b/testsuite/tests/haddock/perf/Makefile
+@@ -4,12 +4,12 @@ include $(TOP)/mk/test.mk
+ 
+ # We accept a 5% increase in parser allocations due to -haddock
+ haddock_parser_perf :
+-	WithHaddock=$(shell '$(TEST_HC)' $(TEST_HC_OPTS) -fno-code -fforce-recomp -Wno-all -ddump-timings -haddock -O0 Fold.hs 2>/dev/null | grep Parser | egrep -o 'alloc=[0-9]+' | cut -c7-  ) ; \
+-	WithoutHaddock=$(shell '$(TEST_HC)' $(TEST_HC_OPTS) -fno-code -fforce-recomp -Wno-all -ddump-timings -O0 Fold.hs 2>/dev/null | grep Parser | egrep -o 'alloc=[0-9]+' | cut -c7-  ) ;  \
++	WithHaddock=$(shell '$(TEST_HC)' $(TEST_HC_OPTS) -fno-code -fforce-recomp -Wno-all -ddump-timings -haddock -O0 Fold.hs 2>/dev/null | grep Parser | grep -E -o 'alloc=[0-9]+' | cut -c7-  ) ; \
++	WithoutHaddock=$(shell '$(TEST_HC)' $(TEST_HC_OPTS) -fno-code -fforce-recomp -Wno-all -ddump-timings -O0 Fold.hs 2>/dev/null | grep Parser | grep -E -o 'alloc=[0-9]+' | cut -c7-  ) ;  \
+ 	  awk "BEGIN { ratio = ($$WithHaddock / $$WithoutHaddock); if (ratio > 1.05) {print \"-haddock allocation ratio too high:\", ratio; exit 1} else {exit 0} }"
+ 
+ # Similarly for the renamer
+ haddock_renamer_perf :
+-	WithoutHaddock=$(shell '$(TEST_HC)' $(TEST_HC_OPTS) -fno-code -fforce-recomp -Wno-all -ddump-timings -O0 Fold.hs 2>/dev/null | grep Renamer | egrep -o 'alloc=[0-9]+' | cut -c7-  ) ; \
+-	WithHaddock=$(shell '$(TEST_HC)' $(TEST_HC_OPTS) -fno-code -fforce-recomp -Wno-all -ddump-timings -haddock -O0 Fold.hs 2>/dev/null | grep Renamer | egrep -o 'alloc=[0-9]+' | cut -c7-  ) ;  \
++	WithoutHaddock=$(shell '$(TEST_HC)' $(TEST_HC_OPTS) -fno-code -fforce-recomp -Wno-all -ddump-timings -O0 Fold.hs 2>/dev/null | grep Renamer | grep -E -o 'alloc=[0-9]+' | cut -c7-  ) ; \
++	WithHaddock=$(shell '$(TEST_HC)' $(TEST_HC_OPTS) -fno-code -fforce-recomp -Wno-all -ddump-timings -haddock -O0 Fold.hs 2>/dev/null | grep Renamer | grep -E -o 'alloc=[0-9]+' | cut -c7-  ) ;  \
+ 	  awk "BEGIN { ratio = ($$WithHaddock / $$WithoutHaddock); if (ratio > 1.05) {print \"-haddock allocation ratio too high:\", ratio; exit 1} else {exit 0} }"
+diff --git a/testsuite/tests/hsc2hs/Makefile b/testsuite/tests/hsc2hs/Makefile
+index d0b2d249..95b011c8 100644
+--- a/testsuite/tests/hsc2hs/Makefile
++++ b/testsuite/tests/hsc2hs/Makefile
+@@ -52,9 +52,9 @@ T11004:
+ T12504:
+ 	'$(HSC2HS)' $(HSC2HS_OPTS) T12504/path/to/$@.hsc
+ ifeq "$(WINDOWS)" "YES"
+-	grep '{-# LINE 1 \"T12504\\\\path\\\\to\\\\$@\.hsc\" #-}' T12504/path/to/$@.hs
++	grep '{-# LINE 1 "T12504\\\\path\\\\to\\\\$@\.hsc" #-}' T12504/path/to/$@.hs
+ else
+-	grep '{-# LINE 1 \"T12504/path/to/$@\.hsc\" #-}' T12504/path/to/$@.hs
++	grep '{-# LINE 1 "T12504/path/to/$@\.hsc" #-}' T12504/path/to/$@.hs
+ endif
+ 
+ .PHONY: T15758
+diff --git a/testsuite/tests/numeric/should_run/T7014.primops b/testsuite/tests/numeric/should_run/T7014.primops
+index 3243666d..c807fb45 100644
+--- a/testsuite/tests/numeric/should_run/T7014.primops
++++ b/testsuite/tests/numeric/should_run/T7014.primops
+@@ -1,8 +1,8 @@
+ and#
+ or#
+ uncheckedShift.*#
+-\+#
+-\-#
+++#
++-#
+ \*#
+ quotInt#
+ remInt#
+diff --git a/testsuite/tests/simplCore/should_compile/Makefile b/testsuite/tests/simplCore/should_compile/Makefile
+index b5041800..c56e04f6 100644
+--- a/testsuite/tests/simplCore/should_compile/Makefile
++++ b/testsuite/tests/simplCore/should_compile/Makefile
+@@ -66,7 +66,7 @@ T13367:
+ 
+ T8832:
+ 	$(RM) -f T8832.o T8832.hi
+-	'$(TEST_HC)' $(TEST_HC_OPTS) -O -c -ddump-simpl -dsuppress-ticks T8832.hs | egrep '^[a-zA-Z0-9]+ ='
++	'$(TEST_HC)' $(TEST_HC_OPTS) -O -c -ddump-simpl -dsuppress-ticks T8832.hs | grep -E '^[a-zA-Z0-9]+ ='
+ 
+ T12603:
+ 	$(RM) -f T12603.o T12603.hi
+@@ -259,7 +259,7 @@ str-rules:
+ # g should have been collapsed into one defininition by CSE.
+ .PHONY: T13340
+ T13340:
+-	'$(TEST_HC)' $(TEST_HC_OPTS) -c -O T13340.hs -ddump-simpl -dsuppress-all | grep -c '\+#'
++	'$(TEST_HC)' $(TEST_HC_OPTS) -c -O T13340.hs -ddump-simpl -dsuppress-all | grep -c '+#'
+ 
+ 
+ # We expect to see all dictionaries specialized away.
+-- 
+2.41.0
+
