diff --git a/compiler/GHC/Core/Opt/ConstantFold.hs b/compiler/GHC/Core/Opt/ConstantFold.hs
index 71e22f8e9f68b5fdd04714dcfcfed5a0c64a0232..b082dff1f7c5ef9335652011e8222461395d2ef3 100644
--- a/compiler/GHC/Core/Opt/ConstantFold.hs
+++ b/compiler/GHC/Core/Opt/ConstantFold.hs
@@ -2635,6 +2635,13 @@ match_inline _ = Nothing
 --------------------------------------------------------
 -- Note [Constant folding through nested expressions]
 -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+-- GHC has some support for constant folding through nested expressions (i.e.
+-- when constants are not only arguments of the considered App node but to one
+-- of its own argument (an App node too), see examples below).
+--
+-- For performance reason, this optimization is only enabled with -O1 and above.
+-- As with all optimizations, it can also be independently enabled with its own
+-- command-line flag too: -fnum-constant-folding (grep Opt_NumConstantFolding).
 --
 -- We use rewrites rules to perform constant folding. It means that we don't
 -- have a global view of the expression we are trying to optimise. As a
diff --git a/compiler/GHC/Core/Rules/Config.hs b/compiler/GHC/Core/Rules/Config.hs
index 2ae1e35a6713749b99254c97109971eae92ad002..fa0ba4baeed054ab91a8e09aa59c7f127a6e9c6c 100644
--- a/compiler/GHC/Core/Rules/Config.hs
+++ b/compiler/GHC/Core/Rules/Config.hs
@@ -5,9 +5,15 @@ import GHC.Platform
 
 -- | Rule options
 data RuleOpts = RuleOpts
-   { roPlatform                :: !Platform -- ^ Target platform
-   , roNumConstantFolding      :: !Bool     -- ^ Enable more advanced numeric constant folding
-   , roExcessRationalPrecision :: !Bool     -- ^ Cut down precision of Rational values to that of Float/Double if disabled
-   , roBignumRules             :: !Bool     -- ^ Enable rules for bignums
+   { roPlatform                :: !Platform
+     -- ^ Target platform
+   , roNumConstantFolding      :: !Bool
+     -- ^ Enable constant folding through nested expressions.
+     --
+     -- See Note [Constant folding through nested expressions] in GHC.Core.Opt.ConstantFold
+   , roExcessRationalPrecision :: !Bool
+     -- ^ Cut down precision of Rational values to that of Float/Double if disabled
+   , roBignumRules             :: !Bool
+     -- ^ Enable rules for bignums
    }
 
diff --git a/compiler/GHC/Driver/Flags.hs b/compiler/GHC/Driver/Flags.hs
index a323ec56fe0623f7c162c6227ac168f39a139392..1096802f17e844a4ea4fdfea44ef3cc178d66eff 100644
--- a/compiler/GHC/Driver/Flags.hs
+++ b/compiler/GHC/Driver/Flags.hs
@@ -678,7 +678,7 @@ data GeneralFlag
    | Opt_SolveConstantDicts
    | Opt_AlignmentSanitisation
    | Opt_CatchNonexhaustiveCases
-   | Opt_NumConstantFolding
+   | Opt_NumConstantFolding   -- ^ See Note [Constant folding through nested expressions] in GHC.Core.Opt.ConstantFold
    | Opt_CoreConstantFolding
    | Opt_FastPAPCalls                  -- #6084
    | Opt_SpecEval
diff --git a/docs/users_guide/expected-undocumented-flags.txt b/docs/users_guide/expected-undocumented-flags.txt
index 87aa92ae720c3738da694d3d003623d88df3647d..bc79591af94bfe4bd2f5e5c46c433815e791c3ee 100644
--- a/docs/users_guide/expected-undocumented-flags.txt
+++ b/docs/users_guide/expected-undocumented-flags.txt
@@ -57,7 +57,6 @@
 -fmax-errors
 -fmax-pmcheck-iterations
 -fmonomorphism-restriction
--fnum-constant-folding
 -fpre-inlining
 -fprint-bind-contents
 -freduction-depth
diff --git a/docs/users_guide/using-optimisation.rst b/docs/users_guide/using-optimisation.rst
index efaca3c387497dd6687b62d49fab16813d2829ba..4dc43b30492a992a738156c3d76dd85ca6758439 100644
--- a/docs/users_guide/using-optimisation.rst
+++ b/docs/users_guide/using-optimisation.rst
@@ -132,6 +132,36 @@ as such you shouldn't need to set any of them explicitly. A flag
     Enables Core-level constant folding, i.e. propagation of values
     that can be computed at compile time.
 
+.. ghc-flag:: -fnum-constant-folding
+    :shortdesc: Enable constant folding on nested numerical expressions. Implied by :ghc-flag:`-O`.
+    :type: dynamic
+    :reverse: -fno-num-constant-folding
+    :category:
+
+    :default: off but enabled by :ghc-flag:`-O`.
+
+    When enabled, the compiler uses associativity, commutativity, and
+    distributivity laws of numerical primops to perform constant folding on
+    nested numerical expressions.
+
+    Examples:
+
+        (10 + x) + 10
+        ===> 20 + x
+
+        5 + x + (y + (z + (t + 5)))
+        ===> 10 + (x + (y + (z + t)))
+
+        (5 + x) * 6
+        ===> 30 + 6*x
+
+        5 + x + (x + (x + (x + 5)))
+        ===> 10 + (4 * x)
+
+        (5 + 4*x) - (3*x + 2)
+        ===> 3 + x
+
+
 .. ghc-flag:: -fcase-merge
     :shortdesc: Enable case-merging. Implied by :ghc-flag:`-O`.
     :type: dynamic