diff --git a/.test-conda-env-py3.yml b/.test-conda-env-py3.yml
index 0688c79603a66aabd0e021855e543f751cd76542..2570718a65a4d924683527d8442a812fdea362ed 100644
--- a/.test-conda-env-py3.yml
+++ b/.test-conda-env-py3.yml
@@ -13,6 +13,6 @@ dependencies:
 - islpy
 
 # Only needed to make pylint succeed
-- matplotlib
+- matplotlib-base
 - ipykernel
 - ply
diff --git a/loopy/check.py b/loopy/check.py
index 552dbaa369ccadeda52572dfe048ca7b95ca48ea..c176b89b588da6696785d9d6b4bae8fc8639c795 100644
--- a/loopy/check.py
+++ b/loopy/check.py
@@ -25,7 +25,7 @@ from islpy import dim_type
 import islpy as isl
 from loopy.symbolic import WalkMapper, CombineMapper, ResolvedFunction
 from loopy.diagnostic import (LoopyError, WriteRaceConditionWarning,
-        warn_with_kernel)
+        warn_with_kernel, LoopyIndexError)
 from loopy.type_inference import TypeReader
 from loopy.kernel.instruction import (MultiAssignmentBase, CallInstruction,
                                       CInstruction, _DataObliviousInstruction,
@@ -537,7 +537,7 @@ class _AccessCheckMapper(WalkMapper):
                     shape_domain = shape_domain.intersect(slab)
 
             if not access_range.is_subset(shape_domain):
-                raise LoopyError("'%s' in instruction '%s' "
+                raise LoopyIndexError("'%s' in instruction '%s' "
                         "accesses out-of-bounds array element (could not"
                         " establish '%s' is a subset of '%s')."
                         % (expr, insn_id, access_range, shape_domain))
@@ -556,10 +556,7 @@ class _AccessCheckMapper(WalkMapper):
         self.rec(expr.else_, domain & else_set, insn_id)
 
 
-def check_bounds(kernel):
-    """
-    Performs out-of-bound check for every array access.
-    """
+def _check_bounds_inner(kernel):
     from loopy.kernel.instruction import get_insn_domain
     temp_var_names = set(kernel.temporary_variables)
     acm = _AccessCheckMapper(kernel)
@@ -583,6 +580,34 @@ def check_bounds(kernel):
 
         insn.with_transformed_expressions(run_acm)
 
+
+def check_bounds(kernel):
+    """
+    Performs out-of-bound check for every array access.
+    """
+    if kernel.options.enforce_array_accesses_within_bounds not in [
+            "no_check",
+            True,
+            False]:
+        raise LoopyError("invalid value for option "
+                "'enforce_array_accesses_within_bounds': %s"
+                % kernel.options.enforce_array_accesses_within_bounds)
+
+    if kernel.options.enforce_array_accesses_within_bounds == "no_check":
+        return
+
+    from pytools import ProcessLogger
+    with ProcessLogger(logger, "%s: check array access within bounds" % kernel.name):
+        if kernel.options.enforce_array_accesses_within_bounds:
+            _check_bounds_inner(kernel)
+        else:
+            from loopy.diagnostic import LoopyIndexError
+            try:
+                _check_bounds_inner(kernel)
+            except LoopyIndexError as e:
+                from loopy.diagnostic import warn_with_kernel
+                warn_with_kernel(kernel, "array_access_out_of_bounds", str(e))
+
 # }}}
 
 
diff --git a/loopy/diagnostic.py b/loopy/diagnostic.py
index c471facc80ca4a043a62dd5d96c6bf3ba4873226..fc8fbe71f8fbec10f31684107f012dc94201618d 100644
--- a/loopy/diagnostic.py
+++ b/loopy/diagnostic.py
@@ -74,6 +74,10 @@ class LoopyError(RuntimeError):
     pass
 
 
+class LoopyIndexError(LoopyError):
+    pass
+
+
 class CannotBranchDomainTree(LoopyError):
     pass
 
@@ -115,6 +119,11 @@ class LoopyTypeError(LoopyError):
 
 
 class ExpressionNotAffineError(LoopyError):
+    """
+    Raised when an expression is not quasi-affine. See
+    `ISL manual <http://isl.gforge.inria.fr//user.html#Primitive-Functions>`_
+    for then definition of a quasi-affine expression.
+    """
     pass
 
 
diff --git a/loopy/frontend/fortran/__init__.py b/loopy/frontend/fortran/__init__.py
index d6311131f935a5b7dc8405e0cad039371131a079..15c6a7dc31f33d0897c4d6cd5293a273a52d2ee0 100644
--- a/loopy/frontend/fortran/__init__.py
+++ b/loopy/frontend/fortran/__init__.py
@@ -294,7 +294,15 @@ def _add_assignees_to_calls(knl, all_kernels):
 
 
 def parse_fortran(source, filename="<floopy code>", free_form=None, strict=None,
-        seq_dependencies=None, auto_dependencies=None, target=None):
+        seq_dependencies=None, auto_dependencies=None, target=None,
+        all_names_known=True):
+    """
+    :arg all_names_known: if set to *False*, enter an undocumented mode
+        in which Fortran parsing will try to tolerate unknown names.
+        If used, ``loopy.frontend.fortran.translator.specialize_fortran_division``
+        must be called as soon as all names are known.
+    :returns: a :class:`loopy.TranslationUnit`
+    """
 
     parse_plog = ProcessLogger(logger, "parsing fortran file '%s'" % filename)
 
@@ -330,7 +338,8 @@ def parse_fortran(source, filename="<floopy code>", free_form=None, strict=None,
                 "and returned invalid data (Sorry!)")
 
     from loopy.frontend.fortran.translator import F2LoopyTranslator
-    f2loopy = F2LoopyTranslator(filename, target=target)
+    f2loopy = F2LoopyTranslator(
+            filename, target=target, all_names_known=all_names_known)
     f2loopy(tree)
 
     kernels = f2loopy.make_kernels(seq_dependencies=seq_dependencies)
diff --git a/loopy/frontend/fortran/translator.py b/loopy/frontend/fortran/translator.py
index 7109f1ed216ab8ede25dadbae076839644b8b268..8dcc32e008497703171c38a446d6e9031e9a708c 100644
--- a/loopy/frontend/fortran/translator.py
+++ b/loopy/frontend/fortran/translator.py
@@ -28,11 +28,13 @@ import loopy as lp
 import numpy as np
 from warnings import warn
 from loopy.frontend.fortran.tree import FTreeWalkerBase
+from loopy.diagnostic import warn_with_kernel
 from loopy.frontend.fortran.diagnostic import (
         TranslationError, TranslatorWarning)
 import islpy as isl
 from islpy import dim_type
-from loopy.symbolic import IdentityMapper
+from loopy.symbolic import (IdentityMapper, RuleAwareIdentityMapper,
+        SubstitutionRuleMappingContext)
 from loopy.diagnostic import LoopyError
 from loopy.kernel.instruction import LegacyStringInstructionTag
 from pymbolic.primitives import (Wildcard, Slice)
@@ -124,7 +126,9 @@ class SubscriptIndexAdjuster(IdentityMapper):
 # {{{ scope
 
 class Scope:
-    def __init__(self, subprogram_name, arg_names=set()):
+    def __init__(self, subprogram_name, arg_names=None):
+        if arg_names is None:
+            arg_names = set()
         self.subprogram_name = subprogram_name
 
         # map first letter to type
@@ -244,13 +248,66 @@ class Scope:
 # }}}
 
 
+# {{{ fortran division specializers
+
+class FortranDivisionToFloorDiv(IdentityMapper):
+    def map_fortran_division(self, expr, *args):
+        from warnings import warn
+        from loopy.diagnostic import LoopyWarning
+        warn(
+                "Integer division in Fortran do loop bound. "
+                "Loopy currently forces this to integers and gets it wrong for "
+                "negative arguments.", LoopyWarning)
+        from pymbolic.primitives import FloorDiv
+        return FloorDiv(
+                self.rec(expr.numerator, *args),
+                self.rec(expr.denominator, *args))
+
+
+class FortranDivisionSpecializer(RuleAwareIdentityMapper):
+    def __init__(self, rule_mapping_context, kernel):
+        super().__init__(rule_mapping_context)
+        from loopy.type_inference import TypeInferenceMapper
+        self.infer_type = TypeInferenceMapper(kernel)
+        self.kernel = kernel
+
+    def map_fortran_division(self, expr, *args):
+        # We remove all these before type inference ever sees them.
+        num_dtype = self.infer_type(expr.numerator).numpy_dtype
+        den_dtype = self.infer_type(expr.denominator).numpy_dtype
+
+        from pymbolic.primitives import Quotient, FloorDiv
+        if num_dtype.kind in "iub" and den_dtype.kind in "iub":
+            warn_with_kernel(self.kernel,
+                    "fortran_int_div",
+                    "Integer division in Fortran code. Loopy currently gets this "
+                    "wrong for negative arguments.")
+            return FloorDiv(
+                    self.rec(expr.numerator, *args),
+                    self.rec(expr.denominator, *args))
+
+        else:
+            return Quotient(
+                    self.rec(expr.numerator, *args),
+                    self.rec(expr.denominator, *args))
+
+
+def specialize_fortran_division(knl):
+    rmc = SubstitutionRuleMappingContext(
+            knl.substitutions, knl.get_var_name_generator())
+    return FortranDivisionSpecializer(rmc, knl).map_kernel(knl)
+
+# }}}
+
+
 # {{{ translator
 
 class F2LoopyTranslator(FTreeWalkerBase):
-    def __init__(self, filename, target=None):
+    def __init__(self, filename, target=None, all_names_known=True):
         FTreeWalkerBase.__init__(self, filename)
 
         self.target = target
+        self.all_names_known = all_names_known
 
         self.scope_stack = []
 
@@ -433,7 +490,9 @@ class F2LoopyTranslator(FTreeWalkerBase):
         for name, data in node.stmts:
             name, = name
             assert name not in scope.data
-            scope.data[name] = [self.parse_expr(node, i) for i in data]
+            scope.data[name] = [
+                    scope.process_expression_for_loopy(
+                        self.parse_expr(node, i)) for i in data]
 
         return []
 
@@ -564,7 +623,9 @@ class F2LoopyTranslator(FTreeWalkerBase):
         cond_var = var(cond_name)
 
         self.add_expression_instruction(
-                cond_var, self.parse_expr(node, node.expr))
+                cond_var,
+                scope.process_expression_for_loopy(
+                    self.parse_expr(node, node.expr)))
 
         cond_expr = cond_var
         if context_cond is not None:
