diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,6 +5,27 @@
 The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
 and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
 
+## [0.25.22]
+
+### Added
+
+* `futhark script` now supports an `-f` option.
+
+* `futhark script` now supports the builtin procedure `$store`.
+
+### Removed
+
+### Changed
+
+### Fixed
+
+* An error in tuning file validation.
+
+* Constant folding for loops that produce floating point results could
+  result in different numerical behaviour.
+
+* Compiler crash in memory short circuiting (#2176).
+
 ## [0.25.21]
 
 ### Added
diff --git a/docs/man/futhark-script.rst b/docs/man/futhark-script.rst
--- a/docs/man/futhark-script.rst
+++ b/docs/man/futhark-script.rst
@@ -9,7 +9,7 @@
 SYNOPSIS
 ========
 
-futhark script [options...] program expression
+futhark script [options...] program [expression]
 
 DESCRIPTION
 ===========
@@ -18,12 +18,18 @@
 run the provided FutharkScript expression ``expr``, and finally print
 the result to stdout. It is essentially a simpler way to access the
 evaluation facilities of :ref:`futhark-literate(1)`, and provides the
-same FutharkScript facilities.
+same FutharkScript facilities, with a few additional built-in
+procedures documented below.
 
 If the provided program does not have a ``.fut`` extension, it is
 assumed to be a previously compiled server-mode program, and simply
 run directly.
 
+When ``-e`` and ``-f`` are used, the expressions are run in the order
+provided, and only the value of the last expression is printed. This
+implies multiple uses of these options is only useful when they invoke
+procedures with side effects.
+
 OPTIONS
 =======
 
@@ -41,11 +47,21 @@
 
   Pass ``-D`` to the executable and show debug prints.
 
+-e, --expression=EXP
+
+  Evaluate this FutharkScript expression. Expressions are run in the
+  order provided.
+
 --futhark=program
 
   The program used to perform operations (eg. compilation). Defaults
   to the binary running ``futhark script`` itself.
 
+-f, --file=FILe
+
+  Read and evaluate FutharkScript expression from this file.
+  Expressions are run in the order provided.
+
 -L, --log
 
   Pass ``-L`` to the executable and show debug prints.
@@ -67,6 +83,12 @@
 
   Print verbose information on stderr about directives as they are
   executing.  This is also needed to see ``#[trace]`` output.
+
+ADDITIONAL BUILTINS
+===================
+
+* ``$store "file" v`` store the value *v* (which must be a primitive
+  or an array) as a binary value in the given file.
 
 BUGS
 ====
diff --git a/futhark.cabal b/futhark.cabal
--- a/futhark.cabal
+++ b/futhark.cabal
@@ -1,6 +1,6 @@
 cabal-version: 2.4
 name:           futhark
-version:        0.25.21
+version:        0.25.22
 synopsis:       An optimising compiler for a functional, array-oriented language.
 
 description:    Futhark is a small programming language designed to be compiled to
diff --git a/rts/c/tuning.h b/rts/c/tuning.h
--- a/rts/c/tuning.h
+++ b/rts/c/tuning.h
@@ -31,7 +31,7 @@
       *eql = 0;
       char *endptr;
       int value = strtol(eql+1, &endptr, 10);
-      if (*endptr) {
+      if (*endptr && *endptr != '\n') {
         snprintf(line, max_line_len, "Invalid line %d (must be of form 'name=int').",
                  lineno);
         return line;
diff --git a/src/Futhark/CLI/Literate.hs b/src/Futhark/CLI/Literate.hs
--- a/src/Futhark/CLI/Literate.hs
+++ b/src/Futhark/CLI/Literate.hs
@@ -671,7 +671,8 @@
     scriptOutput :: Maybe FilePath,
     scriptVerbose :: Int,
     scriptStopOnError :: Bool,
-    scriptBinary :: Bool
+    scriptBinary :: Bool,
+    scriptExps :: [Either FilePath T.Text]
   }
 
 -- | The configuration before any user-provided options are processed.
@@ -686,7 +687,8 @@
       scriptOutput = Nothing,
       scriptVerbose = 0,
       scriptStopOnError = False,
-      scriptBinary = False
+      scriptBinary = False,
+      scriptExps = []
     }
 
 data Env = Env
diff --git a/src/Futhark/CLI/Script.hs b/src/Futhark/CLI/Script.hs
--- a/src/Futhark/CLI/Script.hs
+++ b/src/Futhark/CLI/Script.hs
@@ -2,8 +2,10 @@
 module Futhark.CLI.Script (main) where
 
 import Control.Monad.Except
+import Control.Monad.IO.Class (MonadIO, liftIO)
 import Data.Binary qualified as Bin
 import Data.ByteString.Lazy.Char8 qualified as BS
+import Data.Char (chr)
 import Data.Text qualified as T
 import Data.Text.IO qualified as T
 import Futhark.CLI.Literate
@@ -13,7 +15,7 @@
     scriptCommandLineOptions,
   )
 import Futhark.Script
-import Futhark.Test.Values (Compound (..))
+import Futhark.Test.Values (Compound (..), getValue, valueType)
 import Futhark.Util.Options
 import Futhark.Util.Pretty (prettyText)
 import System.Exit
@@ -46,27 +48,80 @@
            "b"
            ["binary"]
            (NoArg $ Right $ \config -> config {scriptBinary = True})
-           "Produce binary output."
+           "Produce binary output.",
+         Option
+           "f"
+           ["file"]
+           ( ReqArg
+               (\f -> Right $ \config -> config {scriptExps = scriptExps config ++ [Left f]})
+               "FILE"
+           )
+           "Run FutharkScript from this file.",
+         Option
+           "e"
+           ["expression"]
+           ( ReqArg
+               (\s -> Right $ \config -> config {scriptExps = scriptExps config ++ [Right (T.pack s)]})
+               "EXP"
+           )
+           "Run this expression."
        ]
 