@@ -643,9 +704,10 @@ class F2LoopyTranslator(FTreeWalkerBase):
                         % (loop_var, iname_dtype, self.index_dtype))
 
         scope.use_name(loop_var)
-        loop_bounds = self.parse_expr(
-                node,
-                loop_bounds, min_precedence=self.expr_parser._PREC_FUNC_ARGS)
+        loop_bounds = scope.process_expression_for_loopy(
+                self.parse_expr(
+                    node,
+                    loop_bounds, min_precedence=self.expr_parser._PREC_FUNC_ARGS))
 
         if len(loop_bounds) == 2:
             start, stop = loop_bounds
@@ -710,7 +772,8 @@ class F2LoopyTranslator(FTreeWalkerBase):
                     isl.Constraint.inequality_from_aff(
                         iname_rel_aff(space,
                             loopy_loop_var, "<=",
-                            aff_from_expr(space, stop-start)))))
+                            aff_from_expr(space, FortranDivisionToFloorDiv()(
+                                stop-start))))))
 
         from pymbolic import var
         scope.active_iname_aliases[loop_var] = \
@@ -839,8 +902,12 @@ class F2LoopyTranslator(FTreeWalkerBase):
                     seq_dependencies=seq_dependencies,
                     )
 
+            if self.all_names_known:
+                knl = specialize_fortran_division(knl)
+
             from loopy.loop import merge_loop_domains
             knl = merge_loop_domains(knl)