+parseScriptFile :: FilePath -> IO Exp
+parseScriptFile f = do
+  s <- T.readFile f
+  case parseExpFromText f s of
+    Left e -> do
+      T.hPutStrLn stderr e
+      exitFailure
+    Right e -> pure e
+
+getExp :: Either FilePath T.Text -> IO Exp
+getExp (Left f) = parseScriptFile f
+getExp (Right s) = case parseExpFromText "command line option" s of
+  Left e -> do
+    T.hPutStrLn stderr e
+    exitFailure
+  Right e -> pure e
+
+-- A few extra procedures that are not handled by scriptBuiltin.
+extScriptBuiltin :: (MonadError T.Text m, MonadIO m) => EvalBuiltin m
+extScriptBuiltin "store" [ValueAtom fv, ValueAtom vv]
+  | Just path <- getValue fv = do
+      let path' = map (chr . fromIntegral) (path :: [Bin.Word8])
+      liftIO $ BS.writeFile path' $ Bin.encode vv
+      pure $ ValueTuple []
+extScriptBuiltin "store" vs =
+  throwError $
+    "$store does not accept arguments of types: "
+      <> T.intercalate ", " (map (prettyText . fmap valueType) vs)
+extScriptBuiltin f vs =
+  scriptBuiltin "." f vs
+
 -- | Run @futhark script@.
 main :: String -> [String] -> IO ()
-main = mainWithOptions initialOptions commandLineOptions "program script" $ \args opts ->
+main = mainWithOptions initialOptions commandLineOptions "PROGRAM [EXP]" $ \args opts ->
   case args of
-    [prog, script] -> Just $ do
-      script' <- case parseExpFromText "command line argument" $ T.pack script of
-        Left e -> do
-          T.hPutStrLn stderr e
-          exitFailure
-        Right x -> pure x
+    [prog, script] -> Just $ main' prog opts $ scriptExps opts ++ [Right $ T.pack script]
+    [prog] -> Just $ main' prog opts $ scriptExps opts
+    _ -> Nothing
+  where
+    main' prog opts scripts = do
+      scripts' <- mapM getExp scripts
       prepareServer prog opts $ \s -> do
         r <-
-          runExceptT $ getExpValue s =<< evalExp (scriptBuiltin ".") s script'
+          runExceptT $ do
+            vs <- mapM (evalExp extScriptBuiltin s) scripts'
+            case reverse vs of
+              [] -> pure Nothing
+              v : _ -> Just <$> getExpValue s v
         case r of
           Left e -> do
             T.hPutStrLn stderr e
             exitFailure
-          Right v ->
+          Right Nothing ->
+            pure ()
+          Right (Just v) ->
             if scriptBinary opts
               then case v of
                 ValueAtom v' -> BS.putStr $ Bin.encode v'
@@ -75,4 +130,3 @@
                     stderr
                     "Result value cannot be represented in binary format."
               else T.putStrLn $ prettyText v
-    _ -> Nothing
diff --git a/src/Futhark/Optimise/ArrayShortCircuiting/ArrayCoalescing.hs b/src/Futhark/Optimise/ArrayShortCircuiting/ArrayCoalescing.hs
--- a/src/Futhark/Optimise/ArrayShortCircuiting/ArrayCoalescing.hs
+++ b/src/Futhark/Optimise/ArrayShortCircuiting/ArrayCoalescing.hs
@@ -147,9 +147,10 @@
   ComputeScalarTableOnOp rep ->
   Prog (Aliases rep) ->
   m (M.Map Name CoalsTab)
-mkCoalsTabProg (_, lutab_prog) r computeScalarOnOp =
-  fmap M.fromList . mapM onFun . progFuns
+mkCoalsTabProg (_, lutab_prog) r computeScalarOnOp prog =
+  fmap M.fromList . mapM onFun . progFuns $ prog
   where
+    consts_scope = scopeOf (progConsts prog)
     onFun fun@(FunDef _ _ fname _ fpars body) = do
       -- First compute last-use information
       let unique_mems = getUniqueMemFParam fpars
@@ -157,13 +158,17 @@
           scalar_table =
             runReader
               ( concatMapM
-                  (computeScalarTable $ scopeOf fun <> scopeOf (bodyStms body))
+                  ( computeScalarTable $
+                      consts_scope
+                        <> scopeOf fun
+                        <> scopeOf (bodyStms body)
+                  )
                   (stmsToList $ bodyStms body)
               )
               computeScalarOnOp
           topenv =
             emptyTopdownEnv
-              { scope = scopeOfFParams fpars,
+              { scope = consts_scope <> scopeOfFParams fpars,
                 alloc = unique_mems,
                 scalarTable = scalar_table,
                 nonNegatives = foldMap paramSizes fpars
diff --git a/src/Futhark/Optimise/Simplify/Rules/ClosedForm.hs b/src/Futhark/Optimise/Simplify/Rules/ClosedForm.hs
--- a/src/Futhark/Optimise/Simplify/Rules/ClosedForm.hs
+++ b/src/Futhark/Optimise/Simplify/Rules/ClosedForm.hs
@@ -48,6 +48,7 @@
   inputsize <- arraysSize 0 <$> mapM lookupType arrs
 
   t <- case patTypes pat of
+    [Prim FloatType {}] -> cannotSimplify
     [Prim t] -> pure t
     _ -> cannotSimplify
 
@@ -87,6 +88,7 @@
   RuleM rep ()
 loopClosedForm pat merge i it bound body = do
   t <- case patTypes pat of
+    [Prim FloatType {}] -> cannotSimplify
     [Prim t] -> pure t
     _ -> cannotSimplify
 