+
             knl = lp.fold_constants(knl)
 
             result.append(knl)
diff --git a/loopy/frontend/fortran/tree.py b/loopy/frontend/fortran/tree.py
index 0dc426572f69b7a8ce16dbc97a70f874f17954c4..9a703a794ebb20a1881c1ced79258fa83b06ed04 100644
--- a/loopy/frontend/fortran/tree.py
+++ b/loopy/frontend/fortran/tree.py
@@ -23,6 +23,14 @@ THE SOFTWARE.
 import re
 
 from loopy.diagnostic import LoopyError
+from loopy.symbolic import IdentityMapper, FortranDivision
+
+
+class DivisionToFortranDivisionMapper(IdentityMapper):
+    def map_quotient(self, expr):
+        return FortranDivision(
+                self.rec(expr.numerator),
+                self.rec(expr.denominator))
 
 
 class FTreeWalkerBase:
@@ -110,7 +118,8 @@ class FTreeWalkerBase:
 
     def parse_expr(self, node, expr_str, **kwargs):
         try:
-            return self.expr_parser(expr_str, **kwargs)
+            return DivisionToFortranDivisionMapper()(
+                    self.expr_parser(expr_str, **kwargs))
         except Exception as e:
             raise LoopyError(
                     "Error parsing expression '%s' on line %d of '%s': %s"
diff --git a/loopy/kernel/instruction.py b/loopy/kernel/instruction.py
index 42cf4e0173b95ed8bce37509dafb3692bfc1c23d..aed6ae16818df49fab0b03be288b15b611ba30f7 100644
--- a/loopy/kernel/instruction.py
+++ b/loopy/kernel/instruction.py
@@ -383,6 +383,7 @@ class InstructionBase(ImmutableRecord, Taggable):
 
         return result
 
+    @memoize_method
     def dependency_names(self):
         return self.read_dependency_names() | self.write_dependency_names()
 
diff --git a/loopy/options.py b/loopy/options.py
index 45eb3eb63014ad48d0b3b42045c96913bc515c2c..086015dd6b0ef380eae9f56f41f0f487f8982a85 100644
--- a/loopy/options.py
+++ b/loopy/options.py
@@ -169,6 +169,14 @@ class Options(ImmutableRecord):
         helps find and eliminate unintentionally unordered access
         to variables.
 
+        If equal to ``"no_check"``, then no check is performed.
+
+    .. attribute:: enforce_array_accesses_within_bounds
+
+        If *True*, require that :func:`~loopy.check.check_bounds` passes. If
+        *False*, then :func:`~loopy.check.check_bounds` raises a warning for
+        any out-of-bounds accesses.
+
         If equal to ``"no_check"``, then no check is performed.
     """
 
@@ -234,6 +242,8 @@ class Options(ImmutableRecord):
 
                 enforce_variable_access_ordered=kwargs.get(
                     "enforce_variable_access_ordered", True),
+                enforce_array_accesses_within_bounds=kwargs.get(
+                    "enforce_array_accesses_within_bounds", True),
                 )
 
     # {{{ legacy compatibility
diff --git a/loopy/symbolic.py b/loopy/symbolic.py
index 29e22ab31139dbd46fa2df47654548e0991b2a49..9917de098786966a702b8948728f6aae33d835d3 100644
--- a/loopy/symbolic.py
+++ b/loopy/symbolic.py
@@ -157,6 +157,11 @@ class IdentityMapperMixin:
 
     map_rule_argument = map_group_hw_index
 
+    def map_fortran_division(self, expr, *args, **kwargs):
+        return type(expr)(
+                self.rec(expr.numerator, *args, **kwargs),
+                self.rec(expr.denominator, *args, **kwargs))
+
 
 class IdentityMapper(IdentityMapperBase, IdentityMapperMixin):
     pass
@@ -221,6 +226,8 @@ class WalkMapper(WalkMapperBase):
 
         self.rec(expr.function, *args)
 
+    map_fortran_division = WalkMapperBase.map_quotient
+
 
 class CallbackMapper(CallbackMapperBase, IdentityMapper):
     map_reduction = CallbackMapperBase.map_constant
@@ -238,6 +245,8 @@ class CombineMapper(CombineMapperBase):
 
     map_linear_subscript = CombineMapperBase.map_subscript
 
+    map_fortran_division = CombineMapperBase.map_quotient
+
 
 class SubstitutionMapper(
         CSECachingMapperMixin, SubstitutionMapperBase, IdentityMapperMixin):
@@ -305,6 +314,11 @@ class StringifyMapper(StringifyMapperBase):
                     expr.swept_inames),
                 subscr=self.rec(expr.subscript, prec))
 
+    def map_fortran_division(self, expr, enclosing_prec):
+        from pymbolic.mapper.stringifier import PREC_NONE
+        result = self.map_quotient(expr, PREC_NONE)
+        return f"[FORTRANDIV]({result})"
+
 
 class EqualityPreservingStringifyMapper(StringifyMapperBase):
     """
@@ -407,6 +421,8 @@ class DependencyMapper(DependencyMapperBase):
         # See https://github.com/inducer/loopy/pull/323
         raise NotImplementedError
 
+    map_fortran_division = DependencyMapperBase.map_quotient
+
 
 class SubstitutionRuleExpander(IdentityMapper):
     def __init__(self, rules):
@@ -962,6 +978,20 @@ class SubArrayRef(LoopyExpressionBase):
 
     mapper_method = intern("map_sub_array_ref")
 
+
+class FortranDivision(p.QuotientBase, LoopyExpressionBase):
+    """This exists for the benefit of the Fortran frontend, which specializes
+    to floating point division for floating point inputs and round-to-zero
+    division for integer inputs. Despite the name, this would also be usable
+    for C semantics. (:mod:`loopy` division semantics match Python's.)
+
+    .. note::
+
+        This is not a documented expression node type. It may disappear
+        at any moment.
+    """
+    mapper_method = "map_fortran_division"
+
 # }}}
 
 
@@ -1810,7 +1840,8 @@ def aff_from_expr(space, expr, vars_to_zero=None):
         (s, aff), = pieces
         return aff
     else:
-        raise RuntimeError("expression '%s' could not be converted to a "
+        from loopy.diagnostic import ExpressionNotAffineError
+        raise ExpressionNotAffineError("expression '%s' could not be converted to a "
                 "non-piecewise quasi-affine expression" % expr)
 
 
@@ -1821,6 +1852,7 @@ def pwaff_from_expr(space, expr, vars_to_zero=None):
 def with_aff_conversion_guard(f, space, expr, *args):
     import islpy as isl
     from pymbolic.mapper.evaluator import UnknownVariableError
+    from loopy.diagnostic import ExpressionNotAffineError
 
     err = None
     with isl.SuppressedWarnings(space.get_ctx()):
@@ -1832,6 +1864,8 @@ def with_aff_conversion_guard(f, space, expr, *args):
             err = e
         except UnknownVariableError as e:
             err = e
+        except ExpressionNotAffineError as e:
+            err = e
 
         assert err is not None
         from loopy.diagnostic import ExpressionToAffineConversionError
diff --git a/loopy/target/execution.py b/loopy/target/execution.py
index 2f8335848660519833cf78a08a3b650d45cb16a1..fdd38278ecbd2d83727071006ccf08968edba46f 100644
--- a/loopy/target/execution.py
+++ b/loopy/target/execution.py
@@ -704,7 +704,7 @@ typed_and_scheduled_cache = WriteOncePersistentDict(
 
 
 invoker_cache = WriteOncePersistentDict(
-        "loopy-invoker-cache-v1-"+DATA_MODEL_VERSION,
+        "loopy-invoker-cache-v10-"+DATA_MODEL_VERSION,
         key_builder=LoopyKeyBuilder())
 
 
diff --git a/loopy/target/pyopencl.py b/loopy/target/pyopencl.py
index bcced16df351d3b2d11592c9a781cd74b04ae1e9..5a26e8f0b2e0924aebead041ae543a3fc74c7a12 100644
--- a/loopy/target/pyopencl.py
+++ b/loopy/target/pyopencl.py
@@ -544,9 +544,9 @@ class PyOpenCLTarget(OpenCLTarget):
             use_int8_for_bool=use_int8_for_bool)
 
         import pyopencl.version
-        if pyopencl.version.VERSION < (2021, 1):
+        if pyopencl.version.VERSION < (2021, 2):
             raise RuntimeError("The version of loopy you have installed "
-                    "generates invoker code that requires PyOpenCL 2021.1 "
+                    "generates invoker code that requires PyOpenCL 2021.2 "
                     "or newer.")
 
         self.device = device
diff --git a/loopy/target/pyopencl_execution.py b/loopy/target/pyopencl_execution.py
index 5ac37e1520abc774b877d16741302ff7b79810af..76bd323873d5ffd67e4d0d202f0f9e19b2b4cf9a 100644
--- a/loopy/target/pyopencl_execution.py
+++ b/loopy/target/pyopencl_execution.py
@@ -48,6 +48,8 @@ class PyOpenCLExecutionWrapperGenerator(ExecutionWrapperGeneratorBase):
             "out_host=None"
             ]
         super().__init__(system_args)
+        from pytools import UniqueNameGenerator
+        self.dtype_name_generator = UniqueNameGenerator(forced_prefix="_lpy_dtype_")
 
     def python_dtype_str(self, dtype):
         import pyopencl.tools as cl_tools
@@ -90,47 +92,46 @@ class PyOpenCLExecutionWrapperGenerator(ExecutionWrapperGeneratorBase):
         from pymbolic import var
 
         num_axes = len(arg.strides)
-        for i in range(num_axes):
-            gen("_lpy_shape_%d = %s" % (i, strify(arg.unvec_shape[i])))
 
         itemsize = kernel_arg.dtype.numpy_dtype.itemsize
         for i in range(num_axes):
-            gen("_lpy_strides_%d = %s" % (i, strify(
-                itemsize*arg.unvec_strides[i])))
+            gen("_lpy_ustrides_%d = %s" % (i, strify(
+                arg.unvec_strides[i])))
 
         if not skip_arg_checks:
             for i in range(num_axes):
-                gen("assert _lpy_strides_%d > 0, "
+                gen("assert _lpy_ustrides_%d > 0, "
                         "\"'%s' has negative stride in axis %d\""
                         % (i, arg.name, i))
 
-        sym_strides = tuple(
-                var("_lpy_strides_%d" % i)
+        sym_ustrides = tuple(
+                var("_lpy_ustrides_%d" % i)
                 for i in range(num_axes))
         sym_shape = tuple(
-                var("_lpy_shape_%d" % i)
+                arg.unvec_shape[i]
                 for i in range(num_axes))
 
-        alloc_size_expr = (sum(astrd*(alen-1)
-            for alen, astrd in zip(sym_shape, sym_strides))
-            + itemsize)
+        size_expr = (sum(astrd*(alen-1)
+            for alen, astrd in zip(sym_shape, sym_ustrides))
+            + 1)
 
-        gen("_lpy_alloc_size = %s" % strify(alloc_size_expr))
-        gen("%(name)s = _lpy_cl_array.Array(queue, %(shape)s, "
-                "%(dtype)s, strides=%(strides)s, "
-                "data=allocator(_lpy_alloc_size), allocator=allocator)"
-                % dict(
-                    name=arg.name,
-                    shape=strify(sym_shape),
-                    strides=strify(sym_strides),
-                    dtype=self.python_dtype_str(kernel_arg.dtype.numpy_dtype)))
+        gen("_lpy_size = %s" % strify(size_expr))
+        sym_strides = tuple(itemsize*s_i for s_i in sym_ustrides)
+        dtype_str = self.python_dtype_str(kernel_arg.dtype.numpy_dtype)
 
-        if not skip_arg_checks:
-            for i in range(num_axes):
-                gen("del _lpy_shape_%d" % i)
-                gen("del _lpy_strides_%d" % i)
-            gen("del _lpy_alloc_size")
-            gen("")
+        dtype_name = self.dtype_name_generator()
+        gen.add_to_preamble(f"{dtype_name} = _lpy_np.dtype({dtype_str})")
+        gen(f"{arg.name} = _lpy_cl_array.Array(None, {strify(sym_shape)}, "
+                f"{dtype_name}, strides={strify(sym_strides)}, "
+                f"data=allocator({strify(itemsize * var('_lpy_size'))}), "
+                "allocator=allocator, "
+                "_fast=True, _size=_lpy_size, "
+                "_context=queue.context, _queue=queue)")
+
+        for i in range(num_axes):
+            gen("del _lpy_ustrides_%d" % i)
+        gen("del _lpy_size")
+        gen("")
 
     # }}}
 
diff --git a/loopy/transform/iname.py b/loopy/transform/iname.py
index 7f1273d3c7cecc80d69bad44f5cfb59078752f12..85588da3eba4bd259b031aa437ecb51d42bf91c5 100644
--- a/loopy/transform/iname.py
+++ b/loopy/transform/iname.py
@@ -310,7 +310,7 @@ def _split_iname_backend(kernel, iname_to_split,
             loop_priority=frozenset(new_priorities))
 
     rule_mapping_context = SubstitutionRuleMappingContext(
-            kernel.substitutions, kernel.get_var_name_generator())
+            kernel.substitutions, vng)
     ins = _InameSplitter(rule_mapping_context, within,
             iname_to_split, outer_iname, inner_iname, new_loop_index)
 
diff --git a/test/test_fortran.py b/test/test_fortran.py
index 72f7b7e016b91e869bfb103e574c5c2e450a943e..d6bb57162ca6ed4f9194e29491f53ebdaf9f1e14 100644
--- a/test/test_fortran.py
+++ b/test/test_fortran.py
@@ -654,6 +654,28 @@ def test_domain_fusion_imperfectly_nested():
     assert len(t_unit["imperfect"].domains) > 1
 
 
+def test_division_in_shapes(ctx_factory):
+    fortran_src = """
+        subroutine halve(m, a)
+            implicit none
+            integer m, i, j
+            real*8 a(m/2,m/2)
+            do i = 1,m/2
+                do j = 1,m/2
+                    a(i, j) = 2*a(i, j)
+                end do
+            end do
+        end subroutine
+        """
+    knl, = lp.parse_fortran(fortran_src)
+    ref_knl = knl
+
+    print(knl)
+
+    ctx = ctx_factory()
+    lp.auto_test_vs_ref(ref_knl, ctx, knl, parameters=dict(m=128))
+
+
 if __name__ == "__main__":
     if len(sys.argv) > 1:
         exec(sys.argv[1])
diff --git a/test/test_numa_diff.py b/test/test_numa_diff.py
index 40309f70f15a0ffae55bcd7f406d2cc08d95ad46..bfe7c8756a3dc3b12e1dcdce635c5287665018ee 100644
--- a/test/test_numa_diff.py
+++ b/test/test_numa_diff.py
@@ -57,7 +57,8 @@ def test_gnuma_horiz_kernel(ctx_factory, ilp_multiple, Nq, opt_level):  # noqa
 
     source = source.replace("datafloat", "real*4")
 
-    program = lp.parse_fortran(source, filename, seq_dependencies=False)
+    program = lp.parse_fortran(source, filename, seq_dependencies=False,
+               all_names_known=False)
 
     hsv_r, hsv_s = program["strongVolumeKernelR"], program["strongVolumeKernelS"]
 
@@ -77,6 +78,9 @@ def test_gnuma_horiz_kernel(ctx_factory, ilp_multiple, Nq, opt_level):  # noqa
     hsv = lp.assume(hsv, "elements >= 1")
 
     hsv = fix_euler_parameters(hsv, p_p0=1, p_Gamma=1.4, p_R=1)
+    from loopy.frontend.fortran.translator import specialize_fortran_division
+    hsv = specialize_fortran_division(hsv)
+
     for name in ["Q", "rhsQ"]:
         hsv = set_q_storage_format(hsv, name)
 
diff --git a/test/test_transform.py b/test/test_transform.py
index 1e75aa0bc893be49b47b7a13067a0189920b9eac..4853545db20547483bcac86f1ec181434061ee53 100644
--- a/test/test_transform.py
+++ b/test/test_transform.py
@@ -50,7 +50,8 @@ __all__ = [
 from loopy.version import LOOPY_USE_LANGUAGE_VERSION_2018_2  # noqa
 
 
-def test_chunk_iname(ctx_factory):
+@pytest.mark.parametrize("fix_parameters", (True, False))
+def test_chunk_iname(ctx_factory, fix_parameters):
     ctx = ctx_factory()
 
     knl = lp.make_kernel(
@@ -65,7 +66,13 @@ def test_chunk_iname(ctx_factory):
     ref_knl = knl
     knl = lp.chunk_iname(knl, "i", 3, inner_tag="l.0")
     knl = lp.prioritize_loops(knl, "i_outer, i_inner")
-    lp.auto_test_vs_ref(ref_knl, ctx, knl, parameters=dict(n=130))
+
+    if fix_parameters:
+        ref_knl = lp.fix_parameters(ref_knl, n=130)
+        knl = lp.fix_parameters(knl, n=130)
+        lp.auto_test_vs_ref(ref_knl, ctx, knl)
+    else:
+        lp.auto_test_vs_ref(ref_knl, ctx, knl, parameters={"n": 130})
 
 
 def test_collect_common_factors(ctx_factory):