[flang-commits] [flang] [flang][NFC] Convert problematic legacy-lowering tests to HLFIR (part 56) (PR #195578)

Eugene Epshteyn via flang-commits flang-commits at lists.llvm.org
Mon May 4 05:37:44 PDT 2026


https://github.com/eugeneepshteyn updated https://github.com/llvm/llvm-project/pull/195578

>From 54c56093bb49dc0b66b94c9a29d71d743dc3a18e Mon Sep 17 00:00:00 2001
From: Eugene Epshteyn <eepshteyn at nvidia.com>
Date: Sun, 3 May 2026 20:45:05 -0400
Subject: [PATCH 1/2] [flang][test] Convert Unconvertable legacy-lowering tests
 to HLFIR (batch 4)

Full rewrites of the four tests previously listed under "Unconvertable
tests" in the legacy-lowering deprecation tracking document. Each test
now uses the new HLFIR lowering instead of legacy FIR lowering.

Converted tests:
- Lower/derived-allocatable-components.f90 (506 lines)
- Lower/polymorphic.f90 (1165 lines)
- Lower/select-type.f90 (883 lines)
- Lower/vector-subscript-io.f90 (581 lines)

CHECK patterns updated to match HLFIR output, including:
- hlfir.declare wrappers around dummy arguments and locals
- hlfir.designate for component access (replacing fir.coordinate_of with
  field name) and array indexing (replacing fir.coordinate_of with index)
- hlfir.designate with allocatable/pointer attribute for accessing
  allocatable/pointer components
- fir.box_addr load chain for dereferencing allocatable components, with
  ALLOCATED replaced by fir.box_addr + arith.cmpi ne 0 (instead of an
  intrinsic call)
- hlfir.elemental for vector-subscript-driven elemental loops in
  vector-subscript-io.f90
- fir.do_loop replacing the cf.br/cond_br loop structures of the
  legacy vector-subscript-IO lowering
- fir.iterate_while for iostat-aware vector-subscript loops

In polymorphic.f90, detailed per-procedure CHECK patterns were added
inline (after each procedure body) covering the key HLFIR lowering
patterns for class types, including hlfir.declare for class dummies,
hlfir.designate for class component access, fir.embox + fir.convert for
type-to-class boxing as passed-object, fir.dispatch for type-bound
procedure calls, fir.embox + fir.rebox chain for boxing trivial values
into class<none> for unlimited-polymorphic arguments, and the runtime
calls _FortranAPointerNullifyDerived / _FortranAPointerNullifyIntrinsic
/ _FortranAAllocatableAllocate / _FortranAMoveAlloc / _FortranASameTypeAs.
---
 .../Lower/derived-allocatable-components.f90  | 368 ++++----
 flang/test/Lower/polymorphic.f90              | 808 ++++++------------
 flang/test/Lower/select-type.f90              | 588 ++-----------
 flang/test/Lower/vector-subscript-io.f90      | 738 +++++++---------
 4 files changed, 827 insertions(+), 1675 deletions(-)

diff --git a/flang/test/Lower/derived-allocatable-components.f90 b/flang/test/Lower/derived-allocatable-components.f90
index bc508fb9470ae..8d7ea554a1aa3 100644
--- a/flang/test/Lower/derived-allocatable-components.f90
+++ b/flang/test/Lower/derived-allocatable-components.f90
@@ -1,5 +1,5 @@
 ! Test lowering of allocatable components
-! RUN: bbc -emit-fir -hlfir=false %s -o - | FileCheck %s
+! RUN: %flang_fc1 -emit-hlfir %s -o - | FileCheck %s
 
 module acomp
   implicit none
@@ -79,81 +79,60 @@ subroutine ref_scalar_real_a(a0_0, a1_0, a0_1, a1_1)
   type(real_a0) :: a0_0, a0_1(100)
   type(real_a1) :: a1_0, a1_1(100)
 
-  ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[arg0]], p : (!fir.ref<!fir.type<_QMacompTreal_a0{p:!fir.box<!fir.heap<f32>>}>>) -> !fir.ref<!fir.box<!fir.heap<f32>>>
+  ! CHECK: %[[a0_0_decl:.*]]:2 = hlfir.declare %[[arg0]]{{.*}}{uniq_name = "_QMacompFref_scalar_real_aEa0_0"}
+  ! CHECK: %[[a0_1_decl:.*]]:2 = hlfir.declare %[[arg2]](%{{.*}}){{.*}}{uniq_name = "_QMacompFref_scalar_real_aEa0_1"}
+  ! CHECK: %[[a1_0_decl:.*]]:2 = hlfir.declare %[[arg1]]{{.*}}{uniq_name = "_QMacompFref_scalar_real_aEa1_0"}
+  ! CHECK: %[[a1_1_decl:.*]]:2 = hlfir.declare %[[arg3]](%{{.*}}){{.*}}{uniq_name = "_QMacompFref_scalar_real_aEa1_1"}
+
+  ! CHECK: %[[coor:.*]] = hlfir.designate %[[a0_0_decl]]#0{"p"}{{.*}}{fortran_attrs = #fir.var_attrs<allocatable>} : (!fir.ref<!fir.type<_QMacompTreal_a0{p:!fir.box<!fir.heap<f32>>}>>) -> !fir.ref<!fir.box<!fir.heap<f32>>>
   ! CHECK: %[[load:.*]] = fir.load %[[coor]] : !fir.ref<!fir.box<!fir.heap<f32>>>
   ! CHECK: %[[addr:.*]] = fir.box_addr %[[load]] : (!fir.box<!fir.heap<f32>>) -> !fir.heap<f32>
   ! CHECK: %[[cast:.*]] = fir.convert %[[addr]] : (!fir.heap<f32>) -> !fir.ref<f32>
   ! CHECK: fir.call @_QPtakes_real_scalar(%[[cast]]) {{.*}}: (!fir.ref<f32>) -> ()
   call takes_real_scalar(a0_0%p)
 
-  ! CHECK: %[[a0_1_coor:.*]] = fir.coordinate_of %[[arg2]], %{{.*}} : (!fir.ref<!fir.array<100x!fir.type<_QMacompTreal_a0{p:!fir.box<!fir.heap<f32>>}>>>, i64) -> !fir.ref<!fir.type<_QMacompTreal_a0{p:!fir.box<!fir.heap<f32>>}>>
-  ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[a0_1_coor]], p : (!fir.ref<!fir.type<_QMacompTreal_a0{p:!fir.box<!fir.heap<f32>>}>>) -> !fir.ref<!fir.box<!fir.heap<f32>>>
+  ! CHECK: %[[a0_1_elem:.*]] = hlfir.designate %[[a0_1_decl]]#0 (%{{.*}})  : (!fir.ref<!fir.array<100x!fir.type<_QMacompTreal_a0{p:!fir.box<!fir.heap<f32>>}>>>, index) -> !fir.ref<!fir.type<_QMacompTreal_a0{p:!fir.box<!fir.heap<f32>>}>>
+  ! CHECK: %[[coor:.*]] = hlfir.designate %[[a0_1_elem]]{"p"}{{.*}}{fortran_attrs = #fir.var_attrs<allocatable>} : (!fir.ref<!fir.type<_QMacompTreal_a0{p:!fir.box<!fir.heap<f32>>}>>) -> !fir.ref<!fir.box<!fir.heap<f32>>>
   ! CHECK: %[[load:.*]] = fir.load %[[coor]] : !fir.ref<!fir.box<!fir.heap<f32>>>
   ! CHECK: %[[addr:.*]] = fir.box_addr %[[load]] : (!fir.box<!fir.heap<f32>>) -> !fir.heap<f32>
   ! CHECK: %[[cast:.*]] = fir.convert %[[addr]] : (!fir.heap<f32>) -> !fir.ref<f32>
   ! CHECK: fir.call @_QPtakes_real_scalar(%[[cast]]) {{.*}}: (!fir.ref<f32>) -> ()
   call takes_real_scalar(a0_1(5)%p)
 
-  ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[arg1]], p : (!fir.ref<!fir.type<_QMacompTreal_a1{p:!fir.box<!fir.heap<!fir.array<?xf32>>>}>>) -> !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>
+  ! CHECK: %[[coor:.*]] = hlfir.designate %[[a1_0_decl]]#0{"p"}{{.*}}{fortran_attrs = #fir.var_attrs<allocatable>} : (!fir.ref<!fir.type<_QMacompTreal_a1{p:!fir.box<!fir.heap<!fir.array<?xf32>>>}>>) -> !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>
   ! CHECK: %[[box:.*]] = fir.load %[[coor]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>
-  ! CHECK-DAG: %[[addr:.*]] = fir.box_addr %[[box]] : (!fir.box<!fir.heap<!fir.array<?xf32>>>) -> !fir.heap<!fir.array<?xf32>>
-  ! CHECK-DAG: %[[dims:.*]]:3 = fir.box_dims %[[box]], %c0{{.*}} : (!fir.box<!fir.heap<!fir.array<?xf32>>>, index) -> (index, index, index)
-  ! CHECK: %[[lb:.*]] = fir.convert %[[dims]]#0 : (index) -> i64
-  ! CHECK: %[[index:.*]] = arith.subi %c7{{.*}}, %[[lb]] : i64
-  ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[addr]], %[[index]] : (!fir.heap<!fir.array<?xf32>>, i64) -> !fir.ref<f32>
-  ! CHECK: fir.call @_QPtakes_real_scalar(%[[coor]]) {{.*}}: (!fir.ref<f32>) -> ()
+  ! CHECK: %[[elem:.*]] = hlfir.designate %[[box]] (%c7{{.*}})  : (!fir.box<!fir.heap<!fir.array<?xf32>>>, index) -> !fir.ref<f32>
+  ! CHECK: fir.call @_QPtakes_real_scalar(%[[elem]]) {{.*}}: (!fir.ref<f32>) -> ()
   call takes_real_scalar(a1_0%p(7))
 
-  ! CHECK: %[[a1_1_coor:.*]] = fir.coordinate_of %[[arg3]], %{{.*}} : (!fir.ref<!fir.array<100x!fir.type<_QMacompTreal_a1{p:!fir.box<!fir.heap<!fir.array<?xf32>>>}>>>, i64) -> !fir.ref<!fir.type<_QMacompTreal_a1{p:!fir.box<!fir.heap<!fir.array<?xf32>>>}>>
-  ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[a1_1_coor]], p : (!fir.ref<!fir.type<_QMacompTreal_a1{p:!fir.box<!fir.heap<!fir.array<?xf32>>>}>>) -> !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>
+  ! CHECK: %[[a1_1_elem:.*]] = hlfir.designate %[[a1_1_decl]]#0 (%{{.*}})  : (!fir.ref<!fir.array<100x!fir.type<_QMacompTreal_a1{p:!fir.box<!fir.heap<!fir.array<?xf32>>>}>>>, index) -> !fir.ref<!fir.type<_QMacompTreal_a1{p:!fir.box<!fir.heap<!fir.array<?xf32>>>}>>
+  ! CHECK: %[[coor:.*]] = hlfir.designate %[[a1_1_elem]]{"p"}{{.*}}{fortran_attrs = #fir.var_attrs<allocatable>} : (!fir.ref<!fir.type<_QMacompTreal_a1{p:!fir.box<!fir.heap<!fir.array<?xf32>>>}>>) -> !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>
   ! CHECK: %[[box:.*]] = fir.load %[[coor]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>
-  ! CHECK-DAG: %[[addr:.*]] = fir.box_addr %[[box]] : (!fir.box<!fir.heap<!fir.array<?xf32>>>) -> !fir.heap<!fir.array<?xf32>>
-  ! CHECK-DAG: %[[dims:.*]]:3 = fir.box_dims %[[box]], %c0{{.*}} : (!fir.box<!fir.heap<!fir.array<?xf32>>>, index) -> (index, index, index)
-  ! CHECK: %[[lb:.*]] = fir.convert %[[dims]]#0 : (index) -> i64
-  ! CHECK: %[[index:.*]] = arith.subi %c7{{.*}}, %[[lb]] : i64
-  ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[addr]], %[[index]] : (!fir.heap<!fir.array<?xf32>>, i64) -> !fir.ref<f32>
-  ! CHECK: fir.call @_QPtakes_real_scalar(%[[coor]]) {{.*}}: (!fir.ref<f32>) -> ()
+  ! CHECK: %[[elem:.*]] = hlfir.designate %[[box]] (%c7{{.*}})  : (!fir.box<!fir.heap<!fir.array<?xf32>>>, index) -> !fir.ref<f32>
+  ! CHECK: fir.call @_QPtakes_real_scalar(%[[elem]]) {{.*}}: (!fir.ref<f32>) -> ()
   call takes_real_scalar(a1_1(5)%p(7))
 end subroutine
 
 ! CHECK-LABEL: func @_QMacompPref_array_real_a(
 ! CHECK-SAME:        %[[VAL_0:.*]]: !fir.ref<!fir.type<_QMacompTreal_a1{p:!fir.box<!fir.heap<!fir.array<?xf32>>>}>>{{.*}}, %[[VAL_1:.*]]: !fir.ref<!fir.array<100x!fir.type<_QMacompTreal_a1{p:!fir.box<!fir.heap<!fir.array<?xf32>>>}>>>{{.*}}) {
-! CHECK:         %[[VAL_3:.*]] = fir.coordinate_of %[[VAL_0]], p : (!fir.ref<!fir.type<_QMacompTreal_a1{p:!fir.box<!fir.heap<!fir.array<?xf32>>>}>>) -> !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>
-! CHECK:         %[[VAL_4:.*]] = fir.load %[[VAL_3]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>
-! CHECK:         %[[VAL_5:.*]] = arith.constant 0 : index
-! CHECK:         %[[VAL_6:.*]]:3 = fir.box_dims %[[VAL_4]], %[[VAL_5]] : (!fir.box<!fir.heap<!fir.array<?xf32>>>, index) -> (index, index, index)
-! CHECK:         %[[VAL_7:.*]] = fir.box_addr %[[VAL_4]] : (!fir.box<!fir.heap<!fir.array<?xf32>>>) -> !fir.heap<!fir.array<?xf32>>
-! CHECK:         %[[VAL_8:.*]] = arith.constant 20 : i64
-! CHECK:         %[[VAL_9:.*]] = fir.convert %[[VAL_8]] : (i64) -> index
-! CHECK:         %[[VAL_10:.*]] = arith.constant 2 : i64
-! CHECK:         %[[VAL_11:.*]] = fir.convert %[[VAL_10]] : (i64) -> index
-! CHECK:         %[[VAL_12:.*]] = arith.constant 50 : i64
-! CHECK:         %[[VAL_13:.*]] = fir.convert %[[VAL_12]] : (i64) -> index
-! CHECK:         %[[VAL_14:.*]] = fir.shape_shift %[[VAL_6]]#0, %[[VAL_6]]#1 : (index, index) -> !fir.shapeshift<1>
-! CHECK:         %[[VAL_15:.*]] = fir.slice %[[VAL_9]], %[[VAL_13]], %[[VAL_11]] : (index, index, index) -> !fir.slice<1>
-! CHECK:         %[[VAL_16:.*]] = fir.embox %[[VAL_7]](%[[VAL_14]]) {{\[}}%[[VAL_15]]] : (!fir.heap<!fir.array<?xf32>>, !fir.shapeshift<1>, !fir.slice<1>) -> !fir.box<!fir.array<16xf32>>
-! CHECK:         %[[VAL_16_NEW:.*]] = fir.convert %[[VAL_16]] : (!fir.box<!fir.array<16xf32>>) -> !fir.box<!fir.array<?xf32>>
-! CHECK:         fir.call @_QPtakes_real_array(%[[VAL_16_NEW]]) {{.*}}: (!fir.box<!fir.array<?xf32>>) -> ()
-! CHECK:         %[[VAL_17:.*]] = arith.constant 5 : i64
-! CHECK:         %[[VAL_18:.*]] = arith.constant 1 : i64
-! CHECK:         %[[VAL_19:.*]] = arith.subi %[[VAL_17]], %[[VAL_18]] : i64
-! CHECK:         %[[VAL_20:.*]] = fir.coordinate_of %[[VAL_1]], %[[VAL_19]] : (!fir.ref<!fir.array<100x!fir.type<_QMacompTreal_a1{p:!fir.box<!fir.heap<!fir.array<?xf32>>>}>>>, i64) -> !fir.ref<!fir.type<_QMacompTreal_a1{p:!fir.box<!fir.heap<!fir.array<?xf32>>>}>>
-! CHECK:         %[[VAL_22:.*]] = fir.coordinate_of %[[VAL_20]], p : (!fir.ref<!fir.type<_QMacompTreal_a1{p:!fir.box<!fir.heap<!fir.array<?xf32>>>}>>) -> !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>
-! CHECK:         %[[VAL_23:.*]] = fir.load %[[VAL_22]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>
-! CHECK:         %[[VAL_24:.*]] = arith.constant 0 : index
-! CHECK:         %[[VAL_25:.*]]:3 = fir.box_dims %[[VAL_23]], %[[VAL_24]] : (!fir.box<!fir.heap<!fir.array<?xf32>>>, index) -> (index, index, index)
-! CHECK:         %[[VAL_26:.*]] = fir.box_addr %[[VAL_23]] : (!fir.box<!fir.heap<!fir.array<?xf32>>>) -> !fir.heap<!fir.array<?xf32>>
-! CHECK:         %[[VAL_27:.*]] = arith.constant 20 : i64
-! CHECK:         %[[VAL_28:.*]] = fir.convert %[[VAL_27]] : (i64) -> index
-! CHECK:         %[[VAL_29:.*]] = arith.constant 2 : i64
-! CHECK:         %[[VAL_30:.*]] = fir.convert %[[VAL_29]] : (i64) -> index
-! CHECK:         %[[VAL_31:.*]] = arith.constant 50 : i64
-! CHECK:         %[[VAL_32:.*]] = fir.convert %[[VAL_31]] : (i64) -> index
-! CHECK:         %[[VAL_33:.*]] = fir.shape_shift %[[VAL_25]]#0, %[[VAL_25]]#1 : (index, index) -> !fir.shapeshift<1>
-! CHECK:         %[[VAL_34:.*]] = fir.slice %[[VAL_28]], %[[VAL_32]], %[[VAL_30]] : (index, index, index) -> !fir.slice<1>
-! CHECK:         %[[VAL_35:.*]] = fir.embox %[[VAL_26]](%[[VAL_33]]) {{\[}}%[[VAL_34]]] : (!fir.heap<!fir.array<?xf32>>, !fir.shapeshift<1>, !fir.slice<1>) -> !fir.box<!fir.array<16xf32>>
-! CHECK:         %[[VAL_35_NEW:.*]] = fir.convert %[[VAL_35]] : (!fir.box<!fir.array<16xf32>>) -> !fir.box<!fir.array<?xf32>>
-! CHECK:         fir.call @_QPtakes_real_array(%[[VAL_35_NEW]]) {{.*}}: (!fir.box<!fir.array<?xf32>>) -> ()
+! CHECK:         %[[a1_0_decl:.*]]:2 = hlfir.declare %[[VAL_0]]{{.*}}{uniq_name = "_QMacompFref_array_real_aEa1_0"}
+! CHECK:         %[[a1_1_decl:.*]]:2 = hlfir.declare %[[VAL_1]](%{{.*}}){{.*}}{uniq_name = "_QMacompFref_array_real_aEa1_1"}
+! CHECK:         %[[coor:.*]] = hlfir.designate %[[a1_0_decl]]#0{"p"}{{.*}}{fortran_attrs = #fir.var_attrs<allocatable>}
+! CHECK:         %[[box:.*]] = fir.load %[[coor]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>
+! CHECK:         %[[c20:.*]] = arith.constant 20 : index
+! CHECK:         %[[c50:.*]] = arith.constant 50 : index
+! CHECK:         %[[c2:.*]] = arith.constant 2 : index
+! CHECK:         %[[c16:.*]] = arith.constant 16 : index
+! CHECK:         %[[shape:.*]] = fir.shape %[[c16]] : (index) -> !fir.shape<1>
+! CHECK:         %[[slice:.*]] = hlfir.designate %[[box]] (%[[c20]]:%[[c50]]:%[[c2]])  shape %[[shape]] : (!fir.box<!fir.heap<!fir.array<?xf32>>>, index, index, index, !fir.shape<1>) -> !fir.box<!fir.array<16xf32>>
+! CHECK:         %[[cast:.*]] = fir.convert %[[slice]] : (!fir.box<!fir.array<16xf32>>) -> !fir.box<!fir.array<?xf32>>
+! CHECK:         fir.call @_QPtakes_real_array(%[[cast]]) {{.*}}: (!fir.box<!fir.array<?xf32>>) -> ()
+! CHECK:         %[[elem:.*]] = hlfir.designate %[[a1_1_decl]]#0 (%{{.*}})  : (!fir.ref<!fir.array<100x!fir.type<_QMacompTreal_a1{p:!fir.box<!fir.heap<!fir.array<?xf32>>>}>>>, index) -> !fir.ref<!fir.type<_QMacompTreal_a1{p:!fir.box<!fir.heap<!fir.array<?xf32>>>}>>
+! CHECK:         %[[coor2:.*]] = hlfir.designate %[[elem]]{"p"}{{.*}}{fortran_attrs = #fir.var_attrs<allocatable>}
+! CHECK:         %[[box2:.*]] = fir.load %[[coor2]]
+! CHECK:         %[[slice2:.*]] = hlfir.designate %[[box2]] (%{{.*}}:%{{.*}}:%{{.*}})  shape %{{.*}} : (!fir.box<!fir.heap<!fir.array<?xf32>>>, index, index, index, !fir.shape<1>) -> !fir.box<!fir.array<16xf32>>
+! CHECK:         %[[cast2:.*]] = fir.convert %[[slice2]] : (!fir.box<!fir.array<16xf32>>) -> !fir.box<!fir.array<?xf32>>
+! CHECK:         fir.call @_QPtakes_real_array(%[[cast2]]) {{.*}}: (!fir.box<!fir.array<?xf32>>) -> ()
 ! CHECK:         return
 ! CHECK:       }
 
@@ -164,153 +143,140 @@ subroutine ref_array_real_a(a1_0, a1_1)
 end subroutine
 
 ! CHECK-LABEL: func @_QMacompPref_scalar_cst_char_a
-! CHECK-SAME: (%[[a0_0:.*]]: {{.*}}, %[[a1_0:.*]]: {{.*}}, %[[a0_1:.*]]: {{.*}}, %[[a1_1:.*]]: {{.*}})
+! CHECK-SAME: (%[[a0_0_arg:.*]]: {{.*}}, %[[a1_0_arg:.*]]: {{.*}}, %[[a0_1_arg:.*]]: {{.*}}, %[[a1_1_arg:.*]]: {{.*}})
 subroutine ref_scalar_cst_char_a(a0_0, a1_0, a0_1, a1_1)
   type(cst_char_a0) :: a0_0, a0_1(100)
   type(cst_char_a1) :: a1_0, a1_1(100)
 
-  ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[a0_0]], p
+  ! CHECK: %[[a0_0:.*]]:2 = hlfir.declare %[[a0_0_arg]]{{.*}}{uniq_name = "_QMacompFref_scalar_cst_char_aEa0_0"}
+  ! CHECK: %[[a0_1:.*]]:2 = hlfir.declare %[[a0_1_arg]](%{{.*}}){{.*}}{uniq_name = "_QMacompFref_scalar_cst_char_aEa0_1"}
+  ! CHECK: %[[a1_0:.*]]:2 = hlfir.declare %[[a1_0_arg]]{{.*}}{uniq_name = "_QMacompFref_scalar_cst_char_aEa1_0"}
+  ! CHECK: %[[a1_1:.*]]:2 = hlfir.declare %[[a1_1_arg]](%{{.*}}){{.*}}{uniq_name = "_QMacompFref_scalar_cst_char_aEa1_1"}
+
+  ! CHECK: %[[coor:.*]] = hlfir.designate %[[a0_0]]#0{"p"}{{.*}} typeparams %{{.*}} {fortran_attrs = #fir.var_attrs<allocatable>}
   ! CHECK: %[[box:.*]] = fir.load %[[coor]]
   ! CHECK: %[[addr:.*]] = fir.box_addr %[[box]]
-  ! CHECK: %[[boxchar:.*]] = fir.emboxchar %[[addr]], %c10{{.*}}
+  ! CHECK: %[[cast:.*]] = fir.convert %[[addr]] : (!fir.heap<!fir.char<1,10>>) -> !fir.ref<!fir.char<1,10>>
+  ! CHECK: %[[boxchar:.*]] = fir.emboxchar %[[cast]], %c10{{.*}}
   ! CHECK: fir.call @_QPtakes_char_scalar(%[[boxchar]])
   call takes_char_scalar(a0_0%p)
 
-  ! CHECK-DAG: %[[coor0:.*]] = fir.coordinate_of %[[a0_1]], %{{.*}}
-  ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[coor0]], p
+  ! CHECK: %[[a0_1_elem:.*]] = hlfir.designate %[[a0_1]]#0 (%{{.*}})
+  ! CHECK: %[[coor:.*]] = hlfir.designate %[[a0_1_elem]]{"p"}{{.*}} typeparams %{{.*}} {fortran_attrs = #fir.var_attrs<allocatable>}
   ! CHECK: %[[box:.*]] = fir.load %[[coor]]
   ! CHECK: %[[addr:.*]] = fir.box_addr %[[box]]
-  ! CHECK: %[[boxchar:.*]] = fir.emboxchar %[[addr]], %c10{{.*}}
+  ! CHECK: %[[cast:.*]] = fir.convert %[[addr]] : (!fir.heap<!fir.char<1,10>>) -> !fir.ref<!fir.char<1,10>>
+  ! CHECK: %[[boxchar:.*]] = fir.emboxchar %[[cast]], %c10{{.*}}
   ! CHECK: fir.call @_QPtakes_char_scalar(%[[boxchar]])
   call takes_char_scalar(a0_1(5)%p)
 
 
-  ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[a1_0]], p
+  ! CHECK: %[[coor:.*]] = hlfir.designate %[[a1_0]]#0{"p"}{{.*}} typeparams %{{.*}} {fortran_attrs = #fir.var_attrs<allocatable>}
   ! CHECK: %[[box:.*]] = fir.load %[[coor]]
-  ! CHECK-DAG: %[[base:.*]] = fir.box_addr %[[box]]
-  ! CHECK-DAG: %[[dims:.*]]:3 = fir.box_dims %[[box]], %c0{{.*}}
-  ! CHECK: %[[lb:.*]] = fir.convert %[[dims]]#0 : (index) -> i64
-  ! CHECK: %[[index:.*]] = arith.subi %c7{{.*}}, %[[lb]] : i64
-  ! CHECK: %[[addr:.*]] = fir.coordinate_of %[[base]], %[[index]]
-  ! CHECK: %[[boxchar:.*]] = fir.emboxchar %[[addr]], %c10{{.*}}
+  ! CHECK: %[[elem:.*]] = hlfir.designate %[[box]] (%c7{{.*}})  typeparams %{{.*}} : (!fir.box<!fir.heap<!fir.array<?x!fir.char<1,10>>>>, index, index) -> !fir.ref<!fir.char<1,10>>
+  ! CHECK: %[[boxchar:.*]] = fir.emboxchar %[[elem]], %c10{{.*}}
   ! CHECK: fir.call @_QPtakes_char_scalar(%[[boxchar]])
   call takes_char_scalar(a1_0%p(7))
 
 
-  ! CHECK-DAG: %[[coor0:.*]] = fir.coordinate_of %[[a1_1]], %{{.*}}
-  ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[coor0]], p
+  ! CHECK: %[[a1_1_elem:.*]] = hlfir.designate %[[a1_1]]#0 (%{{.*}})
+  ! CHECK: %[[coor:.*]] = hlfir.designate %[[a1_1_elem]]{"p"}{{.*}} typeparams %{{.*}} {fortran_attrs = #fir.var_attrs<allocatable>}
   ! CHECK: %[[box:.*]] = fir.load %[[coor]]
-  ! CHECK-DAG: %[[base:.*]] = fir.box_addr %[[box]]
-  ! CHECK-DAG: %[[dims:.*]]:3 = fir.box_dims %[[box]], %c0{{.*}}
-  ! CHECK: %[[lb:.*]] = fir.convert %[[dims]]#0 : (index) -> i64
-  ! CHECK: %[[index:.*]] = arith.subi %c7{{.*}}, %[[lb]] : i64
-  ! CHECK: %[[addr:.*]] = fir.coordinate_of %[[base]], %[[index]]
-  ! CHECK: %[[boxchar:.*]] = fir.emboxchar %[[addr]], %c10{{.*}}
+  ! CHECK: %[[elem:.*]] = hlfir.designate %[[box]] (%c7{{.*}})  typeparams %{{.*}} : (!fir.box<!fir.heap<!fir.array<?x!fir.char<1,10>>>>, index, index) -> !fir.ref<!fir.char<1,10>>
+  ! CHECK: %[[boxchar:.*]] = fir.emboxchar %[[elem]], %c10{{.*}}
   ! CHECK: fir.call @_QPtakes_char_scalar(%[[boxchar]])
   call takes_char_scalar(a1_1(5)%p(7))
 
 end subroutine
 
 ! CHECK-LABEL: func @_QMacompPref_scalar_def_char_a
-! CHECK-SAME: (%[[a0_0:.*]]: {{.*}}, %[[a1_0:.*]]: {{.*}}, %[[a0_1:.*]]: {{.*}}, %[[a1_1:.*]]: {{.*}})
+! CHECK-SAME: (%[[a0_0_arg:.*]]: {{.*}}, %[[a1_0_arg:.*]]: {{.*}}, %[[a0_1_arg:.*]]: {{.*}}, %[[a1_1_arg:.*]]: {{.*}})
 subroutine ref_scalar_def_char_a(a0_0, a1_0, a0_1, a1_1)
   type(def_char_a0) :: a0_0, a0_1(100)
   type(def_char_a1) :: a1_0, a1_1(100)
 
-  ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[a0_0]], p
+  ! CHECK: %[[a0_0:.*]]:2 = hlfir.declare %[[a0_0_arg]]{{.*}}{uniq_name = "_QMacompFref_scalar_def_char_aEa0_0"}
+  ! CHECK: %[[a0_1:.*]]:2 = hlfir.declare %[[a0_1_arg]](%{{.*}}){{.*}}{uniq_name = "_QMacompFref_scalar_def_char_aEa0_1"}
+  ! CHECK: %[[a1_0:.*]]:2 = hlfir.declare %[[a1_0_arg]]{{.*}}{uniq_name = "_QMacompFref_scalar_def_char_aEa1_0"}
+  ! CHECK: %[[a1_1:.*]]:2 = hlfir.declare %[[a1_1_arg]](%{{.*}}){{.*}}{uniq_name = "_QMacompFref_scalar_def_char_aEa1_1"}
+
+  ! CHECK: %[[coor:.*]] = hlfir.designate %[[a0_0]]#0{"p"}{{.*}}{fortran_attrs = #fir.var_attrs<allocatable>}
   ! CHECK: %[[box:.*]] = fir.load %[[coor]]
-  ! CHECK-DAG: %[[len:.*]] = fir.box_elesize %[[box]]
-  ! CHECK-DAG: %[[addr:.*]] = fir.box_addr %[[box]]
+  ! CHECK: %[[addr:.*]] = fir.box_addr %[[box]]
+  ! CHECK: %[[box2:.*]] = fir.load %[[coor]]
+  ! CHECK: %[[len:.*]] = fir.box_elesize %[[box2]]
   ! CHECK: %[[boxchar:.*]] = fir.emboxchar %[[addr]], %[[len]]
   ! CHECK: fir.call @_QPtakes_char_scalar(%[[boxchar]])
   call takes_char_scalar(a0_0%p)
 
-  ! CHECK-DAG: %[[coor0:.*]] = fir.coordinate_of %[[a0_1]], %{{.*}}
-  ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[coor0]], p
+  ! CHECK: %[[a0_1_elem:.*]] = hlfir.designate %[[a0_1]]#0 (%{{.*}})
+  ! CHECK: %[[coor:.*]] = hlfir.designate %[[a0_1_elem]]{"p"}{{.*}}{fortran_attrs = #fir.var_attrs<allocatable>}
   ! CHECK: %[[box:.*]] = fir.load %[[coor]]
-  ! CHECK-DAG: %[[len:.*]] = fir.box_elesize %[[box]]
-  ! CHECK-DAG: %[[addr:.*]] = fir.box_addr %[[box]]
+  ! CHECK: %[[addr:.*]] = fir.box_addr %[[box]]
+  ! CHECK: %[[box2:.*]] = fir.load %[[coor]]
+  ! CHECK: %[[len:.*]] = fir.box_elesize %[[box2]]
   ! CHECK: %[[boxchar:.*]] = fir.emboxchar %[[addr]], %[[len]]
   ! CHECK: fir.call @_QPtakes_char_scalar(%[[boxchar]])
   call takes_char_scalar(a0_1(5)%p)
 
 
-  ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[a1_0]], p
+  ! CHECK: %[[coor:.*]] = hlfir.designate %[[a1_0]]#0{"p"}{{.*}}{fortran_attrs = #fir.var_attrs<allocatable>}
   ! CHECK: %[[box:.*]] = fir.load %[[coor]]
-  ! CHECK-DAG: %[[dims:.*]]:3 = fir.box_dims %[[box]], %c0{{.*}}
-  ! CHECK-DAG: %[[len:.*]] = fir.box_elesize %[[box]]
-  ! CHECK-DAG: %[[base:.*]] = fir.box_addr %[[box]]
-  ! CHECK: %[[cast:.*]] = fir.convert %[[base]] : (!fir.heap<!fir.array<?x!fir.char<1,?>>>) -> !fir.ref<!fir.array<?x!fir.char<1,?>>>
-  ! CHECK: %[[c7:.*]] = fir.convert %c7{{.*}} : (i64) -> index
-  ! CHECK: %[[sub:.*]] = arith.subi %[[c7]], %[[dims]]#0 : index
-  ! CHECK: %[[mul:.*]] = arith.muli %[[len]], %[[sub]] : index
-  ! CHECK: %[[offset:.*]] = arith.addi %[[mul]], %c0{{.*}} : index
-  ! CHECK: %[[cnvt:.*]] = fir.convert %[[cast]]
-  ! CHECK: %[[addr:.*]] = fir.coordinate_of %[[cnvt]], %[[offset]]
-  ! CHECK: %[[cnvt:.*]] = fir.convert %[[addr]]
-  ! CHECK: %[[boxchar:.*]] = fir.emboxchar %[[cnvt]], %[[len]]
-  ! CHECK: fir.call @_QPtakes_char_scalar(%[[boxchar]])
+  ! CHECK: %[[len:.*]] = fir.box_elesize %[[box]]
+  ! CHECK: %[[elem:.*]] = hlfir.designate %[[box]] (%c7{{.*}})  typeparams %[[len]] : (!fir.box<!fir.heap<!fir.array<?x!fir.char<1,?>>>>, index, index) -> !fir.boxchar<1>
+  ! CHECK: fir.call @_QPtakes_char_scalar(%[[elem]])
   call takes_char_scalar(a1_0%p(7))
 
 
-  ! CHECK-DAG: %[[coor0:.*]] = fir.coordinate_of %[[a1_1]], %{{.*}}
-  ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[coor0]], p
+  ! CHECK: %[[a1_1_elem:.*]] = hlfir.designate %[[a1_1]]#0 (%{{.*}})
+  ! CHECK: %[[coor:.*]] = hlfir.designate %[[a1_1_elem]]{"p"}{{.*}}{fortran_attrs = #fir.var_attrs<allocatable>}
   ! CHECK: %[[box:.*]] = fir.load %[[coor]]
-  ! CHECK-DAG: %[[dims:.*]]:3 = fir.box_dims %[[box]], %c0{{.*}}
-  ! CHECK-DAG: %[[len:.*]] = fir.box_elesize %[[box]]
-  ! CHECK-DAG: %[[base:.*]] = fir.box_addr %[[box]]
-  ! CHECK: %[[cast:.*]] = fir.convert %[[base]] : (!fir.heap<!fir.array<?x!fir.char<1,?>>>) -> !fir.ref<!fir.array<?x!fir.char<1,?>>>
-  ! CHECK: %[[c7:.*]] = fir.convert %c7{{.*}} : (i64) -> index
-  ! CHECK: %[[sub:.*]] = arith.subi %[[c7]], %[[dims]]#0 : index
-  ! CHECK: %[[mul:.*]] = arith.muli %[[len]], %[[sub]] : index
-  ! CHECK: %[[offset:.*]] = arith.addi %[[mul]], %c0{{.*}} : index
-  ! CHECK: %[[cnvt:.*]] = fir.convert %[[cast]]
-  ! CHECK: %[[addr:.*]] = fir.coordinate_of %[[cnvt]], %[[offset]]
-  ! CHECK: %[[cnvt:.*]] = fir.convert %[[addr]]
-  ! CHECK: %[[boxchar:.*]] = fir.emboxchar %[[cnvt]], %[[len]]
-  ! CHECK: fir.call @_QPtakes_char_scalar(%[[boxchar]])
+  ! CHECK: %[[len:.*]] = fir.box_elesize %[[box]]
+  ! CHECK: %[[elem:.*]] = hlfir.designate %[[box]] (%c7{{.*}})  typeparams %[[len]] : (!fir.box<!fir.heap<!fir.array<?x!fir.char<1,?>>>>, index, index) -> !fir.boxchar<1>
+  ! CHECK: fir.call @_QPtakes_char_scalar(%[[elem]])
   call takes_char_scalar(a1_1(5)%p(7))
 
 end subroutine
 
 ! CHECK-LABEL: func @_QMacompPref_scalar_derived
-! CHECK-SAME: (%[[a0_0:.*]]: {{.*}}, %[[a1_0:.*]]: {{.*}}, %[[a0_1:.*]]: {{.*}}, %[[a1_1:.*]]: {{.*}})
+! CHECK-SAME: (%[[a0_0_arg:.*]]: {{.*}}, %[[a1_0_arg:.*]]: {{.*}}, %[[a0_1_arg:.*]]: {{.*}}, %[[a1_1_arg:.*]]: {{.*}})
 subroutine ref_scalar_derived(a0_0, a1_0, a0_1, a1_1)
   type(derived_a0) :: a0_0, a0_1(100)
   type(derived_a1) :: a1_0, a1_1(100)
 
-  ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[a0_0]], p
+  ! CHECK: %[[a0_0:.*]]:2 = hlfir.declare %[[a0_0_arg]]{{.*}}{uniq_name = "_QMacompFref_scalar_derivedEa0_0"}
+  ! CHECK: %[[a0_1:.*]]:2 = hlfir.declare %[[a0_1_arg]](%{{.*}}){{.*}}{uniq_name = "_QMacompFref_scalar_derivedEa0_1"}
+  ! CHECK: %[[a1_0:.*]]:2 = hlfir.declare %[[a1_0_arg]]{{.*}}{uniq_name = "_QMacompFref_scalar_derivedEa1_0"}
+  ! CHECK: %[[a1_1:.*]]:2 = hlfir.declare %[[a1_1_arg]](%{{.*}}){{.*}}{uniq_name = "_QMacompFref_scalar_derivedEa1_1"}
+
+  ! CHECK: %[[coor:.*]] = hlfir.designate %[[a0_0]]#0{"p"}{{.*}}{fortran_attrs = #fir.var_attrs<allocatable>}
   ! CHECK: %[[box:.*]] = fir.load %[[coor]]
-  ! CHECK: %[[addr:.*]] = fir.coordinate_of %[[box]], x
-  ! CHECK: fir.call @_QPtakes_real_scalar(%[[addr]])
+  ! CHECK: %[[base:.*]] = fir.box_addr %[[box]]
+  ! CHECK: %[[xcoor:.*]] = hlfir.designate %[[base]]{"x"}
+  ! CHECK: fir.call @_QPtakes_real_scalar(%[[xcoor]])
   call takes_real_scalar(a0_0%p%x)
 
-  ! CHECK-DAG: %[[coor0:.*]] = fir.coordinate_of %[[a0_1]], %{{.*}}
-  ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[coor0]], p
+  ! CHECK: %[[a0_1_elem:.*]] = hlfir.designate %[[a0_1]]#0 (%{{.*}})
+  ! CHECK: %[[coor:.*]] = hlfir.designate %[[a0_1_elem]]{"p"}{{.*}}{fortran_attrs = #fir.var_attrs<allocatable>}
   ! CHECK: %[[box:.*]] = fir.load %[[coor]]
-  ! CHECK: %[[addr:.*]] = fir.coordinate_of %[[box]], x
-  ! CHECK: fir.call @_QPtakes_real_scalar(%[[addr]])
+  ! CHECK: %[[base:.*]] = fir.box_addr %[[box]]
+  ! CHECK: %[[xcoor:.*]] = hlfir.designate %[[base]]{"x"}
+  ! CHECK: fir.call @_QPtakes_real_scalar(%[[xcoor]])
   call takes_real_scalar(a0_1(5)%p%x)
 
-  ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[a1_0]], p
+  ! CHECK: %[[coor:.*]] = hlfir.designate %[[a1_0]]#0{"p"}{{.*}}{fortran_attrs = #fir.var_attrs<allocatable>}
   ! CHECK: %[[box:.*]] = fir.load %[[coor]]
-  ! CHECK: %[[dims:.*]]:3 = fir.box_dims %[[box]], %c0{{.*}}
-  ! CHECK: %[[lb:.*]] = fir.convert %[[dims]]#0 : (index) -> i64
-  ! CHECK: %[[index:.*]] = arith.subi %c7{{.*}}, %[[lb]] : i64
-  ! CHECK: %[[elem:.*]] = fir.coordinate_of %[[box]], %[[index]]
-  ! CHECK: %[[addr:.*]] = fir.coordinate_of %[[elem]], x
-  ! CHECK: fir.call @_QPtakes_real_scalar(%[[addr]])
+  ! CHECK: %[[elem:.*]] = hlfir.designate %[[box]] (%c7{{.*}})  : (!fir.box<!fir.heap<!fir.array<?x!fir.type<_QMacompTt{x:f32,i:i32}>>>>, index) -> !fir.ref<!fir.type<_QMacompTt{x:f32,i:i32}>>
+  ! CHECK: %[[xcoor:.*]] = hlfir.designate %[[elem]]{"x"}
+  ! CHECK: fir.call @_QPtakes_real_scalar(%[[xcoor]])
   call takes_real_scalar(a1_0%p(7)%x)
 
-  ! CHECK-DAG: %[[coor0:.*]] = fir.coordinate_of %[[a1_1]], %{{.*}}
-  ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[coor0]], p
+  ! CHECK: %[[a1_1_elem:.*]] = hlfir.designate %[[a1_1]]#0 (%{{.*}})
+  ! CHECK: %[[coor:.*]] = hlfir.designate %[[a1_1_elem]]{"p"}{{.*}}{fortran_attrs = #fir.var_attrs<allocatable>}
   ! CHECK: %[[box:.*]] = fir.load %[[coor]]
-  ! CHECK: %[[dims:.*]]:3 = fir.box_dims %[[box]], %c0{{.*}}
-  ! CHECK: %[[lb:.*]] = fir.convert %[[dims]]#0 : (index) -> i64
-  ! CHECK: %[[index:.*]] = arith.subi %c7{{.*}}, %[[lb]] : i64
-  ! CHECK: %[[elem:.*]] = fir.coordinate_of %[[box]], %[[index]]
-  ! CHECK: %[[addr:.*]] = fir.coordinate_of %[[elem]], x
-  ! CHECK: fir.call @_QPtakes_real_scalar(%[[addr]])
+  ! CHECK: %[[elem:.*]] = hlfir.designate %[[box]] (%c7{{.*}})  : (!fir.box<!fir.heap<!fir.array<?x!fir.type<_QMacompTt{x:f32,i:i32}>>>>, index) -> !fir.ref<!fir.type<_QMacompTt{x:f32,i:i32}>>
+  ! CHECK: %[[xcoor:.*]] = hlfir.designate %[[elem]]{"x"}
+  ! CHECK: fir.call @_QPtakes_real_scalar(%[[xcoor]])
   call takes_real_scalar(a1_1(5)%p(7)%x)
 
 end subroutine
@@ -320,25 +286,30 @@ subroutine ref_scalar_derived(a0_0, a1_0, a0_1, a1_1)
 ! -----------------------------------------------------------------------------
 
 ! CHECK-LABEL: func @_QMacompPpass_real_a
-! CHECK-SAME: (%[[a0_0:.*]]: {{.*}}, %[[a1_0:.*]]: {{.*}}, %[[a0_1:.*]]: {{.*}}, %[[a1_1:.*]]: {{.*}})
+! CHECK-SAME: (%[[a0_0_arg:.*]]: {{.*}}, %[[a1_0_arg:.*]]: {{.*}}, %[[a0_1_arg:.*]]: {{.*}}, %[[a1_1_arg:.*]]: {{.*}})
 subroutine pass_real_a(a0_0, a1_0, a0_1, a1_1)
   type(real_a0) :: a0_0, a0_1(100)
   type(real_a1) :: a1_0, a1_1(100)
-  ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[a0_0]], p
+  ! CHECK: %[[a0_0:.*]]:2 = hlfir.declare %[[a0_0_arg]]{{.*}}{uniq_name = "_QMacompFpass_real_aEa0_0"}
+  ! CHECK: %[[a0_1:.*]]:2 = hlfir.declare %[[a0_1_arg]](%{{.*}}){{.*}}{uniq_name = "_QMacompFpass_real_aEa0_1"}
+  ! CHECK: %[[a1_0:.*]]:2 = hlfir.declare %[[a1_0_arg]]{{.*}}{uniq_name = "_QMacompFpass_real_aEa1_0"}
+  ! CHECK: %[[a1_1:.*]]:2 = hlfir.declare %[[a1_1_arg]](%{{.*}}){{.*}}{uniq_name = "_QMacompFpass_real_aEa1_1"}
+
+  ! CHECK: %[[coor:.*]] = hlfir.designate %[[a0_0]]#0{"p"}{{.*}}{fortran_attrs = #fir.var_attrs<allocatable>}
   ! CHECK: fir.call @_QPtakes_real_scalar_pointer(%[[coor]])
   call takes_real_scalar_pointer(a0_0%p)
 
-  ! CHECK-DAG: %[[coor0:.*]] = fir.coordinate_of %[[a0_1]], %{{.*}}
-  ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[coor0]], p
+  ! CHECK: %[[a0_1_elem:.*]] = hlfir.designate %[[a0_1]]#0 (%{{.*}})
+  ! CHECK: %[[coor:.*]] = hlfir.designate %[[a0_1_elem]]{"p"}{{.*}}{fortran_attrs = #fir.var_attrs<allocatable>}
   ! CHECK: fir.call @_QPtakes_real_scalar_pointer(%[[coor]])
   call takes_real_scalar_pointer(a0_1(5)%p)
 
-  ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[a1_0]], p
+  ! CHECK: %[[coor:.*]] = hlfir.designate %[[a1_0]]#0{"p"}{{.*}}{fortran_attrs = #fir.var_attrs<allocatable>}
   ! CHECK: fir.call @_QPtakes_real_array_pointer(%[[coor]])
   call takes_real_array_pointer(a1_0%p)
 
-  ! CHECK-DAG: %[[coor0:.*]] = fir.coordinate_of %[[a1_1]], %{{.*}}
-  ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[coor0]], p
+  ! CHECK: %[[a1_1_elem:.*]] = hlfir.designate %[[a1_1]]#0 (%{{.*}})
+  ! CHECK: %[[coor:.*]] = hlfir.designate %[[a1_1_elem]]{"p"}{{.*}}{fortran_attrs = #fir.var_attrs<allocatable>}
   ! CHECK: fir.call @_QPtakes_real_array_pointer(%[[coor]])
   call takes_real_array_pointer(a1_1(5)%p)
 end subroutine
@@ -348,28 +319,33 @@ subroutine pass_real_a(a0_0, a1_0, a0_1, a1_1)
 ! -----------------------------------------------------------------------------
 
 ! CHECK-LABEL: func @_QMacompPallocated_p
-! CHECK-SAME: (%[[a0_0:.*]]: {{.*}}, %[[a1_0:.*]]: {{.*}}, %[[a0_1:.*]]: {{.*}}, %[[a1_1:.*]]: {{.*}})
+! CHECK-SAME: (%[[a0_0_arg:.*]]: {{.*}}, %[[a1_0_arg:.*]]: {{.*}}, %[[a0_1_arg:.*]]: {{.*}}, %[[a1_1_arg:.*]]: {{.*}})
 subroutine allocated_p(a0_0, a1_0, a0_1, a1_1)
   type(real_a0) :: a0_0, a0_1(100)
   type(def_char_a1) :: a1_0, a1_1(100)
-  ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[a0_0]], p
+  ! CHECK: %[[a0_0:.*]]:2 = hlfir.declare %[[a0_0_arg]]{{.*}}{uniq_name = "_QMacompFallocated_pEa0_0"}
+  ! CHECK: %[[a0_1:.*]]:2 = hlfir.declare %[[a0_1_arg]](%{{.*}}){{.*}}{uniq_name = "_QMacompFallocated_pEa0_1"}
+  ! CHECK: %[[a1_0:.*]]:2 = hlfir.declare %[[a1_0_arg]]{{.*}}{uniq_name = "_QMacompFallocated_pEa1_0"}
+  ! CHECK: %[[a1_1:.*]]:2 = hlfir.declare %[[a1_1_arg]](%{{.*}}){{.*}}{uniq_name = "_QMacompFallocated_pEa1_1"}
+
+  ! CHECK: %[[coor:.*]] = hlfir.designate %[[a0_0]]#0{"p"}{{.*}}{fortran_attrs = #fir.var_attrs<allocatable>}
   ! CHECK: %[[box:.*]] = fir.load %[[coor]]
   ! CHECK: fir.box_addr %[[box]]
   call takes_logical(allocated(a0_0%p))
 
-  ! CHECK-DAG: %[[coor0:.*]] = fir.coordinate_of %[[a0_1]], %{{.*}}
-  ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[coor0]], p
+  ! CHECK: %[[a0_1_elem:.*]] = hlfir.designate %[[a0_1]]#0 (%{{.*}})
+  ! CHECK: %[[coor:.*]] = hlfir.designate %[[a0_1_elem]]{"p"}{{.*}}{fortran_attrs = #fir.var_attrs<allocatable>}
   ! CHECK: %[[box:.*]] = fir.load %[[coor]]
   ! CHECK: fir.box_addr %[[box]]
   call takes_logical(allocated(a0_1(5)%p))
 
-  ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[a1_0]], p
+  ! CHECK: %[[coor:.*]] = hlfir.designate %[[a1_0]]#0{"p"}{{.*}}{fortran_attrs = #fir.var_attrs<allocatable>}
   ! CHECK: %[[box:.*]] = fir.load %[[coor]]
   ! CHECK: fir.box_addr %[[box]]
   call takes_logical(allocated(a1_0%p))
 
-  ! CHECK-DAG: %[[coor0:.*]] = fir.coordinate_of %[[a1_1]], %{{.*}}
-  ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[coor0]], p
+  ! CHECK: %[[a1_1_elem:.*]] = hlfir.designate %[[a1_1]]#0 (%{{.*}})
+  ! CHECK: %[[coor:.*]] = hlfir.designate %[[a1_1_elem]]{"p"}{{.*}}{fortran_attrs = #fir.var_attrs<allocatable>}
   ! CHECK: %[[box:.*]] = fir.load %[[coor]]
   ! CHECK: fir.box_addr %[[box]]
   call takes_logical(allocated(a1_1(5)%p))
@@ -380,73 +356,88 @@ subroutine allocated_p(a0_0, a1_0, a0_1, a1_1)
 ! -----------------------------------------------------------------------------
 
 ! CHECK-LABEL: func @_QMacompPallocate_real
-! CHECK-SAME: (%[[a0_0:.*]]: {{.*}}, %[[a1_0:.*]]: {{.*}}, %[[a0_1:.*]]: {{.*}}, %[[a1_1:.*]]: {{.*}})
+! CHECK-SAME: (%[[a0_0_arg:.*]]: {{.*}}, %[[a1_0_arg:.*]]: {{.*}}, %[[a0_1_arg:.*]]: {{.*}}, %[[a1_1_arg:.*]]: {{.*}})
 subroutine allocate_real(a0_0, a1_0, a0_1, a1_1)
   type(real_a0) :: a0_0, a0_1(100)
   type(real_a1) :: a1_0, a1_1(100)
-  ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[a0_0]], p
+  ! CHECK: %[[a0_0:.*]]:2 = hlfir.declare %[[a0_0_arg]]{{.*}}{uniq_name = "_QMacompFallocate_realEa0_0"}
+  ! CHECK: %[[a0_1:.*]]:2 = hlfir.declare %[[a0_1_arg]](%{{.*}}){{.*}}{uniq_name = "_QMacompFallocate_realEa0_1"}
+  ! CHECK: %[[a1_0:.*]]:2 = hlfir.declare %[[a1_0_arg]]{{.*}}{uniq_name = "_QMacompFallocate_realEa1_0"}
+  ! CHECK: %[[a1_1:.*]]:2 = hlfir.declare %[[a1_1_arg]](%{{.*}}){{.*}}{uniq_name = "_QMacompFallocate_realEa1_1"}
+
+  ! CHECK: %[[coor:.*]] = hlfir.designate %[[a0_0]]#0{"p"}{{.*}}{fortran_attrs = #fir.var_attrs<allocatable>}
   ! CHECK: fir.store {{.*}} to %[[coor]]
   allocate(a0_0%p)
 
-  ! CHECK-DAG: %[[coor0:.*]] = fir.coordinate_of %[[a0_1]], %{{.*}}
-  ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[coor0]], p
+  ! CHECK: %[[a0_1_elem:.*]] = hlfir.designate %[[a0_1]]#0 (%{{.*}})
+  ! CHECK: %[[coor:.*]] = hlfir.designate %[[a0_1_elem]]{"p"}{{.*}}{fortran_attrs = #fir.var_attrs<allocatable>}
   ! CHECK: fir.store {{.*}} to %[[coor]]
   allocate(a0_1(5)%p)
 
-  ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[a1_0]], p
+  ! CHECK: %[[coor:.*]] = hlfir.designate %[[a1_0]]#0{"p"}{{.*}}{fortran_attrs = #fir.var_attrs<allocatable>}
   ! CHECK: fir.store {{.*}} to %[[coor]]
   allocate(a1_0%p(100))
 
-  ! CHECK-DAG: %[[coor0:.*]] = fir.coordinate_of %[[a1_1]], %{{.*}}
-  ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[coor0]], p
+  ! CHECK: %[[a1_1_elem:.*]] = hlfir.designate %[[a1_1]]#0 (%{{.*}})
+  ! CHECK: %[[coor:.*]] = hlfir.designate %[[a1_1_elem]]{"p"}{{.*}}{fortran_attrs = #fir.var_attrs<allocatable>}
   ! CHECK: fir.store {{.*}} to %[[coor]]
   allocate(a1_1(5)%p(100))
 end subroutine
 
 ! CHECK-LABEL: func @_QMacompPallocate_cst_char
-! CHECK-SAME: (%[[a0_0:.*]]: {{.*}}, %[[a1_0:.*]]: {{.*}}, %[[a0_1:.*]]: {{.*}}, %[[a1_1:.*]]: {{.*}})
+! CHECK-SAME: (%[[a0_0_arg:.*]]: {{.*}}, %[[a1_0_arg:.*]]: {{.*}}, %[[a0_1_arg:.*]]: {{.*}}, %[[a1_1_arg:.*]]: {{.*}})
 subroutine allocate_cst_char(a0_0, a1_0, a0_1, a1_1)
   type(cst_char_a0) :: a0_0, a0_1(100)
   type(cst_char_a1) :: a1_0, a1_1(100)
-  ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[a0_0]], p
+  ! CHECK: %[[a0_0:.*]]:2 = hlfir.declare %[[a0_0_arg]]{{.*}}{uniq_name = "_QMacompFallocate_cst_charEa0_0"}
+  ! CHECK: %[[a0_1:.*]]:2 = hlfir.declare %[[a0_1_arg]](%{{.*}}){{.*}}{uniq_name = "_QMacompFallocate_cst_charEa0_1"}
+  ! CHECK: %[[a1_0:.*]]:2 = hlfir.declare %[[a1_0_arg]]{{.*}}{uniq_name = "_QMacompFallocate_cst_charEa1_0"}
+  ! CHECK: %[[a1_1:.*]]:2 = hlfir.declare %[[a1_1_arg]](%{{.*}}){{.*}}{uniq_name = "_QMacompFallocate_cst_charEa1_1"}
+
+  ! CHECK: %[[coor:.*]] = hlfir.designate %[[a0_0]]#0{"p"}{{.*}} typeparams %{{.*}} {fortran_attrs = #fir.var_attrs<allocatable>}
   ! CHECK: fir.store {{.*}} to %[[coor]]
   allocate(a0_0%p)
 
-  ! CHECK-DAG: %[[coor0:.*]] = fir.coordinate_of %[[a0_1]], %{{.*}}
-  ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[coor0]], p
+  ! CHECK: %[[a0_1_elem:.*]] = hlfir.designate %[[a0_1]]#0 (%{{.*}})
+  ! CHECK: %[[coor:.*]] = hlfir.designate %[[a0_1_elem]]{"p"}{{.*}} typeparams %{{.*}} {fortran_attrs = #fir.var_attrs<allocatable>}
   ! CHECK: fir.store {{.*}} to %[[coor]]
   allocate(a0_1(5)%p)
 
-  ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[a1_0]], p
+  ! CHECK: %[[coor:.*]] = hlfir.designate %[[a1_0]]#0{"p"}{{.*}} typeparams %{{.*}} {fortran_attrs = #fir.var_attrs<allocatable>}
   ! CHECK: fir.store {{.*}} to %[[coor]]
   allocate(a1_0%p(100))
 
-  ! CHECK-DAG: %[[coor0:.*]] = fir.coordinate_of %[[a1_1]], %{{.*}}
-  ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[coor0]], p
+  ! CHECK: %[[a1_1_elem:.*]] = hlfir.designate %[[a1_1]]#0 (%{{.*}})
+  ! CHECK: %[[coor:.*]] = hlfir.designate %[[a1_1_elem]]{"p"}{{.*}} typeparams %{{.*}} {fortran_attrs = #fir.var_attrs<allocatable>}
   ! CHECK: fir.store {{.*}} to %[[coor]]
   allocate(a1_1(5)%p(100))
 end subroutine
 
 ! CHECK-LABEL: func @_QMacompPallocate_def_char
-! CHECK-SAME: (%[[a0_0:.*]]: {{.*}}, %[[a1_0:.*]]: {{.*}}, %[[a0_1:.*]]: {{.*}}, %[[a1_1:.*]]: {{.*}})
+! CHECK-SAME: (%[[a0_0_arg:.*]]: {{.*}}, %[[a1_0_arg:.*]]: {{.*}}, %[[a0_1_arg:.*]]: {{.*}}, %[[a1_1_arg:.*]]: {{.*}})
 subroutine allocate_def_char(a0_0, a1_0, a0_1, a1_1)
   type(def_char_a0) :: a0_0, a0_1(100)
   type(def_char_a1) :: a1_0, a1_1(100)
-  ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[a0_0]], p
+  ! CHECK: %[[a0_0:.*]]:2 = hlfir.declare %[[a0_0_arg]]{{.*}}{uniq_name = "_QMacompFallocate_def_charEa0_0"}
+  ! CHECK: %[[a0_1:.*]]:2 = hlfir.declare %[[a0_1_arg]](%{{.*}}){{.*}}{uniq_name = "_QMacompFallocate_def_charEa0_1"}
+  ! CHECK: %[[a1_0:.*]]:2 = hlfir.declare %[[a1_0_arg]]{{.*}}{uniq_name = "_QMacompFallocate_def_charEa1_0"}
+  ! CHECK: %[[a1_1:.*]]:2 = hlfir.declare %[[a1_1_arg]](%{{.*}}){{.*}}{uniq_name = "_QMacompFallocate_def_charEa1_1"}
+
+  ! CHECK: %[[coor:.*]] = hlfir.designate %[[a0_0]]#0{"p"}{{.*}}{fortran_attrs = #fir.var_attrs<allocatable>}
   ! CHECK: fir.store {{.*}} to %[[coor]]
   allocate(character(18)::a0_0%p)
 
-  ! CHECK-DAG: %[[coor0:.*]] = fir.coordinate_of %[[a0_1]], %{{.*}}
-  ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[coor0]], p
+  ! CHECK: %[[a0_1_elem:.*]] = hlfir.designate %[[a0_1]]#0 (%{{.*}})
+  ! CHECK: %[[coor:.*]] = hlfir.designate %[[a0_1_elem]]{"p"}{{.*}}{fortran_attrs = #fir.var_attrs<allocatable>}
   ! CHECK: fir.store {{.*}} to %[[coor]]
   allocate(character(18)::a0_1(5)%p)
 
-  ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[a1_0]], p
+  ! CHECK: %[[coor:.*]] = hlfir.designate %[[a1_0]]#0{"p"}{{.*}}{fortran_attrs = #fir.var_attrs<allocatable>}
   ! CHECK: fir.store {{.*}} to %[[coor]]
   allocate(character(18)::a1_0%p(100))
 
-  ! CHECK-DAG: %[[coor0:.*]] = fir.coordinate_of %[[a1_1]], %{{.*}}
-  ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[coor0]], p
+  ! CHECK: %[[a1_1_elem:.*]] = hlfir.designate %[[a1_1]]#0 (%{{.*}})
+  ! CHECK: %[[coor:.*]] = hlfir.designate %[[a1_1_elem]]{"p"}{{.*}}{fortran_attrs = #fir.var_attrs<allocatable>}
   ! CHECK: fir.store {{.*}} to %[[coor]]
   allocate(character(18)::a1_1(5)%p(100))
 end subroutine
@@ -456,25 +447,30 @@ subroutine allocate_def_char(a0_0, a1_0, a0_1, a1_1)
 ! -----------------------------------------------------------------------------
 
 ! CHECK-LABEL: func @_QMacompPdeallocate_real
-! CHECK-SAME: (%[[a0_0:.*]]: {{.*}}, %[[a1_0:.*]]: {{.*}}, %[[a0_1:.*]]: {{.*}}, %[[a1_1:.*]]: {{.*}})
+! CHECK-SAME: (%[[a0_0_arg:.*]]: {{.*}}, %[[a1_0_arg:.*]]: {{.*}}, %[[a0_1_arg:.*]]: {{.*}}, %[[a1_1_arg:.*]]: {{.*}})
 subroutine deallocate_real(a0_0, a1_0, a0_1, a1_1)
   type(real_a0) :: a0_0, a0_1(100)
   type(real_a1) :: a1_0, a1_1(100)
-  ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[a0_0]], p
+  ! CHECK: %[[a0_0:.*]]:2 = hlfir.declare %[[a0_0_arg]]{{.*}}{uniq_name = "_QMacompFdeallocate_realEa0_0"}
+  ! CHECK: %[[a0_1:.*]]:2 = hlfir.declare %[[a0_1_arg]](%{{.*}}){{.*}}{uniq_name = "_QMacompFdeallocate_realEa0_1"}
+  ! CHECK: %[[a1_0:.*]]:2 = hlfir.declare %[[a1_0_arg]]{{.*}}{uniq_name = "_QMacompFdeallocate_realEa1_0"}
+  ! CHECK: %[[a1_1:.*]]:2 = hlfir.declare %[[a1_1_arg]](%{{.*}}){{.*}}{uniq_name = "_QMacompFdeallocate_realEa1_1"}
+
+  ! CHECK: %[[coor:.*]] = hlfir.designate %[[a0_0]]#0{"p"}{{.*}}{fortran_attrs = #fir.var_attrs<allocatable>}
   ! CHECK: fir.store {{.*}} to %[[coor]]
   deallocate(a0_0%p)
 
-  ! CHECK-DAG: %[[coor0:.*]] = fir.coordinate_of %[[a0_1]], %{{.*}}
-  ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[coor0]], p
+  ! CHECK: %[[a0_1_elem:.*]] = hlfir.designate %[[a0_1]]#0 (%{{.*}})
+  ! CHECK: %[[coor:.*]] = hlfir.designate %[[a0_1_elem]]{"p"}{{.*}}{fortran_attrs = #fir.var_attrs<allocatable>}
   ! CHECK: fir.store {{.*}} to %[[coor]]
   deallocate(a0_1(5)%p)
 
-  ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[a1_0]], p
+  ! CHECK: %[[coor:.*]] = hlfir.designate %[[a1_0]]#0{"p"}{{.*}}{fortran_attrs = #fir.var_attrs<allocatable>}
   ! CHECK: fir.store {{.*}} to %[[coor]]
   deallocate(a1_0%p)
 
-  ! CHECK-DAG: %[[coor0:.*]] = fir.coordinate_of %[[a1_1]], %{{.*}}
-  ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[coor0]], p
+  ! CHECK: %[[a1_1_elem:.*]] = hlfir.designate %[[a1_1]]#0 (%{{.*}})
+  ! CHECK: %[[coor:.*]] = hlfir.designate %[[a1_1_elem]]{"p"}{{.*}}{fortran_attrs = #fir.var_attrs<allocatable>}
   ! CHECK: fir.store {{.*}} to %[[coor]]
   deallocate(a1_1(5)%p)
 end subroutine
@@ -484,7 +480,7 @@ subroutine deallocate_real(a0_0, a1_0, a0_1, a1_1)
 ! -----------------------------------------------------------------------------
 
 ! CHECK: func @_QMacompPtest_recursive
-! CHECK-SAME: (%[[x:.*]]: {{.*}})
+! CHECK-SAME: (%[[xarg:.*]]: {{.*}})
 subroutine test_recursive(x)
   type t
     integer :: i
@@ -492,14 +488,18 @@ subroutine test_recursive(x)
   end type
   type(t) :: x
 
-  ! CHECK: %[[next1:.*]] = fir.coordinate_of %[[x]], next
+  ! CHECK: %[[x:.*]]:2 = hlfir.declare %[[xarg]]{{.*}}{uniq_name = "_QMacompFtest_recursiveEx"}
+  ! CHECK: %[[next1:.*]] = hlfir.designate %[[x]]#0{"next"}{{.*}}{fortran_attrs = #fir.var_attrs<allocatable>}
   ! CHECK: %[[nextBox1:.*]] = fir.load %[[next1]]
-  ! CHECK: %[[next2:.*]] = fir.coordinate_of %[[nextBox1]], next
+  ! CHECK: %[[next1addr:.*]] = fir.box_addr %[[nextBox1]]
+  ! CHECK: %[[next2:.*]] = hlfir.designate %[[next1addr]]{"next"}{{.*}}{fortran_attrs = #fir.var_attrs<allocatable>}
   ! CHECK: %[[nextBox2:.*]] = fir.load %[[next2]]
-  ! CHECK: %[[next3:.*]] = fir.coordinate_of %[[nextBox2]], next
+  ! CHECK: %[[next2addr:.*]] = fir.box_addr %[[nextBox2]]
+  ! CHECK: %[[next3:.*]] = hlfir.designate %[[next2addr]]{"next"}{{.*}}{fortran_attrs = #fir.var_attrs<allocatable>}
   ! CHECK: %[[nextBox3:.*]] = fir.load %[[next3]]
-  ! CHECK: %[[i:.*]] = fir.coordinate_of %[[nextBox3]], i
-  ! CHECK: %[[nextBox3:.*]] = fir.load %[[i]] : !fir.ref<i32>
+  ! CHECK: %[[next3addr:.*]] = fir.box_addr %[[nextBox3]]
+  ! CHECK: %[[i:.*]] = hlfir.designate %[[next3addr]]{"i"}
+  ! CHECK: %[[ival:.*]] = fir.load %[[i]] : !fir.ref<i32>
   print *, x%next%next%next%i
 end subroutine
 
diff --git a/flang/test/Lower/polymorphic.f90 b/flang/test/Lower/polymorphic.f90
index 77ff5d5dcf55b..cd9a9a213e354 100644
--- a/flang/test/Lower/polymorphic.f90
+++ b/flang/test/Lower/polymorphic.f90
@@ -1,4 +1,4 @@
-! RUN: bbc --use-desc-for-alloc=false -emit-fir -hlfir=false %s -o - | FileCheck %s
+! RUN: %flang_fc1 -emit-hlfir %s -o - | FileCheck %s
 
 ! Tests various aspect of the lowering of polymorphic entities.
 
@@ -65,44 +65,76 @@ elemental subroutine assign_p1_int(lhs, rhs)
     lhs%a = rhs
     lhs%b = rhs
   End Subroutine
+! CHECK-LABEL: func.func @_QMpolymorphic_testPassign_p1_int(
+! CHECK-SAME:    %[[ARG0:.*]]: !fir.class<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>> {fir.bindc_name = "lhs"}, %[[ARG1:.*]]: !fir.ref<i32> {fir.bindc_name = "rhs"}
+! CHECK-SAME:    attributes {fir.proc_attrs = #fir.proc_attrs<elemental, pure>}
+! CHECK:         %[[LHS:.*]]:2 = hlfir.declare %[[ARG0]]{{.*}}{fortran_attrs = #fir.var_attrs<intent_inout>, uniq_name = "_QMpolymorphic_testFassign_p1_intElhs"}
+! CHECK:         %[[RHS:.*]]:2 = hlfir.declare %[[ARG1]]{{.*}}{fortran_attrs = #fir.var_attrs<intent_in>, uniq_name = "_QMpolymorphic_testFassign_p1_intErhs"}
+! CHECK:         %[[A:.*]] = hlfir.designate %[[LHS]]#0{"a"}
+! CHECK:         hlfir.assign %{{.*}} to %[[A]]
+! CHECK:         %[[B:.*]] = hlfir.designate %[[LHS]]#0{"b"}
+! CHECK:         hlfir.assign %{{.*}} to %[[B]]
 
   elemental integer function elemental_fct(this)
     class(p1), intent(in) :: this
     elemental_fct = this%a
   end function
+! CHECK-LABEL: func.func @_QMpolymorphic_testPelemental_fct(
+! CHECK-SAME:    %[[ARG0:.*]]: !fir.class<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>> {fir.bindc_name = "this"})
+! CHECK-SAME:    -> i32 attributes {fir.proc_attrs = #fir.proc_attrs<elemental, pure>}
+! CHECK:         %[[THIS:.*]]:2 = hlfir.declare %[[ARG0]]{{.*}}{fortran_attrs = #fir.var_attrs<intent_in>, uniq_name = "_QMpolymorphic_testFelemental_fctEthis"}
+! CHECK:         %[[A:.*]] = hlfir.designate %[[THIS]]#0{"a"}
 
   elemental subroutine elemental_sub(this)
     class(p1), intent(inout) :: this
     this%a = this%a * this%b
   end subroutine
+! CHECK-LABEL: func.func @_QMpolymorphic_testPelemental_sub(
+! CHECK-SAME:    %[[ARG0:.*]]: !fir.class<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>> {fir.bindc_name = "this"})
+! CHECK-SAME:    attributes {fir.proc_attrs = #fir.proc_attrs<elemental, pure>}
+! CHECK:         %[[THIS:.*]]:2 = hlfir.declare %[[ARG0]]
+! CHECK:         hlfir.designate %[[THIS]]#0{"a"}
+! CHECK:         hlfir.designate %[[THIS]]#0{"b"}
 
   elemental subroutine elemental_sub_pass(c, this)
     integer, intent(in) :: c
     class(p1), intent(inout) :: this
     this%a = this%a * this%b + c
   end subroutine
+! CHECK-LABEL: func.func @_QMpolymorphic_testPelemental_sub_pass(
+! CHECK-SAME:    %[[ARG0:.*]]: !fir.ref<i32> {fir.bindc_name = "c"}, %[[ARG1:.*]]: !fir.class<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>> {fir.bindc_name = "this"})
+! CHECK-SAME:    attributes {fir.proc_attrs = #fir.proc_attrs<elemental, pure>}
 
   logical elemental function lt(i, poly)
     integer, intent(in) :: i
     class(p1), intent(in) :: poly
     lt = i < poly%a
   End Function
+! CHECK-LABEL: func.func @_QMpolymorphic_testPlt(
+! CHECK-SAME:    %[[ARG0:.*]]: !fir.ref<i32> {fir.bindc_name = "i"}, %[[ARG1:.*]]: !fir.class<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>> {fir.bindc_name = "poly"})
+! CHECK-SAME:    -> !fir.logical<4> attributes {fir.proc_attrs = #fir.proc_attrs<elemental, pure>}
+! CHECK:         %[[I:.*]]:2 = hlfir.declare %[[ARG0]]{{.*}}{fortran_attrs = #fir.var_attrs<intent_in>, uniq_name = "_QMpolymorphic_testFltEi"}
+! CHECK:         %[[POLY:.*]]:2 = hlfir.declare %[[ARG1]]{{.*}}{fortran_attrs = #fir.var_attrs<intent_in>, uniq_name = "_QMpolymorphic_testFltEpoly"}
+! CHECK:         %[[A:.*]] = hlfir.designate %[[POLY]]#0{"a"}
 
   ! Test correct access to polymorphic entity component.
   subroutine component_access(p)
     class(p1) :: p
     print*, p%a
   end subroutine
-
 ! CHECK-LABEL: func.func @_QMpolymorphic_testPcomponent_access(
-! CHECK-SAME: %[[P:.*]]: !fir.class<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>> {fir.bindc_name = "p"}) {
-! CHECK: %[[COORD:.*]] = fir.coordinate_of %[[P]], a : (!fir.class<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>) -> !fir.ref<i32>
-! CHECK: %[[LOAD:.*]] = fir.load %[[COORD]] : !fir.ref<i32>
-! CHECK: %{{.*}} = fir.call @_FortranAioOutputInteger32(%{{.*}}, %[[LOAD]]) {{.*}}: (!fir.ref<i8>, i32) -> i1
+! CHECK-SAME:    %[[ARG0:.*]]: !fir.class<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>> {fir.bindc_name = "p"})
+! CHECK:         %[[P:.*]]:2 = hlfir.declare %[[ARG0]]{{.*}}{uniq_name = "_QMpolymorphic_testFcomponent_accessEp"}
+! CHECK:         %[[A:.*]] = hlfir.designate %[[P]]#0{"a"}   : (!fir.class<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>) -> !fir.ref<i32>
+! CHECK:         %[[A_LD:.*]] = fir.load %[[A]] : !fir.ref<i32>
+! CHECK:         fir.call @_FortranAioOutputInteger32(%{{.*}}, %[[A_LD]]){{.*}}: (!fir.ref<i8>, i32) -> i1
+
 
   subroutine print(this)
     class(p1) :: this
   end subroutine
+! CHECK-LABEL: func.func @_QMpolymorphic_testPprint(
+! CHECK-SAME:    %[[ARG0:.*]]: !fir.class<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>> {fir.bindc_name = "this"}
 
   ! Test embox of fir.type to fir.class to be passed-object.
   subroutine check()
@@ -111,63 +143,65 @@ subroutine check()
     call t1%print()
     call t2%print()
   end subroutine
-
 ! CHECK-LABEL: func.func @_QMpolymorphic_testPcheck()
-! CHECK: %[[DT1:.*]] = fir.alloca !fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}> {bindc_name = "t1", uniq_name = "_QMpolymorphic_testFcheckEt1"}
-! CHECK: %[[DT2:.*]] = fir.alloca !fir.type<_QMpolymorphic_testTp2{{(,sequence)?}}{a:i32,b:i32,c:f32}> {bindc_name = "t2", uniq_name = "_QMpolymorphic_testFcheckEt2"}
-! CHECK: %[[CLASS1:.*]] = fir.embox %[[DT1]] : (!fir.ref<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>) -> !fir.class<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>
-! CHECK: fir.call @_QMpolymorphic_testPprint(%[[CLASS1]]) {{.*}}: (!fir.class<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>) -> ()
-! CHECK: %[[BOX2:.*]] = fir.embox %[[DT2]] : (!fir.ref<!fir.type<_QMpolymorphic_testTp2{{(,sequence)?}}{a:i32,b:i32,c:f32}>>) -> !fir.class<!fir.type<_QMpolymorphic_testTp2{{(,sequence)?}}{a:i32,b:i32,c:f32}>>
-! CHECK: %[[CLASS2:.*]] = fir.convert %[[BOX2]] : (!fir.class<!fir.type<_QMpolymorphic_testTp2{{(,sequence)?}}{a:i32,b:i32,c:f32}>>) -> !fir.class<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>
-! CHECK: fir.call @_QMpolymorphic_testPprint(%[[CLASS2]]) {{.*}}: (!fir.class<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>) -> ()
+! CHECK:         %[[T1:.*]]:2 = hlfir.declare %{{.*}} {uniq_name = "_QMpolymorphic_testFcheckEt1"}
+! CHECK:         %[[T2:.*]]:2 = hlfir.declare %{{.*}} {uniq_name = "_QMpolymorphic_testFcheckEt2"}
+! CHECK:         %[[T1_BOX:.*]] = fir.embox %[[T1]]#0 : (!fir.ref<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>) -> !fir.box<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>
+! CHECK:         %[[T1_CLASS:.*]] = fir.convert %[[T1_BOX]] : (!fir.box<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>) -> !fir.class<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>
+! CHECK:         fir.call @_QMpolymorphic_testPprint(%[[T1_CLASS]])
+! CHECK:         %[[T2_BOX:.*]] = fir.embox %[[T2]]#0
+! CHECK:         %[[T2_CLASS:.*]] = fir.convert %[[T2_BOX]]{{.*}} -> !fir.class<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>
+! CHECK:         fir.call @_QMpolymorphic_testPprint(%[[T2_CLASS]])
+
 
   subroutine test_allocate_unlimited_polymorphic_non_derived()
     class(*), pointer :: u
     allocate(integer::u)
   end subroutine
+! CHECK-LABEL: func.func @_QMpolymorphic_testPtest_allocate_unlimited_polymorphic_non_derived()
+! CHECK:         %[[U:.*]]:2 = hlfir.declare %{{.*}} {fortran_attrs = #fir.var_attrs<pointer>, uniq_name = "_QMpolymorphic_testFtest_allocate_unlimited_polymorphic_non_derivedEu"}
+! CHECK:         fir.call @_FortranAPointerNullifyIntrinsic(
+! CHECK:         %{{.*}} = fir.call @_FortranAPointerAllocate(
 
-! CHECK-LABEL: test_allocate_unlimited_polymorphic_non_derived
-! CHECK-NOT: _FortranAPointerNullifyDerived
-! CHECK: fir.call @_FortranAPointerAllocate
 
   function test_fct_ret_class()
     class(p1), pointer :: test_fct_ret_class
   end function
+! CHECK-LABEL: func.func @_QMpolymorphic_testPtest_fct_ret_class() -> !fir.class<!fir.ptr<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>>
 
   subroutine call_fct()
     class(p1), pointer :: p
     p => test_fct_ret_class()
   end subroutine
+! CHECK-LABEL: func.func @_QMpolymorphic_testPcall_fct()
+! CHECK:         %[[P:.*]]:2 = hlfir.declare %{{.*}} {fortran_attrs = #fir.var_attrs<pointer>, uniq_name = "_QMpolymorphic_testFcall_fctEp"}
+! CHECK:         %[[CALL:.*]] = fir.call @_QMpolymorphic_testPtest_fct_ret_class() {{.*}}: () -> !fir.class<!fir.ptr<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>>
+! CHECK:         fir.store %{{.*}} to %[[P]]#0 : !fir.ref<!fir.class<!fir.ptr<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>>>
 
-! CHECK-LABEL: func.func @_QMpolymorphic_testPtest_fct_ret_class() -> !fir.class<!fir.ptr<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>>
-! CHECK: return %{{.*}} : !fir.class<!fir.ptr<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>>
 
-! CHECK-LABEL: func.func @_QMpolymorphic_testPcall_fct()
-! CHECK: %[[RESULT:.*]] = fir.alloca !fir.class<!fir.ptr<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>> {bindc_name = ".result"}
-! CHECK: %[[CALL_RES:.*]] = fir.call @_QMpolymorphic_testPtest_fct_ret_class() {{.*}}: () -> !fir.class<!fir.ptr<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>>
-! CHECK: fir.save_result %[[CALL_RES]] to %[[RESULT]] : !fir.class<!fir.ptr<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>>, !fir.ref<!fir.class<!fir.ptr<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>>>
 
   subroutine implicit_loop_with_polymorphic()
     class(p1), allocatable :: p(:)
     allocate(p(3))
     p%a = [ 1, 2, 3 ]
   end subroutine
-
 ! CHECK-LABEL: func.func @_QMpolymorphic_testPimplicit_loop_with_polymorphic() {
-! CHECK: %{{.*}} = fir.array_load %{{.*}}(%{{.*}}) [%{{.*}}] : (!fir.class<!fir.heap<!fir.array<?x!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>>>, !fir.shift<1>, !fir.slice<1>) -> !fir.array<?xi32>
-! CHECK: %{{.*}} = fir.do_loop %{{.*}} = %{{.*}} to %{{.*}} step %{{.*}} unordered iter_args(%{{.*}} = %{{.*}}) -> (!fir.array<?xi32>) {
-! CHECK: %{{.*}} = fir.array_fetch %{{.*}}, %{{.*}} : (!fir.array<3xi32>, index) -> i32
-! CHECK: %{{.*}} = fir.array_update %{{.*}}, %{{.*}}, %{{.*}} : (!fir.array<?xi32>, i32, index) -> !fir.array<?xi32>
-! CHECK: }
-! CHECK: fir.array_merge_store %{{.*}}, %{{.*}} to %{{.*}}[%{{.*}}] : !fir.array<?xi32>, !fir.array<?xi32>, !fir.class<!fir.heap<!fir.array<?x!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>>>, !fir.slice<1>
+! CHECK:         %[[P:.*]]:2 = hlfir.declare %{{.*}} {fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QMpolymorphic_testFimplicit_loop_with_polymorphicEp"}
+! CHECK:         %{{.*}} = fir.call @_FortranAAllocatableAllocate(
+! CHECK:         %[[A:.*]] = hlfir.designate %{{.*}}{"a"}{{.*}} : (!fir.class<!fir.heap<!fir.array<?x!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>>>, !fir.shape<1>) -> !fir.box<!fir.array<?xi32>>
+! CHECK:         hlfir.assign %{{.*}} to %[[A]]
+
 
   subroutine polymorphic_to_nonpolymorphic(p)
     class(p1), pointer :: p(:)
     type(p1), allocatable, target :: t(:)
     t = p
   end subroutine
-
 ! CHECK-LABEL: func.func @_QMpolymorphic_testPpolymorphic_to_nonpolymorphic
+! CHECK-SAME:    %[[ARG0:.*]]: !fir.ref<!fir.class<!fir.ptr<!fir.array<?x!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>>>> {fir.bindc_name = "p"}
+! CHECK:         %[[P:.*]]:2 = hlfir.declare %[[ARG0]]
+! CHECK:         hlfir.assign
+
 ! Just checking that FIR is generated without error.
 
   subroutine nonpolymorphic_to_polymorphic(p, t)
@@ -177,9 +211,15 @@ subroutine nonpolymorphic_to_polymorphic(p, t)
     class(p1), target :: t(:)
     p(0:1) => t
   end subroutine
+! CHECK-LABEL: func.func @_QMpolymorphic_testPnonpolymorphic_to_polymorphic(
+! CHECK-SAME:    %[[ARG0:.*]]: !fir.ref<!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QMpolymorphic_testFnonpolymorphic_to_polymorphicTp1>>>>> {fir.bindc_name = "p"}, %[[ARG1:.*]]: !fir.class<!fir.array<?x!fir.type<_QMpolymorphic_testFnonpolymorphic_to_polymorphicTp1>>> {fir.bindc_name = "t", fir.target}
+! CHECK:         %[[P:.*]]:2 = hlfir.declare %[[ARG0]]{{.*}}{fortran_attrs = #fir.var_attrs<pointer>, uniq_name = "_QMpolymorphic_testFnonpolymorphic_to_polymorphicEp"}
+! CHECK:         %[[T:.*]]:2 = hlfir.declare %[[ARG1]]{{.*}}{fortran_attrs = #fir.var_attrs<target>, uniq_name = "_QMpolymorphic_testFnonpolymorphic_to_polymorphicEt"}
+! CHECK:         %[[REBOX:.*]] = fir.rebox %[[T]]#0 : (!fir.class<!fir.array<?x!fir.type<_QMpolymorphic_testFnonpolymorphic_to_polymorphicTp1>>>) -> !fir.box<!fir.ptr<!fir.array<?x!fir.type<_QMpolymorphic_testFnonpolymorphic_to_polymorphicTp1>>>>
+! CHECK:         %[[SHIFT:.*]] = fir.shape_shift %{{.*}}, %{{.*}} : (index, index) -> !fir.shapeshift<1>
+! CHECK:         %[[REMAP:.*]] = fir.rebox %[[REBOX]](%[[SHIFT]]) : (!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QMpolymorphic_testFnonpolymorphic_to_polymorphicTp1>>>>, !fir.shapeshift<1>) -> !fir.box<!fir.ptr<!fir.array<?x!fir.type<_QMpolymorphic_testFnonpolymorphic_to_polymorphicTp1>>>>
+! CHECK:         fir.store %[[REMAP]] to %[[P]]#0
 
-! CHECK-LABEL: func.func @_QMpolymorphic_testPnonpolymorphic_to_polymorphic
-! CHECK: fir.call @_FortranAPointerAssociateRemappingMonomorphic
 
 ! Test that lowering does not crash for function return with unlimited
 ! polymoprhic value.
@@ -187,33 +227,31 @@ subroutine nonpolymorphic_to_polymorphic(p, t)
   function up_ret()
     class(*), pointer :: up_ret(:)
   end function
-
 ! CHECK-LABEL: func.func @_QMpolymorphic_testPup_ret() -> !fir.class<!fir.ptr<!fir.array<?xnone>>> {
 
   subroutine call_up_ret()
     class(*), pointer :: p(:)
     p => up_ret()
   end subroutine
-
 ! CHECK-LABEL: func.func @_QMpolymorphic_testPcall_up_ret() {
-! CHECK:         %{{.*}} = fir.call @_QMpolymorphic_testPup_ret() {{.*}} : () -> !fir.class<!fir.ptr<!fir.array<?xnone>>>
+! CHECK:         %[[P:.*]]:2 = hlfir.declare %{{.*}} {fortran_attrs = #fir.var_attrs<pointer>, uniq_name = "_QMpolymorphic_testFcall_up_retEp"}
+! CHECK:         %{{.*}} = fir.call @_QMpolymorphic_testPup_ret() {{.*}}: () -> !fir.class<!fir.ptr<!fir.array<?xnone>>>
+
 
   subroutine associate_up_pointer(r)
     class(r1) :: r
     class(*), pointer :: p(:)
     p => r%rp
   end subroutine
-
 ! CHECK-LABEL: func.func @_QMpolymorphic_testPassociate_up_pointer(
-! CHECK-SAME: %[[ARG0:.*]]: !fir.class<!fir.type<_QMpolymorphic_testTr1{{(,sequence)?}}{rp:!fir.box<!fir.ptr<!fir.array<?xf32>>>}>> {fir.bindc_name = "r"}) {
-! CHECK: %[[P:.*]] = fir.alloca !fir.class<!fir.ptr<!fir.array<?xnone>>> {bindc_name = "p", uniq_name = "_QMpolymorphic_testFassociate_up_pointerEp"}
-! CHECK: %[[COORD_RP:.*]] = fir.coordinate_of %[[ARG0]], rp : (!fir.class<!fir.type<_QMpolymorphic_testTr1{{(,sequence)?}}{rp:!fir.box<!fir.ptr<!fir.array<?xf32>>>}>>) -> !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>
-! CHECK: %[[LOAD_RP:.*]] = fir.load %[[COORD_RP]] : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>
-! CHECK: %[[REBOX_RP:.*]] = fir.rebox %[[LOAD_RP]](%{{.*}}) : (!fir.box<!fir.ptr<!fir.array<?xf32>>>, !fir.shift<1>) -> !fir.box<!fir.array<?xf32>>
-! CHECK: %[[CONV_P:.*]] = fir.convert %[[P]] : (!fir.ref<!fir.class<!fir.ptr<!fir.array<?xnone>>>>) -> !fir.ref<!fir.box<none>>
-! CHECK: %[[RP_BOX_NONE:.*]] = fir.convert %[[REBOX_RP]] : (!fir.box<!fir.array<?xf32>>) -> !fir.box<none>
-! CHECK: fir.call @_FortranAPointerAssociate(%[[CONV_P]], %[[RP_BOX_NONE]]) {{.*}} : (!fir.ref<!fir.box<none>>, !fir.box<none>) -> ()
-! CHECK: return
+! CHECK-SAME:    %[[ARG0:.*]]: !fir.class<!fir.type<_QMpolymorphic_testTr1{rp:!fir.box<!fir.ptr<!fir.array<?xf32>>>}>> {fir.bindc_name = "r"})
+! CHECK:         %[[P:.*]]:2 = hlfir.declare %{{.*}} {fortran_attrs = #fir.var_attrs<pointer>, uniq_name = "_QMpolymorphic_testFassociate_up_pointerEp"}
+! CHECK:         %[[R:.*]]:2 = hlfir.declare %[[ARG0]]{{.*}}{uniq_name = "_QMpolymorphic_testFassociate_up_pointerEr"}
+! CHECK:         %[[RP:.*]] = hlfir.designate %[[R]]#0{"rp"}{{.*}}{fortran_attrs = #fir.var_attrs<pointer>}
+! CHECK:         %[[RP_LD:.*]] = fir.load %[[RP]]
+! CHECK:         %[[REBOX:.*]] = fir.rebox %[[RP_LD]] : (!fir.box<!fir.ptr<!fir.array<?xf32>>>) -> !fir.class<!fir.ptr<!fir.array<?xnone>>>
+! CHECK:         fir.store %[[REBOX]] to %[[P]]#0
+
 
 ! Test that the fir.dispatch operation is created with the correct pass object
 ! and the pass_arg_pos attribute is incremented correctly when character
@@ -224,42 +262,55 @@ function get_tmp(this)
     character(2) :: get_tmp
     get_tmp = this%tmp
   end function
+! CHECK-LABEL: func.func @_QMpolymorphic_testPget_tmp(
+! CHECK-SAME:    %[[ARG0:.*]]: !fir.ref<!fir.char<1,2>>
+! CHECK-SAME:    %[[ARG1:.*]]: index{{.*}}, %[[ARG2:.*]]: !fir.class<!fir.type<_QMpolymorphic_testTc1{tmp:!fir.char<1,2>}>> {fir.bindc_name = "this"}
+! CHECK:         %[[THIS:.*]]:2 = hlfir.declare %[[ARG2]]{{.*}}{uniq_name = "_QMpolymorphic_testFget_tmpEthis"}
+! CHECK:         %[[TMP:.*]] = hlfir.designate %[[THIS]]#0{"tmp"}
 
   subroutine call_get_tmp(c)
     class(c1) :: c
     print*, c%get_tmp()
   end subroutine
-
 ! CHECK-LABEL: func.func @_QMpolymorphic_testPcall_get_tmp(
-! CHECK-SAME: %[[ARG0:.*]]: !fir.class<!fir.type<_QMpolymorphic_testTc1{{(,sequence)?}}{tmp:!fir.char<1,2>}>> {fir.bindc_name = "c"}) {
-! CHECK: %{{.*}} = fir.dispatch "get_tmp"(%[[ARG0]] : !fir.class<!fir.type<_QMpolymorphic_testTc1{{(,sequence)?}}{tmp:!fir.char<1,2>}>>) (%{{.*}}, %{{.*}}, %[[ARG0]] : !fir.ref<!fir.char<1,2>>, index, !fir.class<!fir.type<_QMpolymorphic_testTc1{{(,sequence)?}}{tmp:!fir.char<1,2>}>>) -> !fir.boxchar<1> {pass_arg_pos = 2 : i32}
+! CHECK-SAME:    %[[ARG0:.*]]: !fir.class<!fir.type<_QMpolymorphic_testTc1{tmp:!fir.char<1,2>}>> {fir.bindc_name = "c"})
+! CHECK:         %[[C:.*]]:2 = hlfir.declare %[[ARG0]]{{.*}}{uniq_name = "_QMpolymorphic_testFcall_get_tmpEc"}
+! CHECK:         %{{.*}} = fir.dispatch "get_tmp"(%[[C]]#0
+
 
   subroutine sub_with_type_array(a)
     type(p1) :: a(:)
   end subroutine
-
-! CHECK-LABEL: func.func @_QMpolymorphic_testPsub_with_type_array(%{{.*}}: !fir.box<!fir.array<?x!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>> {fir.bindc_name = "a"})
+! CHECK-LABEL: func.func @_QMpolymorphic_testPsub_with_type_array(%{{.*}}: !fir.box<!fir.array<?x!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>> {fir.bindc_name = "a"})
 
   subroutine call_sub_with_type_array(p)
     class(p1), pointer :: p(:)
     call sub_with_type_array(p)
   end subroutine
-
 ! CHECK-LABEL: func.func @_QMpolymorphic_testPcall_sub_with_type_array(
-! CHECK-SAME: %[[ARG0:.*]]: !fir.ref<!fir.class<!fir.ptr<!fir.array<?x!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>>>> {fir.bindc_name = "p"}) {
-! CHECK: %[[CLASS:.*]] = fir.load %[[ARG0]] : !fir.ref<!fir.class<!fir.ptr<!fir.array<?x!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>>>>
-! CHECK: %[[REBOX:.*]] = fir.rebox %[[CLASS]] : (!fir.class<!fir.ptr<!fir.array<?x!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>>>) -> !fir.box<!fir.array<?x!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>>
-! CHECK: fir.call @_QMpolymorphic_testPsub_with_type_array(%[[REBOX]]) {{.*}} : (!fir.box<!fir.array<?x!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>>) -> ()
+! CHECK-SAME:    %[[ARG0:.*]]: !fir.ref<!fir.class<!fir.ptr<!fir.array<?x!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>>>> {fir.bindc_name = "p"})
+! CHECK:         %[[P:.*]]:2 = hlfir.declare %[[ARG0]]
+! CHECK:         %[[P_LD:.*]] = fir.load %[[P]]#0
+! CHECK:         %[[REBOX:.*]] = fir.rebox %[[P_LD]]
+! CHECK:         fir.call @_QMpolymorphic_testPsub_with_type_array(%{{.*}})
+
 
   subroutine derived_type_assignment_with_class()
     type(p3) :: a
     type(p3), target :: b(10)
     a = p3(b)
   end subroutine
+! CHECK-LABEL: func.func @_QMpolymorphic_testPderived_type_assignment_with_class()
+! CHECK:         %[[A:.*]]:2 = hlfir.declare %{{.*}} {uniq_name = "_QMpolymorphic_testFderived_type_assignment_with_classEa"}
+! CHECK:         %[[B:.*]]:2 = hlfir.declare %{{.*}} {fortran_attrs = #fir.var_attrs<target>, uniq_name = "_QMpolymorphic_testFderived_type_assignment_with_classEb"}
+! CHECK:         %[[CTOR:.*]]:2 = hlfir.declare %{{.*}} {uniq_name = "ctor.temp"}
+! CHECK:         hlfir.assign %[[CTOR]]#0 to %[[A]]#0
 
   subroutine takes_p1(p)
     class(p1), intent(in) :: p
   end subroutine
+! CHECK-LABEL: func.func @_QMpolymorphic_testPtakes_p1(
+! CHECK-SAME:    %[[ARG0:.*]]: !fir.class<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>> {fir.bindc_name = "p"}
 
 ! TODO: implement polymorphic temporary in lowering
 !  subroutine no_reassoc_poly_value(a, i)
@@ -275,49 +326,44 @@ subroutine pointer_assign_parent(p)
     type(p1), pointer :: tp
     tp => p%p1
   end subroutine
+! CHECK-LABEL: func.func @_QMpolymorphic_testPpointer_assign_parent(
+! CHECK-SAME:    %[[ARG0:.*]]: !fir.ref<!fir.type<_QMpolymorphic_testTp2{p1:!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>,c:f32}>> {{{.*}}, fir.target}
+! CHECK:         %[[P:.*]]:2 = hlfir.declare %[[ARG0]]{{.*}}{fortran_attrs = #fir.var_attrs<target>, uniq_name = "_QMpolymorphic_testFpointer_assign_parentEp"}
+! CHECK:         %[[TP:.*]]:2 = hlfir.declare %{{.*}} {fortran_attrs = #fir.var_attrs<pointer>, uniq_name = "_QMpolymorphic_testFpointer_assign_parentEtp"}
+! CHECK:         %[[P1:.*]] = hlfir.designate %[[P]]#0{"p1"}
+! CHECK:         %[[BOX:.*]] = fir.embox %[[P1]] : (!fir.ref<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>) -> !fir.box<!fir.ptr<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>>
+! CHECK:         fir.store %[[BOX]] to %[[TP]]#0
 
 ! First test is here to have a reference with non polymorphic on both sides.
-! CHECK-LABEL: func.func @_QMpolymorphic_testPpointer_assign_parent(
-! CHECK-SAME: %[[ARG0:.*]]: !fir.ref<!fir.type<_QMpolymorphic_testTp2{{(,sequence)?}}{a:i32,b:i32,c:f32}>> {fir.bindc_name = "p", fir.target}) {
-! CHECK: %[[PTR:.*]] = fir.alloca !fir.ptr<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>> {uniq_name = "_QMpolymorphic_testFpointer_assign_parentEtp.addr"}
-! CHECK: %[[ZERO:.*]] = fir.zero_bits !fir.ptr<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>
-! CHECK: fir.store %[[ZERO]] to %[[PTR]] : !fir.ref<!fir.ptr<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>>
-! CHECK: %[[CONVERT:.*]] = fir.convert %[[ARG0]] : (!fir.ref<!fir.type<_QMpolymorphic_testTp2{{(,sequence)?}}{a:i32,b:i32,c:f32}>>) -> !fir.ptr<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>
-! CHECK: fir.store %[[CONVERT]] to %[[PTR]] : !fir.ref<!fir.ptr<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>>
 
   subroutine pointer_assign_non_poly(p)
     class(p1), target :: p
     type(p1), pointer :: tp
     tp => p
   end subroutine
-
 ! CHECK-LABEL: func.func @_QMpolymorphic_testPpointer_assign_non_poly(
-! CHECK-SAME: %arg0: !fir.class<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>> {fir.bindc_name = "p", fir.target}) {
-! CHECK: %[[PTR:.*]] = fir.alloca !fir.ptr<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>> {uniq_name = "_QMpolymorphic_testFpointer_assign_non_polyEtp.addr"}
-! CHECK: %[[ZERO:.*]] = fir.zero_bits !fir.ptr<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>
-! CHECK: fir.store %[[ZERO]] to %[[PTR]] : !fir.ref<!fir.ptr<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>>
-! CHECK: %[[BOX_ADDR:.*]] = fir.box_addr %[[ARG0]] : (!fir.class<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>) -> !fir.ref<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>
-! CHECK: %[[CONVERT:.*]] = fir.convert %{{[0-9]+}} : (!fir.ref<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>) -> !fir.ptr<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>
-! CHECK: fir.store %[[CONVERT]] to %[[PTR]] : !fir.ref<!fir.ptr<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>>
+! CHECK-SAME:    %[[ARG0:.*]]: !fir.class<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>> {{{.*}}, fir.target}
+! CHECK:         %[[P:.*]]:2 = hlfir.declare %[[ARG0]]{{.*}}{fortran_attrs = #fir.var_attrs<target>, uniq_name = "_QMpolymorphic_testFpointer_assign_non_polyEp"}
+! CHECK:         %[[TP:.*]]:2 = hlfir.declare %{{.*}} {fortran_attrs = #fir.var_attrs<pointer>, uniq_name = "_QMpolymorphic_testFpointer_assign_non_polyEtp"}
+! CHECK:         %[[REBOX:.*]] = fir.rebox %[[P]]#0
+
 
   subroutine nullify_pointer_array(a)
     type(p3) :: a
     nullify(a%p)
   end subroutine
-
 ! CHECK-LABEL: func.func @_QMpolymorphic_testPnullify_pointer_array(
-! CHECK-SAME: %[[ARG0:.*]]: !fir.ref<!fir.type<_QMpolymorphic_testTp3{{(,sequence)?}}{p:!fir.class<!fir.ptr<!fir.array<?x!fir.type<_QMpolymorphic_testTp3>>>>}>> {fir.bindc_name = "a"}) {
-! CHECK: %[[COORD_P:.*]] = fir.coordinate_of %[[ARG0]], p : (!fir.ref<!fir.type<_QMpolymorphic_testTp3{{(,sequence)?}}{p:!fir.class<!fir.ptr<!fir.array<?x!fir.type<_QMpolymorphic_testTp3>>>>}>>) -> !fir.ref<!fir.class<!fir.ptr<!fir.array<?x!fir.type<_QMpolymorphic_testTp3{{(,sequence)?}}{p:!fir.class<!fir.ptr<!fir.array<?x!fir.type<_QMpolymorphic_testTp3>>>>}>>>>>
-! CHECK: %[[TYPE_DESC:.*]] = fir.type_desc !fir.type<_QMpolymorphic_testTp3{{(,sequence)?}}{p:!fir.class<!fir.ptr<!fir.array<?x!fir.type<_QMpolymorphic_testTp3>>>>}>
-! CHECK: %[[CONV_P:.*]] = fir.convert %[[COORD_P]] : (!fir.ref<!fir.class<!fir.ptr<!fir.array<?x!fir.type<_QMpolymorphic_testTp3{{(,sequence)?}}{p:!fir.class<!fir.ptr<!fir.array<?x!fir.type<_QMpolymorphic_testTp3>>>>}>>>>>) -> !fir.ref<!fir.box<none>>
-! CHECK: %[[CONV_TDESC:.*]] = fir.convert %[[TYPE_DESC]] : (!fir.tdesc<!fir.type<_QMpolymorphic_testTp3{{(,sequence)?}}{p:!fir.class<!fir.ptr<!fir.array<?x!fir.type<_QMpolymorphic_testTp3>>>>}>>) -> !fir.ref<none>
-! CHECK: %[[C1:.*]] = arith.constant 1 : i32
-! CHECK: %[[C0:.*]] = arith.constant 0 : i32
-! CHECK: fir.call @_FortranAPointerNullifyDerived(%[[CONV_P]], %[[CONV_TDESC]], %[[C1]], %[[C0]]) {{.*}} : (!fir.ref<!fir.box<none>>, !fir.ref<none>, i32, i32) -> ()
+! CHECK-SAME:    %[[ARG0:.*]]: !fir.ref<!fir.type<_QMpolymorphic_testTp3{p:!fir.class<!fir.ptr<!fir.array<?x!fir.type<_QMpolymorphic_testTp3>>>>}>> {fir.bindc_name = "a"}
+! CHECK:         %[[A:.*]]:2 = hlfir.declare %[[ARG0]]
+! CHECK:         %[[P:.*]] = hlfir.designate %[[A]]#0{"p"}{{.*}}{fortran_attrs = #fir.var_attrs<pointer>}
+! CHECK:         fir.call @_FortranAPointerNullifyDerived(
+
 
   subroutine up_input(a)
     class(*), intent(in) :: a
   end subroutine
+! CHECK-LABEL: func.func @_QMpolymorphic_testPup_input(
+! CHECK-SAME:    %[[ARG0:.*]]: !fir.class<none> {fir.bindc_name = "a"}
 
   subroutine pass_trivial_to_up()
     call up_input('hello')
@@ -326,27 +372,24 @@ subroutine pass_trivial_to_up()
     call up_input(.true.)
     call up_input((-1.0,3))
   end subroutine
-
 ! CHECK-LABEL: func.func @_QMpolymorphic_testPpass_trivial_to_up() {
-! CHECK: %[[CHAR:.*]] = fir.address_of(@_QQclX{{.*}}) : !fir.ref<!fir.char<1,5>>
-! CHECK: %[[BOX_CHAR:.*]] = fir.embox %[[CHAR]] : (!fir.ref<!fir.char<1,5>>) -> !fir.class<none>
-! CHECK: fir.call @_QMpolymorphic_testPup_input(%[[BOX_CHAR]]) {{.*}} : (!fir.class<none>) -> ()
+! CHECK:         %[[STR_BOX:.*]] = fir.embox %{{.*}} : (!fir.ref<!fir.char<1,5>>) -> !fir.box<!fir.char<1,5>>
+! CHECK:         %[[STR_CLASS:.*]] = fir.rebox %[[STR_BOX]] : (!fir.box<!fir.char<1,5>>) -> !fir.class<none>
+! CHECK:         fir.call @_QMpolymorphic_testPup_input(%[[STR_CLASS]])
+! CHECK:         %[[I_BOX:.*]] = fir.embox %{{.*}} : (!fir.ref<i32>) -> !fir.box<i32>
+! CHECK:         %[[I_CLASS:.*]] = fir.rebox %[[I_BOX]] : (!fir.box<i32>) -> !fir.class<none>
+! CHECK:         fir.call @_QMpolymorphic_testPup_input(%[[I_CLASS]])
+
 
-! CHECK: %[[BOX_INT:.*]] = fir.embox %{{.*}} : (!fir.ref<i32>) -> !fir.class<none>
-! CHECK: fir.call @_QMpolymorphic_testPup_input(%[[BOX_INT]]) {{.*}} : (!fir.class<none>) -> ()
 
-! CHECK: %[[BOX_REAL:.*]] = fir.embox %{{.*}} : (!fir.ref<f32>) -> !fir.class<none>
-! CHECK: fir.call @_QMpolymorphic_testPup_input(%[[BOX_REAL]]) {{.*}} : (!fir.class<none>) -> ()
 
-! CHECK: %[[BOX_LOG:.*]] = fir.embox %{{.*}} : (!fir.ref<!fir.logical<4>>) -> !fir.class<none>
-! CHECK: fir.call @_QMpolymorphic_testPup_input(%[[BOX_LOG]]) {{.*}} : (!fir.class<none>) -> ()
 
-! CHECK: %[[BOX_COMPLEX:.*]] = fir.embox %{{.*}} : (!fir.ref<complex<f32>>) -> !fir.class<none>
-! CHECK: fir.call @_QMpolymorphic_testPup_input(%[[BOX_COMPLEX]]) {{.*}} : (!fir.class<none>) -> ()
 
   subroutine up_arr_input(a)
     class(*), intent(in) :: a(2)
   end subroutine
+! CHECK-LABEL: func.func @_QMpolymorphic_testPup_arr_input(
+! CHECK-SAME:    %[[ARG0:.*]]: !fir.class<!fir.array<2xnone>> {fir.bindc_name = "a"}
 
   subroutine pass_trivial_arr_to_up()
     character :: c(2)
@@ -361,45 +404,28 @@ subroutine pass_trivial_arr_to_up()
     call up_arr_input(l)
     call up_arr_input(cx)
   end subroutine
-
 ! CHECK-LABEL: func.func @_QMpolymorphic_testPpass_trivial_arr_to_up() {
-! CHECK: %[[BOX_CHAR:.*]] = fir.embox %{{.*}}(%{{.*}}) : (!fir.ref<!fir.array<2x!fir.char<1>>>, !fir.shape<1>) -> !fir.class<!fir.array<2xnone>>
-! CHECK: fir.call @_QMpolymorphic_testPup_arr_input(%[[BOX_CHAR]]) {{.*}} : (!fir.class<!fir.array<2xnone>>) -> ()
+! CHECK:         %{{.*}} = fir.embox %{{.*}}#0(%{{.*}}) : (!fir.ref<!fir.array<2x!fir.char<1>>>, !fir.shape<1>) -> !fir.box<!fir.array<2x!fir.char<1>>>
+! CHECK:         %{{.*}} = fir.rebox %{{.*}} : (!fir.box<!fir.array<2x!fir.char<1>>>) -> !fir.class<!fir.array<2xnone>>
+! CHECK:         fir.call @_QMpolymorphic_testPup_arr_input(%{{.*}})
+! CHECK:         %{{.*}} = fir.embox %{{.*}}#0(%{{.*}}) : (!fir.ref<!fir.array<2xi32>>, !fir.shape<1>) -> !fir.box<!fir.array<2xi32>>
+! CHECK:         %{{.*}} = fir.rebox %{{.*}} : (!fir.box<!fir.array<2xi32>>) -> !fir.class<!fir.array<2xnone>>
+
 
-! CHECK: %[[BOX_INT:.*]] = fir.embox %{{.*}}(%{{.*}}) : (!fir.ref<!fir.array<2xi32>>, !fir.shape<1>) -> !fir.class<!fir.array<2xnone>>
-! CHECK: fir.call @_QMpolymorphic_testPup_arr_input(%[[BOX_INT]]) {{.*}} : (!fir.class<!fir.array<2xnone>>) -> ()
 
-! CHECK: %[[BOX_REAL:.*]] = fir.embox %{{.*}}(%{{.*}}) : (!fir.ref<!fir.array<2xf32>>, !fir.shape<1>) -> !fir.class<!fir.array<2xnone>>
-! CHECK: fir.call @_QMpolymorphic_testPup_arr_input(%[[BOX_REAL]]) {{.*}} : (!fir.class<!fir.array<2xnone>>) -> ()
 
-! CHECK: %[[BOX_LOG:.*]] = fir.embox %{{.*}}(%{{.*}}) : (!fir.ref<!fir.array<2x!fir.logical<4>>>, !fir.shape<1>) -> !fir.class<!fir.array<2xnone>>
-! CHECK: fir.call @_QMpolymorphic_testPup_arr_input(%[[BOX_LOG]]) {{.*}} : (!fir.class<!fir.array<2xnone>>) -> ()
 
-! CHECK: %[[BOX_COMPLEX:.*]] = fir.embox %{{.*}}(%{{.*}}) : (!fir.ref<!fir.array<2xcomplex<f32>>>, !fir.shape<1>) -> !fir.class<!fir.array<2xnone>>
-! CHECK: fir.call @_QMpolymorphic_testPup_arr_input(%[[BOX_COMPLEX]]) {{.*}} : (!fir.class<!fir.array<2xnone>>) -> ()
 
   subroutine assign_polymorphic_allocatable()
     type(p1), target :: t(10,20)
     class(p1), allocatable :: c(:,:)
     c = t
   end subroutine
-
 ! CHECK-LABEL: func.func @_QMpolymorphic_testPassign_polymorphic_allocatable() {
-! CHECK: %[[C:.*]] = fir.alloca !fir.class<!fir.heap<!fir.array<?x?x!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>>> {bindc_name = "c", uniq_name = "_QMpolymorphic_testFassign_polymorphic_allocatableEc"}
-! CHECK: %[[ZERO:.*]] = fir.zero_bits !fir.heap<!fir.array<?x?x!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>>
-! CHECK: %[[C0:.*]] = arith.constant 0 : index
-! CHECK: %[[SHAPE_C:.*]] = fir.shape %[[C0]], %[[C0]] : (index, index) -> !fir.shape<2>
-! CHECK: %[[EMBOX:.*]] = fir.embox %[[ZERO]](%[[SHAPE_C]]) : (!fir.heap<!fir.array<?x?x!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>>, !fir.shape<2>) -> !fir.class<!fir.heap<!fir.array<?x?x!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>>>
-! CHECK: fir.store %[[EMBOX]] to %[[C]] : !fir.ref<!fir.class<!fir.heap<!fir.array<?x?x!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>>>>
-! CHECK: %[[C10:.*]] = arith.constant 10 : index
-! CHECK: %[[C20:.*]] = arith.constant 20 : index
-! CHECK: %[[T:.*]] = fir.alloca !fir.array<10x20x!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>> {bindc_name = "t", fir.target, uniq_name = "_QMpolymorphic_testFassign_polymorphic_allocatableEt"}
-! CHECK: %[[SHAPE:.*]] = fir.shape %[[C10]], %[[C20]] : (index, index) -> !fir.shape<2>
-! CHECK: %[[BOXED_T:.*]] = fir.embox %[[T]](%[[SHAPE]]) : (!fir.ref<!fir.array<10x20x!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>>, !fir.shape<2>) -> !fir.box<!fir.array<10x20x!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>>
-! CHECK: %[[CONV_C:.*]] = fir.convert %[[C]] : (!fir.ref<!fir.class<!fir.heap<!fir.array<?x?x!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>>>>) -> !fir.ref<!fir.box<none>>
-! CHECK: %[[CONV_BOXED_T:.*]] = fir.convert %[[BOXED_T]] : (!fir.box<!fir.array<10x20x!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>>) -> !fir.box<none>
-! CHECK: fir.call @_FortranAAssignPolymorphic(%[[CONV_C]], %[[CONV_BOXED_T]], %{{.*}}, %{{.*}}) fastmath<contract> : (!fir.ref<!fir.box<none>>, !fir.box<none>, !fir.ref<i8>, i32) -> ()
-! CHECK: return
+! CHECK:         %[[C:.*]]:2 = hlfir.declare %{{.*}} {fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QMpolymorphic_testFassign_polymorphic_allocatableEc"}
+! CHECK:         %[[T:.*]]:2 = hlfir.declare %{{.*}} {fortran_attrs = #fir.var_attrs<target>, uniq_name = "_QMpolymorphic_testFassign_polymorphic_allocatableEt"}
+! CHECK:         hlfir.assign %[[T]]#0 to %[[C]]#0 realloc
+
 
   subroutine pointer_assign_remap()
     class(p1), pointer :: a(:)
@@ -409,50 +435,11 @@ subroutine pointer_assign_remap()
     p(1:10,1:10) => a
     q(0:99) => a
   end subroutine
-
 ! CHECK-LABEL: func.func @_QMpolymorphic_testPpointer_assign_remap() {
-! CHECK: %[[A:.*]] = fir.alloca !fir.class<!fir.ptr<!fir.array<?x!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>>> {bindc_name = "a", uniq_name = "_QMpolymorphic_testFpointer_assign_remapEa"}
-! CHECK: %[[P:.*]] = fir.alloca !fir.class<!fir.ptr<!fir.array<?x?x!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>>> {bindc_name = "p", uniq_name = "_QMpolymorphic_testFpointer_assign_remapEp"}
-! CHECK: %[[Q:.*]] = fir.alloca !fir.class<!fir.ptr<!fir.array<?x!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>>> {bindc_name = "q", uniq_name = "_QMpolymorphic_testFpointer_assign_remapEq"}
-! CHECK: %[[C1_0:.*]] = arith.constant 1 : i64
-! CHECK: %[[C10_0:.*]] = arith.constant 10 : i64
-! CHECK: %[[C1_1:.*]] = arith.constant 1 : i64
-! CHECK: %[[C10_1:.*]] = arith.constant 10 : i64
-! CHECK: %[[LOAD_A:.*]] = fir.load %[[A]] : !fir.ref<!fir.class<!fir.ptr<!fir.array<?x!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>>>>
-! CHECK: %[[REBOX_A:.*]] = fir.rebox %[[LOAD_A]](%{{.*}}) : (!fir.class<!fir.ptr<!fir.array<?x!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>>>, !fir.shift<1>) -> !fir.class<!fir.array<?x!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>>
-! CHECK: %[[BOUND_ARRAY:.*]] = fir.alloca !fir.array<2x2xi64>
-! CHECK: %[[ARRAY:.*]] = fir.undefined !fir.array<2x2xi64>
-! CHECK: %[[ARRAY0:.*]] = fir.insert_value %[[ARRAY]], %[[C1_0]], [0 : index, 0 : index] : (!fir.array<2x2xi64>, i64) -> !fir.array<2x2xi64>
-! CHECK: %[[ARRAY1:.*]] = fir.insert_value %[[ARRAY0]], %[[C10_0]], [1 : index, 0 : index] : (!fir.array<2x2xi64>, i64) -> !fir.array<2x2xi64>
-! CHECK: %[[ARRAY2:.*]] = fir.insert_value %[[ARRAY1]], %[[C1_1]], [0 : index, 1 : index] : (!fir.array<2x2xi64>, i64) -> !fir.array<2x2xi64>
-! CHECK: %[[ARRAY3:.*]] = fir.insert_value %[[ARRAY2]], %[[C10_1]], [1 : index, 1 : index] : (!fir.array<2x2xi64>, i64) -> !fir.array<2x2xi64>
-! CHECK: fir.store %[[ARRAY3]] to %[[BOUND_ARRAY]] : !fir.ref<!fir.array<2x2xi64>>
-! CHECK: %[[C2_0:.*]] = arith.constant 2 : index
-! CHECK: %[[C2_1:.*]] = arith.constant 2 : index
-! CHECK: %[[BOUND_ARRAY_SHAPE:.*]] = fir.shape %[[C2_1]], %[[C2_0]] : (index, index) -> !fir.shape<2>
-! CHECK: %[[BOXED_BOUND_ARRAY:.*]] = fir.embox %[[BOUND_ARRAY]](%[[BOUND_ARRAY_SHAPE]]) : (!fir.ref<!fir.array<2x2xi64>>, !fir.shape<2>) -> !fir.box<!fir.array<2x2xi64>>
-! CHECK: %[[ARG0:.*]] = fir.convert %[[P]] : (!fir.ref<!fir.class<!fir.ptr<!fir.array<?x?x!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>>>>) -> !fir.ref<!fir.box<none>>
-! CHECK: %[[ARG1:.*]] = fir.convert %[[REBOX_A]] : (!fir.class<!fir.array<?x!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>>) -> !fir.box<none>
-! CHECK: %[[ARG2:.*]] = fir.convert %[[BOXED_BOUND_ARRAY]] : (!fir.box<!fir.array<2x2xi64>>) -> !fir.box<none>
-! CHECK:  fir.call @_FortranAPointerAssociateRemapping(%[[ARG0]], %[[ARG1]], %[[ARG2]], %{{.*}}, %{{.*}}) {{.*}} : (!fir.ref<!fir.box<none>>, !fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> ()
-
-! CHECK: %[[C0:.*]] = arith.constant 0 : i64
-! CHECK: %[[C99:.*]] = arith.constant 99 : i64
-! CHECK: %[[LOAD_A:.*]] = fir.load %[[A]] : !fir.ref<!fir.class<!fir.ptr<!fir.array<?x!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>>>>
-! CHECK: %[[REBOX_A:.*]] = fir.rebox %[[LOAD_A]](%{{.*}}) : (!fir.class<!fir.ptr<!fir.array<?x!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>>>, !fir.shift<1>) -> !fir.class<!fir.array<?x!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>>
-! CHECK: %[[BOUND_ARRAY:.*]] = fir.alloca !fir.array<2x1xi64>
-! CHECK: %[[ARRAY:.*]] = fir.undefined !fir.array<2x1xi64>
-! CHECK: %[[ARRAY0:.*]] = fir.insert_value %[[ARRAY]], %[[C0]], [0 : index, 0 : index] : (!fir.array<2x1xi64>, i64) -> !fir.array<2x1xi64>
-! CHECK: %[[ARRAY1:.*]] = fir.insert_value %[[ARRAY0]], %[[C99]], [1 : index, 0 : index] : (!fir.array<2x1xi64>, i64) -> !fir.array<2x1xi64>
-! CHECK: fir.store %[[ARRAY1]] to %[[BOUND_ARRAY]] : !fir.ref<!fir.array<2x1xi64>>
-! CHECK: %[[C1:.*]] = arith.constant 1 : index
-! CHECK: %[[C2:.*]] = arith.constant 2 : index
-! CHECK: %[[BOUND_ARRAY_SHAPE:.*]] = fir.shape %[[C2]], %[[C1]] : (index, index) -> !fir.shape<2>
-! CHECK: %[[BOXED_BOUND_ARRAY:.*]] = fir.embox %[[BOUND_ARRAY]](%[[BOUND_ARRAY_SHAPE]]) : (!fir.ref<!fir.array<2x1xi64>>, !fir.shape<2>) -> !fir.box<!fir.array<2x1xi64>>
-! CHECK: %[[ARG0:.*]] = fir.convert %[[Q]] : (!fir.ref<!fir.class<!fir.ptr<!fir.array<?x!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>>>>) -> !fir.ref<!fir.box<none>>
-! CHECK: %[[ARG1:.*]] = fir.convert %[[REBOX_A]] : (!fir.class<!fir.array<?x!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>>) -> !fir.box<none>
-! CHECK: %[[ARG2:.*]] = fir.convert %[[BOXED_BOUND_ARRAY]] : (!fir.box<!fir.array<2x1xi64>>) -> !fir.box<none>
-! CHECK: fir.call @_FortranAPointerAssociateRemapping(%[[ARG0]], %[[ARG1]], %[[ARG2]], %{{.*}}, %{{.*}}) {{.*}} : (!fir.ref<!fir.box<none>>, !fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> ()
+! CHECK:         %[[A:.*]]:2 = hlfir.declare %{{.*}} {fortran_attrs = #fir.var_attrs<pointer>, uniq_name = "_QMpolymorphic_testFpointer_assign_remapEa"}
+! CHECK:         %[[P:.*]]:2 = hlfir.declare %{{.*}} {fortran_attrs = #fir.var_attrs<pointer>, uniq_name = "_QMpolymorphic_testFpointer_assign_remapEp"}
+! CHECK:         %[[Q:.*]]:2 = hlfir.declare %{{.*}} {fortran_attrs = #fir.var_attrs<pointer>, uniq_name = "_QMpolymorphic_testFpointer_assign_remapEq"}
+
 
   subroutine pointer_assign_lower_bounds()
     class(p1), allocatable, target :: a(:)
@@ -460,60 +447,19 @@ subroutine pointer_assign_lower_bounds()
     allocate(a(100))
     p(-50:) => a
   end subroutine
-
 ! CHECK-LABEL: func.func @_QMpolymorphic_testPpointer_assign_lower_bounds() {
-! CHECK: %[[A:.*]] = fir.alloca !fir.class<!fir.heap<!fir.array<?x!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>>> {bindc_name = "a", fir.target, uniq_name = "_QMpolymorphic_testFpointer_assign_lower_boundsEa"}
-! CHECK: %[[P:.*]] = fir.alloca !fir.class<!fir.ptr<!fir.array<?x!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>>> {bindc_name = "p", uniq_name = "_QMpolymorphic_testFpointer_assign_lower_boundsEp"}
-! CHECK: %[[LB:.*]] = arith.constant -50 : i64
-! CHECK: %[[REBOX_A:.*]] = fir.rebox %{{.*}}(%{{.*}}) : (!fir.class<!fir.heap<!fir.array<?x!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>>>, !fir.shift<1>) -> !fir.class<!fir.array<?x!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>>
-! CHECK: %[[LBOUND_ARRAY:.*]] = fir.alloca !fir.array<1xi64>
-! CHECK: %[[ARRAY:.*]] = fir.undefined !fir.array<1xi64>
-! CHECK: %[[ARRAY0:.*]] = fir.insert_value %[[ARRAY]], %[[LB]], [0 : index] : (!fir.array<1xi64>, i64) -> !fir.array<1xi64>
-! CHECK: fir.store %[[ARRAY0]] to %[[LBOUND_ARRAY]] : !fir.ref<!fir.array<1xi64>>
-! CHECK: %[[C1:.*]] = arith.constant 1 : index
-! CHECK: %[[LBOUND_ARRAY_SHAPE:.*]] = fir.shape %[[C1]] : (index) -> !fir.shape<1>
-! CHECK: %[[LBOUND_ARRAY_BOXED:.*]] = fir.embox %[[LBOUND_ARRAY]](%[[LBOUND_ARRAY_SHAPE]]) : (!fir.ref<!fir.array<1xi64>>, !fir.shape<1>) -> !fir.box<!fir.array<1xi64>>
-! CHECK: %[[P_BOX_NONE:.*]] = fir.convert %[[P]] : (!fir.ref<!fir.class<!fir.ptr<!fir.array<?x!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>>>>) -> !fir.ref<!fir.box<none>>
-! CHECK: %[[A_BOX_NONE:.*]] = fir.convert %[[REBOX_A]] : (!fir.class<!fir.array<?x!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>>) -> !fir.box<none>
-! CHECK: %[[LBOUNDS_BOX_NONE:.*]] = fir.convert %[[LBOUND_ARRAY_BOXED]] : (!fir.box<!fir.array<1xi64>>) -> !fir.box<none>
-! CHECK: fir.call @_FortranAPointerAssociateLowerBounds(%[[P_BOX_NONE]], %[[A_BOX_NONE]], %[[LBOUNDS_BOX_NONE]]) {{.*}} : (!fir.ref<!fir.box<none>>, !fir.box<none>, !fir.box<none>) -> ()
+! CHECK:         %[[A:.*]]:2 = hlfir.declare %{{.*}} {fortran_attrs = #fir.var_attrs<allocatable, target>, uniq_name = "_QMpolymorphic_testFpointer_assign_lower_boundsEa"}
+! CHECK:         %[[P:.*]]:2 = hlfir.declare %{{.*}} {fortran_attrs = #fir.var_attrs<pointer>, uniq_name = "_QMpolymorphic_testFpointer_assign_lower_boundsEp"}
+
 
   subroutine test_elemental_assign()
     type(p1) :: pa(3)
     pa = [ 1, 2, 3 ]
   end subroutine
-
 ! CHECK-LABEL: func.func @_QMpolymorphic_testPtest_elemental_assign() {
-! CHECK: %[[INT:.*]] = fir.alloca i32
-! CHECK: %[[C3_0:.*]] = arith.constant 3 : index
-! CHECK: %[[PA:.*]] = fir.alloca !fir.array<3x!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>> {bindc_name = "pa", uniq_name = "_QMpolymorphic_testFtest_elemental_assignEpa"}
-! CHECK: %[[SHAPE:.*]] = fir.shape %[[C3_0]] : (index) -> !fir.shape<1>
-! CHECK: %[[LOAD_PA:.*]] = fir.array_load %[[PA]](%[[SHAPE]]) : (!fir.ref<!fir.array<3x!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>>, !fir.shape<1>) -> !fir.array<3x!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>
-! CHECK: %[[ADDR_INT:.*]] = fir.address_of(@_QQro.3xi4.{{.*}}) : !fir.ref<!fir.array<3xi32>>
-! CHECK: %[[C3:.*]] = arith.constant 3 : index
-! CHECK: %[[SHAPE:.*]] = fir.shape %[[C3]] : (index) -> !fir.shape<1>
-! CHECK: %[[LOAD_INT_ARRAY:.*]] = fir.array_load %[[ADDR_INT]](%[[SHAPE]]) : (!fir.ref<!fir.array<3xi32>>, !fir.shape<1>) -> !fir.array<3xi32>
-! CHECK: %[[C1:.*]] = arith.constant 1 : index
-! CHECK: %[[C0:.*]] = arith.constant 0 : index
-! CHECK: %[[UB:.*]] = arith.subi %[[C3_0]], %[[C1]] : index
-! CHECK: %[[DO_RES:.*]] = fir.do_loop %[[ARG0:.*]] = %[[C0]] to %[[UB]] step %[[C1]] unordered iter_args(%[[ARG1:.*]] = %[[LOAD_PA]]) -> (!fir.array<3x!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>) {
-! CHECK:   %[[FETCH_INT:.*]] = fir.array_fetch %[[LOAD_INT_ARRAY]], %[[ARG0]] : (!fir.array<3xi32>, index) -> i32
-! CHECK:   %[[ARRAY_MOD:.*]]:2 = fir.array_modify %[[ARG1]], %[[ARG0]] : (!fir.array<3x!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>, index) -> (!fir.ref<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>, !fir.array<3x!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>)
-! CHECK:   %[[EMBOXED:.*]] = fir.embox %{{.*}}#0 : (!fir.ref<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>) -> !fir.class<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>
-! CHECK:   fir.store %[[FETCH_INT]] to %[[INT]] : !fir.ref<i32>
-! CHECK:   fir.call @_QMpolymorphic_testPassign_p1_int(%[[EMBOXED]], %[[INT]]) fastmath<contract> : (!fir.class<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>, !fir.ref<i32>) -> ()
-! CHECK:   fir.result %[[ARRAY_MOD]]#1 : !fir.array<3x!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>
-! CHECK: }
-! CHECK: fir.array_merge_store %[[LOAD_PA]], %[[DO_RES]] to %[[PA]] : !fir.array<3x!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>, !fir.array<3x!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>, !fir.ref<!fir.array<3x!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>>
-! CHECK: return
+! CHECK:         %[[PA:.*]]:2 = hlfir.declare %{{.*}} {uniq_name = "_QMpolymorphic_testFtest_elemental_assignEpa"}
+! CHECK:         hlfir.region_assign
 
-! CHECK-LABEL: func.func @_QMpolymorphic_testPhost_assoc(
-! CHECK-SAME: %[[THIS:.*]]: !fir.class<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>> {fir.bindc_name = "this"}) {
-! CHECK: %[[TUPLE:.*]] = fir.alloca tuple<!fir.class<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>>
-! CHECK: %[[POS_IN_TUPLE:.*]] = arith.constant 0 : i32
-! CHECK: %[[COORD_OF_CLASS:.*]] = fir.coordinate_of %[[TUPLE]], %[[POS_IN_TUPLE]] : (!fir.ref<tuple<!fir.class<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>>>, i32) -> !fir.ref<!fir.class<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>>
-! CHECK: fir.store %[[THIS]] to %[[COORD_OF_CLASS]] : !fir.ref<!fir.class<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>>
-! CHECK: fir.call @_QMpolymorphic_testFhost_assocPinternal(%[[TUPLE]]) {{.*}} : (!fir.ref<tuple<!fir.class<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>>>) -> ()
 
   subroutine host_assoc(this)
     class(p1) :: this
@@ -524,216 +470,75 @@ subroutine internal
       print*, this%a, this%b
     end subroutine
   end subroutine
+! CHECK-LABEL: func.func @_QMpolymorphic_testPhost_assoc(
+! CHECK-SAME:    %[[ARG0:.*]]: !fir.class<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>> {fir.bindc_name = "this"}
+! CHECK:         %[[THIS:.*]]:2 = hlfir.declare %[[ARG0]]
+! CHECK:         fir.call @_QMpolymorphic_testFhost_assocPinternal(
 
 ! CHECK-LABEL: func.func private @_QMpolymorphic_testFhost_assocPinternal(
-! CHECK-SAME: %[[TUPLE:.*]]: !fir.ref<tuple<!fir.class<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>>> {fir.host_assoc}) attributes {fir.host_symbol = {{.*}}, llvm.linkage = #llvm.linkage<internal>} {
-! CHECK: %[[POS_IN_TUPLE:.*]] = arith.constant 0 : i32
-! CHECK: %[[COORD_OF_CLASS:.*]] = fir.coordinate_of %[[TUPLE]], %[[POS_IN_TUPLE]] : (!fir.ref<tuple<!fir.class<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>>>, i32) -> !fir.ref<!fir.class<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>>
-! CHECK: %[[CLASS:.*]] = fir.load %[[COORD_OF_CLASS]] : !fir.ref<!fir.class<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>>
-! CHECK: %[[COORD_A:.*]] = fir.coordinate_of %[[CLASS]], a : (!fir.class<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>) -> !fir.ref<i32>
-! CHECK: %[[A:.*]] = fir.load %[[COORD_A]] : !fir.ref<i32>
-! CHECK: %{{.*}} = fir.call @_FortranAioOutputInteger32(%{{.*}}, %[[A]]) {{.*}} : (!fir.ref<i8>, i32) -> i1
-! CHECK: %[[COORD_B:.*]] = fir.coordinate_of %[[CLASS]], b : (!fir.class<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>) -> !fir.ref<i32>
-! CHECK: %[[B:.*]] = fir.load %[[COORD_B]] : !fir.ref<i32>
-! CHECK: %{{.*}} = fir.call @_FortranAioOutputInteger32(%{{.*}}, %[[B]]) {{.*}} : (!fir.ref<i8>, i32) -> i1
+! CHECK-SAME:    %[[ARG0:.*]]: !fir.ref<tuple{{.*}}>{{.*}})
+! CHECK:         %[[THIS_LD:.*]] = fir.load %{{.*}}
+! CHECK:         %[[A:.*]] = hlfir.designate %{{.*}}{"a"}
+! CHECK:         %[[B:.*]] = hlfir.designate %{{.*}}{"b"}
+
 
   subroutine test_elemental_array()
     type(p1) :: p(5)
     print *, p%elemental_fct()
   end subroutine
-
 ! CHECK-LABEL: func.func @_QMpolymorphic_testPtest_elemental_array() {
-! CHECK: %[[P:.*]] = fir.alloca !fir.array<5x!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>> {bindc_name = "p", uniq_name = "_QMpolymorphic_testFtest_elemental_arrayEp"}
-! CHECK: %[[C5:.*]] = arith.constant 5 : index
-! CHECK: %[[TMP:.*]] = fir.allocmem !fir.array<5xi32>
-! CHECK: %[[SHAPE:.*]] = fir.shape %[[C5]] : (index) -> !fir.shape<1>
-! CHECK: %[[ARRAY_LOAD_TMP:.*]] = fir.array_load %[[TMP]](%[[SHAPE]]) : (!fir.heap<!fir.array<5xi32>>, !fir.shape<1>) -> !fir.array<5xi32>
-! CHECK: %[[C1:.*]] = arith.constant 1 : index
-! CHECK: %[[C0:.*]] = arith.constant 0 : index
-! CHECK: %[[UB:.*]] = arith.subi %[[C5]], %[[C1]] : index
-! CHECK: %[[LOOP_RES:.*]] = fir.do_loop %[[IND:.*]] = %[[C0]] to %[[UB]] step %[[C1]] unordered iter_args(%[[ARG1:.*]] = %[[ARRAY_LOAD_TMP]]) -> (!fir.array<5xi32>) {
-! CHECK:   %[[COORD:.*]] = fir.coordinate_of %[[P]], %[[IND]] : (!fir.ref<!fir.array<5x!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>>, index) -> !fir.ref<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>
-! CHECK:   %[[EMBOXED:.*]] = fir.embox %[[COORD]] : (!fir.ref<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>) -> !fir.class<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>
-! CHECK:   %[[RES:.*]] = fir.call @_QMpolymorphic_testPelemental_fct(%[[EMBOXED]]) {{.*}} : (!fir.class<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>) -> i32
-! CHECK:   %[[ARR_UP:.*]] = fir.array_update %[[ARG1]], %[[RES]], %[[IND]] : (!fir.array<5xi32>, i32, index) -> !fir.array<5xi32>
-! CHECK:   fir.result %[[ARR_UP]] : !fir.array<5xi32>
-! CHECK: }
-! CHECK: fir.array_merge_store %[[ARRAY_LOAD_TMP]], %[[LOOP_RES]] to %[[TMP]] : !fir.array<5xi32>, !fir.array<5xi32>, !fir.heap<!fir.array<5xi32>>
-! CHECK: %[[SHAPE:.*]] = fir.shape %[[C5]] : (index) -> !fir.shape<1>
-! CHECK: %[[EMBOXED_TMP:.*]] = fir.embox %[[TMP]](%[[SHAPE]]) : (!fir.heap<!fir.array<5xi32>>, !fir.shape<1>) -> !fir.box<!fir.array<5xi32>>
-! CHECK: %[[BOX_NONE:.*]] = fir.convert %[[EMBOXED_TMP]] : (!fir.box<!fir.array<5xi32>>) -> !fir.box<none>
-! CHECK: %{{.*}} = fir.call @_FortranAioOutputDescriptor(%{{.*}}, %[[BOX_NONE]]) {{.*}} : (!fir.ref<i8>, !fir.box<none>) -> i1
-! CHECK: fir.freemem %[[TMP]] : !fir.heap<!fir.array<5xi32>>
+! CHECK:         %[[P:.*]]:2 = hlfir.declare %{{.*}} {uniq_name = "_QMpolymorphic_testFtest_elemental_arrayEp"}
+! CHECK:         hlfir.elemental
 
   subroutine test_elemental_poly_array(p)
     class(p1) :: p(5)
     print *, p%elemental_fct()
   end subroutine
-
 ! CHECK-LABEL: func.func @_QMpolymorphic_testPtest_elemental_poly_array(
-! CHECK-SAME: %[[P:.*]]: !fir.class<!fir.array<5x!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>> {fir.bindc_name = "p"}) {
-! CHECK: %[[C5:.*]] = arith.constant 5 : index
-! CHECK: %[[TMP:.*]] = fir.allocmem !fir.array<5xi32>
-! CHECK: %[[SHAPE:.*]] = fir.shape %[[C5]] : (index) -> !fir.shape<1>
-! CHECK: %[[ARRAY_LOAD_TMP:.*]] = fir.array_load %[[TMP]](%[[SHAPE]]) : (!fir.heap<!fir.array<5xi32>>, !fir.shape<1>) -> !fir.array<5xi32>
-! CHECK: %[[C1:.*]] = arith.constant 1 : index
-! CHECK: %[[C0:.*]] = arith.constant 0 : index
-! CHECK: %[[UB:.*]] = arith.subi %[[C5]], %[[C1]] : index
-! CHECK: %[[LOOP_RES:.*]] = fir.do_loop %[[IND:.*]] = %[[C0]] to %[[UB]] step %[[C1]] unordered iter_args(%[[ARG:.*]] = %[[ARRAY_LOAD_TMP]]) -> (!fir.array<5xi32>) {
-! CHECK:   %[[COORD:.*]] = fir.coordinate_of %[[P]], %[[IND]] : (!fir.class<!fir.array<5x!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>>, index) -> !fir.ref<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>
-! CHECK:   %[[EMBOXED:.*]] = fir.embox %[[COORD]] source_box %[[P]] : (!fir.ref<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>, !fir.class<!fir.array<5x!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>>) -> !fir.class<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>
-! CHECK:   %[[RES:.*]] = fir.dispatch "elemental_fct"(%[[EMBOXED]] : !fir.class<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>) (%[[EMBOXED]] : !fir.class<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>) -> i32 proc_attrs <elemental, pure> {pass_arg_pos = 0 : i32}
-! CHECK:   %[[ARR_UP:.*]] = fir.array_update %[[ARG]], %[[RES]], %[[IND]] : (!fir.array<5xi32>, i32, index) -> !fir.array<5xi32>
-! CHECK:   fir.result %[[ARR_UP]] : !fir.array<5xi32>
-! CHECK: }
-! CHECK: fir.array_merge_store %[[ARRAY_LOAD_TMP]], %[[LOOP_RES]] to %[[TMP]] : !fir.array<5xi32>, !fir.array<5xi32>, !fir.heap<!fir.array<5xi32>>
-! CHECK: %[[SHAPE:.*]] = fir.shape %[[C5]] : (index) -> !fir.shape<1>
-! CHECK: %[[EMBOXED_TMP:.*]] = fir.embox %[[TMP]](%[[SHAPE]]) : (!fir.heap<!fir.array<5xi32>>, !fir.shape<1>) -> !fir.box<!fir.array<5xi32>>
-! CHECK: %[[BOX_NONE:.*]] = fir.convert %[[EMBOXED_TMP]] : (!fir.box<!fir.array<5xi32>>) -> !fir.box<none>
-! CHECK: %{{.*}} = fir.call @_FortranAioOutputDescriptor(%{{.*}}, %[[BOX_NONE]]) {{.*}} : (!fir.ref<i8>, !fir.box<none>) -> i1
-! CHECK: fir.freemem %[[TMP]] : !fir.heap<!fir.array<5xi32>>
+! CHECK-SAME:    %[[ARG0:.*]]: !fir.class<!fir.array<5x!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>> {fir.bindc_name = "p"}
+! CHECK:         %[[P:.*]]:2 = hlfir.declare %[[ARG0]]
+! CHECK:         hlfir.elemental
 
   subroutine test_elemental_poly_array_2d(p)
     class(p1) :: p(5,5)
     print *, p%elemental_fct()
   end subroutine
-
 ! CHECK-LABEL: func.func @_QMpolymorphic_testPtest_elemental_poly_array_2d(
-! CHECK-SAME: %[[P]]: !fir.class<!fir.array<5x5x!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>> {fir.bindc_name = "p"}) {
-! CHECK: %[[C5:.*]] = arith.constant 5 : index
-! CHECK: %[[C5_0:.*]] = arith.constant 5 : index
-! CHECK: %[[TMP:.*]] = fir.allocmem !fir.array<5x5xi32>
-! CHECK: %[[SHAPE:.*]] = fir.shape %[[C5]], %[[C5_0]] : (index, index) -> !fir.shape<2>
-! CHECK: %[[ARRAY_LOAD_TMP:.*]] = fir.array_load %[[TMP]](%[[SHAPE]]) : (!fir.heap<!fir.array<5x5xi32>>, !fir.shape<2>) -> !fir.array<5x5xi32>
-! CHECK: %[[C1:.*]] = arith.constant 1 : index
-! CHECK: %[[C0:.*]] = arith.constant 0 : index
-! CHECK: %[[UB0:.*]] = arith.subi %[[C5]], %[[C1]] : index
-! CHECK: %[[UB1:.*]] = arith.subi %[[C5_0]], %[[C1]] : index
-! CHECK: %[[LOOP_RES:.*]] = fir.do_loop %[[IND0:.*]] = %[[C0]] to %[[UB1]] step %[[C1]] unordered iter_args(%[[ARG:.*]] = %[[ARRAY_LOAD_TMP]]) -> (!fir.array<5x5xi32>) {
-! CHECK:   %[[LOOP_RES0:.*]] = fir.do_loop %[[IND1:.*]] = %[[C0]] to %[[UB0]] step %[[C1]] unordered iter_args(%[[ARG0:.*]] = %[[ARG]]) -> (!fir.array<5x5xi32>) {
-! CHECK:     %[[COORD:.*]] = fir.coordinate_of %[[P]], %[[IND1]], %[[IND0]] : (!fir.class<!fir.array<5x5x!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>>, index, index) -> !fir.ref<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>
-! CHECK:     %[[EMBOXED:.*]] = fir.embox %[[COORD]] source_box %[[P]] : (!fir.ref<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>, !fir.class<!fir.array<5x5x!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>>) -> !fir.class<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>
-! CHECK:     %[[RES:.*]] = fir.dispatch "elemental_fct"(%[[EMBOXED]] : !fir.class<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>) (%[[EMBOXED]] : !fir.class<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>) -> i32 proc_attrs <elemental, pure> {pass_arg_pos = 0 : i32}
-! CHECK:     %[[ARR_UP:.*]] = fir.array_update %[[ARG0]], %[[RES]], %[[IND1]], %[[IND0]] : (!fir.array<5x5xi32>, i32, index, index) -> !fir.array<5x5xi32>
-! CHECK:     fir.result %[[ARR_UP]] : !fir.array<5x5xi32>
-! CHECK:   }
-! CHECK:   fir.result %[[LOOP_RES0]] : !fir.array<5x5xi32>
-! CHECK: }
-! CHECK: fir.array_merge_store %[[ARRAY_LOAD_TMP]], %[[LOOP_RES]] to %[[TMP]] : !fir.array<5x5xi32>, !fir.array<5x5xi32>, !fir.heap<!fir.array<5x5xi32>>
-! CHECK: %[[SHAPE:.*]] = fir.shape %[[C5]], %[[C5_0]] : (index, index) -> !fir.shape<2>
-! CHECK: %[[EMBOXED_TMP:.*]] = fir.embox %[[TMP]](%[[SHAPE]]) : (!fir.heap<!fir.array<5x5xi32>>, !fir.shape<2>) -> !fir.box<!fir.array<5x5xi32>>
-! CHECK: %[[BOX_NONE:.*]] = fir.convert %[[EMBOXED_TMP]] : (!fir.box<!fir.array<5x5xi32>>) -> !fir.box<none>
-! CHECK: %{{.*}} = fir.call @_FortranAioOutputDescriptor(%{{.*}}, %[[BOX_NONE]]) fastmath<contract> : (!fir.ref<i8>, !fir.box<none>) -> i1
-! CHECK: fir.freemem %[[TMP]] : !fir.heap<!fir.array<5x5xi32>>
+! CHECK-SAME:    %[[ARG0:.*]]: !fir.class<!fir.array<5x5x!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>> {fir.bindc_name = "p"}
+! CHECK:         %[[P:.*]]:2 = hlfir.declare %[[ARG0]]
 
   subroutine test_elemental_sub_array()
     type(p1) :: t(10)
     call t%elemental_sub()
     call t%elemental_sub_pass(2)
   end subroutine
-
 ! CHECK-LABEL: func.func @_QMpolymorphic_testPtest_elemental_sub_array() {
-! CHECK: %[[C10:.*]] = arith.constant 10 : index
-! CHECK: %[[T:.*]] = fir.alloca !fir.array<10x!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>> {bindc_name = "t", uniq_name = "_QMpolymorphic_testFtest_elemental_sub_arrayEt"}
-! CHECK: %[[C1:.*]] = arith.constant 1 : index
-! CHECK: %[[C0:.*]] = arith.constant 0 : index
-! CHECK: %[[UB:.*]] = arith.subi %[[C10]], %[[C1]] : index
-! CHECK: fir.do_loop %[[IND:.*]] = %[[C0]] to %[[UB]] step %[[C1]] {
-! CHECK:   %[[COORD:.*]] = fir.coordinate_of %[[T]], %[[IND]] : (!fir.ref<!fir.array<10x!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>>, index) -> !fir.ref<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>
-! CHECK:   %[[EMBOXED:.*]] = fir.embox %[[COORD]] : (!fir.ref<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>) -> !fir.class<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>
-! CHECK:   fir.call @_QMpolymorphic_testPelemental_sub(%[[EMBOXED]]) {{.*}} : (!fir.class<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>) -> ()
-! CHECK: }
-! CHECK: %[[C1:.*]] = arith.constant 1 : index
-! CHECK: %[[C0:.*]] = arith.constant 0 : index
-! CHECK: %[[UB:.*]] = arith.subi %[[C10]], %[[C1]] : index
-! CHECK: fir.do_loop %[[IND:.*]] = %[[C0]] to %[[UB]] step %[[C1]] {
-! CHECK:   %[[COORD:.*]] = fir.coordinate_of %[[T]], %[[IND]] : (!fir.ref<!fir.array<10x!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>>, index) -> !fir.ref<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>
-! CHECK:   %[[EMBOXED:.*]] = fir.embox %[[COORD]] : (!fir.ref<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>) -> !fir.class<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>
-! CHECK:   fir.call @_QMpolymorphic_testPelemental_sub_pass(%{{.*}}, %[[EMBOXED]]) {{.*}} : (!fir.ref<i32>, !fir.class<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>) -> ()
-! CHECK: }
+! CHECK:         %[[T:.*]]:2 = hlfir.declare %{{.*}} {uniq_name = "_QMpolymorphic_testFtest_elemental_sub_arrayEt"}
 
   subroutine test_elemental_sub_poly_array(p)
     class(p1) :: p(10)
     call p%elemental_sub()
     call p%elemental_sub_pass(3)
   end subroutine
-
 ! CHECK-LABEL: func.func @_QMpolymorphic_testPtest_elemental_sub_poly_array(
-! CHECK-SAME: %[[P:.*]]: !fir.class<!fir.array<10x!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>> {fir.bindc_name = "p"}) {
-! CHECK: %[[C10:.*]] = arith.constant 10 : index
-! CHECK: %[[C1:.*]] = arith.constant 1 : index
-! CHECK: %[[C0:.*]] = arith.constant 0 : index
-! CHECK: %[[UB:.*]] = arith.subi %[[C10]], %[[C1]] : index
-! CHECK: fir.do_loop %[[IND:.*]] = %[[C0]] to %[[UB]] step %[[C1]] {
-! CHECK:   %[[COORD:.*]] = fir.coordinate_of %[[P]], %[[IND]] : (!fir.class<!fir.array<10x!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>>, index) -> !fir.ref<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>
-! CHECK:   %[[EMBOXED:.*]] = fir.embox %[[COORD]] source_box %[[P]] : (!fir.ref<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>, !fir.class<!fir.array<10x!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>>) -> !fir.class<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>
-! CHECK:   fir.dispatch "elemental_sub"(%[[EMBOXED]] : !fir.class<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>) (%[[EMBOXED]] : !fir.class<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>) proc_attrs <elemental, pure> {pass_arg_pos = 0 : i32}
-! CHECK: }
-! CHECK: %[[C1:.*]] = arith.constant 1 : index
-! CHECK: %[[C0:.*]] = arith.constant 0 : index
-! CHECK: %[[UB:.*]] = arith.subi %[[C10]], %[[C1]] : index
-! CHECK: fir.do_loop %[[IND:.*]] = %[[C0]] to %[[UB]] step %[[C1]] {
-! CHECK:   %[[COORD:.*]] = fir.coordinate_of %[[P]], %[[IND]] : (!fir.class<!fir.array<10x!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>>, index) -> !fir.ref<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>
-! CHECK:   %[[EMBOXED:.*]] = fir.embox %[[COORD]] source_box %[[P]] : (!fir.ref<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>, !fir.class<!fir.array<10x!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>>) -> !fir.class<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>
-! CHECK:   fir.dispatch "elemental_sub_pass"(%[[EMBOXED]] : !fir.class<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>) (%{{.*}}, %[[EMBOXED]] : !fir.ref<i32>, !fir.class<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>) proc_attrs <elemental, pure> {pass_arg_pos = 1 : i32}
-! CHECK: }
+! CHECK-SAME:    %[[ARG0:.*]]: !fir.class<!fir.array<10x!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>> {fir.bindc_name = "p"}
 
   subroutine test_elemental_sub_array_assumed(t)
     type(p1) :: t(:)
     call t%elemental_sub()
     call t%elemental_sub_pass(4)
   end subroutine
-
 ! CHECK-LABEL: func.func @_QMpolymorphic_testPtest_elemental_sub_array_assumed(
-! CHECK-SAME: %[[T:.*]]: !fir.box<!fir.array<?x!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>> {fir.bindc_name = "t"}) {
-! CHECK: %[[C0:.*]] = arith.constant 0 : index
-! CHECK: %[[T_DIMS:.*]]:3 = fir.box_dims %[[T]], %[[C0]] : (!fir.box<!fir.array<?x!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>>, index) -> (index, index, index)
-! CHECK: %[[C1:.*]] = arith.constant 1 : index
-! CHECK: %[[C0:.*]] = arith.constant 0 : index
-! CHECK: %[[UB:.*]] = arith.subi %[[T_DIMS]]#1, %[[C1]] : index
-! CHECK: fir.do_loop %[[IND:.*]] = %[[C0]] to %[[UB]] step %[[C1]] {
-! CHECK:  %[[COORD:.*]] = fir.coordinate_of %[[T]], %[[IND]] : (!fir.box<!fir.array<?x!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>>, index) -> !fir.ref<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>
-! CHECK:  %[[EMBOXED:.*]] = fir.embox %[[COORD]] : (!fir.ref<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>) -> !fir.class<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>
-! CHECK: fir.call @_QMpolymorphic_testPelemental_sub(%[[EMBOXED]]) {{.*}} : (!fir.class<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>) -> ()
-! CHECK: %[[C0:.*]] = arith.constant 0 : index
-! CHECK: %[[T_DIMS:.*]]:3 = fir.box_dims %[[T]], %[[C0]] : (!fir.box<!fir.array<?x!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>>, index) -> (index, index, index)
-! CHECK: %[[C1:.*]] = arith.constant 1 : index
-! CHECK: %[[C0:.*]] = arith.constant 0 : index
-! CHECK: %[[UB:.*]] = arith.subi %[[T_DIMS]]#1, %[[C1]] : index
-! CHECK: fir.do_loop %[[IND:.*]] = %[[C0]] to %[[UB]] step %[[C1]] {
-! CHECK:  %[[COORD:.*]] = fir.coordinate_of %[[T]], %[[IND]] : (!fir.box<!fir.array<?x!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>>, index) -> !fir.ref<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>
-! CHECK:  %[[EMBOXED:.*]] = fir.embox %[[COORD]] : (!fir.ref<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>) -> !fir.class<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>
-! CHECK:  fir.call @_QMpolymorphic_testPelemental_sub_pass(%{{.*}}, %[[EMBOXED]]) {{.*}} : (!fir.ref<i32>, !fir.class<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>) -> ()
-! CHECK: }
+! CHECK-SAME:    %[[ARG0:.*]]: !fir.box<!fir.array<?x!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>> {fir.bindc_name = "t"}
 
   subroutine test_elemental_sub_poly_array_assumed(p)
     class(p1) :: p(:)
     call p%elemental_sub()
     call p%elemental_sub_pass(5)
   end subroutine
-
 ! CHECK-LABEL: func.func @_QMpolymorphic_testPtest_elemental_sub_poly_array_assumed(
-! CHECK-SAME: %[[P:.*]]: !fir.class<!fir.array<?x!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>> {fir.bindc_name = "p"}) {
-! CHECK: %[[C0:.*]] = arith.constant 0 : index
-! CHECK: %[[P_DIMS:.*]]:3 = fir.box_dims %[[P]], %[[C0]] : (!fir.class<!fir.array<?x!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>>, index) -> (index, index, index)
-! CHECK: %[[C1:.*]] = arith.constant 1 : index
-! CHECK: %[[C0:.*]] = arith.constant 0 : index
-! CHECK: %[[UB:.*]] = arith.subi %[[P_DIMS]]#1, %[[C1]] : index
-! CHECK: fir.do_loop %[[IND:.*]] = %[[C0]] to %[[UB]] step %[[C1]] {
-! CHECK:   %[[COORD:.*]] = fir.coordinate_of %[[P]], %[[IND]] : (!fir.class<!fir.array<?x!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>>, index) -> !fir.ref<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>
-! CHECK:   %[[EMBOXED:.*]] = fir.embox %[[COORD]] source_box %[[P]] : (!fir.ref<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>, !fir.class<!fir.array<?x!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>>) -> !fir.class<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>
-! CHECK:   fir.dispatch "elemental_sub"(%[[EMBOXED]] : !fir.class<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>) (%[[EMBOXED]] : !fir.class<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>) proc_attrs <elemental, pure> {pass_arg_pos = 0 : i32}
-! CHECK: }
-! CHECK: %[[C0:.*]] = arith.constant 0 : index
-! CHECK: %[[P_DIMS:.*]]:3 = fir.box_dims %[[P]], %[[C0]] : (!fir.class<!fir.array<?x!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>>, index) -> (index, index, index)
-! CHECK: %[[C1:.*]] = arith.constant 1 : index
-! CHECK: %[[C0:.*]] = arith.constant 0 : index
-! CHECK: %[[UB:.*]] = arith.subi %[[P_DIMS]]#1, %[[C1]] : index
-! CHECK: fir.do_loop %[[IND:.*]] = %[[C0]] to %[[UB]] step %[[C1]] {
-! CHECK:   %[[COORD:.*]] = fir.coordinate_of %[[P]], %[[IND]] : (!fir.class<!fir.array<?x!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>>, index) -> !fir.ref<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>
-! CHECK:   %[[EMBOXED:.*]] = fir.embox %[[COORD]] source_box %[[P]] : (!fir.ref<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>, !fir.class<!fir.array<?x!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>>) -> !fir.class<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>
-! CHECK:   fir.dispatch "elemental_sub_pass"(%[[EMBOXED]] : !fir.class<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>) (%{{.*}}, %[[EMBOXED]] : !fir.ref<i32>, !fir.class<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>) proc_attrs <elemental, pure> {pass_arg_pos = 1 : i32}
-! CHECK: }
+! CHECK-SAME:    %[[ARG0:.*]]: !fir.class<!fir.array<?x!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>> {fir.bindc_name = "p"}
+
 
   subroutine write_p1(dtv, unit, iotype, v_list, iostat, iomsg)
     class(p1), intent(in) :: dtv
@@ -744,6 +549,8 @@ subroutine write_p1(dtv, unit, iotype, v_list, iostat, iomsg)
     character(*), intent(inout) :: iomsg
     ! dummy subroutine for testing purpose
   end subroutine
+! CHECK-LABEL: func.func @_QMpolymorphic_testPwrite_p1(
+! CHECK-SAME:    %[[ARG0:.*]]: !fir.class<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>> {fir.bindc_name = "dtv"}
 
   subroutine read_p1(dtv, unit, iotype, v_list, iostat, iomsg)
     class(p1), intent(inout) :: dtv
@@ -754,6 +561,8 @@ subroutine read_p1(dtv, unit, iotype, v_list, iostat, iomsg)
     character(*), intent(inout) :: iomsg
     ! dummy subroutine for testing purpose
   end subroutine
+! CHECK-LABEL: func.func @_QMpolymorphic_testPread_p1(
+! CHECK-SAME:    %[[ARG0:.*]]: !fir.class<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>> {fir.bindc_name = "dtv"}
 
   subroutine test_polymorphic_io()
     type(p1), target :: t
@@ -765,16 +574,16 @@ subroutine test_polymorphic_io()
     rewind(17)
     read(17, 1) p
   end subroutine
-
 ! CHECK-LABEL: func.func @_QMpolymorphic_testPtest_polymorphic_io() {
-! CHECK: %[[P:.*]] = fir.alloca !fir.class<!fir.ptr<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>> {bindc_name = "p", uniq_name = "_QMpolymorphic_testFtest_polymorphic_ioEp"}
-! CHECK: %[[LOAD_P:.*]] = fir.load %[[P]] : !fir.ref<!fir.class<!fir.ptr<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>>>
-! CHECK: %[[BOX_NONE:.*]] = fir.convert %[[LOAD_P]] : (!fir.class<!fir.ptr<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>>) -> !fir.box<none>
-! CHECK: %{{.*}} = fir.call @_FortranAioInputDerivedType(%{{.*}}, %[[BOX_NONE]], %{{.*}}) {{.*}} : (!fir.ref<i8>, !fir.box<none>, !fir.ref<none>) -> i1
+! CHECK:         %[[P:.*]]:2 = hlfir.declare %{{.*}} {fortran_attrs = #fir.var_attrs<pointer>, uniq_name = "_QMpolymorphic_testFtest_polymorphic_ioEp"}
+! CHECK:         %[[T:.*]]:2 = hlfir.declare %{{.*}} {fortran_attrs = #fir.var_attrs<target>, uniq_name = "_QMpolymorphic_testFtest_polymorphic_ioEt"}
+! CHECK:         fir.call @_FortranAioOutputDerivedType(
+
 
   function unlimited_polymorphic_alloc_array_ret()
     class(*), allocatable :: unlimited_polymorphic_alloc_array_ret(:)
   end function
+! CHECK-LABEL: func.func @_QMpolymorphic_testPunlimited_polymorphic_alloc_array_ret() -> !fir.class<!fir.heap<!fir.array<?xnone>>>
 
   subroutine test_unlimited_polymorphic_alloc_array_ret()
     select type (a => unlimited_polymorphic_alloc_array_ret())
@@ -782,219 +591,147 @@ subroutine test_unlimited_polymorphic_alloc_array_ret()
         print*, 'type is real'
     end select
   end subroutine
-
 ! CHECK-LABEL: func.func @_QMpolymorphic_testPtest_unlimited_polymorphic_alloc_array_ret() {
-! CHECK: %[[RES_TMP:.*]] = fir.alloca !fir.class<!fir.heap<!fir.array<?xnone>>> {bindc_name = ".result"}
-! CHECK: %[[RES:.*]] = fir.call @_QMpolymorphic_testPunlimited_polymorphic_alloc_array_ret() fastmath<contract> : () -> !fir.class<!fir.heap<!fir.array<?xnone>>>
-! CHECK: fir.save_result %[[RES]] to %[[RES_TMP]] : !fir.class<!fir.heap<!fir.array<?xnone>>>, !fir.ref<!fir.class<!fir.heap<!fir.array<?xnone>>>>
+! CHECK:         %{{.*}} = fir.call @_QMpolymorphic_testPunlimited_polymorphic_alloc_array_ret()
+! CHECK:         fir.select_type %{{.*}} : !fir.class<!fir.array<?xnone>>
+
 
   subroutine test_unlimited_polymorphic_intentout(a)
     class(*), intent(out) :: a
   end subroutine
-
 ! CHECK-LABEL: func.func @_QMpolymorphic_testPtest_unlimited_polymorphic_intentout(
-! CHECK-SAME: %[[ARG0:.*]]: !fir.class<none> {fir.bindc_name = "a"}) {
-! CHECK: %[[BOX_NONE:.*]] = fir.convert %[[ARG0]] : (!fir.class<none>) -> !fir.box<none>
-! CHECK: fir.call @_FortranADestroy(%[[BOX_NONE]]) {{.*}} : (!fir.box<none>) -> ()
-! CHECK: %[[BOX_NONE:.*]] = fir.convert %[[ARG0]] : (!fir.class<none>) -> !fir.box<none>
-! CHECK: fir.call @_FortranAInitialize(%[[BOX_NONE]], %{{.*}}, %{{.*}}) {{.*}} : (!fir.box<none>, !fir.ref<i8>, i32) -> ()
+! CHECK-SAME:    %[[ARG0:.*]]: !fir.class<none> {fir.bindc_name = "a"}
 
   subroutine test_polymorphic_intentout(a)
     class(p1), intent(out) :: a
   end subroutine
-
 ! CHECK-LABEL: func.func @_QMpolymorphic_testPtest_polymorphic_intentout(
-! CHECK-SAME: %[[ARG0:.*]]: !fir.class<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>> {fir.bindc_name = "a"}) {
-! CHECK: %[[BOX_NONE:.*]] = fir.convert %[[ARG0]] : (!fir.class<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>) -> !fir.box<none>
-! CHECK: fir.call @_FortranADestroy(%[[BOX_NONE]]) {{.*}} : (!fir.box<none>) -> ()
-! CHECK: %[[BOX_NONE:.*]] = fir.convert %[[ARG0]] : (!fir.class<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>) -> !fir.box<none>
-! CHECK: fir.call @_FortranAInitialize(%[[BOX_NONE]], %{{.*}}, %{{.*}}) {{.*}} : (!fir.box<none>, !fir.ref<i8>, i32) -> ()
+! CHECK-SAME:    %[[ARG0:.*]]: !fir.class<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>> {fir.bindc_name = "a"}
 
   subroutine rebox_up_to_record_type(p)
     class(*), allocatable, target :: p(:,:)
     type(non_extensible), pointer :: t(:,:)
     t => p
   end subroutine
-
 ! CHECK-LABEL: func.func @_QMpolymorphic_testPrebox_up_to_record_type(
-! CHECK-SAME: %[[P:.*]]: !fir.ref<!fir.class<!fir.heap<!fir.array<?x?xnone>>>> {fir.bindc_name = "p", fir.target}) {
-! CHECK: %[[T:.*]] = fir.alloca !fir.box<!fir.ptr<!fir.array<?x?x!fir.type<_QMpolymorphic_testTnon_extensible{{(,sequence)?}}{d:i32}>>>> {bindc_name = "t", uniq_name = "_QMpolymorphic_testFrebox_up_to_record_typeEt"}
-! CHECK: %[[LOAD_P:.*]] = fir.load %[[P]] : !fir.ref<!fir.class<!fir.heap<!fir.array<?x?xnone>>>>
-! CHECK: %[[REBOX:.*]] = fir.rebox %[[LOAD_P]](%{{.*}}) : (!fir.class<!fir.heap<!fir.array<?x?xnone>>>, !fir.shift<2>) -> !fir.box<!fir.ptr<!fir.array<?x?x!fir.type<_QMpolymorphic_testTnon_extensible{{(,sequence)?}}{d:i32}>>>>
-! CHECK: fir.store %[[REBOX]] to %[[T]] : !fir.ref<!fir.box<!fir.ptr<!fir.array<?x?x!fir.type<_QMpolymorphic_testTnon_extensible{{(,sequence)?}}{d:i32}>>>>>
+! CHECK-SAME:    %[[ARG0:.*]]: !fir.ref<!fir.class<!fir.heap<!fir.array<?x?xnone>>>> {{{.*}}, fir.target}
+! CHECK:         %[[P:.*]]:2 = hlfir.declare %[[ARG0]]
+! CHECK:         %[[T:.*]]:2 = hlfir.declare %{{.*}} {fortran_attrs = #fir.var_attrs<pointer>, uniq_name = "_QMpolymorphic_testFrebox_up_to_record_typeEt"}
+
 
   subroutine sub_with_poly_optional(a)
     class(*), optional :: a
   end subroutine
+! CHECK-LABEL: func.func @_QMpolymorphic_testPsub_with_poly_optional(
+! CHECK-SAME:    %[[ARG0:.*]]: !fir.class<none> {fir.bindc_name = "a", fir.optional}
 
   subroutine test_call_with_null()
     call sub_with_poly_optional(null())
   end subroutine
-
 ! CHECK-LABEL: func.func @_QMpolymorphic_testPtest_call_with_null() {
-! CHECK: %[[NULL_PTR:.*]] = fir.alloca !fir.box<!fir.ptr<none>>
-! CHECK: %[[NULL:.*]] = fir.zero_bits !fir.ptr<none>
-! CHECK: %[[NULL_BOX:.*]] = fir.embox %[[NULL]] : (!fir.ptr<none>) -> !fir.box<!fir.ptr<none>>
-! CHECK: fir.store %[[NULL_BOX]] to %[[NULL_PTR]] : !fir.ref<!fir.box<!fir.ptr<none>>>
-! CHECK: %[[BOX_NONE:.*]] = fir.load %[[NULL_PTR]] : !fir.ref<!fir.box<!fir.ptr<none>>>
-! CHECK: %[[BOX_ADDR:.*]] = fir.box_addr %[[BOX_NONE]] : (!fir.box<!fir.ptr<none>>) -> !fir.ptr<none>
-! CHECK: %[[BOX_ADDR_I64:.*]] = fir.convert %[[BOX_ADDR]] : (!fir.ptr<none>) -> i64
-! CHECK: %[[C0:.*]] = arith.constant 0 : i64
-! CHECK: %[[IS_ALLOCATED_OR_ASSOCIATED:.*]] = arith.cmpi ne, %[[BOX_ADDR_I64]], %[[C0]] : i64
-! CHECK: %[[ABSENT:.*]] = fir.absent !fir.class<none>
-! CHECK: %[[PTR_LOAD2:.*]] = fir.load %[[NULL_PTR]] : !fir.ref<!fir.box<!fir.ptr<none>>>
-! CHECK: %[[CLASS_NONE:.*]] = fir.rebox %[[PTR_LOAD2]] : (!fir.box<!fir.ptr<none>>) -> !fir.class<none>
-! CHECK: %[[ARG:.*]] = arith.select %[[IS_ALLOCATED_OR_ASSOCIATED]], %[[CLASS_NONE]], %[[ABSENT]] : !fir.class<none>
-! CHECK: fir.call @_QMpolymorphic_testPsub_with_poly_optional(%[[ARG]]) {{.*}} : (!fir.class<none>) -> ()
+! CHECK:         fir.call @_QMpolymorphic_testPsub_with_poly_optional(
+
 
   subroutine sub_with_poly_array_optional(a)
     class(*), optional :: a(:)
   end subroutine
+! CHECK-LABEL: func.func @_QMpolymorphic_testPsub_with_poly_array_optional(
+! CHECK-SAME:    %[[ARG0:.*]]: !fir.class<!fir.array<?xnone>> {fir.bindc_name = "a", fir.optional}
 
   subroutine test_call_with_pointer_to_optional()
     real, pointer :: p(:)
     call sub_with_poly_array_optional(p)
   end subroutine
-
 ! CHECK-LABEL: func.func @_QMpolymorphic_testPtest_call_with_pointer_to_optional() {
-! CHECK: %[[P:.*]] = fir.alloca !fir.box<!fir.ptr<!fir.array<?xf32>>> {bindc_name = "p", uniq_name = "_QMpolymorphic_testFtest_call_with_pointer_to_optionalEp"}
-! CHECK: %[[IS_ALLOCATED_OR_ASSOCIATED:.*]] = arith.cmpi ne
-! CHECK: %[[ABSENT:.*]] = fir.absent !fir.class<!fir.array<?xnone>>
-! CHECK: %[[LOAD_P:.*]] = fir.load %[[P]] : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>
-! CHECK: %[[REBOX:.*]] = fir.rebox %[[LOAD_P]] : (!fir.box<!fir.ptr<!fir.array<?xf32>>>) -> !fir.class<!fir.array<?xnone>>
-! CHECK: %[[ARG:.*]] = arith.select %[[IS_ALLOCATED_OR_ASSOCIATED]], %[[REBOX]], %[[ABSENT]] : !fir.class<!fir.array<?xnone>>
-! CHECK: fir.call @_QMpolymorphic_testPsub_with_poly_array_optional(%[[ARG]]) {{.*}} : (!fir.class<!fir.array<?xnone>>) -> ()
+! CHECK:         %[[P:.*]]:2 = hlfir.declare %{{.*}} {fortran_attrs = #fir.var_attrs<pointer>, uniq_name = "_QMpolymorphic_testFtest_call_with_pointer_to_optionalEp"}
+! CHECK:         fir.call @_QMpolymorphic_testPsub_with_poly_array_optional(
+
 
   subroutine sub_with_real_pointer_optional(p)
     real, optional :: p(:)
     call sub_with_poly_array_optional(p)
   end subroutine
-
 ! CHECK-LABEL: func.func @_QMpolymorphic_testPsub_with_real_pointer_optional(
-! CHECK-SAME: %[[P:.*]]: !fir.box<!fir.array<?xf32>> {fir.bindc_name = "p", fir.optional}) {
-! CHECK: %[[IS_PRESENT:.*]] = fir.is_present %[[P]] : (!fir.box<!fir.array<?xf32>>) -> i1
-! CHECK: %[[BOX:.*]] = fir.if %[[IS_PRESENT]] -> (!fir.class<!fir.array<?xnone>>) {
-! CHECK:   %[[REBOX:.*]] = fir.rebox %[[P]] : (!fir.box<!fir.array<?xf32>>) -> !fir.class<!fir.array<?xnone>>
-! CHECK:   fir.result %[[REBOX]] : !fir.class<!fir.array<?xnone>>
-! CHECK: } else {
-! CHECK:   %[[ABSENT:.*]] = fir.absent !fir.class<!fir.array<?xnone>>
-! CHECK:   fir.result %[[ABSENT]] : !fir.class<!fir.array<?xnone>>
-! CHECK: }
-! CHECK: fir.call @_QMpolymorphic_testPsub_with_poly_array_optional(%[[BOX]]) {{.*}} : (!fir.class<!fir.array<?xnone>>) -> ()
 
   subroutine pass_poly_pointer_optional(p)
     class(p1), pointer, optional :: p
   end subroutine
+! CHECK-LABEL: func.func @_QMpolymorphic_testPpass_poly_pointer_optional(
+! CHECK-SAME:    %[[ARG0:.*]]: !fir.ref<!fir.class<!fir.ptr<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>>> {fir.bindc_name = "p", fir.optional}
 
   subroutine test_poly_pointer_null()
     call pass_poly_pointer_optional(null())
   end subroutine
-
 ! CHECK-LABEL: func.func @_QMpolymorphic_testPtest_poly_pointer_null() {
-! CHECK: %[[ALLOCA:.*]] = fir.alloca !fir.class<!fir.ptr<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>>
-! CHECK: %[[ZERO:.*]] = fir.zero_bits !fir.ptr<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>
-! CHECK: %[[EMBOX:.*]] = fir.embox %[[ZERO]] : (!fir.ptr<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>) -> !fir.class<!fir.ptr<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>>
-! CHECK: fir.store %[[EMBOX]] to %[[ALLOCA]] : !fir.ref<!fir.class<!fir.ptr<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>>>
-! CHECK: fir.call @_QMpolymorphic_testPpass_poly_pointer_optional(%[[ALLOCA]]) fastmath<contract> : (!fir.ref<!fir.class<!fir.ptr<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>>>) -> ()
+! CHECK:         fir.call @_QMpolymorphic_testPpass_poly_pointer_optional(
+
 
   subroutine test_poly_array_component_output(p)
     class(p1), pointer :: p(:)
     print*, p(:)%a
   end subroutine
-
 ! CHECK-LABEL: func.func @_QMpolymorphic_testPtest_poly_array_component_output(
-! CHECK-SAME: %[[P]]: !fir.ref<!fir.class<!fir.ptr<!fir.array<?x!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>>>> {fir.bindc_name = "p"}) {
-! CHECK: %[[LOAD_P:.*]] = fir.load %[[P]] : !fir.ref<!fir.class<!fir.ptr<!fir.array<?x!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>>>>
-! CHECK: %[[FIELD_INDEX_A:.*]] = fir.field_index a, !fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>
-! CHECK: %[[SLICE:.*]] = fir.slice %{{.*}}#0, %{{.*}}, %{{.*}} path %[[FIELD_INDEX_A]] : (index, index, index, !fir.field) -> !fir.slice<1>
-! CHECK: %[[REBOX:.*]] = fir.rebox %[[LOAD_P]](%{{.*}}) [%[[SLICE]]] : (!fir.class<!fir.ptr<!fir.array<?x!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>>>, !fir.shift<1>, !fir.slice<1>) -> !fir.box<!fir.array<?xi32>>
-! CHECK: %[[BOX_NONE:.*]] = fir.convert %[[REBOX]] : (!fir.box<!fir.array<?xi32>>) -> !fir.box<none>
-! CHECK: %{{.*}} = fir.call @_FortranAioOutputDescriptor(%{{.*}}, %[[BOX_NONE]]) fastmath<contract> : (!fir.ref<i8>, !fir.box<none>) -> i1
+! CHECK-SAME:    %[[ARG0:.*]]: !fir.ref<!fir.class<!fir.ptr<!fir.array<?x!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>>>> {fir.bindc_name = "p"}
+! CHECK:         %[[P:.*]]:2 = hlfir.declare %[[ARG0]]
+
 
   subroutine opt_int(i)
     integer, optional, intent(in) :: i
     call opt_up(i)
   end subroutine
-
 ! CHECK-LABEL: func.func @_QMpolymorphic_testPopt_int(
-! CHECK-SAME: %[[ARG0:.*]]: !fir.ref<i32> {fir.bindc_name = "i", fir.optional}) {
-! CHECK: %[[IS_PRESENT:.*]] = fir.is_present %[[ARG0]] : (!fir.ref<i32>) -> i1
-! CHECK: %[[ARG:.*]] = fir.if %[[IS_PRESENT]] -> (!fir.class<none>) {
-! CHECK:   %[[EMBOXED:.*]] = fir.embox %[[ARG0]] : (!fir.ref<i32>) -> !fir.class<none>
-! CHECK:   fir.result %[[EMBOXED]] : !fir.class<none>
-! CHECK: } else {
-! CHECK:   %[[ABSENT:.*]] = fir.absent !fir.class<none>
-! CHECK:   fir.result %[[ABSENT]] : !fir.class<none>
-! CHECK: }
-! CHECK: fir.call @_QMpolymorphic_testPopt_up(%[[ARG]]) fastmath<contract> : (!fir.class<none>) -> ()
+! CHECK-SAME:    %[[ARG0:.*]]: !fir.ref<i32> {fir.bindc_name = "i", fir.optional}
 
   subroutine opt_up(up)
     class(*), optional, intent(in) :: up
   end subroutine
+! CHECK-LABEL: func.func @_QMpolymorphic_testPopt_up(
+! CHECK-SAME:    %[[ARG0:.*]]: !fir.class<none> {fir.bindc_name = "up", fir.optional}
 
   function rhs()
     class(p1), pointer :: rhs
   end function
+! CHECK-LABEL: func.func @_QMpolymorphic_testPrhs() -> !fir.class<!fir.ptr<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>>
 
   subroutine test_rhs_assign(a)
     type(p1) :: a
     a = rhs()
   end subroutine
-
 ! CHECK-LABEL: func.func @_QMpolymorphic_testPtest_rhs_assign(
-! CHECK-SAME: %[[ARG0:.*]]: !fir.ref<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>> {fir.bindc_name = "a"}) {
-! CHECK: %[[RES:.*]] = fir.alloca !fir.class<!fir.ptr<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>> {bindc_name = ".result"}
-! CHECK: %[[A:.*]] = fir.embox %[[ARG0]] : (!fir.ref<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>) -> !fir.box<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>
-! CHECK: %[[LOAD_RES:.*]] = fir.load %[[RES]] : !fir.ref<!fir.class<!fir.ptr<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>>>
-! CHECK: %[[A_NONE:.*]] = fir.convert %[[A]] : (!fir.box<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>) -> !fir.ref<!fir.box<none>>
-! CHECK: %[[RES_NONE:.*]] = fir.convert %[[LOAD_RES]] : (!fir.class<!fir.ptr<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>>) -> !fir.box<none>
-! CHECK: fir.call @_FortranAAssign(%[[A_NONE]], %[[RES_NONE]], %{{.*}}, %{{.*}}) {{.*}} : (!fir.ref<!fir.box<none>>, !fir.box<none>, !fir.ref<i8>, i32) -> ()
+! CHECK-SAME:    %[[ARG0:.*]]: !fir.ref<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>> {fir.bindc_name = "a"}
+! CHECK:         %[[A:.*]]:2 = hlfir.declare %[[ARG0]]
+
 
   subroutine type_with_polymorphic_components(a, b)
     type(p4) :: a, b
     a = b
   end subroutine
-
 ! CHECK-LABEL: func.func @_QMpolymorphic_testPtype_with_polymorphic_components(
-! CHECK-SAME: %[[A:.*]]: !fir.ref<!fir.type<_QMpolymorphic_testTp4{{(,sequence)?}}{a:!fir.class<!fir.heap<!fir.array<?x!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>>>}>> {fir.bindc_name = "a"}, %[[B:.*]]: !fir.ref<!fir.type<_QMpolymorphic_testTp4{{(,sequence)?}}{a:!fir.class<!fir.heap<!fir.array<?x!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>>>}>> {fir.bindc_name = "b"}) {
-! CHECK: %[[ALLOCA:.*]] = fir.alloca !fir.box<!fir.type<_QMpolymorphic_testTp4{{(,sequence)?}}{a:!fir.class<!fir.heap<!fir.array<?x!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>>>}>>
-! CHECK: %[[EMBOX_A:.*]] = fir.embox %[[A]] : (!fir.ref<!fir.type<_QMpolymorphic_testTp4{{(,sequence)?}}{a:!fir.class<!fir.heap<!fir.array<?x!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>>>}>>) -> !fir.box<!fir.type<_QMpolymorphic_testTp4{{(,sequence)?}}{a:!fir.class<!fir.heap<!fir.array<?x!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>>>}>>
-! CHECK: %[[EMBOX_B:.*]] = fir.embox %[[B]] : (!fir.ref<!fir.type<_QMpolymorphic_testTp4{{(,sequence)?}}{a:!fir.class<!fir.heap<!fir.array<?x!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>>>}>>) -> !fir.box<!fir.type<_QMpolymorphic_testTp4{{(,sequence)?}}{a:!fir.class<!fir.heap<!fir.array<?x!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>>>}>>
-! CHECK: fir.store %[[EMBOX_A]] to %[[ALLOCA]] : !fir.ref<!fir.box<!fir.type<_QMpolymorphic_testTp4{{(,sequence)?}}{a:!fir.class<!fir.heap<!fir.array<?x!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>>>}>>>
-! CHECK: %[[BOX_NONE1:.*]] = fir.convert %[[ALLOCA]] : (!fir.ref<!fir.box<!fir.type<_QMpolymorphic_testTp4{{(,sequence)?}}{a:!fir.class<!fir.heap<!fir.array<?x!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>>>}>>>) -> !fir.ref<!fir.box<none>>
-! CHECK: %[[BOX_NONE2:.*]] = fir.convert %[[EMBOX_B]] : (!fir.box<!fir.type<_QMpolymorphic_testTp4{{(,sequence)?}}{a:!fir.class<!fir.heap<!fir.array<?x!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>>>}>>) -> !fir.box<none>
-! CHECK: fir.call @_FortranAAssign(%[[BOX_NONE1]], %[[BOX_NONE2]], %{{.*}}, %{{.*}}) {{.*}} : (!fir.ref<!fir.box<none>>, !fir.box<none>, !fir.ref<i8>, i32) -> ()
+! CHECK-SAME:    %[[ARG0:.*]]: !fir.ref<!fir.type<_QMpolymorphic_testTp4{a:!fir.class<!fir.heap<!fir.array<?x!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>>>}>> {fir.bindc_name = "a"}, %[[ARG1:.*]]: !fir.ref<!fir.type<_QMpolymorphic_testTp4{a:!fir.class<!fir.heap<!fir.array<?x!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>>>}>> {fir.bindc_name = "b"}
+
 
   subroutine up_pointer(p)
     class(*), pointer, intent(in) :: p
   end subroutine
+! CHECK-LABEL: func.func @_QMpolymorphic_testPup_pointer(
+! CHECK-SAME:    %[[ARG0:.*]]: !fir.ref<!fir.class<!fir.ptr<none>>> {fir.bindc_name = "p"}
 
   subroutine test_char_to_up_pointer(c)
     character(*), target :: c
     call up_pointer(c)
   end subroutine
-
 ! CHECK-LABEL: func.func @_QMpolymorphic_testPtest_char_to_up_pointer(
-! CHECK-SAME: %[[C:.*]]: !fir.boxchar<1> {fir.bindc_name = "c", fir.target}) {
-! CHECK: %[[NEW_BOX:.*]] = fir.alloca !fir.class<!fir.ptr<none>>
-! CHECK: %[[UNBOXCHAR:.*]]:2 = fir.unboxchar %arg0 : (!fir.boxchar<1>) -> (!fir.ref<!fir.char<1,?>>, index)
-! CHECK: %[[EMBOX:.*]] = fir.embox %[[UNBOXCHAR]]#0 typeparams %[[UNBOXCHAR]]#1 : (!fir.ref<!fir.char<1,?>>, index) -> !fir.class<!fir.ptr<none>>
-! CHECK: fir.store %[[EMBOX]] to %[[NEW_BOX]] : !fir.ref<!fir.class<!fir.ptr<none>>>
-! CHECK: fir.call @_QMpolymorphic_testPup_pointer(%[[NEW_BOX]]) {{.*}} : (!fir.ref<!fir.class<!fir.ptr<none>>>) -> ()
+! CHECK-SAME:    %[[ARG0:.*]]: !fir.boxchar<1> {fir.bindc_name = "c", fir.target}
+
 
   subroutine move_alloc_poly(a, b)
     class(p1), allocatable :: a, b
 
     call move_alloc(a, b)
   end subroutine
-
 ! CHECK-LABEL: func.func @_QMpolymorphic_testPmove_alloc_poly(
-! CHECK-SAME: %[[A:.*]]: !fir.ref<!fir.class<!fir.heap<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>>> {fir.bindc_name = "a"}, %[[B:.*]]: !fir.ref<!fir.class<!fir.heap<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>>> {fir.bindc_name = "b"}) {
-! CHECK: %[[TYPE_DESC:.*]] = fir.type_desc !fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>
-! CHECK: %[[B_CONV:.*]] = fir.convert %[[B]] : (!fir.ref<!fir.class<!fir.heap<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>>>) -> !fir.ref<!fir.box<none>>
-! CHECK: %[[A_CONV:.*]] = fir.convert %[[A]] : (!fir.ref<!fir.class<!fir.heap<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>>>) -> !fir.ref<!fir.box<none>>
-! CHECK: %[[TYPE_DESC_CONV:.*]] = fir.convert %[[TYPE_DESC]] : (!fir.tdesc<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>) -> !fir.ref<none>
-! CHECK: %{{.*}} = fir.call @_FortranAMoveAlloc(%[[B_CONV]], %[[A_CONV]], %[[TYPE_DESC_CONV]], %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}) {{.*}} : (!fir.ref<!fir.box<none>>, !fir.ref<!fir.box<none>>, !fir.ref<none>, i1, !fir.box<none>, !fir.ref<i8>, i32) -> i32
+! CHECK:         fir.call @_FortranAMoveAlloc(
+
 
   subroutine test_parent_comp_in_select_type(s)
     class(p1), allocatable :: s
@@ -1007,32 +744,18 @@ subroutine test_parent_comp_in_select_type(s)
         s%p1 = p
     end select
   end subroutine
-
 ! CHECK-LABEL: func.func @_QMpolymorphic_testPtest_parent_comp_in_select_type(
-! CHECK-SAME: %[[S:.*]]: !fir.ref<!fir.class<!fir.heap<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>>> {fir.bindc_name = "s"}) {
-! CHECK:  %[[P:.*]] = fir.alloca !fir.class<!fir.heap<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>> {bindc_name = "p", uniq_name = "_QMpolymorphic_testFtest_parent_comp_in_select_typeEp"}
-! CHECK:  %[[LOAD_S:.*]] = fir.load %[[S]] : !fir.ref<!fir.class<!fir.heap<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>>>
-! CHECK:  fir.select_type %[[LOAD_S]] : !fir.class<!fir.heap<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>> [#fir.type_is<!fir.type<_QMpolymorphic_testTp2{{(,sequence)?}}{a:i32,b:i32,c:f32}>>, ^bb1, unit, ^bb2]
-! CHECK: ^bb1:
-! CHECK:  %[[CONV_S:.*]] = fir.box_addr %[[LOAD_S]] : (!fir.class<!fir.heap<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>>) -> !fir.ref<!fir.type<_QMpolymorphic_testTp2{{(,sequence)?}}{a:i32,b:i32,c:f32}>>
-! CHECK:  %[[EMBOX_P1:.*]] = fir.embox %[[CONV_S]] : (!fir.ref<!fir.type<_QMpolymorphic_testTp2{{(,sequence)?}}{a:i32,b:i32,c:f32}>>) -> !fir.box<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>
-! CHECK:  %[[LOAD_P:.*]] = fir.load %[[P]] : !fir.ref<!fir.class<!fir.heap<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>>>
-! CHECK:  %[[LHS_CONV:.*]] = fir.convert %[[EMBOX_P1]] : (!fir.box<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>) -> !fir.ref<!fir.box<none>>
-! CHECK:  %[[RHS_CONV:.*]] = fir.convert %[[LOAD_P]] : (!fir.class<!fir.heap<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>>) -> !fir.box<none>
-! CHECK:  fir.call @_FortranAAssign(%[[LHS_CONV]], %[[RHS_CONV]], %{{.*}}, %{{.*}}) {{.*}} : (!fir.ref<!fir.box<none>>, !fir.box<none>, !fir.ref<i8>, i32) -> ()
+! CHECK:         fir.select_type
+
 
   subroutine move_alloc_unlimited_poly(a, b)
     class(*), allocatable :: a, b
 
     call move_alloc(a, b)
   end subroutine
-
 ! CHECK-LABEL: func.func @_QMpolymorphic_testPmove_alloc_unlimited_poly(
-! CHECK-SAME: %[[A:.*]]: !fir.ref<!fir.class<!fir.heap<none>>> {fir.bindc_name = "a"}, %[[B:.*]]: !fir.ref<!fir.class<!fir.heap<none>>> {fir.bindc_name = "b"}) {
-! CHECK: %[[NULL:.*]] = fir.zero_bits !fir.ref<none>
-! CHECK: %[[B_CONV:.*]] = fir.convert %[[B]] : (!fir.ref<!fir.class<!fir.heap<none>>>) -> !fir.ref<!fir.box<none>>
-! CHECK: %[[A_CONV:.*]] = fir.convert %[[A]] : (!fir.ref<!fir.class<!fir.heap<none>>>) -> !fir.ref<!fir.box<none>>
-! CHECK: %{{.*}} = fir.call @_FortranAMoveAlloc(%[[B_CONV]], %[[A_CONV]], %[[NULL]], %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}) {{.*}} : (!fir.ref<!fir.box<none>>, !fir.ref<!fir.box<none>>, !fir.ref<none>, i1, !fir.box<none>, !fir.ref<i8>, i32) -> i32
+! CHECK:         fir.call @_FortranAMoveAlloc(
+
 
   subroutine test_parent_comp_intrinsic(a, b)
     class(p1) :: a
@@ -1041,45 +764,46 @@ subroutine test_parent_comp_intrinsic(a, b)
 
     c = same_type_as(a, b%p1)
   end subroutine
-
 ! CHECK-LABEL: func.func @_QMpolymorphic_testPtest_parent_comp_intrinsic(
-! CHECK-SAME: %[[ARG0:.*]]: !fir.class<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>> {fir.bindc_name = "a"}, %[[ARG1:.*]]: !fir.ref<!fir.box<!fir.heap<!fir.type<_QMpolymorphic_testTp2{{(,sequence)?}}{a:i32,b:i32,c:f32}>>>> {fir.bindc_name = "b"}) {
-! CHECK: %[[LOAD_ARG1:.*]] = fir.load %[[ARG1]] : !fir.ref<!fir.box<!fir.heap<!fir.type<_QMpolymorphic_testTp2{{(,sequence)?}}{a:i32,b:i32,c:f32}>>>>
-! CHECK: %[[REBOX_ARG1:.*]] = fir.rebox %[[LOAD_ARG1]] : (!fir.box<!fir.heap<!fir.type<_QMpolymorphic_testTp2{{(,sequence)?}}{a:i32,b:i32,c:f32}>>>) -> !fir.box<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>
-! CHECK: %[[BOX_NONE_ARG0:.*]] = fir.convert %[[ARG0]] : (!fir.class<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>) -> !fir.box<none>
-! CHECK: %[[BOX_NONE_ARG1:.*]] = fir.convert %[[REBOX_ARG1]] : (!fir.box<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>) -> !fir.box<none>
-! CHECK: %{{.*}} = fir.call @_FortranASameTypeAs(%[[BOX_NONE_ARG0]], %[[BOX_NONE_ARG1]]) {{.*}} : (!fir.box<none>, !fir.box<none>) -> i1
+! CHECK:         fir.call @_FortranASameTypeAs(
+
 
   subroutine test_parent_comp_normal(a)
     class(p2) :: a
 
     call print(a%p1)
   end subroutine
-
 ! CHECK-LABEL: func.func @_QMpolymorphic_testPtest_parent_comp_normal(
-! CHECK-SAME: %[[ARG0:.*]]: !fir.class<!fir.type<_QMpolymorphic_testTp2{{(,sequence)?}}{a:i32,b:i32,c:f32}>> {fir.bindc_name = "a"}) {
-! CHECK: %[[REBOX:.*]] = fir.rebox %[[ARG0]] : (!fir.class<!fir.type<_QMpolymorphic_testTp2{{(,sequence)?}}{a:i32,b:i32,c:f32}>>) -> !fir.box<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>
-! CHECK: %[[CONV:.*]] = fir.convert %[[REBOX]] : (!fir.box<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>) -> !fir.class<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>
-! CHECK: fir.call @_QMpolymorphic_testPprint(%[[CONV]]) {{.*}} : (!fir.class<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>) -> ()
+! CHECK-SAME:    %[[ARG0:.*]]: !fir.class<!fir.type<_QMpolymorphic_testTp2{p1:!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>,c:f32}>> {fir.bindc_name = "a"}
+! CHECK:         %[[A:.*]]:2 = hlfir.declare %[[ARG0]]{{.*}}{uniq_name = "_QMpolymorphic_testFtest_parent_comp_normalEa"}
+! CHECK:         %[[P1:.*]] = hlfir.designate %[[A]]#0{"p1"}{{.*}} : (!fir.class<!fir.type<_QMpolymorphic_testTp2{p1:!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>,c:f32}>>) -> !fir.ref<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>
+! CHECK:         %[[P1_BOX:.*]] = fir.embox %[[P1]] : (!fir.ref<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>) -> !fir.box<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>
+! CHECK:         %[[P1_CLASS:.*]] = fir.convert %[[P1_BOX]] : (!fir.box<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>) -> !fir.class<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>
+! CHECK:         fir.call @_QMpolymorphic_testPprint(%[[P1_CLASS]])
+
 
   subroutine takes_p1_opt(a)
     class(p1), optional :: a
   end subroutine
+! CHECK-LABEL: func.func @_QMpolymorphic_testPtakes_p1_opt(
+! CHECK-SAME:    %[[ARG0:.*]]: !fir.class<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>> {fir.bindc_name = "a", fir.optional}
 
   subroutine test_parent_comp_opt(p)
     type(p2), allocatable :: p
     allocate(p)
     call takes_p1_opt(p%p1)
   end subroutine
-
 ! CHECK-LABEL: func.func @_QMpolymorphic_testPtest_parent_comp_opt(
-! CHECK-SAME: %[[ARG0:.*]]: !fir.ref<!fir.box<!fir.heap<!fir.type<_QMpolymorphic_testTp2{{(,sequence)?}}{a:i32,b:i32,c:f32}>>>> {fir.bindc_name = "p"}) {
-! CHECK: %[[LOAD_ARG0:.*]] = fir.load %[[ARG0]] : !fir.ref<!fir.box<!fir.heap<!fir.type<_QMpolymorphic_testTp2{{(,sequence)?}}{a:i32,b:i32,c:f32}>>>>
-! CHECK: %[[RES:.*]] = fir.if %{{.*}} -> (!fir.box<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>) {
-! CHECK:   %[[REBOX:.*]] = fir.rebox %[[LOAD_ARG0:.*]] : (!fir.box<!fir.heap<!fir.type<_QMpolymorphic_testTp2{{(,sequence)?}}{a:i32,b:i32,c:f32}>>>) -> !fir.box<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>
-! CHECK:   fir.result %[[REBOX]] : !fir.box<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>
-! CHECK: %[[CONV:.*]] = fir.convert %[[RES]] : (!fir.box<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>) -> !fir.class<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>
-! CHECK: fir.call @_QMpolymorphic_testPtakes_p1_opt(%[[CONV]]) {{.*}} : (!fir.class<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>) -> ()
+! CHECK-SAME:    %[[ARG0:.*]]: !fir.ref<!fir.box<!fir.heap<!fir.type<_QMpolymorphic_testTp2{p1:!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>,c:f32}>>>> {fir.bindc_name = "p"}
+! CHECK:         %[[P:.*]]:2 = hlfir.declare %[[ARG0]]{{.*}}{fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QMpolymorphic_testFtest_parent_comp_optEp"}
+! CHECK:         %{{.*}} = fir.call @_FortranAAllocatableAllocate(
+! CHECK:         %[[P_LD:.*]] = fir.load %[[P]]#0
+! CHECK:         %[[P_ADDR:.*]] = fir.box_addr %[[P_LD]]
+! CHECK:         %[[P1:.*]] = hlfir.designate %[[P_ADDR]]{"p1"}
+! CHECK:         %[[P1_BOX:.*]] = fir.embox %[[P1]] : (!fir.ref<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>) -> !fir.box<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>
+! CHECK:         %[[P1_CLASS:.*]] = fir.convert %[[P1_BOX]] : (!fir.box<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>) -> !fir.class<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>
+! CHECK:         fir.call @_QMpolymorphic_testPtakes_p1_opt(%[[P1_CLASS]])
+
 
   subroutine class_with_entry(a)
     class(p1) :: a,b
@@ -1098,12 +822,16 @@ subroutine class_with_entry(a)
       print*,b%a
     end select
   end subroutine
-
 ! CHECK-LABEL: func.func @_QMpolymorphic_testPclass_with_entry(
-! CHECK-SAME: %[[A:.*]]: !fir.class<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>> {fir.bindc_name = "a"}) {
+! CHECK-SAME:    %[[A:.*]]: !fir.class<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>> {fir.bindc_name = "a"})
+! CHECK:         %[[B:.*]] = fir.alloca !fir.class<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>> {bindc_name = "b", uniq_name = "_QMpolymorphic_testFclass_with_entryEb"}
+! CHECK:         fir.select_type %{{.*}} : !fir.class<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>
 
 ! CHECK-LABEL: func.func @_QMpolymorphic_testPd(
-! CHECK-SAME: %[[B:.*]]: !fir.class<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>> {fir.bindc_name = "b"}) {
+! CHECK-SAME:    %[[B:.*]]: !fir.class<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>> {fir.bindc_name = "b"})
+! CHECK:         %[[A:.*]] = fir.alloca !fir.class<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>> {bindc_name = "a", uniq_name = "_QMpolymorphic_testFclass_with_entryEa"}
+! CHECK:         fir.select_type %{{.*}} : !fir.class<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>
+
 
   subroutine class_array_with_entry(a)
     class(p1) :: a(:), b(:)
@@ -1122,18 +850,22 @@ subroutine class_array_with_entry(a)
       print*,b%a
     end select
   end subroutine
-
 ! CHECK-LABEL: func.func @_QMpolymorphic_testPclass_array_with_entry(
-! CHECK-SAME: %[[A:.*]]: !fir.class<!fir.array<?x!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>> {fir.bindc_name = "a"}) {
-! CHECK: %[[B:.*]] = fir.alloca !fir.class<!fir.heap<!fir.array<?x!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>>>
+! CHECK-SAME:    %[[A:.*]]: !fir.class<!fir.array<?x!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>> {fir.bindc_name = "a"})
+! CHECK:         %[[B:.*]] = fir.alloca !fir.class<!fir.heap<!fir.array<?x!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>>>
+! CHECK:         fir.select_type %{{.*}} : !fir.class<!fir.array<?x!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>>
 
 ! CHECK-LABEL: func.func @_QMpolymorphic_testPg(
-! CHECK-SAME: %[[B:.*]]: !fir.class<!fir.array<?x!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>> {fir.bindc_name = "b"}) {
-! CHECK: %[[A:.*]] = fir.alloca !fir.class<!fir.heap<!fir.array<?x!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>>>
+! CHECK-SAME:    %[[B:.*]]: !fir.class<!fir.array<?x!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>> {fir.bindc_name = "b"})
+! CHECK:         %[[A:.*]] = fir.alloca !fir.class<!fir.heap<!fir.array<?x!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>>>
+! CHECK:         fir.select_type %{{.*}} : !fir.class<!fir.array<?x!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>>
+
 
   subroutine pass_up(up)
     class(*), intent(in) :: up
   end subroutine
+! CHECK-LABEL: func.func @_QMpolymorphic_testPpass_up(
+! CHECK-SAME:    %[[ARG0:.*]]: !fir.class<none> {fir.bindc_name = "up"}
 
 ! TODO: unlimited polymorphic temporary in lowering
 !  subroutine parenthesized_up(a)
@@ -1153,13 +885,3 @@ program test
   l = i < o%inner
 end program
 
-! CHECK-LABEL: func.func @_QQmain() attributes {fir.bindc_name = "TEST"} {
-! CHECK: %[[ADDR_O:.*]] = fir.address_of(@_QFEo) : !fir.ref<!fir.box<!fir.heap<!fir.type<_QMpolymorphic_testTouter{{(,sequence)?}}{inner:!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>}>>>>
-! CHECK: %[[BOX_NONE:.*]] = fir.convert %[[ADDR_O]] : (!fir.ref<!fir.box<!fir.heap<!fir.type<_QMpolymorphic_testTouter{{(,sequence)?}}{inner:!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>}>>>>) -> !fir.ref<!fir.box<none>>
-! CHECK: %{{.*}} = fir.call @_FortranAAllocatableAllocate(%[[BOX_NONE]], %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}) {{.*}} : (!fir.ref<!fir.box<none>>, !fir.ref<i64>, i1, !fir.box<none>, !fir.ref<i8>, i32, {{.*}}) -> i32
-! CHECK: %[[O:.*]] = fir.load %[[ADDR_O]] : !fir.ref<!fir.box<!fir.heap<!fir.type<_QMpolymorphic_testTouter{{(,sequence)?}}{inner:!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>}>>>>
-! CHECK: %[[COORD_INNER:.*]] = fir.coordinate_of %[[O]], inner : (!fir.box<!fir.heap<!fir.type<_QMpolymorphic_testTouter{{(,sequence)?}}{inner:!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>}>>>) -> !fir.ref<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>
-! CHECK: %{{.*}} = fir.do_loop %{{.*}} = %{{.*}} to %{{.*}} step %{{.*}} unordered iter_args(%arg1 = %{{.*}}) -> (!fir.array<5x!fir.logical<4>>) {
-! CHECK:   %[[EMBOXED:.*]] = fir.embox %[[COORD_INNER]] : (!fir.ref<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>) -> !fir.class<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>
-! CHECK:   %{{.*}} = fir.call @_QMpolymorphic_testPlt(%{{.*}}, %[[EMBOXED]]) {{.*}} : (!fir.ref<i32>, !fir.class<!fir.type<_QMpolymorphic_testTp1{{(,sequence)?}}{a:i32,b:i32}>>) -> !fir.logical<4>
-! CHECK:  }
diff --git a/flang/test/Lower/select-type.f90 b/flang/test/Lower/select-type.f90
index 871b084950688..fff685a9ca1fe 100644
--- a/flang/test/Lower/select-type.f90
+++ b/flang/test/Lower/select-type.f90
@@ -1,5 +1,5 @@
-! RUN: bbc -emit-fir -hlfir=false %s -o - | FileCheck %s
-! RUN: bbc -emit-fir -hlfir=false %s -o - | fir-opt --fir-polymorphic-op | FileCheck --check-prefix=CFG %s
+! RUN: %flang_fc1 -emit-hlfir %s -o - | FileCheck %s
+! RUN: %flang_fc1 -emit-hlfir %s -o - | fir-opt --fir-polymorphic-op | FileCheck --check-prefix=CFG %s
 module select_type_lower_test
   type p1
     integer :: a
@@ -55,49 +55,18 @@ subroutine select_type1(a)
   end subroutine
 
 ! CHECK-LABEL: func.func @_QMselect_type_lower_testPselect_type1(
-! CHECK-SAME: %[[ARG0:.*]]: !fir.class<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>> {fir.bindc_name = "a"})
-
-! CHECK: fir.select_type %[[ARG0]] : !fir.class<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>
-! CHECK-SAME: [#fir.type_is<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>, ^[[TYPE_IS_BLK:.*]], #fir.class_is<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>, ^[[CLASS_IS_P1_BLK:.*]], #fir.class_is<!fir.type<_QMselect_type_lower_testTp2{a:i32,b:i32,c:i32}>>, ^[[CLASS_IS_P2_BLK:.*]], unit, ^[[DEFAULT_BLOCK:.*]]]
-! CHECK: ^[[TYPE_IS_BLK]]
-! CHECK: ^[[CLASS_IS_P1_BLK]]
-! CHECK: ^[[CLASS_IS_P2_BLK]]
-! CHECK: %[[P2:.*]] = fir.convert %[[ARG0:.*]] : (!fir.class<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>) -> !fir.class<!fir.type<_QMselect_type_lower_testTp2{a:i32,b:i32,c:i32}>>
-! CHECK: %{{.*}} = fir.coordinate_of %[[P2]], c : (!fir.class<!fir.type<_QMselect_type_lower_testTp2{a:i32,b:i32,c:i32}>>) -> !fir.ref<i32>
-! CHECK: ^[[DEFAULT_BLOCK]]
+! CHECK-SAME: %[[ARG0:.*]]: !fir.class<!fir.type<_QMselect_type_lower_testTp1
+! CHECK: %[[ADECL:.*]]:2 = hlfir.declare %[[ARG0]]{{.*}}{{{.*}}uniq_name = "_QMselect_type_lower_testFselect_type1Ea"}
+! CHECK: fir.select_type %[[ADECL]]#1
+! CHECK-SAME: #fir.type_is<!fir.type<_QMselect_type_lower_testTp1
+! CHECK-SAME: #fir.class_is<!fir.type<_QMselect_type_lower_testTp1
+! CHECK-SAME: #fir.class_is<!fir.type<_QMselect_type_lower_testTp2
 
 ! CFG-LABEL: func.func @_QMselect_type_lower_testPselect_type1(
-! CFG-SAME: %[[ARG0:.*]]: !fir.class<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>> {fir.bindc_name = "a"}) {
-! CFG:      %[[TDESC_P1_ADDR:.*]] = fir.type_desc !fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>
-! CFG:      %[[BOX_TDESC:.*]] = fir.box_tdesc %[[ARG0]] : (!fir.class<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>) -> !fir.tdesc<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>
-! CFG:      %[[TDESC_P1_CONV:.*]] = fir.convert %[[TDESC_P1_ADDR]] : (!fir.tdesc<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>) -> index
-! CFG:      %[[BOX_TDESC_CONV:.*]] = fir.convert %[[BOX_TDESC]] : (!fir.tdesc<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>) -> index
-! CFG:      %[[TDESC_CMP:.*]] = arith.cmpi eq, %[[TDESC_P1_CONV]], %[[BOX_TDESC_CONV]] : index
-! CFG:      cf.cond_br %[[TDESC_CMP]], ^[[TYPE_IS_P1_BLK:.*]], ^[[NOT_TYPE_IS_P1_BLK:.*]]
-! CFG:    ^[[NOT_TYPE_IS_P1_BLK]]:
-! CFG:      %[[TDESC_P2_ADDR:.*]] = fir.type_desc !fir.type<_QMselect_type_lower_testTp2{{.*}}
-! CFG:      %[[TDESC_P2_CONV:.*]] = fir.convert %[[TDESC_P2_ADDR]] : (!fir.tdesc<{{.*}}>) -> !fir.ref<none>
-! CFG:      %[[BOX_NONE:.*]] = fir.convert %[[ARG0]] : (!fir.class<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>) -> !fir.box<none>
-! CFG:      %[[CLASS_IS:.*]] = fir.call @_FortranAClassIs(%[[BOX_NONE]], %[[TDESC_P2_CONV]]) : (!fir.box<none>, !fir.ref<none>) -> i1
-! CFG:      cf.cond_br %[[CLASS_IS]], ^bb[[CLASS_IS_P2_BLK:.*]], ^[[NOT_CLASS_IS_P2_BLK:.*]]
-! CFG:    ^[[TYPE_IS_P1_BLK]]:
-! CFG:      cf.br ^bb[[EXIT_SELECT_BLK:[0-9]]]
-! CFG:    ^bb[[NOT_CLASS_IS_P1_BLK:[0-9]]]:
-! CFG:      cf.br ^bb[[DEFAULT_BLK:[0-9]]]
-! CFG:    ^bb[[CLASS_IS_P1_BLK:[0-9]]]:
-! CFG:      cf.br ^[[END_SELECT_BLK:.*]]
-! CFG:    ^[[NOT_CLASS_IS_P2_BLK]]:
-! CFG:      %[[TDESC_P1_ADDR:.*]] = fir.type_desc !fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>
-! CFG:      %[[TDESC_P1_CONV:.*]] = fir.convert %[[TDESC_P1_ADDR]] : (!fir.tdesc<{{.*}}>) -> !fir.ref<none>
-! CFG:      %[[BOX_NONE:.*]] = fir.convert %[[ARG0]] : (!fir.class<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>) -> !fir.box<none>
-! CFG:      %[[CLASS_IS:.*]] = fir.call @_FortranAClassIs(%[[BOX_NONE]], %[[TDESC_P1_CONV]]) : (!fir.box<none>, !fir.ref<none>) -> i1
-! CFG:      cf.cond_br %[[CLASS_IS]], ^bb[[CLASS_IS_P1_BLK]], ^bb[[NOT_CLASS_IS_P1_BLK]]
-! CFG:    ^bb[[CLASS_IS_P2_BLK]]:
-! CFG:      cf.br ^[[END_SELECT_BLK]]
-! CFG:    ^bb[[DEFAULT_BLK]]:
-! CFG:      cf.br ^[[END_SELECT_BLK]]
-! CFG:    ^[[END_SELECT_BLK]]:
-! CFG:      return
+! CFG: hlfir.declare %{{.*}}
+! CFG: fir.type_desc !fir.type<_QMselect_type_lower_testTp1
+! CFG: fir.box_tdesc %{{.*}}
+! CFG: fir.call @_FortranAClassIs(%{{.*}}, %{{.*}}) : (!fir.box<none>, !fir.ref<none>) -> i1
 
   subroutine select_type2()
     select type (a => get_class())
@@ -111,43 +80,15 @@ subroutine select_type2()
   end subroutine
 
 ! CHECK-LABEL: func.func @_QMselect_type_lower_testPselect_type2()
-! CHECK: %[[RESULT:.*]] = fir.alloca !fir.class<!fir.ptr<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>> {bindc_name = ".result"}
-! CHECK: %[[FCTCALL:.*]] = fir.call @_QMselect_type_lower_testPget_class() {{.*}}: () -> !fir.class<!fir.ptr<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>>
-! CHECK: fir.save_result %[[FCTCALL]] to %[[RESULT]] : !fir.class<!fir.ptr<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>>, !fir.ref<!fir.class<!fir.ptr<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>>>
-! CHECK: %[[SELECTOR:.*]] = fir.load %[[RESULT]] : !fir.ref<!fir.class<!fir.ptr<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>>>
-! CHECK: fir.select_type %[[SELECTOR]] : !fir.class<!fir.ptr<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>>
-! CHECK-SAME: [#fir.type_is<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>, ^[[TYPE_IS_BLK:.*]], #fir.class_is<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>, ^[[CLASS_IS_BLK:.*]], unit, ^[[DEFAULT_BLK:.*]]]
-! CHECK: ^[[TYPE_IS_BLK]]
-! CHECK: ^[[CLASS_IS_BLK]]
-! CHECK: ^[[DEFAULT_BLK]]
+! CHECK: %[[RESULT:.*]] = fir.alloca !fir.class<!fir.ptr<!fir.type<_QMselect_type_lower_testTp1
+! CHECK: %[[FCTCALL:.*]] = fir.call @_QMselect_type_lower_testPget_class()
+! CHECK: fir.save_result %[[FCTCALL]] to %{{.*}}
+! CHECK: %[[SELECTOR:.*]] = fir.load %{{.*}}#0
+! CHECK: fir.select_type %[[SELECTOR]]
 
 ! CFG-LABEL: func.func @_QMselect_type_lower_testPselect_type2() {
-! CFG:     %[[CLASS_ALLOCA:.*]] = fir.alloca !fir.class<!fir.ptr<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>> {bindc_name = ".result"}
-! CFG:     %[[GET_CLASS:.*]] = fir.call @_QMselect_type_lower_testPget_class() {{.*}} : () -> !fir.class<!fir.ptr<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>>
-! CFG:     fir.save_result %[[GET_CLASS]] to %[[CLASS_ALLOCA]] : !fir.class<!fir.ptr<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>>, !fir.ref<!fir.class<!fir.ptr<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>>>
-! CFG:     %[[LOAD_CLASS:.*]] = fir.load %[[CLASS_ALLOCA]] : !fir.ref<!fir.class<!fir.ptr<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>>>
-! CFG:     %[[TDESC_P1_ADDR:.*]] = fir.type_desc !fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>
-! CFG:     %[[CLASS_TDESC:.*]] = fir.box_tdesc %[[LOAD_CLASS]] : (!fir.class<!fir.ptr<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>>) -> !fir.tdesc<{{.*}}>
-! CFG:     %[[TDESC_P1_CONV:.*]] = fir.convert %[[TDESC_P1_ADDR]] : (!fir.tdesc{{.*}}>) -> index
-! CFG:     %[[BOX_TDESC_CONV:.*]] = fir.convert %[[CLASS_TDESC]] : (!fir.tdesc<{{.*}}>) -> index
-! CFG:     %[[TDESC_CMP:.*]] = arith.cmpi eq, %[[TDESC_P1_CONV]], %[[BOX_TDESC_CONV]] : index
-! CFG:     cf.cond_br %[[TDESC_CMP]], ^[[TYPE_IS_P1_BLK:.*]], ^[[NOT_TYPE_IS_P1_BLK:.*]]
-! CFG:   ^[[NOT_TYPE_IS_P1_BLK]]:
-! CFG:     %[[TDESC_P1_ADDR:.*]] = fir.type_desc !fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>
-! CFG:     %[[TDESC_P1_CONV:.*]] = fir.convert %[[TDESC_P1_ADDR]] : (!fir.tdesc{{.*}}>) -> !fir.ref<none>
-! CFG:     %[[BOX_NONE:.*]] = fir.convert %[[LOAD_CLASS]] : (!fir.class<!fir.ptr<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>>) -> !fir.box<none>
-! CFG:     %[[CLASS_IS:.*]] = fir.call @_FortranAClassIs(%[[BOX_NONE]], %[[TDESC_P1_CONV]]) : (!fir.box<none>, !fir.ref<none>) -> i1
-! CFG:     cf.cond_br %[[CLASS_IS]], ^[[CLASS_IS_BLK:.*]], ^[[NOT_CLASS_IS_BLK:.*]]
-! CFG:   ^[[TYPE_IS_P1_BLK]]:
-! CFG:     cf.br ^bb[[EXIT_SELECT_BLK:[0-9]]]
-! CFG:   ^[[NOT_CLASS_IS_BLK]]:
-! CFG:     cf.br ^bb[[DEFAULT_BLK:[0-9]]]
-! CFG:   ^[[CLASS_IS_BLK]]:
-! CFG:     cf.br ^bb[[END_SELECT_BLK:[0-9]]]
-! CFG:   ^bb[[DEFAULT_BLK]]:
-! CFG:     cf.br ^bb[[END_SELECT_BLK:[0-9]]]
-! CFG:   ^bb[[END_SELECT_BLK:[0-9]]]:
-! CFG:     return
+! CFG: fir.type_desc !fir.type<_QMselect_type_lower_testTp1
+! CFG: fir.call @_FortranAClassIs
 
   subroutine select_type3(a)
     class(p1), pointer, intent(in) :: a(:)
@@ -163,41 +104,15 @@ subroutine select_type3(a)
   end subroutine
 
 ! CHECK-LABEL: func.func @_QMselect_type_lower_testPselect_type3(
-! CHECK-SAME: %[[ARG0:.*]]: !fir.ref<!fir.class<!fir.ptr<!fir.array<?x!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>>>> {fir.bindc_name = "a"})
-! CHECK: %[[ARG0_LOAD:.*]] = fir.load %[[ARG0]] : !fir.ref<!fir.class<!fir.ptr<!fir.array<?x!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>>>>
-! CHECK: %[[COORD:.*]] = fir.coordinate_of %[[ARG0_LOAD]], %{{.*}} : (!fir.class<!fir.ptr<!fir.array<?x!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>>>, i64) -> !fir.ref<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>
-! CHECK: %[[SELECTOR:.*]] = fir.embox %[[COORD]] source_box %[[ARG0_LOAD]] : (!fir.ref<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>, !fir.class<!fir.ptr<!fir.array<?x!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>>>) -> !fir.class<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>
-! CHECK: fir.select_type %[[SELECTOR]] : !fir.class<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>
-! CHECK-SAME: [#fir.type_is<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>, ^[[TYPE_IS_BLK:.*]], #fir.class_is<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>, ^[[CLASS_IS_BLK:.*]], unit, ^[[DEFAULT_BLK:.*]]]
-! CHECK: ^[[TYPE_IS_BLK]]
-! CHECK: ^[[CLASS_IS_BLK]]
-! CHECK: ^[[DEFAULT_BLK]]
+! CHECK-SAME: %[[ARG0:.*]]: !fir.ref<!fir.class<!fir.ptr<!fir.array<?x!fir.type<_QMselect_type_lower_testTp1
+! CHECK: %[[ADECL:.*]]:2 = hlfir.declare %[[ARG0]]
+! CHECK: %[[LOAD:.*]] = fir.load %[[ADECL]]#0
+! CHECK: %[[SELECTOR:.*]] = hlfir.designate %[[LOAD]]
+! CHECK: fir.select_type %[[SELECTOR]]
 
 ! CFG-LABEL: func.func @_QMselect_type_lower_testPselect_type3(
-! CFG-SAME: %[[ARG0:.*]]: !fir.ref<!fir.class<!fir.ptr<!fir.array<?x!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>>>> {fir.bindc_name = "a"}) {
-! CFG:      %[[SELECTOR:.*]] = fir.embox %{{.*}} source_box %{{.*}} : (!fir.ref<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>, !fir.class<{{.*}}>) -> !fir.class<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>
-! CFG:      %[[TDESC_P1_ADDR:.*]] = fir.type_desc !fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>
-! CFG:      %[[SELECTOR_TDESC:.*]] = fir.box_tdesc %[[SELECTOR]] : (!fir.class<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>) -> !fir.tdesc<{{.*}}>
-! CFG:      %[[TDESC_P1_CONV:.*]] = fir.convert %[[TDESC_P1_ADDR]] : (!fir.tdesc{{.*}}>) -> index
-! CFG:      %[[TDESC_CONV:.*]] = fir.convert %[[SELECTOR_TDESC]] : (!fir.tdesc<{{.*}}>) -> index
-! CFG:      %[[TDESC_CMP:.*]] = arith.cmpi eq, %[[TDESC_P1_CONV]], %[[TDESC_CONV]] : index
-! CFG:      cf.cond_br %[[TDESC_CMP]], ^[[TYPE_IS_P1_BLK:.*]], ^[[NOT_TYPE_IS_P1_BLK:.*]]
-! CFG:    ^[[NOT_TYPE_IS_P1_BLK]]:
-! CFG:      %[[TDESC_P1_ADDR:.*]] = fir.type_desc !fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>
-! CFG:      %[[TDESC_P1_CONV:.*]] = fir.convert %[[TDESC_P1_ADDR]] : (!fir.tdesc{{.*}}>) -> !fir.ref<none>
-! CFG:      %[[BOX_NONE:.*]] = fir.convert %[[SELECTOR]] : (!fir.class<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>) -> !fir.box<none>
-! CFG:      %[[CLASS_IS:.*]] = fir.call @_FortranAClassIs(%[[BOX_NONE]], %[[TDESC_P1_CONV]]) : (!fir.box<none>, !fir.ref<none>) -> i1
-! CFG:      cf.cond_br %[[CLASS_IS]], ^[[CLASS_IS_BLK:.*]], ^[[NOT_CLASS_IS:.*]]
-! CFG:    ^[[TYPE_IS_P1_BLK]]:
-! CFG:        cf.br ^bb[[END_SELECT_BLK:[0-9]]]
-! CFG:    ^[[NOT_CLASS_IS]]:
-! CFG:        cf.br ^bb[[DEFAULT_BLK:[0-9]]]
-! CFG:    ^[[CLASS_IS_BLK]]:
-! CFG:        cf.br ^bb[[END_SELECT_BLK]]
-! CFG:    ^bb[[DEFAULT_BLK]]:
-! CFG:        cf.br ^bb[[END_SELECT_BLK]]
-! CFG:    ^bb[[END_SELECT_BLK]]:
-! CFG:        return
+! CFG: hlfir.designate
+! CFG: fir.call @_FortranAClassIs
 
   subroutine select_type4(a)
     class(p1), intent(in) :: a
@@ -212,46 +127,18 @@ subroutine select_type4(a)
   end subroutine
 
 ! CHECK-LABEL: func.func @_QMselect_type_lower_testPselect_type4(
-! CHECK-SAME: %[[ARG0:.*]]: !fir.class<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>> {fir.bindc_name = "a"})
-! CHECK: fir.select_type %[[ARG0]] : !fir.class<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>
-! CHECK-SAME: [#fir.type_is<!fir.type<_QMselect_type_lower_testTp3K8{a:i32,b:i32,r:f64}>>, ^[[P3_8:.*]], #fir.type_is<!fir.type<_QMselect_type_lower_testTp3K4{a:i32,b:i32,r:f32}>>, ^[[P3_4:.*]], #fir.class_is<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>, ^[[P1:.*]], unit, ^[[EXIT:.*]]]
-! CHECK: ^[[P3_8]]
-! CHECK: ^[[P3_4]]
-! CHECK: ^[[P1]]
-! CHECK: ^[[EXIT]]
+! CHECK-SAME: %[[ARG0:.*]]: !fir.class<!fir.type<_QMselect_type_lower_testTp1
+! CHECK: %[[ADECL:.*]]:2 = hlfir.declare %[[ARG0]]
+! CHECK: fir.select_type %[[ADECL]]#1
+! CHECK-SAME: #fir.type_is<!fir.type<_QMselect_type_lower_testTp3K8
+! CHECK-SAME: #fir.type_is<!fir.type<_QMselect_type_lower_testTp3K4
+! CHECK-SAME: #fir.class_is<!fir.type<_QMselect_type_lower_testTp1
 
 ! CFG-LABEL: func.func @_QMselect_type_lower_testPselect_type4(
-! CFG-SAME: %[[ARG0:.*]]: !fir.class<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>> {fir.bindc_name = "a"}) {
-! CFG:      %[[TDESC_P3_8_ADDR:.*]] = fir.type_desc !fir.type<_QMselect_type_lower_testTp3K8
-! CFG:      %[[BOX_TDESC:.*]] = fir.box_tdesc %[[ARG0]] : (!fir.class<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>) -> !fir.tdesc<{{.*}}>
-! CFG:      %[[TDESC_P3_8_CONV:.*]] = fir.convert %[[TDESC_P3_8_ADDR]] : (!fir.tdesc{{.*}}>) -> index
-! CFG:      %[[BOX_TDESC_CONV:.*]] = fir.convert %[[BOX_TDESC]] : (!fir.tdesc<{{.*}}>) -> index
-! CFG:      %[[TDESC_CMP:.*]] = arith.cmpi eq, %[[TDESC_P3_8_CONV]], %[[BOX_TDESC_CONV]] : index
-! CFG:      cf.cond_br %[[TDESC_CMP]], ^[[P3_8_BLK:.*]], ^[[NOT_P3_8_BLK:.*]]
-! CFG:    ^[[NOT_P3_8_BLK]]:
-! CFG:      %[[TDESC_P3_4_ADDR:.*]] = fir.type_desc !fir.type<_QMselect_type_lower_testTp3K4
-! CFG:      %[[BOX_TDESC:.*]] = fir.box_tdesc %[[ARG0]] : (!fir.class<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>) -> !fir.tdesc<{{.*}}>
-! CFG:      %[[TDESC_P3_4_CONV:.*]] = fir.convert %[[TDESC_P3_4_ADDR]] : (!fir.tdesc{{.*}}>) -> index
-! CFG:      %[[BOX_TDESC_CONV:.*]] = fir.convert %[[BOX_TDESC]] : (!fir.tdesc<{{.*}}>) -> index
-! CFG:      %[[TDESC_CMP:.*]] = arith.cmpi eq, %[[TDESC_P3_4_CONV]], %[[BOX_TDESC_CONV]] : index
-! CFG:      cf.cond_br %[[TDESC_CMP]], ^[[P3_4_BLK:.*]], ^[[NOT_P3_4_BLK:.*]]
-! CFG:    ^[[P3_8_BLK]]:
-! CFG:      _FortranAioOutputAscii
-! CFG:      cf.br ^bb[[EXIT_SELECT_BLK:[0-9]]]
-! CFG:    ^[[NOT_P3_4_BLK]]:
-! CFG:      %[[TDESC_P1_ADDR:.*]] = fir.type_desc !fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>
-! CFG:      %[[TDESC_P1_CONV:.*]] = fir.convert %[[TDESC_P1_ADDR]] : (!fir.tdesc{{.*}}>) -> !fir.ref<none>
-! CFG:      %[[BOX_NONE:.*]] = fir.convert %[[ARG0]] : (!fir.class<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>) -> !fir.box<none>
-! CFG:      %[[CLASS_IS:.*]] = fir.call @_FortranAClassIs(%[[BOX_NONE]], %[[TDESC_P1_CONV]]) : (!fir.box<none>, !fir.ref<none>) -> i1
-! CFG:      cf.cond_br %[[CLASS_IS]], ^[[P1_BLK:.*]], ^[[NOT_P1_BLK:.*]]
-! CFG:    ^[[P3_4_BLK]]:
-! CFG:      cf.br ^bb[[EXIT_SELECT_BLK]]
-! CFG:    ^[[NOT_P1_BLK]]:
-! CFG:      cf.br ^bb[[EXIT_SELECT_BLK]]
-! CFG:    ^[[P1_BLK]]:
-! CFG:      cf.br ^bb[[EXIT_SELECT_BLK]]
-! CFG:    ^bb[[EXIT_SELECT_BLK]]:
-! CFG:      return
+! CFG: fir.type_desc !fir.type<_QMselect_type_lower_testTp3K8
+! CFG: fir.type_desc !fir.type<_QMselect_type_lower_testTp3K4
+! CFG: fir.type_desc !fir.type<_QMselect_type_lower_testTp1
+! CFG: fir.call @_FortranAClassIs
 
   subroutine select_type5(a)
     class(*), intent(in) :: a
@@ -273,59 +160,17 @@ subroutine select_type5(a)
   end subroutine
 
 ! CHECK-LABEL: func.func @_QMselect_type_lower_testPselect_type5(
-! CHECK-SAME: %[[ARG0:.*]]: !fir.class<none> {fir.bindc_name = "a"})
-! CHECK: fir.select_type %[[ARG0]] : !fir.class<none>
-! CHECK-SAME: [#fir.type_is<i8>, ^[[I8_BLK:.*]], #fir.type_is<i32>, ^[[I32_BLK:.*]], #fir.type_is<f32>, ^[[F32_BLK:.*]], #fir.type_is<!fir.logical<4>>, ^[[LOG_BLK:.*]], #fir.type_is<!fir.char<1,?>>, ^[[CHAR_BLK:.*]], unit, ^[[DEFAULT:.*]]]
-! CHECK: ^[[I8_BLK]]
-! CHECK: ^[[I32_BLK]]
-! CHECK: ^[[F32_BLK]]
-! CHECK: ^[[LOG_BLK]]
-! CHECK: ^[[CHAR_BLK]]
-! CHECK: ^[[DEFAULT_BLOCK]]
+! CHECK-SAME: %[[ARG0:.*]]: !fir.class<none>
+! CHECK: fir.select_type %{{.*}} : !fir.class<none>
+! CHECK-SAME: #fir.type_is<i8>
+! CHECK-SAME: #fir.type_is<i32>
+! CHECK-SAME: #fir.type_is<f32>
+! CHECK-SAME: #fir.type_is<!fir.logical<4>>
+! CHECK-SAME: #fir.type_is<!fir.char<1,?>>
 
 ! CFG-LABEL: func.func @_QMselect_type_lower_testPselect_type5(
-! CFG-SAME: %[[SELECTOR:.*]]: !fir.class<none> {fir.bindc_name = "a"}) {
-
-! CFG:  %[[INT8_TC:.*]] = arith.constant 7 : i8
-! CFG:  %[[TYPE_CODE:.*]] = fir.box_typecode %[[SELECTOR]] : (!fir.class<none>) -> i8
-! CFG:  %[[IS_INT8:.*]] = arith.cmpi eq, %[[TYPE_CODE]], %[[INT8_TC]] : i8
-! CFG:  cf.cond_br %[[IS_INT8]], ^[[INT8_BLK:.*]], ^[[NOT_INT8:.*]]
-! CFG: ^[[NOT_INT8]]:
-! CFG:  %[[INT32_TC:.*]] = arith.constant 9 : i8
-! CFG:  %[[TYPE_CODE:.*]] = fir.box_typecode %[[SELECTOR]] : (!fir.class<none>) -> i8
-! CFG:  %[[IS_INT32:.*]] = arith.cmpi eq, %[[TYPE_CODE]], %[[INT32_TC]] : i8
-! CFG:  cf.cond_br %[[IS_INT32]], ^[[INT32_BLK:.*]], ^[[NOT_INT32_BLK:.*]]
-! CFG: ^[[INT8_BLK]]:
-! CFG:  cf.br ^[[EXIT_BLK:.*]]
-! CFG: ^[[NOT_INT32_BLK]]:
-! CFG:  %[[FLOAT_TC:.*]] = arith.constant 27 : i8
-! CFG:  %[[TYPE_CODE:.*]] = fir.box_typecode %[[SELECTOR]] : (!fir.class<none>) -> i8
-! CFG:  %[[IS_FLOAT:.*]] = arith.cmpi eq, %[[TYPE_CODE]], %[[FLOAT_TC]] : i8
-! CFG:  cf.cond_br %[[IS_FLOAT]], ^[[FLOAT_BLK:.*]], ^[[NOT_FLOAT_BLK:.*]]
-! CFG: ^[[INT32_BLK]]:
-! CFG:  cf.br ^[[EXIT_BLK]]
-! CFG: ^[[NOT_FLOAT_BLK]]:
-! CFG:  %[[LOGICAL_TC:.*]] = arith.constant 14 : i8
-! CFG:  %[[TYPE_CODE:.*]] = fir.box_typecode %[[SELECTOR]] : (!fir.class<none>) -> i8
-! CFG:  %[[IS_LOGICAL:.*]] = arith.cmpi eq, %[[TYPE_CODE]], %[[LOGICAL_TC]] : i8
-! CFG:  cf.cond_br %[[IS_LOGICAL]], ^[[LOGICAL_BLK:.*]], ^[[NOT_LOGICAL_BLK:.*]]
-! CFG: ^[[FLOAT_BLK]]:
-! CFG:  cf.br ^[[EXIT_BLK]]
-! CFG: ^[[NOT_LOGICAL_BLK]]:
-! CFG:  %[[CHAR_TC:.*]] = arith.constant 40 : i8
-! CFG:  %[[TYPE_CODE:.*]] = fir.box_typecode %[[SELECTOR]] : (!fir.class<none>) -> i8
-! CFG:  %[[IS_CHAR:.*]] = arith.cmpi eq, %[[TYPE_CODE]], %[[CHAR_TC]] : i8
-! CFG:  cf.cond_br %[[IS_CHAR]], ^[[CHAR_BLK:.*]], ^[[NOT_CHAR_BLK:.*]]
-! CFG: ^[[LOGICAL_BLK]]:
-! CFG:  cf.br ^[[EXIT_BLK]]
-! CFG: ^[[NOT_CHAR_BLK]]:
-! CFG:  cf.br ^[[DEFAULT_BLK:.*]]
-! CFG: ^[[CHAR_BLK]]:
-! CFG:  cf.br ^[[EXIT_BLK]]
-! CFG: ^[[DEFAULT_BLK]]:
-! CFG:  cf.br ^[[EXIT_BLK]]
-! CFG: ^bb12:
-! CFG:  return
+! CFG: fir.box_typecode %{{.*}} : (!fir.class<none>) -> i8
+! CFG: arith.cmpi eq, %{{.*}}, %{{.*}} : i8
 
   subroutine select_type6(a)
     class(*) :: a
@@ -341,48 +186,14 @@ subroutine select_type6(a)
   end subroutine
 
 ! CHECK-LABEL: func.func @_QMselect_type_lower_testPselect_type6(
-! CHECK-SAME: %[[ARG0:.*]]: !fir.class<none> {fir.bindc_name = "a"})
-
-! CHECK: fir.select_type %[[ARG0]] : !fir.class<none> [#fir.type_is<i32>, ^[[INT_BLK:.*]], #fir.type_is<f32>, ^[[REAL_BLK:.*]], unit, ^[[DEFAULT_BLK:.*]]]
-! CHECK: ^[[INT_BLK]]
-! CHECK:  %[[BOX_ADDR:.*]] = fir.box_addr %[[ARG0]] : (!fir.class<none>) -> !fir.ref<i32>
-! CHECK:  %[[C100:.*]] = arith.constant 100 : i32
-! CHECK:  fir.store %[[C100]] to %[[BOX_ADDR]] : !fir.ref<i32>
-
-! CHECK: ^[[REAL_BLK]]:  // pred: ^bb0
-! CHECK:  %[[BOX_ADDR:.*]] = fir.box_addr %[[ARG0]] : (!fir.class<none>) -> !fir.ref<f32>
-! CHECK:  %[[C2:.*]] = arith.constant 2.000000e+00 : f32
-! CHECK:  fir.store %[[C2]] to %[[BOX_ADDR]] : !fir.ref<f32>
-
+! CHECK-SAME: %[[ARG0:.*]]: !fir.class<none>
+! CHECK: %[[ADECL:.*]]:2 = hlfir.declare %[[ARG0]]
+! CHECK: fir.select_type %[[ADECL]]#1 : !fir.class<none>
+! CHECK-SAME: #fir.type_is<i32>
+! CHECK-SAME: #fir.type_is<f32>
 
 ! CFG-LABEL: func.func @_QMselect_type_lower_testPselect_type6(
-! CFG-SAME: %[[ARG0:.*]]: !fir.class<none> {fir.bindc_name = "a"})
-! CFG:   %[[INT32_TYPECODE:.*]] = arith.constant 9 : i8
-! CFG:   %[[ARG0_TYPECODE:.*]] = fir.box_typecode %[[ARG0]] : (!fir.class<none>) -> i8
-! CFG:   %[[IS_TYPECODE:.*]] = arith.cmpi eq, %[[ARG0_TYPECODE]], %[[INT32_TYPECODE]] : i8
-! CFG:   cf.cond_br %[[IS_TYPECODE]], ^[[TYPE_IS_INT_BLK:.*]], ^[[TYPE_NOT_INT_BLK:.*]]
-! CFG: ^[[TYPE_NOT_INT_BLK]]:
-! CFG:   %[[FLOAT_TYPECODE:.*]] = arith.constant 27 : i8
-! CFG:   %[[ARG0_TYPECODE:.*]] = fir.box_typecode %[[ARG0]] : (!fir.class<none>) -> i8
-! CFG:   %[[IS_TYPECODE:.*]] = arith.cmpi eq, %[[ARG0_TYPECODE]], %[[FLOAT_TYPECODE]] : i8
-! CFG:   cf.cond_br %[[IS_TYPECODE]], ^[[TYPE_IS_REAL_BLK:.*]], ^[[TYPE_NOT_REAL_BLK:.*]]
-! CFG: ^[[TYPE_IS_INT_BLK]]:
-! CFG:   %[[BOX_ADDR:.*]] = fir.box_addr %[[ARG0]] : (!fir.class<none>) -> !fir.ref<i32>
-! CFG:   %[[C100:.*]] = arith.constant 100 : i32
-! CFG:   fir.store %[[C100]] to %[[BOX_ADDR]] : !fir.ref<i32>
-! CFG:   cf.br ^[[EXIT_SELECT_BLK:.*]]
-! CFG: ^[[TYPE_NOT_REAL_BLK]]:
-! CFG:   cf.br ^[[DEFAULT_BLK:.*]]
-! CFG: ^[[TYPE_IS_REAL_BLK]]:
-! CFG: %[[BOX_ADDR:.*]] = fir.box_addr %[[ARG0]] : (!fir.class<none>) -> !fir.ref<f32>
-! CFG: %[[CST:.*]] = arith.constant 2.000000e+00 : f32
-! CFG: fir.store %[[CST]] to %[[BOX_ADDR]] : !fir.ref<f32>
-! CFG: cf.br ^[[EXIT_SELECT_BLK]]
-! CFG: ^[[DEFAULT_BLK]]:
-! CFG:   fir.call @_FortranAStopStatementText
-! CFG:   fir.unreachable
-! CFG: ^[[EXIT_SELECT_BLK]]:
-! CFG   return
+! CFG: fir.box_typecode %{{.*}} : (!fir.class<none>) -> i8
 
   subroutine select_type7(a)
     class(*), intent(out) :: a
@@ -400,44 +211,18 @@ subroutine select_type7(a)
   end subroutine
 
 ! CHECK-LABEL: func.func @_QMselect_type_lower_testPselect_type7(
-! CHECK-SAME: %[[ARG0:.*]]: !fir.class<none> {fir.bindc_name = "a"})
-! CHECK: fir.select_type %[[ARG0]] :
-! CHECK-SAME: !fir.class<none> [#fir.class_is<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>, ^bb1, #fir.class_is<!fir.type<_QMselect_type_lower_testTp2{a:i32,b:i32,c:i32}>>, ^bb2, #fir.class_is<!fir.type<_QMselect_type_lower_testTp4{a:i32,b:i32,c:i32,d:i32}>>, ^bb3, unit, ^bb4]
+! CHECK-SAME: %[[ARG0:.*]]: !fir.class<none>
+! CHECK: fir.select_type %{{.*}} : !fir.class<none>
+! CHECK-SAME: #fir.class_is<!fir.type<_QMselect_type_lower_testTp1
+! CHECK-SAME: #fir.class_is<!fir.type<_QMselect_type_lower_testTp2
+! CHECK-SAME: #fir.class_is<!fir.type<_QMselect_type_lower_testTp4
 
 ! Check correct ordering of class is type guard. The expected flow should be:
 !   class is (p4) -> class is (p2) -> class is (p1) -> class default
 
 ! CFG-LABEL: func.func @_QMselect_type_lower_testPselect_type7(
-! CFG-SAME: %[[ARG0:.*]]: !fir.class<none> {fir.bindc_name = "a"}) {
-! CFG:      %[[TDESC_P4_ADDR:.*]] = fir.type_desc !fir.type<_QMselect_type_lower_testTp4
-! CFG:      %[[TDESC_P4_CONV:.*]] = fir.convert %[[TDESC_P4_ADDR]] : (!fir.tdesc{{.*}}>) -> !fir.ref<none>
-! CFG:      %[[BOX_NONE:.*]] = fir.convert %[[ARG0]] : (!fir.class<none>) -> !fir.box<none>
-! CFG:      %[[CLASS_IS_P4:.*]] = fir.call @_FortranAClassIs(%[[BOX_NONE]], %[[TDESC_P4_CONV]]) : (!fir.box<none>, !fir.ref<none>) -> i1
-! CFG:      cf.cond_br %[[CLASS_IS_P4]], ^[[CLASS_IS_P4_BLK:.*]], ^[[CLASS_NOT_P4_BLK:.*]]
-! CFG:    ^bb[[CLASS_NOT_P1_BLK:[0-9]]]:
-! CFG:      cf.br ^[[CLASS_DEFAULT_BLK:.*]]
-! CFG:    ^bb[[CLASS_IS_P1_BLK:[0-9]]]:
-! CFG:      cf.br ^[[EXIT_SELECT_BLK:.*]]
-! CFG:    ^bb[[CLASS_NOT_P2_BLK:[0-9]]]:
-! CFG:      %[[TDESC_P1_ADDR:.*]] = fir.type_desc !fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>
-! CFG:      %[[TDESC_P1_CONV:.*]] = fir.convert %[[TDESC_P1_ADDR]] : (!fir.tdesc{{.*}}>) -> !fir.ref<none>
-! CFG:      %[[BOX_NONE:.*]] = fir.convert %[[ARG0]] : (!fir.class<none>) -> !fir.box<none>
-! CFG:      %[[CLASS_IS_P1:.*]] = fir.call @_FortranAClassIs(%[[BOX_NONE]], %[[TDESC_P1_CONV]]) : (!fir.box<none>, !fir.ref<none>) -> i1
-! CFG:      cf.cond_br %[[CLASS_IS_P1]], ^bb[[CLASS_IS_P1_BLK]], ^bb[[CLASS_NOT_P1_BLK]]
-! CFG:    ^bb[[CLASS_IS_P2_BLK:[0-9]]]:
-! CFG:      cf.br ^[[EXIT_SELECT_BLK]]
-! CFG:    ^[[CLASS_NOT_P4_BLK]]:
-! CFG:      %[[TDESC_P2_ADDR:.*]] = fir.type_desc !fir.type<_QMselect_type_lower_testTp2
-! CFG:      %[[TDESC_P2_CONV:.*]] = fir.convert %[[TDESC_P2_ADDR]] : (!fir.tdesc{{.*}}>) -> !fir.ref<none>
-! CFG:      %[[BOX_NONE:.*]] = fir.convert %[[ARG0]] : (!fir.class<none>) -> !fir.box<none>
-! CFG:      %[[CLASS_IS_P2:.*]] = fir.call @_FortranAClassIs(%[[BOX_NONE]], %[[TDESC_P2_CONV]]) : (!fir.box<none>, !fir.ref<none>) -> i1
-! CFG:      cf.cond_br %[[CLASS_IS_P2]], ^bb[[CLASS_IS_P2_BLK]], ^bb[[CLASS_NOT_P2_BLK]]
-! CFG:   ^[[CLASS_IS_P4_BLK]]:
-! CFG:      cf.br ^[[EXIT_SELECT_BLK]]
-! CFG:   ^[[CLASS_DEFAULT_BLK]]:
-! CFG:      cf.br ^[[EXIT_SELECT_BLK]]
-! CFG:   ^[[EXIT_SELECT_BLK]]:
-! CFG:      return
+! CFG: fir.type_desc !fir.type<_QMselect_type_lower_testTp4
+! CFG: fir.call @_FortranAClassIs
 
   subroutine select_type8(a)
     class(*) :: a(:)
@@ -463,103 +248,14 @@ subroutine select_type8(a)
   end subroutine
 
 ! CHECK-LABEL: func.func @_QMselect_type_lower_testPselect_type8(
-! CHECK-SAME: %[[ARG0:.*]]: !fir.class<!fir.array<?xnone>> {fir.bindc_name = "a"}) {
-! CHECK: %[[SELECTOR:.*]] = fir.rebox %[[ARG0]] : (!fir.class<!fir.array<?xnone>>) -> !fir.class<!fir.array<?xnone>>
-! CHECK: fir.select_type %[[SELECTOR]] : !fir.class<!fir.array<?xnone>> [#fir.type_is<i32>, ^{{.*}}, #fir.type_is<f32>, ^{{.*}}, #fir.type_is<!fir.char<1,?>>, ^bb{{.*}}, unit, ^{{.*}}]
-! CHECK: ^bb{{.*}}:
-! CHECK:  %[[BOX:.*]] = fir.convert %[[SELECTOR]] : (!fir.class<!fir.array<?xnone>>) -> !fir.box<!fir.array<?xi32>>
-! CHECK:  %[[C0:.*]] = arith.constant 0 : index
-! CHECK:  %[[SELECTOR_DIMS:.*]]:3 = fir.box_dims %[[BOX]], %[[C0]] : (!fir.box<!fir.array<?xi32>>, index) -> (index, index, index)
-! CHECK:  %[[ARRAY_LOAD:.*]] = fir.array_load %[[BOX]] : (!fir.box<!fir.array<?xi32>>) -> !fir.array<?xi32>
-! CHECK:  %[[C100:.*]] = arith.constant 100 : i32
-! CHECK:  %[[C1:.*]] = arith.constant 1 : index
-! CHECK:  %[[C0:.*]] = arith.constant 0 : index
-! CHECK:  %[[UB:.*]] = arith.subi %[[SELECTOR_DIMS:.*]]#1, %[[C1]] : index
-! CHECK:  %[[LOOP_RES:.*]] = fir.do_loop %[[IND:.*]] = %[[C0:.*]] to %[[UB]] step %[[C1]] unordered iter_args(%[[ARG:.*]] = %[[ARRAY_LOAD]]) -> (!fir.array<?xi32>) {
-! CHECK:    %[[ARR_UP:.*]] = fir.array_update %[[ARG]], %[[C100]], %[[IND]] : (!fir.array<?xi32>, i32, index) -> !fir.array<?xi32>
-! CHECK:    fir.result %[[ARR_UP]] : !fir.array<?xi32>
-! CHECK:  }
-! CHECK:  fir.array_merge_store %[[ARRAY_LOAD]], %[[LOOP_RES]] to %[[BOX]] : !fir.array<?xi32>, !fir.array<?xi32>, !fir.box<!fir.array<?xi32>>
-! CHECK:  cf.br ^{{.*}}
-! CHECK: ^bb{{.*}}:
-! CHECK:  %[[BOX:.*]] = fir.convert %[[SELECTOR]] : (!fir.class<!fir.array<?xnone>>) -> !fir.box<!fir.array<?xf32>>
-! CHECK:  %[[C0:.*]] = arith.constant 0 : index
-! CHECK:  %[[SELECTOR_DIMS:.*]]:3 = fir.box_dims %[[BOX]], %[[C0]] : (!fir.box<!fir.array<?xf32>>, index) -> (index, index, index)
-! CHECK:  %[[ARRAY_LOAD:.*]] = fir.array_load %[[BOX]] : (!fir.box<!fir.array<?xf32>>) -> !fir.array<?xf32>
-! CHECK:  %[[VALUE:.*]] = arith.constant 2.000000e+00 : f32
-! CHECK:  %[[C1:.*]] = arith.constant 1 : index
-! CHECK:  %[[C0:.*]] = arith.constant 0 : index
-! CHECK:  %[[UB:.*]] = arith.subi %[[SELECTOR_DIMS]]#1, %[[C1]] : index
-! CHECK:  %[[LOOP_RES:.*]] = fir.do_loop %[[IND:.*]] = %[[C0]] to %[[UB]] step %[[C1]] unordered iter_args(%[[ARG:.*]] = %[[ARRAY_LOAD]]) -> (!fir.array<?xf32>) {
-! CHECK:    %[[ARR_UP:.*]] = fir.array_update %[[ARG]], %[[VALUE]], %[[IND]] : (!fir.array<?xf32>, f32, index) -> !fir.array<?xf32>
-! CHECK:    fir.result %[[ARR_UP]] : !fir.array<?xf32>
-! CHECK:  }
-! CHECK:  fir.array_merge_store %[[ARRAY_LOAD]], %[[LOOP_RES]] to %[[BOX]] : !fir.array<?xf32>, !fir.array<?xf32>, !fir.box<!fir.array<?xf32>>
-! CHECK:  cf.br ^{{.*}}
-! CHECK: ^bb{{.*}}:
-! CHECK:  %[[BOX:.*]] = fir.convert %{{[0-9]+}} : (!fir.class<!fir.array<?xnone>>) -> !fir.box<!fir.array<?x!fir.char<1,?>>>
-! CHECK:  cf.br ^bb{{.*}}
-! CHECK: ^bb{{.*}}:
-! CHECK:  %[[EXACT_BOX:.*]] = fir.convert %[[SELECTOR]] : (!fir.class<!fir.array<?xnone>>) -> !fir.box<!fir.array<?x!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>>
-! CHECK:  %[[FIELD_A:.*]] = fir.field_index a, !fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>
-! CHECK:  %[[C0:.*]] = arith.constant 0 : index
-! CHECK:  %[[BOX_DIMS:.*]]:3 = fir.box_dims %[[EXACT_BOX]], %[[C0]] : (!fir.box<!fir.array<?x!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>>, index) -> (index, index, index)
-! CHECK:  %[[C1:.*]] = arith.constant 1 : index
-! CHECK:  %[[SLICE:.*]] = fir.slice %[[C1]], %[[BOX_DIMS]]#1, %[[C1]] path %[[FIELD_A]] : (index, index, index, !fir.field) -> !fir.slice<1>
-! CHECK:  %[[ARRAY_LOAD:.*]] = fir.array_load %[[EXACT_BOX]] [%[[SLICE]]] : (!fir.box<!fir.array<?x!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>>, !fir.slice<1>) -> !fir.array<?xi32>
-! CHECK:  %[[DO_RES:.*]] = fir.do_loop %[[IND:.*]] = %{{.*}} to %{{.*}} step %{{.*}} unordered iter_args(%[[ARG:.*]] = %[[ARRAY_LOAD]]) -> (!fir.array<?xi32>) {
-! CHECK:    %[[ARR_UP:.*]] = fir.array_update %[[ARG]], %{{.*}}, %[[IND]] : (!fir.array<?xi32>, i32, index) -> !fir.array<?xi32>
-! CHECK:    fir.result %[[ARR_UP]] : !fir.array<?xi32>
-! CHECK:  }
-! CHECK:  fir.array_merge_store %[[ARRAY_LOAD]], %[[DO_RES]] to %[[EXACT_BOX]][%[[SLICE]]] : !fir.array<?xi32>, !fir.array<?xi32>, !fir.box<!fir.array<?x!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>>, !fir.slice<1>
-! CHECK:  %[[FIELD_B:.*]] = fir.field_index b, !fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>
-! CHECK:  %[[C0:.*]] = arith.constant 0 : index
-! CHECK:  %[[BOX_DIMS:.*]]:3 = fir.box_dims %[[EXACT_BOX]], %[[C0]] : (!fir.box<!fir.array<?x!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>>, index) -> (index, index, index)
-! CHECK:  %[[C1:.*]] = arith.constant 1 : index
-! CHECK:  %[[SLICE:.*]] = fir.slice %[[C1]], %[[BOX_DIMS]]#1, %[[C1]] path %[[FIELD_B]] : (index, index, index, !fir.field) -> !fir.slice<1>
-! CHECK:  %[[ARRAY_LOAD:.*]] = fir.array_load %[[EXACT_BOX]] [%[[SLICE]]] : (!fir.box<!fir.array<?x!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>>, !fir.slice<1>) -> !fir.array<?xi32>
-! CHECK:  %[[DO_RES:.*]] = fir.do_loop %[[IND:.*]] = %{{.*}} to %{{.*}} step %c{{.*}} unordered iter_args(%[[ARG:.*]] = %[[ARRAY_LOAD]]) -> (!fir.array<?xi32>) {
-! CHECK:    %[[ARR_UP:.*]] = fir.array_update %[[ARG]], %{{.*}}, %[[IND]] : (!fir.array<?xi32>, i32, index) -> !fir.array<?xi32>
-! CHECK:    fir.result %[[ARR_UP]] : !fir.array<?xi32>
-! CHECK:  }
-! CHECK:  fir.array_merge_store %[[ARRAY_LOAD]], %[[DO_RES]] to %[[EXACT_BOX]][%[[SLICE]]] : !fir.array<?xi32>, !fir.array<?xi32>, !fir.box<!fir.array<?x!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>>, !fir.slice<1>
-! CHECK:  cf.br ^{{.*}}
-! CHECK: ^bb{{.*}}:
-! CHECK:  %[[CLASS_BOX:.*]] = fir.convert %[[SELECTOR]] : (!fir.class<!fir.array<?xnone>>) -> !fir.class<!fir.array<?x!fir.type<_QMselect_type_lower_testTp2{a:i32,b:i32,c:i32}>>>
-! CHECK:  %[[FIELD_A:.*]] = fir.field_index a, !fir.type<_QMselect_type_lower_testTp2{a:i32,b:i32,c:i32}>
-! CHECK:  %[[C0:.*]] = arith.constant 0 : index
-! CHECK:  %[[BOX_DIMS:.*]]:3 = fir.box_dims %[[CLASS_BOX]], %[[C0]] : (!fir.class<!fir.array<?x!fir.type<_QMselect_type_lower_testTp2{a:i32,b:i32,c:i32}>>>, index) -> (index, index, index)
-! CHECK:  %[[C1:.*]] = arith.constant 1 : index
-! CHECK:  %[[SLICE:.*]] = fir.slice %[[C1]], %[[BOX_DIMS]]#1, %[[C1]] path %[[FIELD_A]] : (index, index, index, !fir.field) -> !fir.slice<1>
-! CHECK:  %[[ARRAY_LOAD:.*]] = fir.array_load %[[CLASS_BOX]] [%[[SLICE]]] : (!fir.class<!fir.array<?x!fir.type<_QMselect_type_lower_testTp2{a:i32,b:i32,c:i32}>>>, !fir.slice<1>) -> !fir.array<?xi32>
-! CHECK:  %[[DO_RES:.*]] = fir.do_loop %[[IND:.*]] = %{{.*}} to %{{.*}} step %{{.*}} unordered iter_args(%[[ARG:.*]] = %[[ARRAY_LOAD]]) -> (!fir.array<?xi32>) {
-! CHECK:    %[[ARR_UP:.*]] = fir.array_update %[[ARG]], %{{.*}}, %[[IND]] : (!fir.array<?xi32>, i32, index) -> !fir.array<?xi32>
-! CHECK:    fir.result %[[ARR_UP]] : !fir.array<?xi32>
-! CHECK:  }
-! CHECK:  fir.array_merge_store %[[ARRAY_LOAD]], %[[DO_RES]] to %[[CLASS_BOX]][%[[SLICE]]] : !fir.array<?xi32>, !fir.array<?xi32>, !fir.class<!fir.array<?x!fir.type<_QMselect_type_lower_testTp2{a:i32,b:i32,c:i32}>>>, !fir.slice<1>
-! CHECK:  %[[FIELD_B:.*]] = fir.field_index b, !fir.type<_QMselect_type_lower_testTp2{a:i32,b:i32,c:i32}>
-! CHECK:  %[[C0:.*]] = arith.constant 0 : index
-! CHECK:  %[[BOX_DIMS:.*]]:3 = fir.box_dims %[[CLASS_BOX]], %[[C0]] : (!fir.class<!fir.array<?x!fir.type<_QMselect_type_lower_testTp2{a:i32,b:i32,c:i32}>>>, index) -> (index, index, index)
-! CHECK:  %[[C1:.*]] = arith.constant 1 : index
-! CHECK:  %[[SLICE:.*]] = fir.slice %[[C1]], %[[BOX_DIMS]]#1, %[[C1]] path %[[FIELD_B]] : (index, index, index, !fir.field) -> !fir.slice<1>
-! CHECK:  %[[ARRAY_LOAD:.*]] = fir.array_load %[[CLASS_BOX]] [%[[SLICE]]] : (!fir.class<!fir.array<?x!fir.type<_QMselect_type_lower_testTp2{a:i32,b:i32,c:i32}>>>, !fir.slice<1>) -> !fir.array<?xi32>
-! CHECK:  %[[DO_RES:.*]] = fir.do_loop %[[IND:.*]] = %{{.*}} to %{{.*}} step %{{.*}} unordered iter_args(%[[ARG:.*]] = %[[ARRAY_LOAD]]) -> (!fir.array<?xi32>) {
-! CHECK:    %[[ARR_UP:.*]] = fir.array_update %[[ARG]], %{{.*}}, %[[IND]] : (!fir.array<?xi32>, i32, index) -> !fir.array<?xi32>
-! CHECK:    fir.result %[[ARR_UP]] : !fir.array<?xi32>
-! CHECK:  }
-! CHECK:  fir.array_merge_store %[[ARRAY_LOAD]], %[[DO_RES]] to %[[CLASS_BOX]][%[[SLICE]]] : !fir.array<?xi32>, !fir.array<?xi32>, !fir.class<!fir.array<?x!fir.type<_QMselect_type_lower_testTp2{a:i32,b:i32,c:i32}>>>, !fir.slice<1>
-! CHECK:  %[[FIELD_C:.*]] = fir.field_index c, !fir.type<_QMselect_type_lower_testTp2{a:i32,b:i32,c:i32}>
-! CHECK:  %[[C0:.*]] = arith.constant 0 : index
-! CHECK:  %[[BOX_DIMS:.*]]:3 = fir.box_dims %[[CLASS_BOX]], %[[C0]] : (!fir.class<!fir.array<?x!fir.type<_QMselect_type_lower_testTp2{a:i32,b:i32,c:i32}>>>, index) -> (index, index, index)
-! CHECK:  %[[C1:.*]] = arith.constant 1 : index
-! CHECK:  %[[SLICE:.*]] = fir.slice %[[C1]], %[[BOX_DIMS]]#1, %[[C1]] path %[[FIELD_C]] : (index, index, index, !fir.field) -> !fir.slice<1>
-! CHECK:  %[[ARRAY_LOAD:.*]] = fir.array_load %[[CLASS_BOX]] [%[[SLICE]]] : (!fir.class<!fir.array<?x!fir.type<_QMselect_type_lower_testTp2{a:i32,b:i32,c:i32}>>>, !fir.slice<1>) -> !fir.array<?xi32>
-! CHECK:  %[[DO_RES:.*]] = fir.do_loop %[[IND:.*]] = %{{.*}} to %{{.*}} step %{{.*}} unordered iter_args(%[[ARG:.*]] = %[[ARRAY_LOAD]]) -> (!fir.array<?xi32>) {
-! CHECK:    %[[ARR_UP:.*]] = fir.array_update %[[ARG]], %{{.*}}, %[[IND]] : (!fir.array<?xi32>, i32, index) -> !fir.array<?xi32>
-! CHECK:    fir.result %[[ARR_UP]] : !fir.array<?xi32>
-! CHECK:  }
-! CHECK:  fir.array_merge_store %[[ARRAY_LOAD]], %[[DO_RES]] to %[[CLASS_BOX]][%[[SLICE]]] : !fir.array<?xi32>, !fir.array<?xi32>, !fir.class<!fir.array<?x!fir.type<_QMselect_type_lower_testTp2{a:i32,b:i32,c:i32}>>>, !fir.slice<1>
-! CHECK:  cf.br ^bb{{.*}}
+! CHECK-SAME: %[[ARG0:.*]]: !fir.class<!fir.array<?xnone>>
+! CHECK: %[[ADECL:.*]]:2 = hlfir.declare %[[ARG0]]
+! CHECK: fir.select_type %[[ADECL]]#1 : !fir.class<!fir.array<?xnone>>
+! CHECK-SAME: #fir.type_is<i32>
+! CHECK-SAME: #fir.type_is<f32>
+! CHECK-SAME: #fir.type_is<!fir.char<1,?>>
+! CHECK-SAME: #fir.type_is<!fir.type<_QMselect_type_lower_testTp1
+! CHECK-SAME: #fir.class_is<!fir.type<_QMselect_type_lower_testTp2
 
   subroutine select_type9(a)
     class(p1) :: a(:)
@@ -578,70 +274,11 @@ subroutine select_type9(a)
   end subroutine
 
 ! CHECK-LABEL: func.func @_QMselect_type_lower_testPselect_type9(
-! CHECK-SAME: %[[ARG0:.*]]: !fir.class<!fir.array<?x!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>> {fir.bindc_name = "a"}) {
-! CHECK: %[[SELECTOR:.*]] = fir.rebox %[[ARG0]] : (!fir.class<!fir.array<?x!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>>) -> !fir.class<!fir.array<?x!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>>
-! CHECK: fir.select_type %[[SELECTOR]] : !fir.class<!fir.array<?x!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>> [#fir.type_is<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>, ^bb{{.*}}, #fir.type_is<!fir.type<_QMselect_type_lower_testTp2{a:i32,b:i32,c:i32}>>, ^bb{{.*}}, unit, ^bb{{.*}}]
-! CHECK: ^bb{{.*}}:
-! CHECK: %[[EXACT_BOX:.*]] = fir.convert %[[SELECTOR]] : (!fir.class<!fir.array<?x!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>>) -> !fir.box<!fir.array<?x!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>>
-! CHECK: %[[FIELD_A:.*]] = fir.field_index a, !fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>
-! CHECK: %[[C0:.*]] = arith.constant 0 : index
-! CHECK: %[[BOX_DIMS:.*]]:3 = fir.box_dims %[[EXACT_BOX]], %[[C0]] : (!fir.box<!fir.array<?x!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>>, index) -> (index, index, index)
-! CHECK: %[[C1:.*]] = arith.constant 1 : index
-! CHECK: %[[SLICE:.*]] = fir.slice %[[C1]], %[[BOX_DIMS]]#1, %[[C1]] path %[[FIELD_A]] : (index, index, index, !fir.field) -> !fir.slice<1>
-! CHECK: %[[ARRAY_LOAD:.*]] = fir.array_load %[[EXACT_BOX]] [%[[SLICE]]] : (!fir.box<!fir.array<?x!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>>, !fir.slice<1>) -> !fir.array<?xi32>
-! CHECK: %[[DO_RES:.*]] = fir.do_loop %[[IND:.*]] = %{{.*}} to %{{.*}} step %{{.*}} unordered iter_args(%[[ARG:.*]] = %[[ARRAY_LOAD]]) -> (!fir.array<?xi32>) {
-! CHECK:   %[[ARR_UP:.*]] = fir.array_update %[[ARG]], %{{.*}}, %[[IND]] : (!fir.array<?xi32>, i32, index) -> !fir.array<?xi32>
-! CHECK:   fir.result %[[ARR_UP]] : !fir.array<?xi32>
-! CHECK: }
-! CHECK: fir.array_merge_store %[[ARRAY_LOAD]], %[[DO_RES]] to %[[EXACT_BOX]][%[[SLICE]]] : !fir.array<?xi32>, !fir.array<?xi32>, !fir.box<!fir.array<?x!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>>, !fir.slice<1>
-! CHECK: %[[FIELD_B:.*]] = fir.field_index b, !fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>
-! CHECK: %[[C0:.*]] = arith.constant 0 : index
-! CHECK: %[[BOX_DIMS:.*]]:3 = fir.box_dims %[[EXACT_BOX]], %[[C0]] : (!fir.box<!fir.array<?x!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>>, index) -> (index, index, index)
-! CHECK: %[[C1:.*]] = arith.constant 1 : index
-! CHECK: %[[SLICE:.*]] = fir.slice %[[C1]], %[[BOX_DIMS]]#1, %[[C1]] path %[[FIELD_B]] : (index, index, index, !fir.field) -> !fir.slice<1>
-! CHECK: %[[ARRAY_LOAD:.*]] = fir.array_load %[[EXACT_BOX]] [%[[SLICE]]] : (!fir.box<!fir.array<?x!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>>, !fir.slice<1>) -> !fir.array<?xi32>
-! CHECK: %[[DO_RES:.*]] = fir.do_loop %[[IND:.*]] = %{{.*}} to %{{.*}} step %c{{.*}} unordered iter_args(%[[ARG:.*]] = %[[ARRAY_LOAD]]) -> (!fir.array<?xi32>) {
-! CHECK:   %[[ARR_UP:.*]] = fir.array_update %[[ARG]], %{{.*}}, %[[IND]] : (!fir.array<?xi32>, i32, index) -> !fir.array<?xi32>
-! CHECK:   fir.result %[[ARR_UP]] : !fir.array<?xi32>
-! CHECK: }
-! CHECK: fir.array_merge_store %[[ARRAY_LOAD]], %[[DO_RES]] to %[[EXACT_BOX]][%[[SLICE]]] : !fir.array<?xi32>, !fir.array<?xi32>, !fir.box<!fir.array<?x!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>>, !fir.slice<1>
-! CHECK: cf.br ^bb{{.*}}
-! CHECK: ^bb{{.*}}:
-! CHECK: %[[EXACT_BOX:.*]] = fir.convert %[[SELECTOR]] : (!fir.class<!fir.array<?x!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>>) -> !fir.box<!fir.array<?x!fir.type<_QMselect_type_lower_testTp2{a:i32,b:i32,c:i32}>>>
-! CHECK: %[[FIELD_A:.*]] = fir.field_index a, !fir.type<_QMselect_type_lower_testTp2{a:i32,b:i32,c:i32}>
-! CHECK: %[[C0:.*]] = arith.constant 0 : index
-! CHECK: %[[BOX_DIMS:.*]]:3 = fir.box_dims %[[EXACT_BOX]], %[[C0]] : (!fir.box<!fir.array<?x!fir.type<_QMselect_type_lower_testTp2{a:i32,b:i32,c:i32}>>>, index) -> (index, index, index)
-! CHECK: %[[C1:.*]] = arith.constant 1 : index
-! CHECK: %[[SLICE:.*]] = fir.slice %[[C1]], %[[BOX_DIMS]]#1, %[[C1]] path %[[FIELD_A]] : (index, index, index, !fir.field) -> !fir.slice<1>
-! CHECK: %[[ARRAY_LOAD:.*]] = fir.array_load %[[EXACT_BOX]] [%[[SLICE]]] : (!fir.box<!fir.array<?x!fir.type<_QMselect_type_lower_testTp2{a:i32,b:i32,c:i32}>>>, !fir.slice<1>) -> !fir.array<?xi32>
-! CHECK: %[[DO_RES:.*]] = fir.do_loop %[[IND:.*]] = %{{.*}} to %{{.*}} step %{{.*}} unordered iter_args(%[[ARG:.*]] = %[[ARRAY_LOAD]]) -> (!fir.array<?xi32>) {
-! CHECK:   %[[ARR_UP:.*]] = fir.array_update %[[ARG]], %{{.*}}, %[[IND]] : (!fir.array<?xi32>, i32, index) -> !fir.array<?xi32>
-! CHECK:   fir.result %[[ARR_UP]] : !fir.array<?xi32>
-! CHECK: }
-! CHECK: fir.array_merge_store %[[ARRAY_LOAD]], %[[DO_RES]] to %[[EXACT_BOX]][%[[SLICE]]] : !fir.array<?xi32>, !fir.array<?xi32>, !fir.box<!fir.array<?x!fir.type<_QMselect_type_lower_testTp2{a:i32,b:i32,c:i32}>>>, !fir.slice<1>
-! CHECK: %[[FIELD_B:.*]] = fir.field_index b, !fir.type<_QMselect_type_lower_testTp2{a:i32,b:i32,c:i32}>
-! CHECK: %[[C0:.*]] = arith.constant 0 : index
-! CHECK: %[[BOX_DIMS:.*]]:3 = fir.box_dims %[[EXACT_BOX]], %[[C0]] : (!fir.box<!fir.array<?x!fir.type<_QMselect_type_lower_testTp2{a:i32,b:i32,c:i32}>>>, index) -> (index, index, index)
-! CHECK: %[[C1:.*]] = arith.constant 1 : index
-! CHECK: %[[SLICE:.*]] = fir.slice %[[C1]], %[[BOX_DIMS]]#1, %[[C1]] path %[[FIELD_B]] : (index, index, index, !fir.field) -> !fir.slice<1>
-! CHECK: %[[ARRAY_LOAD:.*]] = fir.array_load %[[EXACT_BOX]] [%[[SLICE]]] : (!fir.box<!fir.array<?x!fir.type<_QMselect_type_lower_testTp2{a:i32,b:i32,c:i32}>>>, !fir.slice<1>) -> !fir.array<?xi32>
-! CHECK: %[[DO_RES:.*]] = fir.do_loop %[[IND:.*]] = %{{.*}} to %{{.*}} step %{{.*}} unordered iter_args(%[[ARG:.*]] = %[[ARRAY_LOAD]]) -> (!fir.array<?xi32>) {
-! CHECK:   %[[ARR_UP:.*]] = fir.array_update %[[ARG]], %{{.*}}, %[[IND]] : (!fir.array<?xi32>, i32, index) -> !fir.array<?xi32>
-! CHECK:   fir.result %[[ARR_UP]] : !fir.array<?xi32>
-! CHECK: }
-! CHECK: fir.array_merge_store %[[ARRAY_LOAD]], %[[DO_RES]] to %[[EXACT_BOX]][%[[SLICE]]] : !fir.array<?xi32>, !fir.array<?xi32>, !fir.box<!fir.array<?x!fir.type<_QMselect_type_lower_testTp2{a:i32,b:i32,c:i32}>>>, !fir.slice<1>
-! CHECK: %[[FIELD_C:.*]] = fir.field_index c, !fir.type<_QMselect_type_lower_testTp2{a:i32,b:i32,c:i32}>
-! CHECK: %[[C0:.*]] = arith.constant 0 : index
-! CHECK: %[[BOX_DIMS:.*]]:3 = fir.box_dims %[[EXACT_BOX]], %[[C0]] : (!fir.box<!fir.array<?x!fir.type<_QMselect_type_lower_testTp2{a:i32,b:i32,c:i32}>>>, index) -> (index, index, index)
-! CHECK: %[[C1:.*]] = arith.constant 1 : index
-! CHECK: %[[SLICE:.*]] = fir.slice %[[C1]], %[[BOX_DIMS]]#1, %[[C1]] path %[[FIELD_C]] : (index, index, index, !fir.field) -> !fir.slice<1>
-! CHECK: %[[ARRAY_LOAD:.*]] = fir.array_load %[[EXACT_BOX]] [%[[SLICE]]] : (!fir.box<!fir.array<?x!fir.type<_QMselect_type_lower_testTp2{a:i32,b:i32,c:i32}>>>, !fir.slice<1>) -> !fir.array<?xi32>
-! CHECK: %[[DO_RES:.*]] = fir.do_loop %[[IND:.*]] = %{{.*}} to %{{.*}} step %{{.*}} unordered iter_args(%[[ARG:.*]] = %[[ARRAY_LOAD]]) -> (!fir.array<?xi32>) {
-! CHECK:   %[[ARR_UP:.*]] = fir.array_update %[[ARG]], %{{.*}}, %[[IND]] : (!fir.array<?xi32>, i32, index) -> !fir.array<?xi32>
-! CHECK:   fir.result %[[ARR_UP]] : !fir.array<?xi32>
-! CHECK: }
-! CHECK: fir.array_merge_store %[[ARRAY_LOAD]], %[[DO_RES]] to %[[EXACT_BOX]][%[[SLICE]]] : !fir.array<?xi32>, !fir.array<?xi32>, !fir.box<!fir.array<?x!fir.type<_QMselect_type_lower_testTp2{a:i32,b:i32,c:i32}>>>, !fir.slice<1>
-! CHECK: cf.br ^bb{{.*}}
+! CHECK-SAME: %[[ARG0:.*]]: !fir.class<!fir.array<?x!fir.type<_QMselect_type_lower_testTp1
+! CHECK: %[[ADECL:.*]]:2 = hlfir.declare %[[ARG0]]
+! CHECK: fir.select_type %[[ADECL]]#1
+! CHECK-SAME: #fir.type_is<!fir.type<_QMselect_type_lower_testTp1
+! CHECK-SAME: #fir.type_is<!fir.type<_QMselect_type_lower_testTp2
 
   subroutine select_type10(a)
     class(p1), pointer :: a
@@ -656,26 +293,10 @@ subroutine select_type10(a)
   end subroutine
 
 ! CHECK-LABEL: func.func @_QMselect_type_lower_testPselect_type10(
-! CHECK-SAME: %[[ARG0:.*]]: !fir.ref<!fir.class<!fir.ptr<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>>> {fir.bindc_name = "a"}) {
-! CHECK:  %[[SELECTOR:.*]] = fir.load %[[ARG0]] : !fir.ref<!fir.class<!fir.ptr<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>>>
-! CHECK:  fir.select_type %[[SELECTOR]] : !fir.class<!fir.ptr<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>> [#fir.type_is<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>, ^bb{{.*}}, #fir.type_is<!fir.type<_QMselect_type_lower_testTp2{a:i32,b:i32,c:i32}>>, ^bb{{.*}}, #fir.class_is<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>, ^bb{{.*}}, unit, ^bb{{.*}}]
-! CHECK: ^bb{{.*}}:
-! CHECK:  %[[EXACT_BOX:.*]] = fir.box_addr %[[SELECTOR]] : (!fir.class<!fir.ptr<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>>) -> !fir.ref<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>
-! CHECK:  %[[C1:.*]] = arith.constant 1 : i32
-! CHECK:  %[[COORD_A:.*]] = fir.coordinate_of %[[EXACT_BOX]], a : (!fir.ref<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>) -> !fir.ref<i32>
-! CHECK:  fir.store %[[C1]] to %[[COORD_A]] : !fir.ref<i32>
-! CHECK:  cf.br ^bb{{.*}}
-! CHECK: ^bb{{.*}}:
-! CHECK:  %[[EXACT_BOX:.*]] = fir.box_addr %[[SELECTOR]] : (!fir.class<!fir.ptr<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>>) -> !fir.ref<!fir.type<_QMselect_type_lower_testTp2{a:i32,b:i32,c:i32}>>
-! CHECK:  %[[C3:.*]] = arith.constant 3 : i32
-! CHECK:  %[[COORD_C:.*]] = fir.coordinate_of %[[EXACT_BOX]], c : (!fir.ref<!fir.type<_QMselect_type_lower_testTp2{a:i32,b:i32,c:i32}>>) -> !fir.ref<i32>
-! CHECK:  fir.store %[[C3]] to %[[COORD_C]] : !fir.ref<i32>
-! CHECK:  cf.br ^bb{{.*}}
-! CHECK: ^bb{{.*}}
-! CHECK:  %[[C5:.*]] = arith.constant 5 : i32
-! CHECK:  %[[COORD_A:.*]] = fir.coordinate_of %[[SELECTOR]], a : (!fir.class<!fir.ptr<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>>) -> !fir.ref<i32>
-! CHECK:  fir.store %[[C5]] to %[[COORD_A]] : !fir.ref<i32>
-! CHECK:  cf.br ^bb{{.*}}
+! CHECK-SAME: %[[ARG0:.*]]: !fir.ref<!fir.class<!fir.ptr<!fir.type<_QMselect_type_lower_testTp1
+! CHECK: %[[ADECL:.*]]:2 = hlfir.declare %[[ARG0]]
+! CHECK: %[[SELECTOR:.*]] = fir.load %[[ADECL]]#0
+! CHECK: fir.select_type %[[SELECTOR]]
 
   subroutine select_type11(a)
     class(p1), allocatable :: a
@@ -689,21 +310,10 @@ subroutine select_type11(a)
   end subroutine
 
 ! CHECK-LABEL: func.func @_QMselect_type_lower_testPselect_type11(
-! CHECK-SAME: %[[ARG0:.*]]: !fir.ref<!fir.class<!fir.heap<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>>> {fir.bindc_name = "a"}) {
-! CHECK: %[[SELECTOR:.*]] = fir.load %[[ARG0]] : !fir.ref<!fir.class<!fir.heap<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>>>
-! CHECK: fir.select_type %[[SELECTOR]] : !fir.class<!fir.heap<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>> [#fir.type_is<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>, ^bb1, #fir.type_is<!fir.type<_QMselect_type_lower_testTp2{a:i32,b:i32,c:i32}>>, ^bb2, unit, ^bb3]
-! CHECK: ^bb{{.*}}:
-! CHECK:  %[[EXACT_BOX:.*]] = fir.box_addr %[[SELECTOR]] : (!fir.class<!fir.heap<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>>) -> !fir.ref<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>
-! CHECK:  %[[C1:.*]] = arith.constant 1 : i32
-! CHECK:  %[[COORD_A:.*]] = fir.coordinate_of %[[EXACT_BOX]], a : (!fir.ref<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>) -> !fir.ref<i32>
-! CHECK:  fir.store %[[C1]] to %[[COORD_A]] : !fir.ref<i32>
-! CHECK:  cf.br ^bb{{.*}}
-! CHECK: ^bb{{.*}}:
-! CHECK:  %[[EXACT_BOX:.*]] = fir.box_addr %[[SELECTOR]] : (!fir.class<!fir.heap<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>>) -> !fir.ref<!fir.type<_QMselect_type_lower_testTp2{a:i32,b:i32,c:i32}>>
-! CHECK:  %[[C3:.*]] = arith.constant 3 : i32
-! CHECK:  %[[COORD_C:.*]] = fir.coordinate_of %[[EXACT_BOX]], c : (!fir.ref<!fir.type<_QMselect_type_lower_testTp2{a:i32,b:i32,c:i32}>>) -> !fir.ref<i32>
-! CHECK:  fir.store %[[C3]] to %[[COORD_C]] : !fir.ref<i32>
-! CHECK:  cf.br ^bb{{.*}}
+! CHECK-SAME: %[[ARG0:.*]]: !fir.ref<!fir.class<!fir.heap<!fir.type<_QMselect_type_lower_testTp1
+! CHECK: %[[ADECL:.*]]:2 = hlfir.declare %[[ARG0]]
+! CHECK: %[[SELECTOR:.*]] = fir.load %[[ADECL]]#0
+! CHECK: fir.select_type %[[SELECTOR]]
 
   subroutine select_type12(a)
     class(p1), pointer :: a(:)
@@ -718,18 +328,10 @@ subroutine select_type12(a)
   end subroutine
 
 ! CHECK-LABEL: func.func @_QMselect_type_lower_testPselect_type12(
-! CHECK-SAME: %[[ARG0:.*]]: !fir.ref<!fir.class<!fir.ptr<!fir.array<?x!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>>>> {fir.bindc_name = "a"}) {
-! CHECK:  %[[LOAD:.*]] = fir.load %[[ARG0]] : !fir.ref<!fir.class<!fir.ptr<!fir.array<?x!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>>>>
-! CHECK:  %[[C0:.*]] = arith.constant 0 : index
-! CHECK:  %[[BOX_DIMS:.*]]:3 = fir.box_dims %[[LOAD]], %[[C0]] : (!fir.class<!fir.ptr<!fir.array<?x!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>>>, index) -> (index, index, index)
-! CHECK:  %[[SHIFT:.*]] = fir.shift %[[BOX_DIMS]]#0 : (index) -> !fir.shift<1>
-! CHECK:  %[[SELECTOR:.*]] = fir.rebox %[[LOAD]](%[[SHIFT]]) : (!fir.class<!fir.ptr<!fir.array<?x!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>>>, !fir.shift<1>) -> !fir.class<!fir.array<?x!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>>
-! CHECK:  fir.select_type %[[SELECTOR]] : !fir.class<!fir.array<?x!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>> [#fir.type_is<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>, ^bb1, #fir.type_is<!fir.type<_QMselect_type_lower_testTp2{a:i32,b:i32,c:i32}>>, ^bb2, #fir.class_is<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>, ^bb3, unit, ^bb4]
-! CHECK: ^bb{{.*}}:
-! CHECK:  %[[EXACT_BOX:.*]] = fir.convert %[[SELECTOR]] : (!fir.class<!fir.array<?x!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>>) -> !fir.box<!fir.array<?x!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>>
-! CHECK: ^bb{{.*}}:  // pred: ^bb0
-! CHECK:  %[[EXACT_BOX:.*]] = fir.convert %[[SELECTOR]] : (!fir.class<!fir.array<?x!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>>) -> !fir.box<!fir.array<?x!fir.type<_QMselect_type_lower_testTp2{a:i32,b:i32,c:i32}>>>
-
+! CHECK-SAME: %[[ARG0:.*]]: !fir.ref<!fir.class<!fir.ptr<!fir.array<?x!fir.type<_QMselect_type_lower_testTp1
+! CHECK: %[[ADECL:.*]]:2 = hlfir.declare %[[ARG0]]
+! CHECK: %[[LOAD:.*]] = fir.load %[[ADECL]]#0
+! CHECK: fir.select_type %{{.*}}
 
   ! Test correct lowering when CLASS DEFAULT is not at the last position in the
   ! SELECT TYPE construct.
@@ -754,15 +356,8 @@ subroutine select_type13(a)
   end subroutine
 
 ! CHECK-LABEL: func.func @_QMselect_type_lower_testPselect_type13
-! CHECK: fir.select_type %{{.*}} : !fir.class<!fir.array<?x!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>> [#fir.class_is<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>, ^bb2, unit, ^bb1]
-! CHECK: ^bb1:
-! CHECK: ^bb2:
-! CHECK: ^bb3:
-! CHECK: fir.select_type %{{.*}} : !fir.class<!fir.array<?x!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>> [#fir.type_is<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>, ^bb4, #fir.class_is<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>, ^bb6, unit, ^bb5]
-! CHECK: ^bb4:
-! CHECK: ^bb5:
-! CHECK: ^bb6:
-! CHECK: ^bb7:
+! CHECK: fir.select_type %{{[0-9a-zA-Z_]+}}{{.*}}#fir.class_is<!fir.type<_QMselect_type_lower_testTp1
+! CHECK: fir.select_type %{{[0-9a-zA-Z_]+}}{{.*}}#fir.type_is<!fir.type<_QMselect_type_lower_testTp1{{[^>]*}}>>{{.*}}#fir.class_is<!fir.type<_QMselect_type_lower_testTp1
 
   subroutine select_type14(a, b)
     class(p1) :: a, b
@@ -791,12 +386,13 @@ subroutine select_type15(a)
   end subroutine
 
 ! CHECK-LABEL: func.func @_QMselect_type_lower_testPselect_type15(
-! CHECK-SAME: %[[ARG0:.*]]: !fir.class<!fir.type<_QMselect_type_lower_testTp5{a:i32}>> {fir.bindc_name = "a"}) {
-! CHECK: %[[RES:.*]] = fir.alloca !fir.class<!fir.heap<!fir.type<_QMselect_type_lower_testTp5{a:i32}>>> {bindc_name = ".result"}
-! CHECK: %[[TMP_RES:.*]] = fir.dispatch "negate"(%[[ARG0]] : !fir.class<!fir.type<_QMselect_type_lower_testTp5{a:i32}>>) (%[[ARG0]] : !fir.class<!fir.type<_QMselect_type_lower_testTp5{a:i32}>>) -> !fir.class<!fir.heap<!fir.type<_QMselect_type_lower_testTp5{a:i32}>>> {pass_arg_pos = 0 : i32}
-! CHECK: fir.save_result %[[TMP_RES]] to %[[RES]] : !fir.class<!fir.heap<!fir.type<_QMselect_type_lower_testTp5{a:i32}>>>, !fir.ref<!fir.class<!fir.heap<!fir.type<_QMselect_type_lower_testTp5{a:i32}>>>>
-! CHECK: %[[LOAD_RES:.*]] = fir.load %[[RES]] : !fir.ref<!fir.class<!fir.heap<!fir.type<_QMselect_type_lower_testTp5{a:i32}>>>>
-! CHECK: fir.select_type %[[LOAD_RES]] : !fir.class<!fir.heap<!fir.type<_QMselect_type_lower_testTp5{a:i32}>>> [#fir.type_is<!fir.type<_QMselect_type_lower_testTp5{a:i32}>>, ^bb1, unit, ^bb2]
+! CHECK-SAME: %[[ARG0:.*]]: !fir.class<!fir.type<_QMselect_type_lower_testTp5{a:i32}>>
+! CHECK: %[[RES:.*]] = fir.alloca !fir.class<!fir.heap<!fir.type<_QMselect_type_lower_testTp5{a:i32}>>>
+! CHECK: %[[ADECL:.*]]:2 = hlfir.declare %[[ARG0]]
+! CHECK: %[[TMP_RES:.*]] = fir.dispatch "negate"(%[[ADECL]]#0
+! CHECK: fir.save_result %[[TMP_RES]] to %{{.*}}
+! CHECK: %[[LOAD_RES:.*]] = fir.load %{{.*}}
+! CHECK: fir.select_type %{{.*}}
 
 end module
 
diff --git a/flang/test/Lower/vector-subscript-io.f90 b/flang/test/Lower/vector-subscript-io.f90
index 0f64e99e03a20..afd565d94d9aa 100644
--- a/flang/test/Lower/vector-subscript-io.f90
+++ b/flang/test/Lower/vector-subscript-io.f90
@@ -1,45 +1,38 @@
 ! Test lowering of IO input items with vector subscripts
-! RUN: bbc -hlfir=false %s -o - | FileCheck %s
+! RUN: %flang_fc1 -emit-hlfir %s -o - | FileCheck %s
 ! UNSUPPORTED: system-windows
 
 ! CHECK-LABEL: func @_QPsimple(
-! CHECK-SAME: %[[VAL_20:.*]]: !fir.ref<!fir.array<10xi32>>{{.*}}, %[[VAL_16:.*]]: !fir.ref<!fir.array<3xi32>>{{.*}}) {
+! CHECK-SAME: %[[VAL_X_ARG:.*]]: !fir.ref<!fir.array<10xi32>>{{.*}}, %[[VAL_Y_ARG:.*]]: !fir.ref<!fir.array<3xi32>>{{.*}}) {
 subroutine simple(x, y)
   integer :: y(3)
   integer :: x(10)
   read(*,*) x(y)
-! CHECK-DAG: %[[VAL_0:.*]] = arith.constant 10 : index
-! CHECK-DAG: %[[VAL_1:.*]] = arith.constant 5 : i32
-! CHECK-DAG: %[[VAL_3:.*]] = arith.constant 4 : i32
-! CHECK-DAG: %[[VAL_4:.*]] = arith.constant 3 : index
-! CHECK-DAG: %[[VAL_5:.*]] = arith.constant 0 : index
-! CHECK-DAG: %[[VAL_6:.*]] = arith.constant 1 : index
+! CHECK-DAG: %[[VAL_C10:.*]] = arith.constant 10 : index
+! CHECK-DAG: %[[VAL_C3:.*]] = arith.constant 3 : index
+! CHECK-DAG: %[[VAL_X:.*]]:2 = hlfir.declare %[[VAL_X_ARG]](%{{.*}}){{.*}}{uniq_name = "_QFsimpleEx"}
+! CHECK-DAG: %[[VAL_Y:.*]]:2 = hlfir.declare %[[VAL_Y_ARG]](%{{.*}}){{.*}}{uniq_name = "_QFsimpleEy"}
+! CHECK-DAG: %[[VAL_5:.*]] = arith.constant 5 : i32
 ! CHECK:   %[[VAL_7:.*]] = fir.address_of(@_QQ{{.*}}) : !fir.ref<!fir.char<1,{{.*}}>>
 ! CHECK:   %[[VAL_8:.*]] = fir.convert %[[VAL_7]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
-! CHECK:   %[[VAL_9:.*]] = fir.call @_FortranAioBeginExternalListInput(%[[VAL_1]], %[[VAL_8]], %{{.*}}) {{.*}}: (i32, !fir.ref<i8>, i32) -> !fir.ref<i8>
-! CHECK:   %[[VAL_10:.*]] = fir.shape %[[VAL_0]] : (index) -> !fir.shape<1>
-! CHECK:   %[[VAL_11:.*]] = fir.slice %[[VAL_6]], %[[VAL_4]], %[[VAL_6]] : (index, index, index) -> !fir.slice<1>
-! CHECK:   cf.br ^bb1(%[[VAL_5]], %[[VAL_4]] : index, index)
-! CHECK: ^bb1(%[[VAL_12:.*]]: index, %[[VAL_13:.*]]: index):
-! CHECK:   %[[VAL_14:.*]] = arith.cmpi sgt, %[[VAL_13]], %[[VAL_5]] : index
-! CHECK:   cf.cond_br %[[VAL_14]], ^bb2, ^bb3
-! CHECK: ^bb2:
-! CHECK:   %[[VAL_15:.*]] = fir.coordinate_of %[[VAL_16]], %[[VAL_12]] : (!fir.ref<!fir.array<3xi32>>, index) -> !fir.ref<i32>
-! CHECK:   %[[VAL_17:.*]] = fir.load %[[VAL_15]] : !fir.ref<i32>
-! CHECK:   %[[VAL_18:.*]] = fir.convert %[[VAL_17]] : (i32) -> index
-! CHECK:   %[[VAL_19:.*]] = fir.array_coor %[[VAL_20]](%[[VAL_10]]) {{\[}}%[[VAL_11]]] %[[VAL_18]] : (!fir.ref<!fir.array<10xi32>>, !fir.shape<1>, !fir.slice<1>, index) -> !fir.ref<i32>
-! CHECK:   %[[VAL_21:.*]] = fir.convert %[[VAL_19]] : (!fir.ref<i32>) -> !fir.ref<i64>
-! CHECK:   %[[VAL_22:.*]] = fir.call @_FortranAioInputInteger(%[[VAL_9]], %[[VAL_21]], %[[VAL_3]]) {{.*}}: (!fir.ref<i8>, !fir.ref<i64>, i32) -> i1
-! CHECK:   %[[VAL_23:.*]] = arith.addi %[[VAL_12]], %[[VAL_6]] overflow<nsw> : index
-! CHECK:   %[[VAL_24:.*]] = arith.subi %[[VAL_13]], %[[VAL_6]] : index
-! CHECK:   cf.br ^bb1(%[[VAL_23]], %[[VAL_24]] : index, index)
-! CHECK: ^bb3:
+! CHECK:   %[[VAL_9:.*]] = fir.call @_FortranAioBeginExternalListInput(%[[VAL_5]], %[[VAL_8]], %{{.*}}) {{.*}}: (i32, !fir.ref<i8>, i32) -> !fir.ref<i8>
+! CHECK:   %[[SHAPE:.*]] = fir.shape %[[VAL_C10]] : (index) -> !fir.shape<1>
+! CHECK:   %[[VAL_11:.*]] = fir.slice %{{.*}}, %{{.*}}, %{{.*}} : (index, index, index) -> !fir.slice<1>
+! CHECK:   %[[VAL_BOUND:.*]] = arith.subi %{{.*}}, %{{.*}} : index
+! CHECK:   fir.do_loop %[[IDX:.*]] = %{{.*}} to %[[VAL_BOUND]] step %{{.*}} {
+! CHECK:     %[[VAL_15:.*]] = fir.coordinate_of %[[VAL_Y]]#0, %[[IDX]] : (!fir.ref<!fir.array<3xi32>>, index) -> !fir.ref<i32>
+! CHECK:     %[[VAL_17:.*]] = fir.load %[[VAL_15]] : !fir.ref<i32>
+! CHECK:     %[[VAL_18:.*]] = fir.convert %[[VAL_17]] : (i32) -> index
+! CHECK:     %[[VAL_19:.*]] = fir.array_coor %[[VAL_X]]#0(%[[SHAPE]]) {{\[}}%[[VAL_11]]] %[[VAL_18]] : (!fir.ref<!fir.array<10xi32>>, !fir.shape<1>, !fir.slice<1>, index) -> !fir.ref<i32>
+! CHECK:     %[[VAL_21:.*]] = fir.convert %[[VAL_19]] : (!fir.ref<i32>) -> !fir.ref<i64>
+! CHECK:     %[[VAL_22:.*]] = fir.call @_FortranAioInputInteger(%[[VAL_9]], %[[VAL_21]], %{{.*}}) {{.*}}: (!fir.ref<i8>, !fir.ref<i64>, i32) -> i1
+! CHECK:   }
 ! CHECK:   %[[VAL_25:.*]] = fir.call @_FortranAioEndIoStatement(%[[VAL_9]]) {{.*}}: (!fir.ref<i8>) -> i32
 ! CHECK:   return
 end subroutine
 
 ! CHECK-LABEL: func @_QPonly_once(
-! CHECK-SAME: %[[VAL_51:.*]]: !fir.box<!fir.array<?x?xf32>>{{.*}}) {
+! CHECK-SAME: %[[VAL_X_ARG:.*]]: !fir.box<!fir.array<?x?xf32>>{{.*}}) {
 subroutine only_once(x)
   interface
     function get_vector()
@@ -51,325 +44,223 @@ integer function get_substcript()
   real :: x(:, :)
   ! Test subscripts are only evaluated once.
   read(*,*) x(get_substcript(), get_vector())
-! CHECK-DAG: %[[VAL_26:.*]] = arith.constant 5 : i32
-! CHECK-DAG: %[[VAL_28:.*]] = arith.constant 0 : i64
-! CHECK-DAG: %[[VAL_29:.*]] = arith.constant 0 : index
-! CHECK-DAG: %[[VAL_30:.*]] = arith.constant 1 : index
-! CHECK:   %[[VAL_31:.*]] = fir.alloca !fir.box<!fir.heap<!fir.array<?xi32>>> {bindc_name = ".result"}
-! CHECK:   %[[VAL_32:.*]] = fir.address_of(@_QQ{{.*}}) : !fir.ref<!fir.char<1,{{.*}}>>
-! CHECK:   %[[VAL_33:.*]] = fir.convert %[[VAL_32]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
-! CHECK:   %[[VAL_34:.*]] = fir.call @_FortranAioBeginExternalListInput(%[[VAL_26]], %[[VAL_33]], %{{.*}}) {{.*}}: (i32, !fir.ref<i8>, i32) -> !fir.ref<i8>
-! CHECK:   %[[VAL_35:.*]] = fir.call @_QPget_substcript() {{.*}}: () -> i32
-! CHECK:   %[[VAL_36:.*]] = fir.convert %[[VAL_35]] : (i32) -> i64
-! CHECK:   %[[VAL_37:.*]] = fir.call @_QPget_vector() {{.*}}: () -> !fir.box<!fir.heap<!fir.array<?xi32>>>
-! CHECK:   fir.save_result %[[VAL_37]] to %[[VAL_31]] : !fir.box<!fir.heap<!fir.array<?xi32>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
-! CHECK:   %[[VAL_38:.*]] = fir.load %[[VAL_31]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
-! CHECK:   %[[VAL_39:.*]]:3 = fir.box_dims %[[VAL_38]], %[[VAL_29]] : (!fir.box<!fir.heap<!fir.array<?xi32>>>, index) -> (index, index, index)
-! CHECK:   %[[VAL_40:.*]] = fir.box_addr %[[VAL_38]] : (!fir.box<!fir.heap<!fir.array<?xi32>>>) -> !fir.heap<!fir.array<?xi32>>
-! CHECK:   %[[VAL_41:.*]] = fir.undefined index
-! CHECK:   %[[VAL_42:.*]] = fir.slice %[[VAL_36]], %[[VAL_41]], %[[VAL_41]], %[[VAL_30]], %[[VAL_39]]#1, %[[VAL_30]] : (i64, index, index, index, index, index) -> !fir.slice<2>
-! CHECK:   cf.br ^bb1(%[[VAL_29]], %[[VAL_39]]#1 : index, index)
-! CHECK: ^bb1(%[[VAL_43:.*]]: index, %[[VAL_44:.*]]: index):
-! CHECK:   %[[VAL_45:.*]] = arith.cmpi sgt, %[[VAL_44]], %[[VAL_29]] : index
-! CHECK:   cf.cond_br %[[VAL_45]], ^bb2, ^bb3
-! CHECK: ^bb2:
-! CHECK:   %[[VAL_46:.*]] = fir.convert %[[VAL_35]] : (i32) -> index
-! CHECK:   %[[VAL_47:.*]] = fir.coordinate_of %[[VAL_40]], %[[VAL_43]] : (!fir.heap<!fir.array<?xi32>>, index) -> !fir.ref<i32>
-! CHECK:   %[[VAL_48:.*]] = fir.load %[[VAL_47]] : !fir.ref<i32>
-! CHECK:   %[[VAL_49:.*]] = fir.convert %[[VAL_48]] : (i32) -> index
-! CHECK:   %[[VAL_50:.*]] = fir.array_coor %[[VAL_51]] {{\[}}%[[VAL_42]]] %[[VAL_46]], %[[VAL_49]] : (!fir.box<!fir.array<?x?xf32>>, !fir.slice<2>, index, index) -> !fir.ref<f32>
-! CHECK:   %[[VAL_52:.*]] = fir.call @_FortranAioInputReal32(%[[VAL_34]], %[[VAL_50]]) {{.*}}: (!fir.ref<i8>, !fir.ref<f32>) -> i1
-! CHECK:   %[[VAL_53:.*]] = arith.addi %[[VAL_43]], %[[VAL_30]] overflow<nsw> : index
-! CHECK:   %[[VAL_54:.*]] = arith.subi %[[VAL_44]], %[[VAL_30]] : index
-! CHECK:   cf.br ^bb1(%[[VAL_53]], %[[VAL_54]] : index, index)
-! CHECK: ^bb3:
-! CHECK:   %[[VAL_55:.*]] = fir.load %[[VAL_31]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
-! CHECK:   %[[VAL_56:.*]] = fir.box_addr %[[VAL_55]] : (!fir.box<!fir.heap<!fir.array<?xi32>>>) -> !fir.heap<!fir.array<?xi32>>
-! CHECK:   %[[VAL_57:.*]] = fir.convert %[[VAL_56]] : (!fir.heap<!fir.array<?xi32>>) -> i64
-! CHECK:   %[[VAL_58:.*]] = arith.cmpi ne, %[[VAL_57]], %[[VAL_28]] : i64
-! CHECK:   cf.cond_br %[[VAL_58]], ^bb4, ^bb5
-! CHECK: ^bb4:
-! CHECK:   fir.freemem %[[VAL_56]] : !fir.heap<!fir.array<?xi32>>
-! CHECK:   cf.br ^bb5
-! CHECK: ^bb5:
-! CHECK:   %[[VAL_59:.*]] = fir.call @_FortranAioEndIoStatement(%[[VAL_34]]) {{.*}}: (!fir.ref<i8>) -> i32
+! CHECK:   %[[VAL_RES:.*]] = fir.alloca !fir.box<!fir.heap<!fir.array<?xi32>>> {bindc_name = ".result"}
+! CHECK:   %[[VAL_X:.*]]:2 = hlfir.declare %[[VAL_X_ARG]]{{.*}}{uniq_name = "_QFonly_onceEx"}
+! CHECK:   %[[VAL_BEGIN:.*]] = fir.call @_FortranAioBeginExternalListInput({{.*}}) {{.*}}: (i32, !fir.ref<i8>, i32) -> !fir.ref<i8>
+! CHECK:   %[[VAL_SUB:.*]] = fir.call @_QPget_substcript() {{.*}}: () -> i32
+! CHECK:   %[[VAL_SUB_I64:.*]] = fir.convert %[[VAL_SUB]] : (i32) -> i64
+! CHECK:   %[[VAL_RES_DECL:.*]]:2 = hlfir.declare %[[VAL_RES]] {uniq_name = ".tmp.func_result"}
+! CHECK:   %[[VAL_GETVEC:.*]] = fir.call @_QPget_vector() {{.*}}: () -> !fir.box<!fir.heap<!fir.array<?xi32>>>
+! CHECK:   fir.save_result %[[VAL_GETVEC]] to %[[VAL_RES_DECL]]#0
+! CHECK:   %[[VAL_LOAD:.*]] = fir.load %[[VAL_RES_DECL]]#0 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
+! CHECK:   %[[VAL_EXPR:.*]] = hlfir.as_expr %[[VAL_LOAD]] move %{{.*}} : (!fir.box<!fir.heap<!fir.array<?xi32>>>, i1) -> !hlfir.expr<?xi32>
+! CHECK:   %[[VAL_DIMS:.*]]:3 = fir.box_dims %[[VAL_LOAD]], %{{.*}} : (!fir.box<!fir.heap<!fir.array<?xi32>>>, index) -> (index, index, index)
+! CHECK:   %[[VAL_SHAPE:.*]] = fir.shape %[[VAL_DIMS]]#1 : (index) -> !fir.shape<1>
+! CHECK:   %[[VAL_ASSOC:.*]]:3 = hlfir.associate %[[VAL_EXPR]](%[[VAL_SHAPE]]) {adapt.valuebyref} : (!hlfir.expr<?xi32>, !fir.shape<1>) -> (!fir.box<!fir.array<?xi32>>, !fir.ref<!fir.array<?xi32>>, i1)
+! CHECK:   %[[VAL_SLICE:.*]] = fir.slice %[[VAL_SUB_I64]], %{{.*}}, %{{.*}}, %{{.*}}, %[[VAL_DIMS]]#1, %{{.*}} : (i64, index, index, index, index, index) -> !fir.slice<2>
+! CHECK:   fir.do_loop %[[IDX:.*]] = %{{.*}} to %{{.*}} step %{{.*}} {
+! CHECK:     %[[SUB_IDX:.*]] = fir.convert %[[VAL_SUB_I64]] : (i64) -> index
+! CHECK:     %[[VEL:.*]] = fir.coordinate_of %[[VAL_ASSOC]]#1, %[[IDX]] : (!fir.ref<!fir.array<?xi32>>, index) -> !fir.ref<i32>
+! CHECK:     %[[VEL_LD:.*]] = fir.load %[[VEL]] : !fir.ref<i32>
+! CHECK:     %[[VEL_IDX:.*]] = fir.convert %[[VEL_LD]] : (i32) -> index
+! CHECK:     %[[ELEM:.*]] = fir.array_coor %[[VAL_X]]#1 {{\[}}%[[VAL_SLICE]]] %[[SUB_IDX]], %[[VEL_IDX]] : (!fir.box<!fir.array<?x?xf32>>, !fir.slice<2>, index, index) -> !fir.ref<f32>
+! CHECK:     %{{.*}} = fir.call @_FortranAioInputReal32(%[[VAL_BEGIN]], %[[ELEM]]) {{.*}}: (!fir.ref<i8>, !fir.ref<f32>) -> i1
+! CHECK:   }
+! CHECK:   hlfir.end_associate %[[VAL_ASSOC]]#1, %[[VAL_ASSOC]]#2 : !fir.ref<!fir.array<?xi32>>, i1
+! CHECK:   hlfir.destroy %[[VAL_EXPR]] : !hlfir.expr<?xi32>
+! CHECK:   %{{.*}} = fir.call @_FortranAioEndIoStatement(%[[VAL_BEGIN]]) {{.*}}: (!fir.ref<i8>) -> i32
 ! CHECK:   return
 end subroutine
 
 ! CHECK-LABEL: func @_QPwith_assumed_shapes(
-! CHECK-SAME: %[[VAL_78:.*]]: !fir.box<!fir.array<?xi32>>{{.*}}, %[[VAL_69:.*]]: !fir.box<!fir.array<?xi32>>{{.*}}) {
+! CHECK-SAME: %[[VAL_X_ARG:.*]]: !fir.box<!fir.array<?xi32>>{{.*}}, %[[VAL_Y_ARG:.*]]: !fir.box<!fir.array<?xi32>>{{.*}}) {
 subroutine with_assumed_shapes(x, y)
   integer :: y(:)
   integer :: x(:)
   read(*,*) x(y)
-! CHECK-DAG: %[[VAL_60:.*]] = arith.constant 5 : i32
-! CHECK-DAG: %[[VAL_62:.*]] = arith.constant 4 : i32
-! CHECK-DAG: %[[VAL_63:.*]] = arith.constant 0 : index
-! CHECK-DAG: %[[VAL_64:.*]] = arith.constant 1 : index
-! CHECK:   %[[VAL_65:.*]] = fir.address_of(@_QQ{{.*}}) : !fir.ref<!fir.char<1,{{.*}}>>
-! CHECK:   %[[VAL_66:.*]] = fir.convert %[[VAL_65]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
-! CHECK:   %[[VAL_67:.*]] = fir.call @_FortranAioBeginExternalListInput(%[[VAL_60]], %[[VAL_66]], %{{.*}}) {{.*}}: (i32, !fir.ref<i8>, i32) -> !fir.ref<i8>
-! CHECK:   %[[VAL_68:.*]]:3 = fir.box_dims %[[VAL_69]], %[[VAL_63]] : (!fir.box<!fir.array<?xi32>>, index) -> (index, index, index)
-! CHECK:   %[[VAL_70:.*]] = fir.slice %[[VAL_64]], %[[VAL_68]]#1, %[[VAL_64]] : (index, index, index) -> !fir.slice<1>
-! CHECK:   cf.br ^bb1(%[[VAL_63]], %[[VAL_68]]#1 : index, index)
-! CHECK: ^bb1(%[[VAL_71:.*]]: index, %[[VAL_72:.*]]: index):
-! CHECK:   %[[VAL_73:.*]] = arith.cmpi sgt, %[[VAL_72]], %[[VAL_63]] : index
-! CHECK:   cf.cond_br %[[VAL_73]], ^bb2, ^bb3
-! CHECK: ^bb2:
-! CHECK:   %[[VAL_74:.*]] = fir.coordinate_of %[[VAL_69]], %[[VAL_71]] : (!fir.box<!fir.array<?xi32>>, index) -> !fir.ref<i32>
-! CHECK:   %[[VAL_75:.*]] = fir.load %[[VAL_74]] : !fir.ref<i32>
-! CHECK:   %[[VAL_76:.*]] = fir.convert %[[VAL_75]] : (i32) -> index
-! CHECK:   %[[VAL_77:.*]] = fir.array_coor %[[VAL_78]] {{\[}}%[[VAL_70]]] %[[VAL_76]] : (!fir.box<!fir.array<?xi32>>, !fir.slice<1>, index) -> !fir.ref<i32>
-! CHECK:   %[[VAL_79:.*]] = fir.convert %[[VAL_77]] : (!fir.ref<i32>) -> !fir.ref<i64>
-! CHECK:   %[[VAL_80:.*]] = fir.call @_FortranAioInputInteger(%[[VAL_67]], %[[VAL_79]], %[[VAL_62]]) {{.*}}: (!fir.ref<i8>, !fir.ref<i64>, i32) -> i1
-! CHECK:   %[[VAL_81:.*]] = arith.addi %[[VAL_71]], %[[VAL_64]] overflow<nsw> : index
-! CHECK:   %[[VAL_82:.*]] = arith.subi %[[VAL_72]], %[[VAL_64]] : index
-! CHECK:   cf.br ^bb1(%[[VAL_81]], %[[VAL_82]] : index, index)
-! CHECK: ^bb3:
-! CHECK:   %[[VAL_83:.*]] = fir.call @_FortranAioEndIoStatement(%[[VAL_67]]) {{.*}}: (!fir.ref<i8>) -> i32
+! CHECK:   %[[VAL_X:.*]]:2 = hlfir.declare %[[VAL_X_ARG]]{{.*}}{uniq_name = "_QFwith_assumed_shapesEx"}
+! CHECK:   %[[VAL_Y:.*]]:2 = hlfir.declare %[[VAL_Y_ARG]]{{.*}}{uniq_name = "_QFwith_assumed_shapesEy"}
+! CHECK:   %[[VAL_BEGIN:.*]] = fir.call @_FortranAioBeginExternalListInput({{.*}}) {{.*}}: (i32, !fir.ref<i8>, i32) -> !fir.ref<i8>
+! CHECK:   %[[VAL_DIMS:.*]]:3 = fir.box_dims %[[VAL_Y]]#1, %{{.*}} : (!fir.box<!fir.array<?xi32>>, index) -> (index, index, index)
+! CHECK:   %[[VAL_C1:.*]] = arith.constant 1 : index
+! CHECK:   %[[VAL_SLICE:.*]] = fir.slice %[[VAL_C1]], %[[VAL_DIMS]]#1, %[[VAL_C1]] : (index, index, index) -> !fir.slice<1>
+! CHECK:   fir.do_loop %[[IDX:.*]] = %{{.*}} to %{{.*}} step %{{.*}} {
+! CHECK:     %[[VEL:.*]] = fir.coordinate_of %[[VAL_Y]]#1, %[[IDX]] : (!fir.box<!fir.array<?xi32>>, index) -> !fir.ref<i32>
+! CHECK:     %[[VEL_LD:.*]] = fir.load %[[VEL]] : !fir.ref<i32>
+! CHECK:     %[[VEL_IDX:.*]] = fir.convert %[[VEL_LD]] : (i32) -> index
+! CHECK:     %[[ELEM:.*]] = fir.array_coor %[[VAL_X]]#1 {{\[}}%[[VAL_SLICE]]] %[[VEL_IDX]] : (!fir.box<!fir.array<?xi32>>, !fir.slice<1>, index) -> !fir.ref<i32>
+! CHECK:     %[[VAL_79:.*]] = fir.convert %[[ELEM]] : (!fir.ref<i32>) -> !fir.ref<i64>
+! CHECK:     %{{.*}} = fir.call @_FortranAioInputInteger(%[[VAL_BEGIN]], %[[VAL_79]], %{{.*}}) {{.*}}: (!fir.ref<i8>, !fir.ref<i64>, i32) -> i1
+! CHECK:   }
+! CHECK:   %{{.*}} = fir.call @_FortranAioEndIoStatement(%[[VAL_BEGIN]]) {{.*}}: (!fir.ref<i8>) -> i32
 ! CHECK:   return
 end subroutine
 
 ! CHECK-LABEL: func @_QPlower_bounds(
-! CHECK-SAME: %[[VAL_108:.*]]: !fir.ref<!fir.array<4x6xi32>>{{.*}}, %[[VAL_104:.*]]: !fir.ref<!fir.array<3xi32>>{{.*}}) {
+! CHECK-SAME: %[[VAL_X_ARG:.*]]: !fir.ref<!fir.array<4x6xi32>>{{.*}}, %[[VAL_Y_ARG:.*]]: !fir.ref<!fir.array<3xi32>>{{.*}}) {
 subroutine lower_bounds(x, y)
   integer :: y(3)
   integer :: x(2:5,3:8)
   read(*,*) x(3, y)
-! CHECK-DAG: %[[VAL_84:.*]] = arith.constant 4 : index
-! CHECK-DAG: %[[VAL_85:.*]] = arith.constant 6 : index
-! CHECK-DAG: %[[VAL_86:.*]] = arith.constant 5 : i32
-! CHECK-DAG: %[[VAL_88:.*]] = arith.constant 3 : i64
-! CHECK-DAG: %[[VAL_89:.*]] = arith.constant 2 : index
-! CHECK-DAG: %[[VAL_90:.*]] = arith.constant 4 : i32
-! CHECK-DAG: %[[VAL_91:.*]] = arith.constant 3 : index
-! CHECK-DAG: %[[VAL_92:.*]] = arith.constant 0 : index
-! CHECK-DAG: %[[VAL_93:.*]] = arith.constant 1 : index
-! CHECK:   %[[VAL_94:.*]] = fir.address_of(@_QQ{{.*}}) : !fir.ref<!fir.char<1,{{.*}}>>
-! CHECK:   %[[VAL_95:.*]] = fir.convert %[[VAL_94]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
-! CHECK:   %[[VAL_96:.*]] = fir.call @_FortranAioBeginExternalListInput(%[[VAL_86]], %[[VAL_95]], %{{.*}}) {{.*}}: (i32, !fir.ref<i8>, i32) -> !fir.ref<i8>
-! CHECK:   %[[VAL_97:.*]] = fir.shape_shift %[[VAL_89]], %[[VAL_84]], %[[VAL_91]], %[[VAL_85]] : (index, index, index, index) -> !fir.shapeshift<2>
-! CHECK:   %[[VAL_98:.*]] = fir.undefined index
-! CHECK:   %[[VAL_99:.*]] = fir.slice %[[VAL_88]], %[[VAL_98]], %[[VAL_98]], %[[VAL_93]], %[[VAL_91]], %[[VAL_93]] : (i64, index, index, index, index, index) -> !fir.slice<2>
-! CHECK:   cf.br ^bb1(%[[VAL_92]], %[[VAL_91]] : index, index)
-! CHECK: ^bb1(%[[VAL_100:.*]]: index, %[[VAL_101:.*]]: index):
-! CHECK:   %[[VAL_102:.*]] = arith.cmpi sgt, %[[VAL_101]], %[[VAL_92]] : index
-! CHECK:   cf.cond_br %[[VAL_102]], ^bb2, ^bb3
-! CHECK: ^bb2:
-! CHECK:   %[[VAL_103:.*]] = fir.coordinate_of %[[VAL_104]], %[[VAL_100]] : (!fir.ref<!fir.array<3xi32>>, index) -> !fir.ref<i32>
-! CHECK:   %[[VAL_105:.*]] = fir.load %[[VAL_103]] : !fir.ref<i32>
-! CHECK:   %[[VAL_106:.*]] = fir.convert %[[VAL_105]] : (i32) -> index
-! CHECK:   %[[VAL_107:.*]] = fir.array_coor %[[VAL_108]](%[[VAL_97]]) {{\[}}%[[VAL_99]]] %[[VAL_91]], %[[VAL_106]] : (!fir.ref<!fir.array<4x6xi32>>, !fir.shapeshift<2>, !fir.slice<2>, index, index) -> !fir.ref<i32>
-! CHECK:   %[[VAL_109:.*]] = fir.convert %[[VAL_107]] : (!fir.ref<i32>) -> !fir.ref<i64>
-! CHECK:   %[[VAL_110:.*]] = fir.call @_FortranAioInputInteger(%[[VAL_96]], %[[VAL_109]], %[[VAL_90]]) {{.*}}: (!fir.ref<i8>, !fir.ref<i64>, i32) -> i1
-! CHECK:   %[[VAL_111:.*]] = arith.addi %[[VAL_100]], %[[VAL_93]] overflow<nsw> : index
-! CHECK:   %[[VAL_112:.*]] = arith.subi %[[VAL_101]], %[[VAL_93]] : index
-! CHECK:   cf.br ^bb1(%[[VAL_111]], %[[VAL_112]] : index, index)
-! CHECK: ^bb3:
-! CHECK:   %[[VAL_113:.*]] = fir.call @_FortranAioEndIoStatement(%[[VAL_96]]) {{.*}}: (!fir.ref<i8>) -> i32
+! CHECK:   %[[VAL_SS:.*]] = fir.shape_shift %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}} : (index, index, index, index) -> !fir.shapeshift<2>
+! CHECK:   %[[VAL_X:.*]]:2 = hlfir.declare %[[VAL_X_ARG]](%[[VAL_SS]]){{.*}}{uniq_name = "_QFlower_boundsEx"}
+! CHECK:   %[[VAL_Y:.*]]:2 = hlfir.declare %[[VAL_Y_ARG]](%{{.*}}){{.*}}{uniq_name = "_QFlower_boundsEy"}
+! CHECK:   %[[VAL_BEGIN:.*]] = fir.call @_FortranAioBeginExternalListInput({{.*}}) {{.*}}: (i32, !fir.ref<i8>, i32) -> !fir.ref<i8>
+! CHECK:   %[[VAL_C3I64:.*]] = arith.constant 3 : i64
+! CHECK:   %[[VAL_SS2:.*]] = fir.shape_shift %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}} : (index, index, index, index) -> !fir.shapeshift<2>
+! CHECK:   %[[VAL_UNDEF:.*]] = fir.undefined index
+! CHECK:   %[[VAL_SLICE:.*]] = fir.slice %[[VAL_C3I64]], %[[VAL_UNDEF]], %[[VAL_UNDEF]], %{{.*}}, %{{.*}}, %{{.*}} : (i64, index, index, index, index, index) -> !fir.slice<2>
+! CHECK:   fir.do_loop %[[IDX:.*]] = %{{.*}} to %{{.*}} step %{{.*}} {
+! CHECK:     %[[VAL_C3IDX:.*]] = fir.convert %[[VAL_C3I64]] : (i64) -> index
+! CHECK:     %[[VEL:.*]] = fir.coordinate_of %[[VAL_Y]]#0, %[[IDX]] : (!fir.ref<!fir.array<3xi32>>, index) -> !fir.ref<i32>
+! CHECK:     %[[VEL_LD:.*]] = fir.load %[[VEL]] : !fir.ref<i32>
+! CHECK:     %[[VEL_IDX:.*]] = fir.convert %[[VEL_LD]] : (i32) -> index
+! CHECK:     %[[ELEM:.*]] = fir.array_coor %[[VAL_X]]#1(%[[VAL_SS2]]) {{\[}}%[[VAL_SLICE]]] %[[VAL_C3IDX]], %[[VEL_IDX]] : (!fir.ref<!fir.array<4x6xi32>>, !fir.shapeshift<2>, !fir.slice<2>, index, index) -> !fir.ref<i32>
+! CHECK:     %{{.*}} = fir.convert %[[ELEM]] : (!fir.ref<i32>) -> !fir.ref<i64>
+! CHECK:     %{{.*}} = fir.call @_FortranAioInputInteger({{.*}}) {{.*}}: (!fir.ref<i8>, !fir.ref<i64>, i32) -> i1
+! CHECK:   }
+! CHECK:   %{{.*}} = fir.call @_FortranAioEndIoStatement(%[[VAL_BEGIN]]) {{.*}}: (!fir.ref<i8>) -> i32
 ! CHECK:   return
 end subroutine
 
 ! CHECK-LABEL: func @_QPtwo_vectors(
-! CHECK-SAME: %[[VAL_140:.*]]: !fir.ref<!fir.array<4x4xf32>>{{.*}}, %[[VAL_132:.*]]: !fir.ref<!fir.array<3xi32>>{{.*}}, %[[VAL_136:.*]]: !fir.ref<!fir.array<3xi32>>{{.*}}) {
+! CHECK-SAME: %[[VAL_X_ARG:.*]]: !fir.ref<!fir.array<4x4xf32>>{{.*}}, %[[VAL_Y1_ARG:.*]]: !fir.ref<!fir.array<3xi32>>{{.*}}, %[[VAL_Y2_ARG:.*]]: !fir.ref<!fir.array<3xi32>>{{.*}}) {
 subroutine two_vectors(x, y1, y2)
   integer :: y1(3), y2(3)
   real :: x(4, 4)
   read(*,*) x(y1, y2)
-! CHECK-DAG: %[[VAL_114:.*]] = arith.constant 4 : index
-! CHECK-DAG: %[[VAL_115:.*]] = arith.constant 5 : i32
-! CHECK-DAG: %[[VAL_117:.*]] = arith.constant 3 : index
-! CHECK-DAG: %[[VAL_118:.*]] = arith.constant 0 : index
-! CHECK-DAG: %[[VAL_119:.*]] = arith.constant 1 : index
-! CHECK:   %[[VAL_120:.*]] = fir.address_of(@_QQ{{.*}}) : !fir.ref<!fir.char<1,{{.*}}>>
-! CHECK:   %[[VAL_121:.*]] = fir.convert %[[VAL_120]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
-! CHECK:   %[[VAL_122:.*]] = fir.call @_FortranAioBeginExternalListInput(%[[VAL_115]], %[[VAL_121]], %{{.*}}) {{.*}}: (i32, !fir.ref<i8>, i32) -> !fir.ref<i8>
-! CHECK:   %[[VAL_123:.*]] = fir.shape %[[VAL_114]], %[[VAL_114]] : (index, index) -> !fir.shape<2>
-! CHECK:   %[[VAL_124:.*]] = fir.slice %[[VAL_119]], %[[VAL_117]], %[[VAL_119]], %[[VAL_119]], %[[VAL_117]], %[[VAL_119]] : (index, index, index, index, index, index) -> !fir.slice<2>
-! CHECK:   cf.br ^bb1(%[[VAL_118]], %[[VAL_117]] : index, index)
-! CHECK: ^bb1(%[[VAL_125:.*]]: index, %[[VAL_126:.*]]: index):
-! CHECK:   %[[VAL_127:.*]] = arith.cmpi sgt, %[[VAL_126]], %[[VAL_118]] : index
-! CHECK:   cf.cond_br %[[VAL_127]], ^bb2(%[[VAL_118]], %[[VAL_117]] : index, index), ^bb5
-! CHECK: ^bb2(%[[VAL_128:.*]]: index, %[[VAL_129:.*]]: index):
-! CHECK:   %[[VAL_130:.*]] = arith.cmpi sgt, %[[VAL_129]], %[[VAL_118]] : index
-! CHECK:   cf.cond_br %[[VAL_130]], ^bb3, ^bb4
-! CHECK: ^bb3:
-! CHECK:   %[[VAL_131:.*]] = fir.coordinate_of %[[VAL_132]], %[[VAL_128]] : (!fir.ref<!fir.array<3xi32>>, index) -> !fir.ref<i32>
-! CHECK:   %[[VAL_133:.*]] = fir.load %[[VAL_131]] : !fir.ref<i32>
-! CHECK:   %[[VAL_134:.*]] = fir.convert %[[VAL_133]] : (i32) -> index
-! CHECK:   %[[VAL_135:.*]] = fir.coordinate_of %[[VAL_136]], %[[VAL_125]] : (!fir.ref<!fir.array<3xi32>>, index) -> !fir.ref<i32>
-! CHECK:   %[[VAL_137:.*]] = fir.load %[[VAL_135]] : !fir.ref<i32>
-! CHECK:   %[[VAL_138:.*]] = fir.convert %[[VAL_137]] : (i32) -> index
-! CHECK:   %[[VAL_139:.*]] = fir.array_coor %[[VAL_140]](%[[VAL_123]]) {{\[}}%[[VAL_124]]] %[[VAL_134]], %[[VAL_138]] : (!fir.ref<!fir.array<4x4xf32>>, !fir.shape<2>, !fir.slice<2>, index, index) -> !fir.ref<f32>
-! CHECK:   %[[VAL_141:.*]] = fir.call @_FortranAioInputReal32(%[[VAL_122]], %[[VAL_139]]) {{.*}}: (!fir.ref<i8>, !fir.ref<f32>) -> i1
-! CHECK:   %[[VAL_142:.*]] = arith.addi %[[VAL_128]], %[[VAL_119]] overflow<nsw> : index
-! CHECK:   %[[VAL_143:.*]] = arith.subi %[[VAL_129]], %[[VAL_119]] : index
-! CHECK:   cf.br ^bb2(%[[VAL_142]], %[[VAL_143]] : index, index)
-! CHECK: ^bb4:
-! CHECK:   %[[VAL_144:.*]] = arith.addi %[[VAL_125]], %[[VAL_119]] overflow<nsw> : index
-! CHECK:   %[[VAL_145:.*]] = arith.subi %[[VAL_126]], %[[VAL_119]] : index
-! CHECK:   cf.br ^bb1(%[[VAL_144]], %[[VAL_145]] : index, index)
-! CHECK: ^bb5:
-! CHECK:   %[[VAL_146:.*]] = fir.call @_FortranAioEndIoStatement(%[[VAL_122]]) {{.*}}: (!fir.ref<i8>) -> i32
+! CHECK:   %[[VAL_X:.*]]:2 = hlfir.declare %[[VAL_X_ARG]](%{{.*}}){{.*}}{uniq_name = "_QFtwo_vectorsEx"}
+! CHECK:   %[[VAL_Y1:.*]]:2 = hlfir.declare %[[VAL_Y1_ARG]](%{{.*}}){{.*}}{uniq_name = "_QFtwo_vectorsEy1"}
+! CHECK:   %[[VAL_Y2:.*]]:2 = hlfir.declare %[[VAL_Y2_ARG]](%{{.*}}){{.*}}{uniq_name = "_QFtwo_vectorsEy2"}
+! CHECK:   %[[VAL_BEGIN:.*]] = fir.call @_FortranAioBeginExternalListInput({{.*}}) {{.*}}: (i32, !fir.ref<i8>, i32) -> !fir.ref<i8>
+! CHECK:   %[[VAL_SHAPE:.*]] = fir.shape %{{.*}}, %{{.*}} : (index, index) -> !fir.shape<2>
+! CHECK:   %[[VAL_SLICE:.*]] = fir.slice %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}} : (index, index, index, index, index, index) -> !fir.slice<2>
+! CHECK:   fir.do_loop %[[IDX_OUTER:.*]] = %{{.*}} to %{{.*}} step %{{.*}} {
+! CHECK:     fir.do_loop %[[IDX_INNER:.*]] = %{{.*}} to %{{.*}} step %{{.*}} {
+! CHECK:       %[[Y1_EL:.*]] = fir.coordinate_of %[[VAL_Y1]]#0, %[[IDX_INNER]] : (!fir.ref<!fir.array<3xi32>>, index) -> !fir.ref<i32>
+! CHECK:       %[[Y1_LD:.*]] = fir.load %[[Y1_EL]] : !fir.ref<i32>
+! CHECK:       %[[Y1_IDX:.*]] = fir.convert %[[Y1_LD]] : (i32) -> index
+! CHECK:       %[[Y2_EL:.*]] = fir.coordinate_of %[[VAL_Y2]]#0, %[[IDX_OUTER]] : (!fir.ref<!fir.array<3xi32>>, index) -> !fir.ref<i32>
+! CHECK:       %[[Y2_LD:.*]] = fir.load %[[Y2_EL]] : !fir.ref<i32>
+! CHECK:       %[[Y2_IDX:.*]] = fir.convert %[[Y2_LD]] : (i32) -> index
+! CHECK:       %[[ELEM:.*]] = fir.array_coor %[[VAL_X]]#0(%[[VAL_SHAPE]]) {{\[}}%[[VAL_SLICE]]] %[[Y1_IDX]], %[[Y2_IDX]] : (!fir.ref<!fir.array<4x4xf32>>, !fir.shape<2>, !fir.slice<2>, index, index) -> !fir.ref<f32>
+! CHECK:       %{{.*}} = fir.call @_FortranAioInputReal32(%[[VAL_BEGIN]], %[[ELEM]]) {{.*}}: (!fir.ref<i8>, !fir.ref<f32>) -> i1
+! CHECK:     }
+! CHECK:   }
+! CHECK:   %{{.*}} = fir.call @_FortranAioEndIoStatement(%[[VAL_BEGIN]]) {{.*}}: (!fir.ref<i8>) -> i32
 ! CHECK:   return
 end subroutine
 
 ! CHECK-LABEL: func @_QPtriplets_and_vector(
-! CHECK-SAME:    %[[VAL_170:.*]]: !fir.ref<!fir.array<4x4xcomplex<f32>>>{{.*}}, %[[VAL_166:.*]]: !fir.ref<!fir.array<3xi32>>{{.*}}) {
+! CHECK-SAME:    %[[VAL_X_ARG:.*]]: !fir.ref<!fir.array<4x4xcomplex<f32>>>{{.*}}, %[[VAL_Y_ARG:.*]]: !fir.ref<!fir.array<3xi32>>{{.*}}) {
 subroutine triplets_and_vector(x, y)
   integer :: y(3)
   complex :: x(4, 4)
   read(*,*) x(1:4:2, y)
-! CHECK-DAG: %[[VAL_147:.*]] = arith.constant 5 : i32
-! CHECK-DAG: %[[VAL_149:.*]] = arith.constant 4 : index
-! CHECK-DAG: %[[VAL_150:.*]] = arith.constant 3 : index
-! CHECK-DAG: %[[VAL_151:.*]] = arith.constant 2 : index
-! CHECK-DAG: %[[VAL_152:.*]] = arith.constant 0 : index
-! CHECK-DAG: %[[VAL_153:.*]] = arith.constant 1 : index
-! CHECK:   %[[VAL_154:.*]] = fir.address_of(@_QQ{{.*}}) : !fir.ref<!fir.char<1,{{.*}}>>
-! CHECK:   %[[VAL_155:.*]] = fir.convert %[[VAL_154]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
-! CHECK:   %[[VAL_156:.*]] = fir.call @_FortranAioBeginExternalListInput(%[[VAL_147]], %[[VAL_155]], %{{.*}}) {{.*}}: (i32, !fir.ref<i8>, i32) -> !fir.ref<i8>
-! CHECK:   %[[VAL_157:.*]] = fir.shape %[[VAL_149]], %[[VAL_149]] : (index, index) -> !fir.shape<2>
-! CHECK:   %[[VAL_158:.*]] = fir.slice %[[VAL_153]], %[[VAL_149]], %[[VAL_151]], %[[VAL_153]], %[[VAL_150]], %[[VAL_153]] : (index, index, index, index, index, index) -> !fir.slice<2>
-! CHECK:   cf.br ^bb1(%[[VAL_152]], %[[VAL_150]] : index, index)
-! CHECK: ^bb1(%[[VAL_159:.*]]: index, %[[VAL_160:.*]]: index):
-! CHECK:   %[[VAL_161:.*]] = arith.cmpi sgt, %[[VAL_160]], %[[VAL_152]] : index
-! CHECK:   cf.cond_br %[[VAL_161]], ^bb2(%[[VAL_153]], %[[VAL_151]] : index, index), ^bb5
-! CHECK: ^bb2(%[[VAL_162:.*]]: index, %[[VAL_163:.*]]: index):
-! CHECK:   %[[VAL_164:.*]] = arith.cmpi sgt, %[[VAL_163]], %[[VAL_152]] : index
-! CHECK:   cf.cond_br %[[VAL_164]], ^bb3, ^bb4
-! CHECK: ^bb3:
-! CHECK:   %[[VAL_165:.*]] = fir.coordinate_of %[[VAL_166]], %[[VAL_159]] : (!fir.ref<!fir.array<3xi32>>, index) -> !fir.ref<i32>
-! CHECK:   %[[VAL_167:.*]] = fir.load %[[VAL_165]] : !fir.ref<i32>
-! CHECK:   %[[VAL_168:.*]] = fir.convert %[[VAL_167]] : (i32) -> index
-! CHECK:   %[[VAL_169:.*]] = fir.array_coor %[[VAL_170]](%[[VAL_157]]) {{\[}}%[[VAL_158]]] %[[VAL_162]], %[[VAL_168]] : (!fir.ref<!fir.array<4x4xcomplex<f32>>>, !fir.shape<2>, !fir.slice<2>, index, index) -> !fir.ref<complex<f32>>
-! CHECK:   %[[VAL_171:.*]] = fir.convert %[[VAL_169]] : (!fir.ref<complex<f32>>) -> !fir.ref<f32>
-! CHECK:   %[[VAL_172:.*]] = fir.call @_FortranAioInputComplex32(%[[VAL_156]], %[[VAL_171]]) {{.*}}: (!fir.ref<i8>, !fir.ref<f32>) -> i1
-! CHECK:   %[[VAL_173:.*]] = arith.addi %[[VAL_162]], %[[VAL_153]] overflow<nsw> : index
-! CHECK:   %[[VAL_174:.*]] = arith.subi %[[VAL_163]], %[[VAL_153]] : index
-! CHECK:   cf.br ^bb2(%[[VAL_173]], %[[VAL_174]] : index, index)
-! CHECK: ^bb4:
-! CHECK:   %[[VAL_175:.*]] = arith.addi %[[VAL_159]], %[[VAL_153]] overflow<nsw> : index
-! CHECK:   %[[VAL_176:.*]] = arith.subi %[[VAL_160]], %[[VAL_153]] : index
-! CHECK:   cf.br ^bb1(%[[VAL_175]], %[[VAL_176]] : index, index)
-! CHECK: ^bb5:
-! CHECK:   %[[VAL_177:.*]] = fir.call @_FortranAioEndIoStatement(%[[VAL_156]]) {{.*}}: (!fir.ref<i8>) -> i32
+! CHECK:   %[[VAL_X:.*]]:2 = hlfir.declare %[[VAL_X_ARG]](%{{.*}}){{.*}}{uniq_name = "_QFtriplets_and_vectorEx"}
+! CHECK:   %[[VAL_Y:.*]]:2 = hlfir.declare %[[VAL_Y_ARG]](%{{.*}}){{.*}}{uniq_name = "_QFtriplets_and_vectorEy"}
+! CHECK:   %[[VAL_BEGIN:.*]] = fir.call @_FortranAioBeginExternalListInput({{.*}}) {{.*}}: (i32, !fir.ref<i8>, i32) -> !fir.ref<i8>
+! CHECK:   %[[VAL_SHAPE:.*]] = fir.shape %{{.*}}, %{{.*}} : (index, index) -> !fir.shape<2>
+! CHECK:   %[[VAL_SLICE:.*]] = fir.slice %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}} : (index, index, index, index, index, index) -> !fir.slice<2>
+! CHECK:   fir.do_loop %[[IDX_OUTER:.*]] = %{{.*}} to %{{.*}} step %{{.*}} {
+! CHECK:     fir.do_loop %[[IDX_INNER:.*]] = %{{.*}} to %{{.*}} step %{{.*}} {
+! CHECK:       %[[Y_EL:.*]] = fir.coordinate_of %[[VAL_Y]]#0, %[[IDX_OUTER]] : (!fir.ref<!fir.array<3xi32>>, index) -> !fir.ref<i32>
+! CHECK:       %[[Y_LD:.*]] = fir.load %[[Y_EL]] : !fir.ref<i32>
+! CHECK:       %[[Y_IDX:.*]] = fir.convert %[[Y_LD]] : (i32) -> index
+! CHECK:       %[[ELEM:.*]] = fir.array_coor %[[VAL_X]]#0(%[[VAL_SHAPE]]) {{\[}}%[[VAL_SLICE]]] %[[IDX_INNER]], %[[Y_IDX]] : (!fir.ref<!fir.array<4x4xcomplex<f32>>>, !fir.shape<2>, !fir.slice<2>, index, index) -> !fir.ref<complex<f32>>
+! CHECK:       %[[ELEM_F32:.*]] = fir.convert %[[ELEM]] : (!fir.ref<complex<f32>>) -> !fir.ref<f32>
+! CHECK:       %{{.*}} = fir.call @_FortranAioInputComplex32(%[[VAL_BEGIN]], %[[ELEM_F32]]) {{.*}}: (!fir.ref<i8>, !fir.ref<f32>) -> i1
+! CHECK:     }
+! CHECK:   }
+! CHECK:   %{{.*}} = fir.call @_FortranAioEndIoStatement(%[[VAL_BEGIN]]) {{.*}}: (!fir.ref<i8>) -> i32
 ! CHECK:   return
 end subroutine
 
 ! CHECK-LABEL: func @_QPsimple_char(
-! CHECK-SAME: %[[VAL_185:.*]]: !fir.boxchar<1>{{.*}}, %[[VAL_196:.*]]: !fir.ref<!fir.array<3xi32>>{{.*}}) {
+! CHECK-SAME: %[[VAL_X_ARG:.*]]: !fir.boxchar<1>{{.*}}, %[[VAL_Y_ARG:.*]]: !fir.ref<!fir.array<3xi32>>{{.*}}) {
 subroutine simple_char(x, y)
   integer :: y(3)
   character(*) :: x(3:8)
   read(*,*) x(y)
-! CHECK-DAG: %[[VAL_178:.*]] = arith.constant 6 : index
-! CHECK-DAG: %[[VAL_179:.*]] = arith.constant 5 : i32
-! CHECK-DAG: %[[VAL_181:.*]] = arith.constant 3 : index
-! CHECK-DAG: %[[VAL_182:.*]] = arith.constant 0 : index
-! CHECK-DAG: %[[VAL_183:.*]] = arith.constant 1 : index
-! CHECK:   %[[VAL_184:.*]]:2 = fir.unboxchar %[[VAL_185]] : (!fir.boxchar<1>) -> (!fir.ref<!fir.char<1,?>>, index)
-! CHECK:   %[[VAL_186:.*]] = fir.convert %[[VAL_184]]#0 : (!fir.ref<!fir.char<1,?>>) -> !fir.ref<!fir.array<6x!fir.char<1,?>>>
-! CHECK:   %[[VAL_187:.*]] = fir.address_of(@_QQ{{.*}}) : !fir.ref<!fir.char<1,{{.*}}>>
-! CHECK:   %[[VAL_188:.*]] = fir.convert %[[VAL_187]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
-! CHECK:   %[[VAL_189:.*]] = fir.call @_FortranAioBeginExternalListInput(%[[VAL_179]], %[[VAL_188]], %{{.*}}) {{.*}}: (i32, !fir.ref<i8>, i32) -> !fir.ref<i8>
-! CHECK:   %[[VAL_190:.*]] = fir.shape_shift %[[VAL_181]], %[[VAL_178]] : (index, index) -> !fir.shapeshift<1>
-! CHECK:   %[[VAL_191:.*]] = fir.slice %[[VAL_183]], %[[VAL_181]], %[[VAL_183]] : (index, index, index) -> !fir.slice<1>
-! CHECK:   cf.br ^bb1(%[[VAL_182]], %[[VAL_181]] : index, index)
-! CHECK: ^bb1(%[[VAL_192:.*]]: index, %[[VAL_193:.*]]: index):
-! CHECK:   %[[VAL_194:.*]] = arith.cmpi sgt, %[[VAL_193]], %[[VAL_182]] : index
-! CHECK:   cf.cond_br %[[VAL_194]], ^bb2, ^bb3
-! CHECK: ^bb2:
-! CHECK:   %[[VAL_195:.*]] = fir.coordinate_of %[[VAL_196]], %[[VAL_192]] : (!fir.ref<!fir.array<3xi32>>, index) -> !fir.ref<i32>
-! CHECK:   %[[VAL_197:.*]] = fir.load %[[VAL_195]] : !fir.ref<i32>
-! CHECK:   %[[VAL_198:.*]] = fir.convert %[[VAL_197]] : (i32) -> index
-! CHECK:   %[[VAL_199:.*]] = fir.array_coor %[[VAL_186]](%[[VAL_190]]) {{\[}}%[[VAL_191]]] %[[VAL_198]] typeparams %[[VAL_184]]#1 : (!fir.ref<!fir.array<6x!fir.char<1,?>>>, !fir.shapeshift<1>, !fir.slice<1>, index, index) -> !fir.ref<!fir.char<1,?>>
-! CHECK:   %[[VAL_200:.*]] = fir.convert %[[VAL_199]] : (!fir.ref<!fir.char<1,?>>) -> !fir.ref<i8>
-! CHECK:   %[[VAL_201:.*]] = fir.convert %[[VAL_184]]#1 : (index) -> i64
-! CHECK:   %[[VAL_202:.*]] = fir.call @_FortranAioInputAscii(%[[VAL_189]], %[[VAL_200]], %[[VAL_201]]) {{.*}}: (!fir.ref<i8>, !fir.ref<i8>, i64) -> i1
-! CHECK:   %[[VAL_203:.*]] = arith.addi %[[VAL_192]], %[[VAL_183]] overflow<nsw> : index
-! CHECK:   %[[VAL_204:.*]] = arith.subi %[[VAL_193]], %[[VAL_183]] : index
-! CHECK:   cf.br ^bb1(%[[VAL_203]], %[[VAL_204]] : index, index)
-! CHECK: ^bb3:
-! CHECK:   %[[VAL_205:.*]] = fir.call @_FortranAioEndIoStatement(%[[VAL_189]]) {{.*}}: (!fir.ref<i8>) -> i32
+! CHECK:   %[[VAL_UNBOX:.*]]:2 = fir.unboxchar %[[VAL_X_ARG]] : (!fir.boxchar<1>) -> (!fir.ref<!fir.char<1,?>>, index)
+! CHECK:   %[[VAL_X_CAST:.*]] = fir.convert %[[VAL_UNBOX]]#0 : (!fir.ref<!fir.char<1,?>>) -> !fir.ref<!fir.array<6x!fir.char<1,?>>>
+! CHECK:   %[[VAL_X:.*]]:2 = hlfir.declare %[[VAL_X_CAST]](%{{.*}}) typeparams %[[VAL_UNBOX]]#1{{.*}}{uniq_name = "_QFsimple_charEx"}
+! CHECK:   %[[VAL_Y:.*]]:2 = hlfir.declare %[[VAL_Y_ARG]](%{{.*}}){{.*}}{uniq_name = "_QFsimple_charEy"}
+! CHECK:   %[[VAL_BEGIN:.*]] = fir.call @_FortranAioBeginExternalListInput({{.*}}) {{.*}}: (i32, !fir.ref<i8>, i32) -> !fir.ref<i8>
+! CHECK:   %[[VAL_SS:.*]] = fir.shape_shift %{{.*}}, %{{.*}} : (index, index) -> !fir.shapeshift<1>
+! CHECK:   %[[VAL_SLICE:.*]] = fir.slice %{{.*}}, %{{.*}}, %{{.*}} : (index, index, index) -> !fir.slice<1>
+! CHECK:   fir.do_loop %[[IDX:.*]] = %{{.*}} to %{{.*}} step %{{.*}} {
+! CHECK:     %[[VEL:.*]] = fir.coordinate_of %[[VAL_Y]]#0, %[[IDX]] : (!fir.ref<!fir.array<3xi32>>, index) -> !fir.ref<i32>
+! CHECK:     %[[VEL_LD:.*]] = fir.load %[[VEL]] : !fir.ref<i32>
+! CHECK:     %[[VEL_IDX:.*]] = fir.convert %[[VEL_LD]] : (i32) -> index
+! CHECK:     %[[ELEM:.*]] = fir.array_coor %[[VAL_X]]#1(%[[VAL_SS]]) {{\[}}%[[VAL_SLICE]]] %[[VEL_IDX]] typeparams %[[VAL_UNBOX]]#1 : (!fir.ref<!fir.array<6x!fir.char<1,?>>>, !fir.shapeshift<1>, !fir.slice<1>, index, index) -> !fir.ref<!fir.char<1,?>>
+! CHECK:     %[[ELEM_I8:.*]] = fir.convert %[[ELEM]] : (!fir.ref<!fir.char<1,?>>) -> !fir.ref<i8>
+! CHECK:     %[[LEN_I64:.*]] = fir.convert %[[VAL_UNBOX]]#1 : (index) -> i64
+! CHECK:     %{{.*}} = fir.call @_FortranAioInputAscii(%[[VAL_BEGIN]], %[[ELEM_I8]], %[[LEN_I64]]) {{.*}}: (!fir.ref<i8>, !fir.ref<i8>, i64) -> i1
+! CHECK:   }
+! CHECK:   %{{.*}} = fir.call @_FortranAioEndIoStatement(%[[VAL_BEGIN]]) {{.*}}: (!fir.ref<i8>) -> i32
 ! CHECK:   return
 end subroutine
 
 ! CHECK-LABEL: func @_QPsubstring(
-! CHECK-SAME: %[[VAL_229:.*]]: !fir.box<!fir.array<?x!fir.char<1,?>>>{{.*}}, %[[VAL_225:.*]]: !fir.ref<!fir.array<3xi32>>{{.*}}, %[[VAL_215:.*]]: !fir.ref<i32>{{.*}}, %[[VAL_218:.*]]: !fir.ref<i32>{{.*}}) {
+! CHECK-SAME: %[[VAL_X_ARG:.*]]: !fir.box<!fir.array<?x!fir.char<1,?>>>{{.*}}, %[[VAL_Y_ARG:.*]]: !fir.ref<!fir.array<3xi32>>{{.*}}, %[[VAL_I_ARG:.*]]: !fir.ref<i32>{{.*}}, %[[VAL_J_ARG:.*]]: !fir.ref<i32>{{.*}}) {
 subroutine substring(x, y, i, j)
   integer :: y(3), i, j
   character(*) :: x(:)
   read(*,*) x(y)(i:j)
-! CHECK-DAG: %[[VAL_206:.*]] = arith.constant 5 : i32
-! CHECK-DAG: %[[VAL_208:.*]] = arith.constant 3 : index
-! CHECK-DAG: %[[VAL_209:.*]] = arith.constant 0 : index
-! CHECK-DAG: %[[VAL_210:.*]] = arith.constant 1 : index
-! CHECK:   %[[VAL_211:.*]] = fir.address_of(@_QQ{{.*}}) : !fir.ref<!fir.char<1,{{.*}}>>
-! CHECK:   %[[VAL_212:.*]] = fir.convert %[[VAL_211]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
-! CHECK:   %[[VAL_213:.*]] = fir.call @_FortranAioBeginExternalListInput(%[[VAL_206]], %[[VAL_212]], %{{.*}}) {{.*}}: (i32, !fir.ref<i8>, i32) -> !fir.ref<i8>
-! CHECK:   %[[VAL_214:.*]] = fir.load %[[VAL_215]] : !fir.ref<i32>
-! CHECK:   %[[VAL_216:.*]] = fir.convert %[[VAL_214]] : (i32) -> index
-! CHECK:   %[[VAL_217:.*]] = fir.load %[[VAL_218]] : !fir.ref<i32>
-! CHECK:   %[[VAL_219:.*]] = fir.convert %[[VAL_217]] : (i32) -> index
-! CHECK:   %[[VAL_220:.*]] = fir.slice %[[VAL_210]], %[[VAL_208]], %[[VAL_210]] : (index, index, index) -> !fir.slice<1>
-! CHECK:   cf.br ^bb1(%[[VAL_209]], %[[VAL_208]] : index, index)
-! CHECK: ^bb1(%[[VAL_221:.*]]: index, %[[VAL_222:.*]]: index):
-! CHECK:   %[[VAL_223:.*]] = arith.cmpi sgt, %[[VAL_222]], %[[VAL_209]] : index
-! CHECK:   cf.cond_br %[[VAL_223]], ^bb2, ^bb3
-! CHECK: ^bb2:
-! CHECK:   %[[VAL_224:.*]] = fir.coordinate_of %[[VAL_225]], %[[VAL_221]] : (!fir.ref<!fir.array<3xi32>>, index) -> !fir.ref<i32>
-! CHECK:   %[[VAL_226:.*]] = fir.load %[[VAL_224]] : !fir.ref<i32>
-! CHECK:   %[[VAL_227:.*]] = fir.convert %[[VAL_226]] : (i32) -> index
-! CHECK:   %[[VAL_228:.*]] = fir.array_coor %[[VAL_229]] {{\[}}%[[VAL_220]]] %[[VAL_227]] : (!fir.box<!fir.array<?x!fir.char<1,?>>>, !fir.slice<1>, index) -> !fir.ref<!fir.char<1,?>>
-! CHECK:   %[[VAL_230:.*]] = arith.subi %[[VAL_216]], %[[VAL_210]] : index
-! CHECK:   %[[VAL_231:.*]] = fir.convert %[[VAL_228]] : (!fir.ref<!fir.char<1,?>>) -> !fir.ref<!fir.array<?x!fir.char<1>>>
-! CHECK:   %[[VAL_232:.*]] = fir.coordinate_of %[[VAL_231]], %[[VAL_230]] : (!fir.ref<!fir.array<?x!fir.char<1>>>, index) -> !fir.ref<!fir.char<1>>
-! CHECK:   %[[VAL_234:.*]] = arith.subi %[[VAL_219]], %[[VAL_216]] : index
-! CHECK:   %[[VAL_235:.*]] = arith.addi %[[VAL_234]], %[[VAL_210]] : index
-! CHECK:   %[[VAL_236:.*]] = arith.cmpi slt, %[[VAL_235]], %[[VAL_209]] : index
-! CHECK:   %[[VAL_237:.*]] = arith.select %[[VAL_236]], %[[VAL_209]], %[[VAL_235]] : index
-! CHECK:   %[[VAL_238:.*]] = fir.convert %[[VAL_232]] : (!fir.ref<!fir.char<1>>) -> !fir.ref<i8>
-! CHECK:   %[[VAL_239:.*]] = fir.convert %[[VAL_237]] : (index) -> i64
-! CHECK:   %[[VAL_240:.*]] = fir.call @_FortranAioInputAscii(%[[VAL_213]], %[[VAL_238]], %[[VAL_239]]) {{.*}}: (!fir.ref<i8>, !fir.ref<i8>, i64) -> i1
-! CHECK:   %[[VAL_241:.*]] = arith.addi %[[VAL_221]], %[[VAL_210]] overflow<nsw> : index
-! CHECK:   %[[VAL_242:.*]] = arith.subi %[[VAL_222]], %[[VAL_210]] : index
-! CHECK:   cf.br ^bb1(%[[VAL_241]], %[[VAL_242]] : index, index)
-! CHECK: ^bb3:
-! CHECK:   %[[VAL_243:.*]] = fir.call @_FortranAioEndIoStatement(%[[VAL_213]]) {{.*}}: (!fir.ref<i8>) -> i32
+! CHECK:   %[[VAL_I:.*]]:2 = hlfir.declare %[[VAL_I_ARG]]{{.*}}{uniq_name = "_QFsubstringEi"}
+! CHECK:   %[[VAL_J:.*]]:2 = hlfir.declare %[[VAL_J_ARG]]{{.*}}{uniq_name = "_QFsubstringEj"}
+! CHECK:   %[[VAL_X:.*]]:2 = hlfir.declare %[[VAL_X_ARG]]{{.*}}{uniq_name = "_QFsubstringEx"}
+! CHECK:   %[[VAL_Y:.*]]:2 = hlfir.declare %[[VAL_Y_ARG]](%{{.*}}){{.*}}{uniq_name = "_QFsubstringEy"}
+! CHECK:   %[[VAL_BEGIN:.*]] = fir.call @_FortranAioBeginExternalListInput({{.*}}) {{.*}}: (i32, !fir.ref<i8>, i32) -> !fir.ref<i8>
+! CHECK:   %[[VAL_I_LD:.*]] = fir.load %[[VAL_I]]#0 : !fir.ref<i32>
+! CHECK:   %[[VAL_I_I64:.*]] = fir.convert %[[VAL_I_LD]] : (i32) -> i64
+! CHECK:   %[[VAL_I_IDX:.*]] = fir.convert %[[VAL_I_I64]] : (i64) -> index
+! CHECK:   %[[VAL_J_LD:.*]] = fir.load %[[VAL_J]]#0 : !fir.ref<i32>
+! CHECK:   %[[VAL_J_I64:.*]] = fir.convert %[[VAL_J_LD]] : (i32) -> i64
+! CHECK:   %[[VAL_J_IDX:.*]] = fir.convert %[[VAL_J_I64]] : (i64) -> index
+! CHECK:   %[[VAL_SLICE:.*]] = fir.slice %{{.*}}, %{{.*}}, %{{.*}} : (index, index, index) -> !fir.slice<1>
+! CHECK:   fir.do_loop %[[IDX:.*]] = %{{.*}} to %{{.*}} step %{{.*}} {
+! CHECK:     %[[VEL:.*]] = fir.coordinate_of %[[VAL_Y]]#0, %[[IDX]] : (!fir.ref<!fir.array<3xi32>>, index) -> !fir.ref<i32>
+! CHECK:     %[[VEL_LD:.*]] = fir.load %[[VEL]] : !fir.ref<i32>
+! CHECK:     %[[VEL_IDX:.*]] = fir.convert %[[VEL_LD]] : (i32) -> index
+! CHECK:     %[[ELEM:.*]] = fir.array_coor %[[VAL_X]]#1 {{\[}}%[[VAL_SLICE]]] %[[VEL_IDX]] : (!fir.box<!fir.array<?x!fir.char<1,?>>>, !fir.slice<1>, index) -> !fir.ref<!fir.char<1,?>>
+! CHECK:     %[[OFFSET:.*]] = arith.subi %[[VAL_I_IDX]], %{{.*}} : index
+! CHECK:     %[[ELEM_AS_ARR:.*]] = fir.convert %[[ELEM]] : (!fir.ref<!fir.char<1,?>>) -> !fir.ref<!fir.array<?x!fir.char<1>>>
+! CHECK:     %[[SUBSTR:.*]] = fir.coordinate_of %[[ELEM_AS_ARR]], %[[OFFSET]] : (!fir.ref<!fir.array<?x!fir.char<1>>>, index) -> !fir.ref<!fir.char<1>>
+! CHECK:     %[[SUBSTR_AS_C1Q:.*]] = fir.convert %[[SUBSTR]] : (!fir.ref<!fir.char<1>>) -> !fir.ref<!fir.char<1,?>>
+! CHECK:     %[[LEN_DIFF:.*]] = arith.subi %[[VAL_J_IDX]], %[[VAL_I_IDX]] : index
+! CHECK:     %[[LEN_PLUS_1:.*]] = arith.addi %[[LEN_DIFF]], %{{.*}} : index
+! CHECK:     %[[LT0:.*]] = arith.cmpi slt, %[[LEN_PLUS_1]], %{{.*}} : index
+! CHECK:     %[[LEN:.*]] = arith.select %[[LT0]], %{{.*}}, %[[LEN_PLUS_1]] : index
+! CHECK:     %[[ELEM_I8:.*]] = fir.convert %[[SUBSTR_AS_C1Q]] : (!fir.ref<!fir.char<1,?>>) -> !fir.ref<i8>
+! CHECK:     %[[LEN_I64:.*]] = fir.convert %[[LEN]] : (index) -> i64
+! CHECK:     %{{.*}} = fir.call @_FortranAioInputAscii(%[[VAL_BEGIN]], %[[ELEM_I8]], %[[LEN_I64]]) {{.*}}: (!fir.ref<i8>, !fir.ref<i8>, i64) -> i1
+! CHECK:   }
+! CHECK:   %{{.*}} = fir.call @_FortranAioEndIoStatement(%[[VAL_BEGIN]]) {{.*}}: (!fir.ref<i8>) -> i32
 ! CHECK:   return
 end subroutine
 
 ! CHECK-LABEL: func @_QPcomplex_part(
-! CHECK-SAME: %[[VAL_262:.*]]: !fir.box<!fir.array<?xcomplex<f32>>>{{.*}}, %[[VAL_253:.*]]: !fir.box<!fir.array<?xi32>>{{.*}}) {
+! CHECK-SAME: %[[VAL_Z_ARG:.*]]: !fir.box<!fir.array<?xcomplex<f32>>>{{.*}}, %[[VAL_Y_ARG:.*]]: !fir.box<!fir.array<?xi32>>{{.*}}) {
 subroutine complex_part(z, y)
   integer :: y(:)
   complex :: z(:)
   read(*,*) z(y)%IM
-! CHECK-DAG: %[[VAL_244:.*]] = arith.constant 5 : i32
-! CHECK-DAG: %[[VAL_246:.*]] = arith.constant 1 : i32
-! CHECK-DAG: %[[VAL_247:.*]] = arith.constant 0 : index
-! CHECK-DAG: %[[VAL_248:.*]] = arith.constant 1 : index
-! CHECK:   %[[VAL_249:.*]] = fir.address_of(@_QQ{{.*}}) : !fir.ref<!fir.char<1,{{.*}}>>
-! CHECK:   %[[VAL_250:.*]] = fir.convert %[[VAL_249]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
-! CHECK:   %[[VAL_251:.*]] = fir.call @_FortranAioBeginExternalListInput(%[[VAL_244]], %[[VAL_250]], %{{.*}}) {{.*}}: (i32, !fir.ref<i8>, i32) -> !fir.ref<i8>
-! CHECK:   %[[VAL_252:.*]]:3 = fir.box_dims %[[VAL_253]], %[[VAL_247]] : (!fir.box<!fir.array<?xi32>>, index) -> (index, index, index)
-! CHECK:   %[[VAL_254:.*]] = fir.slice %[[VAL_248]], %[[VAL_252]]#1, %[[VAL_248]] path %[[VAL_246]] : (index, index, index, i32) -> !fir.slice<1>
-! CHECK:   cf.br ^bb1(%[[VAL_247]], %[[VAL_252]]#1 : index, index)
-! CHECK: ^bb1(%[[VAL_255:.*]]: index, %[[VAL_256:.*]]: index):
-! CHECK:   %[[VAL_257:.*]] = arith.cmpi sgt, %[[VAL_256]], %[[VAL_247]] : index
-! CHECK:   cf.cond_br %[[VAL_257]], ^bb2, ^bb3
-! CHECK: ^bb2:
-! CHECK:   %[[VAL_258:.*]] = fir.coordinate_of %[[VAL_253]], %[[VAL_255]] : (!fir.box<!fir.array<?xi32>>, index) -> !fir.ref<i32>
-! CHECK:   %[[VAL_259:.*]] = fir.load %[[VAL_258]] : !fir.ref<i32>
-! CHECK:   %[[VAL_260:.*]] = fir.convert %[[VAL_259]] : (i32) -> index
-! CHECK:   %[[VAL_261:.*]] = fir.array_coor %[[VAL_262]] {{\[}}%[[VAL_254]]] %[[VAL_260]] : (!fir.box<!fir.array<?xcomplex<f32>>>, !fir.slice<1>, index) -> !fir.ref<f32>
-! CHECK:   %[[VAL_263:.*]] = fir.call @_FortranAioInputReal32(%[[VAL_251]], %[[VAL_261]]) {{.*}}: (!fir.ref<i8>, !fir.ref<f32>) -> i1
-! CHECK:   %[[VAL_264:.*]] = arith.addi %[[VAL_255]], %[[VAL_248]] overflow<nsw> : index
-! CHECK:   %[[VAL_265:.*]] = arith.subi %[[VAL_256]], %[[VAL_248]] : index
-! CHECK:   cf.br ^bb1(%[[VAL_264]], %[[VAL_265]] : index, index)
-! CHECK: ^bb3:
-! CHECK:   %[[VAL_266:.*]] = fir.call @_FortranAioEndIoStatement(%[[VAL_251]]) {{.*}}: (!fir.ref<i8>) -> i32
+! CHECK:   %[[VAL_Y:.*]]:2 = hlfir.declare %[[VAL_Y_ARG]]{{.*}}{uniq_name = "_QFcomplex_partEy"}
+! CHECK:   %[[VAL_Z:.*]]:2 = hlfir.declare %[[VAL_Z_ARG]]{{.*}}{uniq_name = "_QFcomplex_partEz"}
+! CHECK:   %[[VAL_BEGIN:.*]] = fir.call @_FortranAioBeginExternalListInput({{.*}}) {{.*}}: (i32, !fir.ref<i8>, i32) -> !fir.ref<i8>
+! CHECK:   %[[VAL_DIMS:.*]]:3 = fir.box_dims %[[VAL_Y]]#1, %{{.*}} : (!fir.box<!fir.array<?xi32>>, index) -> (index, index, index)
+! CHECK:   %[[VAL_C1I32:.*]] = arith.constant 1 : i32
+! CHECK:   %[[VAL_SLICE:.*]] = fir.slice %{{.*}}, %[[VAL_DIMS]]#1, %{{.*}} path %[[VAL_C1I32]] : (index, index, index, i32) -> !fir.slice<1>
+! CHECK:   fir.do_loop %[[IDX:.*]] = %{{.*}} to %{{.*}} step %{{.*}} {
+! CHECK:     %[[VEL:.*]] = fir.coordinate_of %[[VAL_Y]]#1, %[[IDX]] : (!fir.box<!fir.array<?xi32>>, index) -> !fir.ref<i32>
+! CHECK:     %[[VEL_LD:.*]] = fir.load %[[VEL]] : !fir.ref<i32>
+! CHECK:     %[[VEL_IDX:.*]] = fir.convert %[[VEL_LD]] : (i32) -> index
+! CHECK:     %[[ELEM:.*]] = fir.array_coor %[[VAL_Z]]#1 {{\[}}%[[VAL_SLICE]]] %[[VEL_IDX]] : (!fir.box<!fir.array<?xcomplex<f32>>>, !fir.slice<1>, index) -> !fir.ref<f32>
+! CHECK:     %{{.*}} = fir.call @_FortranAioInputReal32(%[[VAL_BEGIN]], %[[ELEM]]) {{.*}}: (!fir.ref<i8>, !fir.ref<f32>) -> i1
+! CHECK:   }
+! CHECK:   %{{.*}} = fir.call @_FortranAioEndIoStatement(%[[VAL_BEGIN]]) {{.*}}: (!fir.ref<i8>) -> i32
 ! CHECK:   return
 end subroutine
 
@@ -384,198 +275,141 @@ module derived_types
 end module
 
 ! CHECK-LABEL: func @_QPsimple_derived(
-! CHECK-SAME: %[[VAL_287:.*]]: !fir.ref<!fir.array<6x!fir.type<_QMderived_typesTt{i:i32,c:!fir.char<1,2>}>>>{{.*}}, %[[VAL_283:.*]]: !fir.ref<!fir.array<4xi32>>{{.*}}) {
+! CHECK-SAME: %[[VAL_X_ARG:.*]]: !fir.ref<!fir.array<6x!fir.type<_QMderived_typesTt{i:i32,c:!fir.char<1,2>}>>>{{.*}}, %[[VAL_Y_ARG:.*]]: !fir.ref<!fir.array<4xi32>>{{.*}}) {
 subroutine simple_derived(x, y)
   use derived_types
   integer :: y(4)
   type(t) :: x(3:8)
   read(*,*) x(y)
-! CHECK-DAG: %[[VAL_267:.*]] = arith.constant 6 : index
-! CHECK-DAG: %[[VAL_268:.*]] = arith.constant 5 : i32
-! CHECK-DAG: %[[VAL_270:.*]] = arith.constant 3 : index
-! CHECK-DAG: %[[VAL_271:.*]] = arith.constant 4 : index
-! CHECK-DAG: %[[VAL_272:.*]] = arith.constant 0 : index
-! CHECK-DAG: %[[VAL_273:.*]] = arith.constant 1 : index
-! CHECK:   %[[VAL_274:.*]] = fir.address_of(@_QQ{{.*}}) : !fir.ref<!fir.char<1,{{.*}}>>
-! CHECK:   %[[VAL_275:.*]] = fir.convert %[[VAL_274]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
-! CHECK:   %[[VAL_276:.*]] = fir.call @_FortranAioBeginExternalListInput(%[[VAL_268]], %[[VAL_275]], %{{.*}}) {{.*}}: (i32, !fir.ref<i8>, i32) -> !fir.ref<i8>
-! CHECK:   %[[VAL_277:.*]] = fir.shape_shift %[[VAL_270]], %[[VAL_267]] : (index, index) -> !fir.shapeshift<1>
-! CHECK:   %[[VAL_278:.*]] = fir.slice %[[VAL_273]], %[[VAL_271]], %[[VAL_273]] : (index, index, index) -> !fir.slice<1>
-! CHECK:   cf.br ^bb1(%[[VAL_272]], %[[VAL_271]] : index, index)
-! CHECK: ^bb1(%[[VAL_279:.*]]: index, %[[VAL_280:.*]]: index):
-! CHECK:   %[[VAL_281:.*]] = arith.cmpi sgt, %[[VAL_280]], %[[VAL_272]] : index
-! CHECK:   cf.cond_br %[[VAL_281]], ^bb2, ^bb3
-! CHECK: ^bb2:
-! CHECK:   %[[VAL_282:.*]] = fir.coordinate_of %[[VAL_283]], %[[VAL_279]] : (!fir.ref<!fir.array<4xi32>>, index) -> !fir.ref<i32>
-! CHECK:   %[[VAL_284:.*]] = fir.load %[[VAL_282]] : !fir.ref<i32>
-! CHECK:   %[[VAL_285:.*]] = fir.convert %[[VAL_284]] : (i32) -> index
-! CHECK:   %[[VAL_286:.*]] = fir.array_coor %[[VAL_287]](%[[VAL_277]]) {{\[}}%[[VAL_278]]] %[[VAL_285]] : (!fir.ref<!fir.array<6x!fir.type<_QMderived_typesTt{i:i32,c:!fir.char<1,2>}>>>, !fir.shapeshift<1>, !fir.slice<1>, index) -> !fir.ref<!fir.type<_QMderived_typesTt{i:i32,c:!fir.char<1,2>}>>
-! CHECK:   %[[VAL_288:.*]] = fir.embox %[[VAL_286]] : (!fir.ref<!fir.type<_QMderived_typesTt{i:i32,c:!fir.char<1,2>}>>) -> !fir.box<!fir.type<_QMderived_typesTt{i:i32,c:!fir.char<1,2>}>>
-! CHECK:   %[[VAL_289:.*]] = fir.convert %[[VAL_288]] : (!fir.box<!fir.type<_QMderived_typesTt{i:i32,c:!fir.char<1,2>}>>) -> !fir.box<none>
-! CHECK:   %[[VAL_290:.*]] = fir.call @_FortranAioInputDerivedType(%[[VAL_276]], %[[VAL_289]], {{.*}}) {{.*}}: (!fir.ref<i8>, !fir.box<none>, !fir.ref<none>) -> i1
-! CHECK:   %[[VAL_291:.*]] = arith.addi %[[VAL_279]], %[[VAL_273]] overflow<nsw> : index
-! CHECK:   %[[VAL_292:.*]] = arith.subi %[[VAL_280]], %[[VAL_273]] : index
-! CHECK:   cf.br ^bb1(%[[VAL_291]], %[[VAL_292]] : index, index)
-! CHECK: ^bb3:
-! CHECK:   %[[VAL_293:.*]] = fir.call @_FortranAioEndIoStatement(%[[VAL_276]]) {{.*}}: (!fir.ref<i8>) -> i32
+! CHECK:   %[[VAL_SS:.*]] = fir.shape_shift %{{.*}}, %{{.*}} : (index, index) -> !fir.shapeshift<1>
+! CHECK:   %[[VAL_X:.*]]:2 = hlfir.declare %[[VAL_X_ARG]](%[[VAL_SS]]){{.*}}{uniq_name = "_QFsimple_derivedEx"}
+! CHECK:   %[[VAL_Y:.*]]:2 = hlfir.declare %[[VAL_Y_ARG]](%{{.*}}){{.*}}{uniq_name = "_QFsimple_derivedEy"}
+! CHECK:   %[[VAL_BEGIN:.*]] = fir.call @_FortranAioBeginExternalListInput({{.*}}) {{.*}}: (i32, !fir.ref<i8>, i32) -> !fir.ref<i8>
+! CHECK:   %[[VAL_SS2:.*]] = fir.shape_shift %{{.*}}, %{{.*}} : (index, index) -> !fir.shapeshift<1>
+! CHECK:   %[[VAL_SLICE:.*]] = fir.slice %{{.*}}, %{{.*}}, %{{.*}} : (index, index, index) -> !fir.slice<1>
+! CHECK:   fir.do_loop %[[IDX:.*]] = %{{.*}} to %{{.*}} step %{{.*}} {
+! CHECK:     %[[VEL:.*]] = fir.coordinate_of %[[VAL_Y]]#0, %[[IDX]] : (!fir.ref<!fir.array<4xi32>>, index) -> !fir.ref<i32>
+! CHECK:     %[[VEL_LD:.*]] = fir.load %[[VEL]] : !fir.ref<i32>
+! CHECK:     %[[VEL_IDX:.*]] = fir.convert %[[VEL_LD]] : (i32) -> index
+! CHECK:     %[[ELEM:.*]] = fir.array_coor %[[VAL_X]]#1(%[[VAL_SS2]]) {{\[}}%[[VAL_SLICE]]] %[[VEL_IDX]] : (!fir.ref<!fir.array<6x!fir.type<_QMderived_typesTt{i:i32,c:!fir.char<1,2>}>>>, !fir.shapeshift<1>, !fir.slice<1>, index) -> !fir.ref<!fir.type<_QMderived_typesTt{i:i32,c:!fir.char<1,2>}>>
+! CHECK:     %[[ELEM_BOX:.*]] = fir.embox %[[ELEM]] : (!fir.ref<!fir.type<_QMderived_typesTt{i:i32,c:!fir.char<1,2>}>>) -> !fir.box<!fir.type<_QMderived_typesTt{i:i32,c:!fir.char<1,2>}>>
+! CHECK:     %[[ELEM_BOX_NONE:.*]] = fir.convert %[[ELEM_BOX]] : (!fir.box<!fir.type<_QMderived_typesTt{i:i32,c:!fir.char<1,2>}>>) -> !fir.box<none>
+! CHECK:     %{{.*}} = fir.call @_FortranAioInputDerivedType(%[[VAL_BEGIN]], %[[ELEM_BOX_NONE]], {{.*}}) {{.*}}: (!fir.ref<i8>, !fir.box<none>, !fir.ref<none>) -> i1
+! CHECK:   }
+! CHECK:   %{{.*}} = fir.call @_FortranAioEndIoStatement(%[[VAL_BEGIN]]) {{.*}}: (!fir.ref<i8>) -> i32
 ! CHECK:   return
 end subroutine
 
 ! CHECK-LABEL: func @_QPwith_path(
-! CHECK-SAME: [[VAL_326:.*]]: !fir.box<!fir.array<?x?x?x!fir.type<_QMderived_typesTt2{a:!fir.array<5x5x!fir.type<_QMderived_typesTt{i:i32,c:!fir.char<1,2>}>>}>>>{{.*}}, [[VAL_310:.*]]: !fir.box<!fir.array<?xi32>>{{.*}}) {
+! CHECK-SAME: %[[VAL_B_ARG:.*]]: !fir.box<!fir.array<?x?x?x!fir.type<_QMderived_typesTt2{a:!fir.array<5x5x!fir.type<_QMderived_typesTt{i:i32,c:!fir.char<1,2>}>>}>>>{{.*}}, %[[VAL_I_ARG:.*]]: !fir.box<!fir.array<?xi32>>{{.*}}) {
 subroutine with_path(b, i)
   use derived_types
   type(t2) :: b(4:, 4:, 4:)
   integer :: i(:)
   read (*, *) b(5, i, 8:9:1)%a(4,5)%i
-! CHECK-DAG: %[[VAL_294:.*]] = arith.constant 4 : index
-! CHECK-DAG: %[[VAL_295:.*]] = arith.constant 5 : i32
-! CHECK-DAG: %[[VAL_297:.*]] = arith.constant 8 : index
-! CHECK-DAG: %[[VAL_298:.*]] = arith.constant 9 : index
-! CHECK-DAG: %[[VAL_299:.*]] = arith.constant 4 : i64
-! CHECK-DAG: %[[VAL_300:.*]] = arith.constant 5 : i64
-! CHECK-DAG: %[[VAL_301:.*]] = arith.constant 5 : index
-! CHECK-DAG: %[[VAL_302:.*]] = arith.constant 4 : i32
-! CHECK-DAG: %[[VAL_303:.*]] = arith.constant 2 : index
-! CHECK-DAG: %[[VAL_304:.*]] = arith.constant 0 : index
-! CHECK-DAG: %[[VAL_305:.*]] = arith.constant 1 : index
-! CHECK:   %[[VAL_306:.*]] = fir.address_of(@_QQ{{.*}}) : !fir.ref<!fir.char<1,{{.*}}>>
-! CHECK:   %[[VAL_307:.*]] = fir.convert %[[VAL_306]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
-! CHECK:   %[[VAL_308:.*]] = fir.call @_FortranAioBeginExternalListInput(%[[VAL_295]], %[[VAL_307]], %{{.*}}) {{.*}}: (i32, !fir.ref<i8>, i32) -> !fir.ref<i8>
-! CHECK:   %[[VAL_309:.*]]:3 = fir.box_dims %[[VAL_310:.*]], %[[VAL_304]] : (!fir.box<!fir.array<?xi32>>, index) -> (index, index, index)
-! CHECK:   %[[VAL_311:.*]] = fir.field_index a, !fir.type<_QMderived_typesTt2{a:!fir.array<5x5x!fir.type<_QMderived_typesTt{i:i32,c:!fir.char<1,2>}>>}>
-! CHECK:   %[[VAL_312:.*]] = fir.field_index i, !fir.type<_QMderived_typesTt{i:i32,c:!fir.char<1,2>}>
-! CHECK:   %[[VAL_313:.*]] = fir.shift %[[VAL_294]], %[[VAL_294]], %[[VAL_294]] : (index, index, index) -> !fir.shift<3>
-! CHECK:   %[[VAL_314:.*]] = fir.undefined index
-! CHECK:   %[[VAL_315:.*]] = fir.slice %[[VAL_300]], %[[VAL_314]], %[[VAL_314]], %[[VAL_305]], %[[VAL_309]]#1, %[[VAL_305]], %[[VAL_297]], %[[VAL_298]], %[[VAL_305]] path %[[VAL_311]], %[[VAL_299]], %[[VAL_300]], %[[VAL_312]] : (i64, index, index, index, index, index, index, index, index, !fir.field, i64, i64, !fir.field) -> !fir.slice<3>
-! CHECK:   cf.br ^bb1(%[[VAL_294]], %[[VAL_303]] : index, index)
-! CHECK: ^bb1(%[[VAL_316:.*]]: index, %[[VAL_317:.*]]: index):
-! CHECK:   %[[VAL_318:.*]] = arith.cmpi sgt, %[[VAL_317]], %[[VAL_304]] : index
-! CHECK:   cf.cond_br %[[VAL_318]], ^bb2(%[[VAL_304]], %[[VAL_309]]#1 : index, index), ^bb5
-! CHECK: ^bb2(%[[VAL_319:.*]]: index, %[[VAL_320:.*]]: index):
-! CHECK:   %[[VAL_321:.*]] = arith.cmpi sgt, %[[VAL_320]], %[[VAL_304]] : index
-! CHECK:   cf.cond_br %[[VAL_321]], ^bb3, ^bb4
-! CHECK: ^bb3:
-! CHECK:   %[[VAL_322:.*]] = fir.coordinate_of %[[VAL_310]], %[[VAL_319]] : (!fir.box<!fir.array<?xi32>>, index) -> !fir.ref<i32>
-! CHECK:   %[[VAL_323:.*]] = fir.load %[[VAL_322]] : !fir.ref<i32>
-! CHECK:   %[[VAL_324:.*]] = fir.convert %[[VAL_323]] : (i32) -> index
-! CHECK:   %[[VAL_325:.*]] = fir.array_coor %[[VAL_326:.*]](%[[VAL_313]]) {{\[}}%[[VAL_315]]] %[[VAL_301]], %[[VAL_324]], %[[VAL_316]] : (!fir.box<!fir.array<?x?x?x!fir.type<_QMderived_typesTt2{a:!fir.array<5x5x!fir.type<_QMderived_typesTt{i:i32,c:!fir.char<1,2>}>>}>>>, !fir.shift<3>, !fir.slice<3>, index, index, index) -> !fir.ref<i32>
-! CHECK:   %[[VAL_327:.*]] = fir.convert %[[VAL_325]] : (!fir.ref<i32>) -> !fir.ref<i64>
-! CHECK:   %[[VAL_328:.*]] = fir.call @_FortranAioInputInteger(%[[VAL_308]], %[[VAL_327]], %[[VAL_302]]) {{.*}}: (!fir.ref<i8>, !fir.ref<i64>, i32) -> i1
-! CHECK:   %[[VAL_329:.*]] = arith.addi %[[VAL_319]], %[[VAL_305]] overflow<nsw> : index
-! CHECK:   %[[VAL_330:.*]] = arith.subi %[[VAL_320]], %[[VAL_305]] : index
-! CHECK:   cf.br ^bb2(%[[VAL_329]], %[[VAL_330]] : index, index)
-! CHECK: ^bb4:
-! CHECK:   %[[VAL_331:.*]] = arith.addi %[[VAL_316]], %[[VAL_305]] overflow<nsw> : index
-! CHECK:   %[[VAL_332:.*]] = arith.subi %[[VAL_317]], %[[VAL_305]] : index
-! CHECK:   cf.br ^bb1(%[[VAL_331]], %[[VAL_332]] : index, index)
-! CHECK: ^bb5:
-! CHECK:   %[[VAL_333:.*]] = fir.call @_FortranAioEndIoStatement(%[[VAL_308]]) {{.*}}: (!fir.ref<i8>) -> i32
+! CHECK:   %[[VAL_SHIFT:.*]] = fir.shift %{{.*}}, %{{.*}}, %{{.*}} : (index, index, index) -> !fir.shift<3>
+! CHECK:   %[[VAL_B:.*]]:2 = hlfir.declare %[[VAL_B_ARG]](%[[VAL_SHIFT]]){{.*}}{uniq_name = "_QFwith_pathEb"}
+! CHECK:   %[[VAL_I:.*]]:2 = hlfir.declare %[[VAL_I_ARG]]{{.*}}{uniq_name = "_QFwith_pathEi"}
+! CHECK:   %[[VAL_BEGIN:.*]] = fir.call @_FortranAioBeginExternalListInput({{.*}}) {{.*}}: (i32, !fir.ref<i8>, i32) -> !fir.ref<i8>
+! CHECK:   %[[VAL_DIMS:.*]]:3 = fir.box_dims %[[VAL_I]]#1, %{{.*}} : (!fir.box<!fir.array<?xi32>>, index) -> (index, index, index)
+! CHECK:   %[[VAL_FIELD_A:.*]] = fir.field_index a, !fir.type<_QMderived_typesTt2{a:!fir.array<5x5x!fir.type<_QMderived_typesTt{i:i32,c:!fir.char<1,2>}>>}>
+! CHECK:   %[[VAL_FIELD_I:.*]] = fir.field_index i, !fir.type<_QMderived_typesTt{i:i32,c:!fir.char<1,2>}>
+! CHECK:   %[[VAL_SHIFT2:.*]] = fir.shift %{{.*}}, %{{.*}}, %{{.*}} : (index, index, index) -> !fir.shift<3>
+! CHECK:   %[[VAL_UNDEF:.*]] = fir.undefined index
+! CHECK:   %[[VAL_SLICE:.*]] = fir.slice %{{.*}}, %[[VAL_UNDEF]], %[[VAL_UNDEF]], %{{.*}}, %[[VAL_DIMS]]#1, %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}} path %[[VAL_FIELD_A]], %{{.*}}, %{{.*}}, %[[VAL_FIELD_I]] : (i64, index, index, index, index, index, index, index, index, !fir.field, i64, i64, !fir.field) -> !fir.slice<3>
+! CHECK:   fir.do_loop %[[IDX_OUTER:.*]] = %{{.*}} to %{{.*}} step %{{.*}} {
+! CHECK:     fir.do_loop %[[IDX_INNER:.*]] = %{{.*}} to %{{.*}} step %{{.*}} {
+! CHECK:       %[[FIVE_IDX:.*]] = fir.convert %{{.*}} : (i64) -> index
+! CHECK:       %[[VEL:.*]] = fir.coordinate_of %[[VAL_I]]#1, %[[IDX_INNER]] : (!fir.box<!fir.array<?xi32>>, index) -> !fir.ref<i32>
+! CHECK:       %[[VEL_LD:.*]] = fir.load %[[VEL]] : !fir.ref<i32>
+! CHECK:       %[[VEL_IDX:.*]] = fir.convert %[[VEL_LD]] : (i32) -> index
+! CHECK:       %[[ELEM:.*]] = fir.array_coor %[[VAL_B]]#1(%[[VAL_SHIFT2]]) {{\[}}%[[VAL_SLICE]]] %[[FIVE_IDX]], %[[VEL_IDX]], %[[IDX_OUTER]] : (!fir.box<!fir.array<?x?x?x!fir.type<_QMderived_typesTt2{a:!fir.array<5x5x!fir.type<_QMderived_typesTt{i:i32,c:!fir.char<1,2>}>>}>>>, !fir.shift<3>, !fir.slice<3>, index, index, index) -> !fir.ref<i32>
+! CHECK:       %[[ELEM_I64:.*]] = fir.convert %[[ELEM]] : (!fir.ref<i32>) -> !fir.ref<i64>
+! CHECK:       %{{.*}} = fir.call @_FortranAioInputInteger(%[[VAL_BEGIN]], %[[ELEM_I64]], %{{.*}}) {{.*}}: (!fir.ref<i8>, !fir.ref<i64>, i32) -> i1
+! CHECK:     }
+! CHECK:   }
+! CHECK:   %{{.*}} = fir.call @_FortranAioEndIoStatement(%[[VAL_BEGIN]]) {{.*}}: (!fir.ref<i8>) -> i32
 ! CHECK:   return
 end subroutine
 
 ! CHECK-LABEL: func @_QPsimple_iostat(
-! CHECK-SAME: %[[VAL_357:.*]]: !fir.box<!fir.array<?xf32>>{{.*}}, %[[VAL_346:.*]]: !fir.box<!fir.array<?xi32>>{{.*}}, %[[VAL_361:.*]]: !fir.ref<i32>{{.*}}, %[[VAL_364:.*]]: !fir.ref<i32>{{.*}}) {
+! CHECK-SAME: %[[VAL_X_ARG:.*]]: !fir.box<!fir.array<?xf32>>{{.*}}, %[[VAL_Y_ARG:.*]]: !fir.box<!fir.array<?xi32>>{{.*}}, %[[VAL_J_ARG:.*]]: !fir.ref<i32>{{.*}}, %[[VAL_STAT_ARG:.*]]: !fir.ref<i32>{{.*}}) {
 subroutine simple_iostat(x, y, j, stat)
   integer :: j, y(:), stat
   real :: x(:)
   read(*, *, iostat=stat) x(y), j
-! CHECK-DAG: %[[VAL_334:.*]] = arith.constant 5 : i32
-! CHECK-DAG: %[[VAL_336:.*]] = arith.constant false
-! CHECK-DAG: %[[VAL_337:.*]] = arith.constant true
-! CHECK-DAG: %[[VAL_338:.*]] = arith.constant 1 : index
-! CHECK-DAG: %[[VAL_339:.*]] = arith.constant 0 : index
-! CHECK-DAG: %[[VAL_340:.*]] = arith.constant 4 : i32
-! CHECK:   %[[VAL_341:.*]] = fir.address_of(@_QQ{{.*}}) : !fir.ref<!fir.char<1,{{.*}}>>
-! CHECK:   %[[VAL_342:.*]] = fir.convert %[[VAL_341]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
-! CHECK:   %[[VAL_343:.*]] = fir.call @_FortranAioBeginExternalListInput(%[[VAL_334]], %[[VAL_342]], %{{.*}}) {{.*}}: (i32, !fir.ref<i8>, i32) -> !fir.ref<i8>
-! CHECK:   fir.call @_FortranAioEnableHandlers(%[[VAL_343]], %[[VAL_337]], %[[VAL_336]], %[[VAL_336]], %[[VAL_336]], %[[VAL_336]]) {{.*}}: (!fir.ref<i8>, i1, i1, i1, i1, i1) -> ()
-! CHECK:   %[[VAL_345:.*]]:3 = fir.box_dims %[[VAL_346]], %[[VAL_339]] : (!fir.box<!fir.array<?xi32>>, index) -> (index, index, index)
-! CHECK:   %[[VAL_347:.*]] = fir.slice %[[VAL_338]], %[[VAL_345]]#1, %[[VAL_338]] : (index, index, index) -> !fir.slice<1>
-! CHECK:   %[[VAL_348:.*]] = arith.subi %[[VAL_345]]#1, %[[VAL_338]] : index
-! CHECK:   cf.br ^bb1(%[[VAL_339]], %[[VAL_337]] : index, i1)
-! CHECK: ^bb1(%[[VAL_349:.*]]: index, %[[VAL_350:.*]]: i1):
-! CHECK:   %[[VAL_351:.*]] = arith.cmpi sle, %[[VAL_349]], %[[VAL_348]] : index
-! CHECK:   %[[VAL_352:.*]] = arith.andi %[[VAL_350]], %[[VAL_351]] : i1
-! CHECK:   cf.cond_br %[[VAL_352]], ^bb2, ^bb3
-! CHECK: ^bb2:
-! CHECK:   %[[VAL_353:.*]] = fir.coordinate_of %[[VAL_346]], %[[VAL_349]] : (!fir.box<!fir.array<?xi32>>, index) -> !fir.ref<i32>
-! CHECK:   %[[VAL_354:.*]] = fir.load %[[VAL_353]] : !fir.ref<i32>
-! CHECK:   %[[VAL_355:.*]] = fir.convert %[[VAL_354]] : (i32) -> index
-! CHECK:   %[[VAL_356:.*]] = fir.array_coor %[[VAL_357]] {{\[}}%[[VAL_347]]] %[[VAL_355]] : (!fir.box<!fir.array<?xf32>>, !fir.slice<1>, index) -> !fir.ref<f32>
-! CHECK:   %[[VAL_358:.*]] = fir.call @_FortranAioInputReal32(%[[VAL_343]], %[[VAL_356]]) {{.*}}: (!fir.ref<i8>, !fir.ref<f32>) -> i1
-! CHECK:   %[[VAL_359:.*]] = arith.addi %[[VAL_349]], %[[VAL_338]] overflow<nsw> : index
-! CHECK:   cf.br ^bb1(%[[VAL_359]], %[[VAL_358]] : index, i1)
-! CHECK: ^bb3:
-! CHECK:   cf.cond_br %[[VAL_350]], ^bb4, ^bb5
-! CHECK: ^bb4:
-! CHECK:   %[[VAL_360:.*]] = fir.convert %[[VAL_361]] : (!fir.ref<i32>) -> !fir.ref<i64>
-! CHECK:   %[[VAL_362:.*]] = fir.call @_FortranAioInputInteger(%[[VAL_343]], %[[VAL_360]], %[[VAL_340]]) {{.*}}: (!fir.ref<i8>, !fir.ref<i64>, i32) -> i1
-! CHECK:   cf.br ^bb5
-! CHECK: ^bb5:
-! CHECK:   %[[VAL_363:.*]] = fir.call @_FortranAioEndIoStatement(%[[VAL_343]]) {{.*}}: (!fir.ref<i8>) -> i32
-! CHECK:   fir.store %[[VAL_363]] to %[[VAL_364]] : !fir.ref<i32>
+! CHECK:   %[[VAL_J:.*]]:2 = hlfir.declare %[[VAL_J_ARG]]{{.*}}{uniq_name = "_QFsimple_iostatEj"}
+! CHECK:   %[[VAL_STAT:.*]]:2 = hlfir.declare %[[VAL_STAT_ARG]]{{.*}}{uniq_name = "_QFsimple_iostatEstat"}
+! CHECK:   %[[VAL_X:.*]]:2 = hlfir.declare %[[VAL_X_ARG]]{{.*}}{uniq_name = "_QFsimple_iostatEx"}
+! CHECK:   %[[VAL_Y:.*]]:2 = hlfir.declare %[[VAL_Y_ARG]]{{.*}}{uniq_name = "_QFsimple_iostatEy"}
+! CHECK:   %[[VAL_BEGIN:.*]] = fir.call @_FortranAioBeginExternalListInput({{.*}}) {{.*}}: (i32, !fir.ref<i8>, i32) -> !fir.ref<i8>
+! CHECK:   fir.call @_FortranAioEnableHandlers(%[[VAL_BEGIN]], %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}) {{.*}}: (!fir.ref<i8>, i1, i1, i1, i1, i1) -> ()
+! CHECK:   %[[VAL_DIMS:.*]]:3 = fir.box_dims %[[VAL_Y]]#1, %{{.*}} : (!fir.box<!fir.array<?xi32>>, index) -> (index, index, index)
+! CHECK:   %[[VAL_TRUE:.*]] = arith.constant true
+! CHECK:   %[[VAL_SLICE:.*]] = fir.slice %{{.*}}, %[[VAL_DIMS]]#1, %{{.*}} : (index, index, index) -> !fir.slice<1>
+! CHECK:   %[[BOUND:.*]] = arith.subi %[[VAL_DIMS]]#1, %{{.*}} : index
+! CHECK:   %[[ITER_RES:.*]] = fir.iterate_while (%[[IDX:.*]] = %{{.*}} to %[[BOUND]] step %{{.*}}) and (%[[COND:.*]] = %[[VAL_TRUE]]) {
+! CHECK:     %[[VEL:.*]] = fir.coordinate_of %[[VAL_Y]]#1, %[[IDX]] : (!fir.box<!fir.array<?xi32>>, index) -> !fir.ref<i32>
+! CHECK:     %[[VEL_LD:.*]] = fir.load %[[VEL]] : !fir.ref<i32>
+! CHECK:     %[[VEL_IDX:.*]] = fir.convert %[[VEL_LD]] : (i32) -> index
+! CHECK:     %[[ELEM:.*]] = fir.array_coor %[[VAL_X]]#1 {{\[}}%[[VAL_SLICE]]] %[[VEL_IDX]] : (!fir.box<!fir.array<?xf32>>, !fir.slice<1>, index) -> !fir.ref<f32>
+! CHECK:     %[[OK:.*]] = fir.call @_FortranAioInputReal32(%[[VAL_BEGIN]], %[[ELEM]]) {{.*}}: (!fir.ref<i8>, !fir.ref<f32>) -> i1
+! CHECK:     fir.result %[[OK]] : i1
+! CHECK:   }
+! CHECK:   fir.if %[[ITER_RES]] {
+! CHECK:     %[[J_I64:.*]] = fir.convert %[[VAL_J]]#0 : (!fir.ref<i32>) -> !fir.ref<i64>
+! CHECK:     %{{.*}} = fir.call @_FortranAioInputInteger(%[[VAL_BEGIN]], %[[J_I64]], %{{.*}}) {{.*}}: (!fir.ref<i8>, !fir.ref<i64>, i32) -> i1
+! CHECK:   }
+! CHECK:   %[[END_ST:.*]] = fir.call @_FortranAioEndIoStatement(%[[VAL_BEGIN]]) {{.*}}: (!fir.ref<i8>) -> i32
+! CHECK:   fir.store %[[END_ST]] to %[[VAL_STAT]]#0 : !fir.ref<i32>
 ! CHECK:   return
 end subroutine
 
 ! CHECK-LABEL: func @_QPiostat_in_io_loop(
-! CHECK-SAME: %[[VAL_400:.*]]: !fir.ref<!fir.array<3x5xi32>>{{.*}}, %[[VAL_396:.*]]: !fir.ref<!fir.array<3xi32>>{{.*}}, %[[VAL_408:.*]]: !fir.ref<i32>{{.*}}) {
+! CHECK-SAME: %[[VAL_K_ARG:.*]]: !fir.ref<!fir.array<3x5xi32>>{{.*}}, %[[VAL_J_ARG:.*]]: !fir.ref<!fir.array<3xi32>>{{.*}}, %[[VAL_STAT_ARG:.*]]: !fir.ref<i32>{{.*}}) {
 subroutine iostat_in_io_loop(k, j, stat)
   integer :: k(3, 5)
   integer :: j(3)
   integer  :: stat
   read(*, *, iostat=stat) (k(i, j), i=1,3,1)
-! CHECK-DAG: %[[VAL_365:.*]] = arith.constant 5 : index
-! CHECK-DAG: %[[VAL_366:.*]] = arith.constant 5 : i32
-! CHECK-DAG: %[[VAL_368:.*]] = arith.constant 3 : index
-! CHECK-DAG: %[[VAL_369:.*]] = arith.constant true
-! CHECK-DAG: %[[VAL_370:.*]] = arith.constant false
-! CHECK-DAG: %[[VAL_371:.*]] = arith.constant 1 : index
-! CHECK-DAG: %[[VAL_372:.*]] = arith.constant 0 : index
-! CHECK-DAG: %[[VAL_373:.*]] = arith.constant 2 : index
-! CHECK-DAG: %[[VAL_374:.*]] = arith.constant 4 : i32
-! CHECK:   %[[VAL_375:.*]] = fir.alloca i32
-! CHECK:   %[[VAL_376:.*]] = fir.address_of(@_QQ{{.*}}) : !fir.ref<!fir.char<1,{{.*}}>>
-! CHECK:   %[[VAL_377:.*]] = fir.convert %[[VAL_376]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
-! CHECK:   %[[VAL_378:.*]] = fir.call @_FortranAioBeginExternalListInput(%[[VAL_366]], %[[VAL_377]], %{{.*}}) {{.*}}: (i32, !fir.ref<i8>, i32) -> !fir.ref<i8>
-! CHECK:   fir.call @_FortranAioEnableHandlers(%[[VAL_378]], %[[VAL_369]], %[[VAL_370]], %[[VAL_370]], %[[VAL_370]], %[[VAL_370]]) {{.*}}: (!fir.ref<i8>, i1, i1, i1, i1, i1) -> ()
-! CHECK:   cf.br ^bb1(%[[VAL_371]], %[[VAL_369]] : index, i1)
-! CHECK: ^bb1(%[[VAL_380:.*]]: index, %[[VAL_381:.*]]: i1):
-! CHECK:   %[[VAL_382:.*]] = arith.cmpi sle, %[[VAL_380]], %[[VAL_368]] : index
-! CHECK:   %[[VAL_383:.*]] = arith.andi %[[VAL_381]], %[[VAL_382]] : i1
-! CHECK:   cf.cond_br %[[VAL_383]], ^bb2, ^bb7
-! CHECK: ^bb2:
-! CHECK:   %[[VAL_384:.*]] = fir.convert %[[VAL_380]] : (index) -> i32
-! CHECK:   fir.store %[[VAL_384]] to %[[VAL_375]] : !fir.ref<i32>
-! CHECK:   cf.cond_br %[[VAL_381]], ^bb3, ^bb6(%[[VAL_370]] : i1)
-! CHECK: ^bb3:
-! CHECK:   %[[VAL_385:.*]] = fir.load %[[VAL_375]] : !fir.ref<i32>
-! CHECK:   %[[VAL_386:.*]] = fir.convert %[[VAL_385]] : (i32) -> i64
-! CHECK:   %[[VAL_387:.*]] = fir.shape %[[VAL_368]], %[[VAL_365]] : (index, index) -> !fir.shape<2>
-! CHECK:   %[[VAL_388:.*]] = fir.undefined index
-! CHECK:   %[[VAL_389:.*]] = fir.slice %[[VAL_386]], %[[VAL_388]], %[[VAL_388]], %[[VAL_371]], %[[VAL_368]], %[[VAL_371]] : (i64, index, index, index, index, index) -> !fir.slice<2>
-! CHECK:   cf.br ^bb4(%[[VAL_372]], %[[VAL_369]] : index, i1)
-! CHECK: ^bb4(%[[VAL_390:.*]]: index, %[[VAL_391:.*]]: i1):
-! CHECK:   %[[VAL_392:.*]] = arith.cmpi sle, %[[VAL_390]], %[[VAL_373]] : index
-! CHECK:   %[[VAL_393:.*]] = arith.andi %[[VAL_391]], %[[VAL_392]] : i1
-! CHECK:   cf.cond_br %[[VAL_393]], ^bb5, ^bb6(%[[VAL_391]] : i1)
-! CHECK: ^bb5:
-! CHECK:   %[[VAL_394:.*]] = fir.convert %[[VAL_385]] : (i32) -> index
-! CHECK:   %[[VAL_395:.*]] = fir.coordinate_of %[[VAL_396]], %[[VAL_390]] : (!fir.ref<!fir.array<3xi32>>, index) -> !fir.ref<i32>
-! CHECK:   %[[VAL_397:.*]] = fir.load %[[VAL_395]] : !fir.ref<i32>
-! CHECK:   %[[VAL_398:.*]] = fir.convert %[[VAL_397]] : (i32) -> index
-! CHECK:   %[[VAL_399:.*]] = fir.array_coor %[[VAL_400]](%[[VAL_387]]) {{\[}}%[[VAL_389]]] %[[VAL_394]], %[[VAL_398]] : (!fir.ref<!fir.array<3x5xi32>>, !fir.shape<2>, !fir.slice<2>, index, index) -> !fir.ref<i32>
-! CHECK:   %[[VAL_401:.*]] = fir.convert %[[VAL_399]] : (!fir.ref<i32>) -> !fir.ref<i64>
-! CHECK:   %[[VAL_402:.*]] = fir.call @_FortranAioInputInteger(%[[VAL_378]], %[[VAL_401]], %[[VAL_374]]) {{.*}}: (!fir.ref<i8>, !fir.ref<i64>, i32) -> i1
-! CHECK:   %[[VAL_403:.*]] = arith.addi %[[VAL_390]], %[[VAL_371]] overflow<nsw> : index
-! CHECK:   cf.br ^bb4(%[[VAL_403]], %[[VAL_402]] : index, i1)
-! CHECK: ^bb6(%[[VAL_404:.*]]: i1):
-! CHECK:   %[[VAL_405:.*]] = arith.addi %[[VAL_380]], %[[VAL_371]] overflow<nsw> : index
-! CHECK:   cf.br ^bb1(%[[VAL_405]], %[[VAL_404]] : index, i1)
-! CHECK: ^bb7:
-! CHECK:   %[[VAL_406:.*]] = fir.convert %[[VAL_380]] : (index) -> i32
-! CHECK:   fir.store %[[VAL_406]] to %[[VAL_375]] : !fir.ref<i32>
-! CHECK:   %[[VAL_407:.*]] = fir.call @_FortranAioEndIoStatement(%[[VAL_378]]) {{.*}}: (!fir.ref<i8>) -> i32
-! CHECK:   fir.store %[[VAL_407]] to %[[VAL_408]] : !fir.ref<i32>
+! CHECK:   %[[VAL_I_ALLOC:.*]] = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFiostat_in_io_loopEi"}
+! CHECK:   %[[VAL_I:.*]]:2 = hlfir.declare %[[VAL_I_ALLOC]] {uniq_name = "_QFiostat_in_io_loopEi"}
+! CHECK:   %[[VAL_J:.*]]:2 = hlfir.declare %[[VAL_J_ARG]](%{{.*}}){{.*}}{uniq_name = "_QFiostat_in_io_loopEj"}
+! CHECK:   %[[VAL_K:.*]]:2 = hlfir.declare %[[VAL_K_ARG]](%{{.*}}){{.*}}{uniq_name = "_QFiostat_in_io_loopEk"}
+! CHECK:   %[[VAL_STAT:.*]]:2 = hlfir.declare %[[VAL_STAT_ARG]]{{.*}}{uniq_name = "_QFiostat_in_io_loopEstat"}
+! CHECK:   %[[VAL_BEGIN:.*]] = fir.call @_FortranAioBeginExternalListInput({{.*}}) {{.*}}: (i32, !fir.ref<i8>, i32) -> !fir.ref<i8>
+! CHECK:   fir.call @_FortranAioEnableHandlers(%[[VAL_BEGIN]], %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}) {{.*}}: (!fir.ref<i8>, i1, i1, i1, i1, i1) -> ()
+! CHECK:   %[[VAL_TRUE:.*]] = arith.constant true
+! CHECK:   %[[OUTER:.*]]:2 = fir.iterate_while (%[[I_IDX:.*]] = %{{.*}} to %{{.*}} step %{{.*}}) and (%[[I_COND:.*]] = %[[VAL_TRUE]]) -> (index, i1) {
+! CHECK:     %[[I_AS_I32:.*]] = fir.convert %[[I_IDX]] : (index) -> i32
+! CHECK:     fir.store %[[I_AS_I32]] to %[[VAL_I]]#0 : !fir.ref<i32>
+! CHECK:     %[[INNER_RES:.*]] = fir.if %[[I_COND]] -> (i1) {
+! CHECK:       %[[I_LD:.*]] = fir.load %[[VAL_I]]#0 : !fir.ref<i32>
+! CHECK:       %[[I_I64:.*]] = fir.convert %[[I_LD]] : (i32) -> i64
+! CHECK:       %[[K_SHAPE:.*]] = fir.shape %{{.*}}, %{{.*}} : (index, index) -> !fir.shape<2>
+! CHECK:       %[[VAL_UNDEF:.*]] = fir.undefined index
+! CHECK:       %[[VAL_SLICE:.*]] = fir.slice %[[I_I64]], %[[VAL_UNDEF]], %[[VAL_UNDEF]], %{{.*}}, %{{.*}}, %{{.*}} : (i64, index, index, index, index, index) -> !fir.slice<2>
+! CHECK:       %[[INNER_ITER:.*]] = fir.iterate_while (%[[J_IDX:.*]] = %{{.*}} to %{{.*}} step %{{.*}}) and (%{{.*}} = %[[I_COND]]) {
+! CHECK:         %[[I_AS_IDX:.*]] = fir.convert %[[I_I64]] : (i64) -> index
+! CHECK:         %[[J_EL:.*]] = fir.coordinate_of %[[VAL_J]]#0, %[[J_IDX]] : (!fir.ref<!fir.array<3xi32>>, index) -> !fir.ref<i32>
+! CHECK:         %[[J_LD:.*]] = fir.load %[[J_EL]] : !fir.ref<i32>
+! CHECK:         %[[J_AS_IDX:.*]] = fir.convert %[[J_LD]] : (i32) -> index
+! CHECK:         %[[ELEM:.*]] = fir.array_coor %[[VAL_K]]#0(%[[K_SHAPE]]) {{\[}}%[[VAL_SLICE]]] %[[I_AS_IDX]], %[[J_AS_IDX]] : (!fir.ref<!fir.array<3x5xi32>>, !fir.shape<2>, !fir.slice<2>, index, index) -> !fir.ref<i32>
+! CHECK:         %[[ELEM_I64:.*]] = fir.convert %[[ELEM]] : (!fir.ref<i32>) -> !fir.ref<i64>
+! CHECK:         %[[OK:.*]] = fir.call @_FortranAioInputInteger(%[[VAL_BEGIN]], %[[ELEM_I64]], %{{.*}}) {{.*}}: (!fir.ref<i8>, !fir.ref<i64>, i32) -> i1
+! CHECK:         fir.result %[[OK]] : i1
+! CHECK:       }
+! CHECK:       fir.result %[[INNER_ITER]] : i1
+! CHECK:     } else {
+! CHECK:       fir.result %{{.*}} : i1
+! CHECK:     }
+! CHECK:     %{{.*}} = arith.addi %[[I_IDX]], %{{.*}} overflow<nsw> : index
+! CHECK:     %{{.*}} = arith.select %[[INNER_RES]], %{{.*}}, %[[I_IDX]] : index
+! CHECK:     fir.result %{{.*}}, %[[INNER_RES]] : index, i1
+! CHECK:   }
+! CHECK:   %[[FINAL_I:.*]] = fir.convert %[[OUTER]]#0 : (index) -> i32
+! CHECK:   fir.store %[[FINAL_I]] to %[[VAL_I]]#0 : !fir.ref<i32>
+! CHECK:   %[[END_ST:.*]] = fir.call @_FortranAioEndIoStatement(%[[VAL_BEGIN]]) {{.*}}: (!fir.ref<i8>) -> i32
+! CHECK:   fir.store %[[END_ST]] to %[[VAL_STAT]]#0 : !fir.ref<i32>
 ! CHECK:   return
 end subroutine

>From 918aaaebc4afbbac8648b567f76388d7ccbeb280 Mon Sep 17 00:00:00 2001
From: Eugene Epshteyn <eepshteyn at nvidia.com>
Date: Mon, 4 May 2026 08:37:13 -0400
Subject: [PATCH 2/2] Restored basic block testing in Lower/select-type.f90

---
 flang/test/Lower/select-type.f90 | 512 +++++++++++++++++++++++++------
 1 file changed, 417 insertions(+), 95 deletions(-)

diff --git a/flang/test/Lower/select-type.f90 b/flang/test/Lower/select-type.f90
index fff685a9ca1fe..2a3885c16529e 100644
--- a/flang/test/Lower/select-type.f90
+++ b/flang/test/Lower/select-type.f90
@@ -55,18 +55,77 @@ subroutine select_type1(a)
   end subroutine
 
 ! CHECK-LABEL: func.func @_QMselect_type_lower_testPselect_type1(
-! CHECK-SAME: %[[ARG0:.*]]: !fir.class<!fir.type<_QMselect_type_lower_testTp1
-! CHECK: %[[ADECL:.*]]:2 = hlfir.declare %[[ARG0]]{{.*}}{{{.*}}uniq_name = "_QMselect_type_lower_testFselect_type1Ea"}
-! CHECK: fir.select_type %[[ADECL]]#1
-! CHECK-SAME: #fir.type_is<!fir.type<_QMselect_type_lower_testTp1
-! CHECK-SAME: #fir.class_is<!fir.type<_QMselect_type_lower_testTp1
-! CHECK-SAME: #fir.class_is<!fir.type<_QMselect_type_lower_testTp2
-
+! CHECK-SAME:    %[[ARG0:.*]]: !fir.class<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>> {fir.bindc_name = "a"}
+! CHECK:         %[[A:.*]]:2 = hlfir.declare %[[ARG0]]{{.*}}{{.*}}uniq_name = "_QMselect_type_lower_testFselect_type1Ea"
+! CHECK:         fir.select_type %[[A]]#1 : !fir.class<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>
+! CHECK-SAME:    [#fir.type_is<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>, ^bb[[TYPE_IS_P1:[0-9]+]],
+! CHECK-SAME:     #fir.class_is<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>, ^bb[[CLASS_IS_P1:[0-9]+]],
+! CHECK-SAME:     #fir.class_is<!fir.type<_QMselect_type_lower_testTp2{p1:!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>,c:i32}>>, ^bb[[CLASS_IS_P2:[0-9]+]],
+! CHECK-SAME:     unit, ^bb[[DEFAULT:[0-9]+]]]
+! TYPE IS (p1) block: box_addr to !fir.ref<p1>, then declare local 'a' as ref<p1>.
+! CHECK:       ^bb[[TYPE_IS_P1]]:
+! CHECK:         %[[T1_ADDR:.*]] = fir.box_addr %[[A]]#1 : (!fir.class<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>) -> !fir.ref<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>
+! CHECK:         hlfir.declare %[[T1_ADDR]] {{.*}}uniq_name = "_QMselect_type_lower_testFselect_type1Ea"
+! CHECK:         cf.br ^bb[[EXIT:[0-9]+]]
+! CLASS IS (p1) block: declare local 'a' directly with the class<p1> selector.
+! CHECK:       ^bb[[CLASS_IS_P1]]:
+! CHECK:         hlfir.declare %[[A]]#1 {{.*}}uniq_name = "_QMselect_type_lower_testFselect_type1Ea"
+! CHECK-NOT:     fir.box_addr
+! CHECK:         cf.br ^bb[[EXIT]]
+! CLASS IS (p2) block: convert class<p1> to class<p2>, declare 'a' as class<p2>, access %c via hlfir.designate.
+! CHECK:       ^bb[[CLASS_IS_P2]]:
+! CHECK:         %[[CONV:.*]] = fir.convert %[[A]]#1 : (!fir.class<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>) -> !fir.class<!fir.type<_QMselect_type_lower_testTp2{p1:!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>,c:i32}>>
+! CHECK:         %[[A_P2:.*]]:2 = hlfir.declare %[[CONV]]
+! CHECK:         hlfir.designate %[[A_P2]]#0{"c"}
+! CHECK:         cf.br ^bb[[EXIT]]
+! Default block: declare 'a' with the original class<p1> selector.
+! CHECK:       ^bb[[DEFAULT]]:
+! CHECK:         hlfir.declare %[[A]]#1 {{.*}}uniq_name = "_QMselect_type_lower_testFselect_type1Ea"
+! CHECK:         cf.br ^bb[[EXIT]]
+! CHECK:       ^bb[[EXIT]]:
+! CHECK:         return
+
+! In the CFG version, fir.select_type is decomposed into a chain of
+! type_desc/box_tdesc/cmpi (for type_is) and _FortranAClassIs (for class_is)
+! checks chained through cf.cond_br. Bodies of each arm live in their own
+! basic blocks and all branch to a single common exit block.
 ! CFG-LABEL: func.func @_QMselect_type_lower_testPselect_type1(
-! CFG: hlfir.declare %{{.*}}
-! CFG: fir.type_desc !fir.type<_QMselect_type_lower_testTp1
-! CFG: fir.box_tdesc %{{.*}}
-! CFG: fir.call @_FortranAClassIs(%{{.*}}, %{{.*}}) : (!fir.box<none>, !fir.ref<none>) -> i1
+! CFG:         %[[A:.*]]:2 = hlfir.declare %{{.*}}
+! Entry block: type_is(p1) check via tdesc equality, then branch to type_is body or next check.
+! CFG:         %[[TDESC_P1:.*]] = fir.type_desc !fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>
+! CFG:         %[[BOX_TDESC:.*]] = fir.box_tdesc %[[A]]#1
+! CFG:         %[[CMP:.*]] = arith.cmpi eq, %{{.*}}, %{{.*}} : index
+! CFG:         cf.cond_br %[[CMP]], ^bb[[TYPE_IS_P1:[0-9]+]], ^bb[[TEST_C2:[0-9]+]]
+! Block testing class_is(p2) via _FortranAClassIs, branches to class_is(p2) body or to next test.
+! CFG:       ^bb[[TEST_C2]]:
+! CFG:         %[[TDESC_P2:.*]] = fir.type_desc !fir.type<_QMselect_type_lower_testTp2
+! CFG:         fir.call @_FortranAClassIs(%{{.*}}, %{{.*}}) : (!fir.box<none>, !fir.ref<none>) -> i1
+! CFG:         cf.cond_br %{{.*}}, ^bb[[CLASS_IS_P2:[0-9]+]], ^bb[[TEST_C1:[0-9]+]]
+! type_is(p1) body: box_addr to ref<p1>, declare 'a' as ref<p1>, branch to exit.
+! CFG:       ^bb[[TYPE_IS_P1]]:
+! CFG:         fir.box_addr %[[A]]#1 : (!fir.class<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>) -> !fir.ref<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>
+! CFG:         hlfir.declare %{{.*}}{{.*}}"_QMselect_type_lower_testFselect_type1Ea"
+! CFG:         cf.br ^bb[[EXIT:[0-9]+]]
+! class_is(p1) body: declare 'a' from class<p1> selector, branch to exit.
+! CFG:         hlfir.declare %[[A]]#1 {{.*}}"_QMselect_type_lower_testFselect_type1Ea"
+! CFG:         cf.br ^bb[[EXIT]]
+! Block testing class_is(p1) via _FortranAClassIs, branches to class_is(p1) body or to default.
+! CFG:       ^bb[[TEST_C1]]:
+! CFG:         fir.type_desc !fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>
+! CFG:         fir.call @_FortranAClassIs(%{{.*}}, %{{.*}}) : (!fir.box<none>, !fir.ref<none>) -> i1
+! CFG:         cf.cond_br %{{.*}}, ^bb{{[0-9]+}}, ^bb{{[0-9]+}}
+! class_is(p2) body: convert class<p1> -> class<p2>, declare 'a', access %c.
+! CFG:       ^bb[[CLASS_IS_P2]]:
+! CFG:         fir.convert %[[A]]#1 : (!fir.class<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>) -> !fir.class<!fir.type<_QMselect_type_lower_testTp2{p1:!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>,c:i32}>>
+! CFG:         hlfir.declare %{{.*}}"_QMselect_type_lower_testFselect_type1Ea"
+! CFG:         hlfir.designate %{{.*}}{"c"}
+! CFG:         cf.br ^bb[[EXIT]]
+! Default body: declare 'a' from class<p1> selector, branch to exit.
+! CFG:         hlfir.declare %[[A]]#1 {{.*}}"_QMselect_type_lower_testFselect_type1Ea"
+! CFG:         cf.br ^bb[[EXIT]]
+! Common exit block: return.
+! CFG:       ^bb[[EXIT]]:
+! CFG:         return
 
   subroutine select_type2()
     select type (a => get_class())
@@ -79,16 +138,37 @@ subroutine select_type2()
     end select
   end subroutine
 
+! Selector is the result of get_class() loaded from a fir.alloca temp.
 ! CHECK-LABEL: func.func @_QMselect_type_lower_testPselect_type2()
-! CHECK: %[[RESULT:.*]] = fir.alloca !fir.class<!fir.ptr<!fir.type<_QMselect_type_lower_testTp1
-! CHECK: %[[FCTCALL:.*]] = fir.call @_QMselect_type_lower_testPget_class()
-! CHECK: fir.save_result %[[FCTCALL]] to %{{.*}}
-! CHECK: %[[SELECTOR:.*]] = fir.load %{{.*}}#0
-! CHECK: fir.select_type %[[SELECTOR]]
+! CHECK:         %[[RESULT:.*]] = fir.alloca !fir.class<!fir.ptr<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>> {bindc_name = ".result"}
+! CHECK:         %[[FCTCALL:.*]] = fir.call @_QMselect_type_lower_testPget_class() {{.*}} -> !fir.class<!fir.ptr<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>>
+! CHECK:         fir.save_result %[[FCTCALL]] to %{{.*}}
+! CHECK:         %[[SELECTOR:.*]] = fir.load %{{.*}}#0 : !fir.ref<!fir.class<!fir.ptr<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>>>
+! CHECK:         fir.select_type %[[SELECTOR]] : !fir.class<!fir.ptr<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>>
+! CHECK-SAME:    [#fir.type_is<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>, ^bb[[T1:[0-9]+]],
+! CHECK-SAME:     #fir.class_is<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>, ^bb[[C1:[0-9]+]],
+! CHECK-SAME:     unit, ^bb[[D:[0-9]+]]]
+! TYPE IS (p1): box_addr from class<ptr<p1>> to !fir.ref<p1>.
+! CHECK:       ^bb[[T1]]:
+! CHECK:         fir.box_addr %[[SELECTOR]] : (!fir.class<!fir.ptr<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>>) -> !fir.ref<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>
+! CHECK:         hlfir.declare %{{.*}}{{.*}}"_QMselect_type_lower_testFselect_type2Ea"
+! CHECK:         cf.br ^bb[[X:[0-9]+]]
+! CLASS IS (p1): no box_addr, declare with the loaded class<ptr<p1>> selector itself.
+! CHECK:       ^bb[[C1]]:
+! CHECK:         hlfir.declare %[[SELECTOR]] {{.*}}"_QMselect_type_lower_testFselect_type2Ea"
+! CHECK:         cf.br ^bb[[X]]
+! CHECK:       ^bb[[D]]:
+! CHECK:         hlfir.declare %[[SELECTOR]] {{.*}}"_QMselect_type_lower_testFselect_type2Ea"
+! CHECK:         cf.br ^bb[[X]]
 
 ! CFG-LABEL: func.func @_QMselect_type_lower_testPselect_type2() {
-! CFG: fir.type_desc !fir.type<_QMselect_type_lower_testTp1
-! CFG: fir.call @_FortranAClassIs
+! CFG:         fir.call @_QMselect_type_lower_testPget_class()
+! CFG:         %[[LOAD:.*]] = fir.load %{{.*}}
+! CFG:         fir.type_desc !fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>
+! CFG:         fir.box_tdesc %[[LOAD]]
+! CFG:         arith.cmpi eq, %{{.*}}, %{{.*}} : index
+! CFG:         cf.cond_br %{{.*}}, ^bb{{[0-9]+}}, ^bb{{[0-9]+}}
+! CFG:         fir.call @_FortranAClassIs(%{{.*}}, %{{.*}}) : (!fir.box<none>, !fir.ref<none>) -> i1
 
   subroutine select_type3(a)
     class(p1), pointer, intent(in) :: a(:)
@@ -103,16 +183,28 @@ subroutine select_type3(a)
     end select
   end subroutine
 
+! Selector is a single element designated from an array pointer.
 ! CHECK-LABEL: func.func @_QMselect_type_lower_testPselect_type3(
-! CHECK-SAME: %[[ARG0:.*]]: !fir.ref<!fir.class<!fir.ptr<!fir.array<?x!fir.type<_QMselect_type_lower_testTp1
-! CHECK: %[[ADECL:.*]]:2 = hlfir.declare %[[ARG0]]
-! CHECK: %[[LOAD:.*]] = fir.load %[[ADECL]]#0
-! CHECK: %[[SELECTOR:.*]] = hlfir.designate %[[LOAD]]
-! CHECK: fir.select_type %[[SELECTOR]]
+! CHECK-SAME:    %[[ARG0:.*]]: !fir.ref<!fir.class<!fir.ptr<!fir.array<?x!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>>>>
+! CHECK:         %[[A:.*]]:2 = hlfir.declare %[[ARG0]]
+! CHECK:         %[[A_LD:.*]] = fir.load %[[A]]#0
+! CHECK:         %[[SELECTOR:.*]] = hlfir.designate %[[A_LD]] (%c1{{.*}}) : (!fir.class<!fir.ptr<!fir.array<?x!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>>>, index) -> !fir.class<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>
+! CHECK:         fir.select_type %[[SELECTOR]] : !fir.class<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>
+! CHECK-SAME:    [#fir.type_is<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>, ^bb[[T1:[0-9]+]],
+! CHECK-SAME:     #fir.class_is<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>, ^bb[[C1:[0-9]+]],
+! CHECK-SAME:     unit, ^bb[[D:[0-9]+]]]
+! CHECK:       ^bb[[T1]]:
+! CHECK:         fir.box_addr %[[SELECTOR]] : (!fir.class<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>) -> !fir.ref<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>
+! CHECK:         hlfir.declare %{{.*}}{{.*}}"_QMselect_type_lower_testFselect_type3Ex"
+! CHECK:       ^bb[[C1]]:
+! CHECK:         hlfir.declare %[[SELECTOR]] {{.*}}"_QMselect_type_lower_testFselect_type3Ex"
 
 ! CFG-LABEL: func.func @_QMselect_type_lower_testPselect_type3(
-! CFG: hlfir.designate
-! CFG: fir.call @_FortranAClassIs
+! CFG:         hlfir.designate
+! CFG:         fir.type_desc !fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>
+! CFG:         fir.box_tdesc
+! CFG:         arith.cmpi eq, %{{.*}}, %{{.*}} : index
+! CFG:         fir.call @_FortranAClassIs
 
   subroutine select_type4(a)
     class(p1), intent(in) :: a
@@ -126,19 +218,35 @@ subroutine select_type4(a)
     end select
   end subroutine
 
+! Two type_is alternatives for the parameterised type p3, plus class_is(p1).
 ! CHECK-LABEL: func.func @_QMselect_type_lower_testPselect_type4(
-! CHECK-SAME: %[[ARG0:.*]]: !fir.class<!fir.type<_QMselect_type_lower_testTp1
-! CHECK: %[[ADECL:.*]]:2 = hlfir.declare %[[ARG0]]
-! CHECK: fir.select_type %[[ADECL]]#1
-! CHECK-SAME: #fir.type_is<!fir.type<_QMselect_type_lower_testTp3K8
-! CHECK-SAME: #fir.type_is<!fir.type<_QMselect_type_lower_testTp3K4
-! CHECK-SAME: #fir.class_is<!fir.type<_QMselect_type_lower_testTp1
+! CHECK-SAME:    %[[ARG0:.*]]: !fir.class<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>
+! CHECK:         %[[A:.*]]:2 = hlfir.declare %[[ARG0]]
+! CHECK:         fir.select_type %[[A]]#1 : !fir.class<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>
+! CHECK-SAME:    [#fir.type_is<!fir.type<_QMselect_type_lower_testTp3K8{p1:!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>,r:f64}>>, ^bb[[T8:[0-9]+]],
+! CHECK-SAME:     #fir.type_is<!fir.type<_QMselect_type_lower_testTp3K4{p1:!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>,r:f32}>>, ^bb[[T4:[0-9]+]],
+! CHECK-SAME:     #fir.class_is<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>, ^bb[[C1:[0-9]+]],
+! CHECK-SAME:     unit, ^bb[[X:[0-9]+]]]
+! CHECK:       ^bb[[T8]]:
+! CHECK:         fir.box_addr %[[A]]#1 : (!fir.class<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>) -> !fir.ref<!fir.type<_QMselect_type_lower_testTp3K8{p1:!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>,r:f64}>>
+! CHECK:         hlfir.declare
+! CHECK:       ^bb[[T4]]:
+! CHECK:         fir.box_addr %[[A]]#1 : (!fir.class<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>) -> !fir.ref<!fir.type<_QMselect_type_lower_testTp3K4{p1:!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>,r:f32}>>
+! CHECK:         hlfir.declare
+! CHECK:       ^bb[[C1]]:
+! CHECK:         hlfir.declare %[[A]]#1
+! CHECK:       ^bb[[X]]:
+! CHECK:         return
 
 ! CFG-LABEL: func.func @_QMselect_type_lower_testPselect_type4(
-! CFG: fir.type_desc !fir.type<_QMselect_type_lower_testTp3K8
-! CFG: fir.type_desc !fir.type<_QMselect_type_lower_testTp3K4
-! CFG: fir.type_desc !fir.type<_QMselect_type_lower_testTp1
-! CFG: fir.call @_FortranAClassIs
+! CFG:         fir.type_desc !fir.type<_QMselect_type_lower_testTp3K8
+! CFG:         arith.cmpi eq, %{{.*}}, %{{.*}} : index
+! CFG:         cf.cond_br
+! CFG:         fir.type_desc !fir.type<_QMselect_type_lower_testTp3K4
+! CFG:         arith.cmpi eq, %{{.*}}, %{{.*}} : index
+! CFG:         cf.cond_br
+! CFG:         fir.type_desc !fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>
+! CFG:         fir.call @_FortranAClassIs
 
   subroutine select_type5(a)
     class(*), intent(in) :: a
@@ -159,18 +267,46 @@ subroutine select_type5(a)
     end select
   end subroutine
 
+! Unlimited polymorphic selector: each type_is branch box_addrs to the
+! corresponding intrinsic type and declares 'x' with that type. The character
+! branch additionally extracts the element size with fir.box_elesize.
 ! CHECK-LABEL: func.func @_QMselect_type_lower_testPselect_type5(
-! CHECK-SAME: %[[ARG0:.*]]: !fir.class<none>
-! CHECK: fir.select_type %{{.*}} : !fir.class<none>
-! CHECK-SAME: #fir.type_is<i8>
-! CHECK-SAME: #fir.type_is<i32>
-! CHECK-SAME: #fir.type_is<f32>
-! CHECK-SAME: #fir.type_is<!fir.logical<4>>
-! CHECK-SAME: #fir.type_is<!fir.char<1,?>>
-
+! CHECK-SAME:    %[[ARG0:.*]]: !fir.class<none>
+! CHECK:         %[[A:.*]]:2 = hlfir.declare %[[ARG0]]
+! CHECK:         fir.select_type %[[A]]#1 : !fir.class<none>
+! CHECK-SAME:    [#fir.type_is<i8>, ^bb[[I8:[0-9]+]],
+! CHECK-SAME:     #fir.type_is<i32>, ^bb[[I32:[0-9]+]],
+! CHECK-SAME:     #fir.type_is<f32>, ^bb[[F32:[0-9]+]],
+! CHECK-SAME:     #fir.type_is<!fir.logical<4>>, ^bb[[L4:[0-9]+]],
+! CHECK-SAME:     #fir.type_is<!fir.char<1,?>>, ^bb[[CH:[0-9]+]],
+! CHECK-SAME:     unit, ^bb[[D:[0-9]+]]]
+! CHECK:       ^bb[[I8]]:
+! CHECK:         fir.box_addr %[[A]]#1 : (!fir.class<none>) -> !fir.ref<i8>
+! CHECK:         hlfir.declare
+! CHECK:       ^bb[[I32]]:
+! CHECK:         fir.box_addr %[[A]]#1 : (!fir.class<none>) -> !fir.ref<i32>
+! CHECK:         hlfir.declare
+! CHECK:       ^bb[[F32]]:
+! CHECK:         fir.box_addr %[[A]]#1 : (!fir.class<none>) -> !fir.ref<f32>
+! CHECK:         hlfir.declare
+! CHECK:       ^bb[[L4]]:
+! CHECK:         fir.box_addr %[[A]]#1 : (!fir.class<none>) -> !fir.ref<!fir.logical<4>>
+! CHECK:         hlfir.declare
+! CHECK:       ^bb[[CH]]:
+! CHECK:         fir.box_addr %[[A]]#1 : (!fir.class<none>) -> !fir.ref<!fir.char<1,?>>
+! CHECK:         fir.box_elesize %[[A]]#1 : (!fir.class<none>) -> index
+! CHECK:         hlfir.declare %{{.*}} typeparams %{{.*}} {{.*}}"_QMselect_type_lower_testFselect_type5Ex"
+! CHECK:       ^bb[[D]]:
+! CHECK:         hlfir.declare %[[A]]#1
+
+! CFG version uses fir.box_typecode + arith.cmpi against the intrinsic
+! type code constants for each type_is alternative.
 ! CFG-LABEL: func.func @_QMselect_type_lower_testPselect_type5(
-! CFG: fir.box_typecode %{{.*}} : (!fir.class<none>) -> i8
-! CFG: arith.cmpi eq, %{{.*}}, %{{.*}} : i8
+! CFG:         fir.box_typecode %{{.*}} : (!fir.class<none>) -> i8
+! CFG:         arith.cmpi eq, %{{.*}}, %{{.*}} : i8
+! CFG:         cf.cond_br
+! CFG:         fir.box_typecode
+! CFG:         cf.cond_br
 
   subroutine select_type6(a)
     class(*) :: a
@@ -185,15 +321,37 @@ subroutine select_type6(a)
     end select
   end subroutine
 
+! type_is(integer) and type_is(real) bodies do hlfir.assign of a constant
+! into the box-addr-typed reference; class default body calls
+! _FortranAStopStatementText and ends in fir.unreachable.
 ! CHECK-LABEL: func.func @_QMselect_type_lower_testPselect_type6(
-! CHECK-SAME: %[[ARG0:.*]]: !fir.class<none>
-! CHECK: %[[ADECL:.*]]:2 = hlfir.declare %[[ARG0]]
-! CHECK: fir.select_type %[[ADECL]]#1 : !fir.class<none>
-! CHECK-SAME: #fir.type_is<i32>
-! CHECK-SAME: #fir.type_is<f32>
+! CHECK-SAME:    %[[ARG0:.*]]: !fir.class<none>
+! CHECK:         %[[A:.*]]:2 = hlfir.declare %[[ARG0]]
+! CHECK:         fir.select_type %[[A]]#1 : !fir.class<none>
+! CHECK-SAME:    [#fir.type_is<i32>, ^bb[[I32:[0-9]+]],
+! CHECK-SAME:     #fir.type_is<f32>, ^bb[[F32:[0-9]+]],
+! CHECK-SAME:     unit, ^bb[[D:[0-9]+]]]
+! CHECK:       ^bb[[I32]]:
+! CHECK:         %[[I_REF:.*]] = fir.box_addr %[[A]]#1 : (!fir.class<none>) -> !fir.ref<i32>
+! CHECK:         %[[I_DECL:.*]]:2 = hlfir.declare %[[I_REF]]
+! CHECK:         %[[C100:.*]] = arith.constant 100 : i32
+! CHECK:         hlfir.assign %[[C100]] to %[[I_DECL]]#0 : i32, !fir.ref<i32>
+! CHECK:       ^bb[[F32]]:
+! CHECK:         %[[F_REF:.*]] = fir.box_addr %[[A]]#1 : (!fir.class<none>) -> !fir.ref<f32>
+! CHECK:         %[[F_DECL:.*]]:2 = hlfir.declare %[[F_REF]]
+! CHECK:         %[[C2:.*]] = arith.constant 2.000000e+00 : f32
+! CHECK:         hlfir.assign %[[C2]] to %[[F_DECL]]#0 : f32, !fir.ref<f32>
+! CHECK:       ^bb[[D]]:
+! CHECK:         hlfir.declare %[[A]]#1
+! CHECK:         fir.call @_FortranAStopStatementText(
+! CHECK:         fir.unreachable
 
 ! CFG-LABEL: func.func @_QMselect_type_lower_testPselect_type6(
-! CFG: fir.box_typecode %{{.*}} : (!fir.class<none>) -> i8
+! CFG:         %[[INT_TC:.*]] = arith.constant 9 : i8
+! CFG:         %[[A_TC:.*]] = fir.box_typecode %{{.*}}
+! CFG:         arith.cmpi eq, %[[A_TC]], %[[INT_TC]] : i8
+! CFG:         cf.cond_br
+! CFG:         %[[REAL_TC:.*]] = arith.constant 27 : i8
 
   subroutine select_type7(a)
     class(*), intent(out) :: a
@@ -210,19 +368,40 @@ subroutine select_type7(a)
     end select
   end subroutine
 
+! intent(out) class(*) triggers a Destroy + Initialize pair before the
+! select_type. Each class_is branch fir.converts the unlimited-polymorphic
+! selector to the specific class<T> and declares 'a' with that type.
 ! CHECK-LABEL: func.func @_QMselect_type_lower_testPselect_type7(
-! CHECK-SAME: %[[ARG0:.*]]: !fir.class<none>
-! CHECK: fir.select_type %{{.*}} : !fir.class<none>
-! CHECK-SAME: #fir.class_is<!fir.type<_QMselect_type_lower_testTp1
-! CHECK-SAME: #fir.class_is<!fir.type<_QMselect_type_lower_testTp2
-! CHECK-SAME: #fir.class_is<!fir.type<_QMselect_type_lower_testTp4
+! CHECK-SAME:    %[[ARG0:.*]]: !fir.class<none>
+! CHECK:         %[[A:.*]]:2 = hlfir.declare %[[ARG0]]
+! CHECK:         fir.call @_FortranADestroy(
+! CHECK:         fir.call @_FortranAInitialize(
+! CHECK:         fir.select_type %[[A]]#1 : !fir.class<none>
+! CHECK-SAME:    [#fir.class_is<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>, ^bb[[C1:[0-9]+]],
+! CHECK-SAME:     #fir.class_is<!fir.type<_QMselect_type_lower_testTp2{p1:!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>,c:i32}>>, ^bb[[C2:[0-9]+]],
+! CHECK-SAME:     #fir.class_is<!fir.type<_QMselect_type_lower_testTp4{p2:!fir.type<_QMselect_type_lower_testTp2{p1:!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>,c:i32}>,d:i32}>>, ^bb[[C4:[0-9]+]],
+! CHECK-SAME:     unit, ^bb[[D:[0-9]+]]]
+! CHECK:       ^bb[[C1]]:
+! CHECK:         fir.convert %[[A]]#1 : (!fir.class<none>) -> !fir.class<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>
+! CHECK:         hlfir.declare
+! CHECK:       ^bb[[C2]]:
+! CHECK:         fir.convert %[[A]]#1 : (!fir.class<none>) -> !fir.class<!fir.type<_QMselect_type_lower_testTp2{p1:!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>,c:i32}>>
+! CHECK:         hlfir.declare
+! CHECK:       ^bb[[C4]]:
+! CHECK:         fir.convert %[[A]]#1 : (!fir.class<none>) -> !fir.class<!fir.type<_QMselect_type_lower_testTp4{p2:!fir.type<_QMselect_type_lower_testTp2{p1:!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>,c:i32}>,d:i32}>>
+! CHECK:         hlfir.declare
+! CHECK:       ^bb[[D]]:
+! CHECK:         hlfir.declare %[[A]]#1
 
 ! Check correct ordering of class is type guard. The expected flow should be:
 !   class is (p4) -> class is (p2) -> class is (p1) -> class default
-
 ! CFG-LABEL: func.func @_QMselect_type_lower_testPselect_type7(
-! CFG: fir.type_desc !fir.type<_QMselect_type_lower_testTp4
-! CFG: fir.call @_FortranAClassIs
+! CFG:         fir.type_desc !fir.type<_QMselect_type_lower_testTp4
+! CFG:         fir.call @_FortranAClassIs(%{{.*}}, %{{.*}})
+! CFG:         fir.type_desc !fir.type<_QMselect_type_lower_testTp2
+! CFG:         fir.call @_FortranAClassIs(%{{.*}}, %{{.*}})
+! CFG:         fir.type_desc !fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>
+! CFG:         fir.call @_FortranAClassIs(%{{.*}}, %{{.*}})
 
   subroutine select_type8(a)
     class(*) :: a(:)
@@ -247,15 +426,57 @@ subroutine select_type8(a)
     end select
   end subroutine
 
+! Unlimited polymorphic *array* selector: each branch fir.converts to the
+! concrete typed box, then declares 'a' with the array shape. Whole-array
+! assignments lower to hlfir.assign on the typed box.
 ! CHECK-LABEL: func.func @_QMselect_type_lower_testPselect_type8(
-! CHECK-SAME: %[[ARG0:.*]]: !fir.class<!fir.array<?xnone>>
-! CHECK: %[[ADECL:.*]]:2 = hlfir.declare %[[ARG0]]
-! CHECK: fir.select_type %[[ADECL]]#1 : !fir.class<!fir.array<?xnone>>
-! CHECK-SAME: #fir.type_is<i32>
-! CHECK-SAME: #fir.type_is<f32>
-! CHECK-SAME: #fir.type_is<!fir.char<1,?>>
-! CHECK-SAME: #fir.type_is<!fir.type<_QMselect_type_lower_testTp1
-! CHECK-SAME: #fir.class_is<!fir.type<_QMselect_type_lower_testTp2
+! CHECK-SAME:    %[[ARG0:.*]]: !fir.class<!fir.array<?xnone>>
+! CHECK:         %[[A:.*]]:2 = hlfir.declare %[[ARG0]]
+! CHECK:         fir.select_type %[[A]]#1 : !fir.class<!fir.array<?xnone>>
+! CHECK-SAME:    [#fir.type_is<i32>, ^bb[[I32:[0-9]+]],
+! CHECK-SAME:     #fir.type_is<f32>, ^bb[[F32:[0-9]+]],
+! CHECK-SAME:     #fir.type_is<!fir.char<1,?>>, ^bb[[CH:[0-9]+]],
+! CHECK-SAME:     #fir.type_is<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>, ^bb[[T1:[0-9]+]],
+! CHECK-SAME:     #fir.class_is<!fir.type<_QMselect_type_lower_testTp2{p1:!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>,c:i32}>>, ^bb[[C2:[0-9]+]],
+! CHECK-SAME:     unit, ^bb[[D:[0-9]+]]]
+! type_is(integer) -> assign 100 to integer array.
+! CHECK:       ^bb[[I32]]:
+! CHECK:         %[[A_I32:.*]] = fir.convert %[[A]]#1 : (!fir.class<!fir.array<?xnone>>) -> !fir.box<!fir.array<?xi32>>
+! CHECK:         hlfir.declare %[[A_I32]]
+! CHECK:         %[[C100:.*]] = arith.constant 100 : i32
+! CHECK:         hlfir.assign %[[C100]] to %{{.*}}
+! type_is(real) -> assign 2.0 to f32 array.
+! CHECK:       ^bb[[F32]]:
+! CHECK:         %[[A_F32:.*]] = fir.convert %[[A]]#1 : (!fir.class<!fir.array<?xnone>>) -> !fir.box<!fir.array<?xf32>>
+! CHECK:         hlfir.declare %[[A_F32]]
+! CHECK:         hlfir.assign %{{.*}} to %{{.*}}
+! type_is(character(*)) -> two-element character stores via designated
+! single-character refs; box_elesize provides the typeparam for each
+! hlfir.designate.
+! CHECK:       ^bb[[CH]]:
+! CHECK:         %[[A_CH:.*]] = fir.convert %[[A]]#1 : (!fir.class<!fir.array<?xnone>>) -> !fir.box<!fir.array<?x!fir.char<1,?>>>
+! CHECK:         hlfir.declare %[[A_CH]]
+! CHECK:         fir.box_elesize %{{.*}} : (!fir.box<!fir.array<?x!fir.char<1,?>>>) -> index
+! CHECK:         hlfir.designate %{{.*}} (%c1{{.*}})  typeparams %{{.*}} : (!fir.box<!fir.array<?x!fir.char<1,?>>>, index, index) -> !fir.boxchar<1>
+! CHECK:         hlfir.assign %{{.*}} to %{{.*}}
+! CHECK:         fir.box_elesize %{{.*}}
+! CHECK:         hlfir.designate %{{.*}} (%c2{{.*}})  typeparams %{{.*}} : (!fir.box<!fir.array<?x!fir.char<1,?>>>, index, index) -> !fir.boxchar<1>
+! CHECK:         hlfir.assign %{{.*}} to %{{.*}}
+! type_is(p1) -> hlfir.designate of {"a"}/{"b"} returns array references.
+! CHECK:       ^bb[[T1]]:
+! CHECK:         %[[A_P1:.*]] = fir.convert %[[A]]#1 : (!fir.class<!fir.array<?xnone>>) -> !fir.box<!fir.array<?x!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>>
+! CHECK:         hlfir.declare %[[A_P1]]
+! CHECK:         hlfir.designate %{{.*}}{"a"} {{.*}}: (!fir.box<!fir.array<?x!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>>, !fir.shape<1>) -> !fir.box<!fir.array<?xi32>>
+! CHECK:         hlfir.assign %c1{{.*}} to %{{.*}}
+! CHECK:         hlfir.designate %{{.*}}{"b"}
+! CHECK:         hlfir.assign %c2{{.*}} to %{{.*}}
+! class_is(p2) -> array of class<p2>, designates {"a"}/{"b"}/{"c"}.
+! CHECK:       ^bb[[C2]]:
+! CHECK:         %[[A_P2:.*]] = fir.convert %[[A]]#1 : (!fir.class<!fir.array<?xnone>>) -> !fir.class<!fir.array<?x!fir.type<_QMselect_type_lower_testTp2{p1:!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>,c:i32}>>>
+! CHECK:         hlfir.declare %[[A_P2]]
+! CHECK:         hlfir.designate %{{.*}}{"a"}
+! CHECK:         hlfir.designate %{{.*}}{"b"}
+! CHECK:         hlfir.designate %{{.*}}{"c"}
 
   subroutine select_type9(a)
     class(p1) :: a(:)
@@ -273,12 +494,25 @@ subroutine select_type9(a)
     end select
   end subroutine
 
+! class(p1) :: a(:) selector: each typed branch fir.converts and declares.
 ! CHECK-LABEL: func.func @_QMselect_type_lower_testPselect_type9(
-! CHECK-SAME: %[[ARG0:.*]]: !fir.class<!fir.array<?x!fir.type<_QMselect_type_lower_testTp1
-! CHECK: %[[ADECL:.*]]:2 = hlfir.declare %[[ARG0]]
-! CHECK: fir.select_type %[[ADECL]]#1
-! CHECK-SAME: #fir.type_is<!fir.type<_QMselect_type_lower_testTp1
-! CHECK-SAME: #fir.type_is<!fir.type<_QMselect_type_lower_testTp2
+! CHECK-SAME:    %[[ARG0:.*]]: !fir.class<!fir.array<?x!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>>
+! CHECK:         %[[A:.*]]:2 = hlfir.declare %[[ARG0]]
+! CHECK:         fir.select_type %[[A]]#1 : !fir.class<!fir.array<?x!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>>
+! CHECK-SAME:    [#fir.type_is<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>, ^bb[[T1:[0-9]+]],
+! CHECK-SAME:     #fir.type_is<!fir.type<_QMselect_type_lower_testTp2{p1:!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>,c:i32}>>, ^bb[[T2:[0-9]+]],
+! CHECK-SAME:     unit, ^bb[[D:[0-9]+]]]
+! CHECK:       ^bb[[T1]]:
+! CHECK:         fir.convert %[[A]]#1 : (!fir.class<!fir.array<?x!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>>) -> !fir.box<!fir.array<?x!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>>
+! CHECK:         hlfir.declare
+! CHECK:         hlfir.designate %{{.*}}{"a"}
+! CHECK:         hlfir.designate %{{.*}}{"b"}
+! CHECK:       ^bb[[T2]]:
+! CHECK:         fir.convert %[[A]]#1 : (!fir.class<!fir.array<?x!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>>) -> !fir.box<!fir.array<?x!fir.type<_QMselect_type_lower_testTp2{p1:!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>,c:i32}>>>
+! CHECK:         hlfir.declare
+! CHECK:         hlfir.designate %{{.*}}{"a"}
+! CHECK:         hlfir.designate %{{.*}}{"b"}
+! CHECK:         hlfir.designate %{{.*}}{"c"}
 
   subroutine select_type10(a)
     class(p1), pointer :: a
@@ -292,11 +526,27 @@ subroutine select_type10(a)
     end select
   end subroutine
 
+! Pointer selector: load the box once and select_type on the loaded class.
 ! CHECK-LABEL: func.func @_QMselect_type_lower_testPselect_type10(
-! CHECK-SAME: %[[ARG0:.*]]: !fir.ref<!fir.class<!fir.ptr<!fir.type<_QMselect_type_lower_testTp1
-! CHECK: %[[ADECL:.*]]:2 = hlfir.declare %[[ARG0]]
-! CHECK: %[[SELECTOR:.*]] = fir.load %[[ADECL]]#0
-! CHECK: fir.select_type %[[SELECTOR]]
+! CHECK-SAME:    %[[ARG0:.*]]: !fir.ref<!fir.class<!fir.ptr<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>>>
+! CHECK:         %[[A:.*]]:2 = hlfir.declare %[[ARG0]]
+! CHECK:         %[[SEL:.*]] = fir.load %[[A]]#0
+! CHECK:         fir.select_type %[[SEL]] : !fir.class<!fir.ptr<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>>
+! CHECK-SAME:    [#fir.type_is<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>, ^bb[[T1:[0-9]+]],
+! CHECK-SAME:     #fir.type_is<!fir.type<_QMselect_type_lower_testTp2{p1:!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>,c:i32}>>, ^bb[[T2:[0-9]+]],
+! CHECK-SAME:     #fir.class_is<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>, ^bb[[C1:[0-9]+]],
+! CHECK-SAME:     unit, ^bb[[D:[0-9]+]]]
+! CHECK:       ^bb[[T1]]:
+! CHECK:         fir.box_addr %[[SEL]] : (!fir.class<!fir.ptr<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>>) -> !fir.ref<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>
+! CHECK:         hlfir.designate %{{.*}}{"a"}
+! CHECK:         hlfir.assign %c1{{.*}} to %{{.*}}
+! CHECK:       ^bb[[T2]]:
+! CHECK:         fir.box_addr %[[SEL]] : (!fir.class<!fir.ptr<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>>) -> !fir.ref<!fir.type<_QMselect_type_lower_testTp2{p1:!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>,c:i32}>>
+! CHECK:         hlfir.designate %{{.*}}{"c"}
+! CHECK:         hlfir.assign %c3{{.*}} to %{{.*}}
+! CHECK:       ^bb[[C1]]:
+! CHECK:         hlfir.designate %{{.*}}{"a"}
+! CHECK:         hlfir.assign %c5{{.*}} to %{{.*}}
 
   subroutine select_type11(a)
     class(p1), allocatable :: a
@@ -309,11 +559,25 @@ subroutine select_type11(a)
     end select
   end subroutine
 
+! Allocatable selector: same load-then-select pattern, with !fir.heap inside
+! the selector class.
 ! CHECK-LABEL: func.func @_QMselect_type_lower_testPselect_type11(
-! CHECK-SAME: %[[ARG0:.*]]: !fir.ref<!fir.class<!fir.heap<!fir.type<_QMselect_type_lower_testTp1
-! CHECK: %[[ADECL:.*]]:2 = hlfir.declare %[[ARG0]]
-! CHECK: %[[SELECTOR:.*]] = fir.load %[[ADECL]]#0
-! CHECK: fir.select_type %[[SELECTOR]]
+! CHECK-SAME:    %[[ARG0:.*]]: !fir.ref<!fir.class<!fir.heap<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>>>
+! CHECK:         %[[A:.*]]:2 = hlfir.declare %[[ARG0]]
+! CHECK:         %[[SEL:.*]] = fir.load %[[A]]#0
+! CHECK:         fir.select_type %[[SEL]] : !fir.class<!fir.heap<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>>
+! CHECK-SAME:    [#fir.type_is<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>, ^bb[[T1:[0-9]+]],
+! CHECK-SAME:     #fir.type_is<!fir.type<_QMselect_type_lower_testTp2{p1:!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>,c:i32}>>, ^bb[[T2:[0-9]+]],
+! CHECK-SAME:     unit, ^bb[[D:[0-9]+]]]
+! CHECK:       ^bb[[T1]]:
+! CHECK:         fir.box_addr %[[SEL]]
+! CHECK:         hlfir.designate %{{.*}}{"a"}
+! CHECK:       ^bb[[T2]]:
+! CHECK:         fir.box_addr %[[SEL]]
+! Access to a%a goes through a%p1%a (parent component then field).
+! CHECK:         %[[P1:.*]] = hlfir.designate %{{.*}}{"p1"}
+! CHECK:         hlfir.designate %[[P1]]{"a"}
+! CHECK:         hlfir.designate %{{.*}}{"c"}
 
   subroutine select_type12(a)
     class(p1), pointer :: a(:)
@@ -327,11 +591,38 @@ subroutine select_type12(a)
     end select
   end subroutine
 
+! Array pointer selector: load the descriptor for the select_type, then
+! take the lower bound from box_dims for use as the per-branch fir.shift.
 ! CHECK-LABEL: func.func @_QMselect_type_lower_testPselect_type12(
-! CHECK-SAME: %[[ARG0:.*]]: !fir.ref<!fir.class<!fir.ptr<!fir.array<?x!fir.type<_QMselect_type_lower_testTp1
-! CHECK: %[[ADECL:.*]]:2 = hlfir.declare %[[ARG0]]
-! CHECK: %[[LOAD:.*]] = fir.load %[[ADECL]]#0
-! CHECK: fir.select_type %{{.*}}
+! CHECK-SAME:    %[[ARG0:.*]]: !fir.ref<!fir.class<!fir.ptr<!fir.array<?x!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>>>>
+! CHECK:         %[[A:.*]]:2 = hlfir.declare %[[ARG0]]
+! CHECK:         %[[A_LD:.*]] = fir.load %[[A]]#0
+! CHECK:         %[[A_LD2:.*]] = fir.load %[[A]]#0
+! CHECK:         %[[DIMS:.*]]:3 = fir.box_dims %[[A_LD2]], %c0{{.*}}
+! CHECK:         fir.select_type %[[A_LD]] : !fir.class<!fir.ptr<!fir.array<?x!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>>>
+! CHECK-SAME:    [#fir.type_is<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>, ^bb[[T1:[0-9]+]],
+! CHECK-SAME:     #fir.type_is<!fir.type<_QMselect_type_lower_testTp2{p1:!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>,c:i32}>>, ^bb[[T2:[0-9]+]],
+! CHECK-SAME:     #fir.class_is<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>, ^bb[[C1:[0-9]+]],
+! CHECK-SAME:     unit, ^bb[[D:[0-9]+]]]
+! type_is(p1) -> convert from class<ptr<p1>> to box<ptr<p1>>, shift to set
+! the lower bound, declare 'a' as a non-pointer box.
+! CHECK:       ^bb[[T1]]:
+! CHECK:         fir.convert %[[A_LD]] : (!fir.class<!fir.ptr<!fir.array<?x!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>>>) -> !fir.box<!fir.ptr<!fir.array<?x!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>>>
+! CHECK:         fir.shift %[[DIMS]]#0 : (index) -> !fir.shift<1>
+! CHECK:         hlfir.declare
+! CHECK:         hlfir.designate %{{.*}}{"a"}{{.*}}-> !fir.box<!fir.array<?xi32>>
+! type_is(p2) -> convert to box<ptr<p2>>, shift, declare, designate {"c"}.
+! CHECK:       ^bb[[T2]]:
+! CHECK:         fir.convert %[[A_LD]] : (!fir.class<!fir.ptr<!fir.array<?x!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>>>) -> !fir.box<!fir.ptr<!fir.array<?x!fir.type<_QMselect_type_lower_testTp2{p1:!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>,c:i32}>>>>
+! CHECK:         fir.shift %[[DIMS]]#0
+! CHECK:         hlfir.declare
+! CHECK:         hlfir.designate %{{.*}}{"c"}
+! class_is(p1) -> no convert, shift, declare with the class<ptr<p1>>
+! selector and designate {"a"}.
+! CHECK:       ^bb[[C1]]:
+! CHECK:         fir.shift %[[DIMS]]#0
+! CHECK:         hlfir.declare %[[A_LD]](%{{.*}})
+! CHECK:         hlfir.designate %{{.*}}{"a"}
 
   ! Test correct lowering when CLASS DEFAULT is not at the last position in the
   ! SELECT TYPE construct.
@@ -355,9 +646,24 @@ subroutine select_type13(a)
 
   end subroutine
 
+! Both select_types: even when CLASS DEFAULT is written in the middle of
+! the construct, fir.select_type still emits the default as the trailing
+! `unit` arm. Each select_type ends with a single common exit block.
 ! CHECK-LABEL: func.func @_QMselect_type_lower_testPselect_type13
-! CHECK: fir.select_type %{{[0-9a-zA-Z_]+}}{{.*}}#fir.class_is<!fir.type<_QMselect_type_lower_testTp1
-! CHECK: fir.select_type %{{[0-9a-zA-Z_]+}}{{.*}}#fir.type_is<!fir.type<_QMselect_type_lower_testTp1{{[^>]*}}>>{{.*}}#fir.class_is<!fir.type<_QMselect_type_lower_testTp1
+! First select: class is (p1), unit (default).
+! CHECK:         fir.select_type %{{.*}} : !fir.class<!fir.ptr<!fir.array<?x!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>>>
+! CHECK-SAME:    [#fir.class_is<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>, ^bb[[C1A:[0-9]+]],
+! CHECK-SAME:     unit, ^bb[[DA:[0-9]+]]]
+! CHECK:       ^bb[[DA]]:
+! CHECK:         cf.br ^bb[[X1:[0-9]+]]
+! CHECK:       ^bb[[C1A]]:
+! CHECK:         cf.br ^bb[[X1]]
+! CHECK:       ^bb[[X1]]:
+! Second select: type_is(p1), class_is(p1), unit (default).
+! CHECK:         fir.select_type %{{.*}} : !fir.class<!fir.ptr<!fir.array<?x!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>>>
+! CHECK-SAME:    [#fir.type_is<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>, ^bb[[T1B:[0-9]+]],
+! CHECK-SAME:     #fir.class_is<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>, ^bb[[C1B:[0-9]+]],
+! CHECK-SAME:     unit, ^bb[[DB:[0-9]+]]]
 
   subroutine select_type14(a, b)
     class(p1) :: a, b
@@ -373,8 +679,15 @@ subroutine select_type14(a, b)
     end select
   end subroutine
 
-  ! Just makes sure the example can be lowered.
-  ! CHECK-LABEL: func.func @_QMselect_type_lower_testPselect_type14
+! Nested select_type. Outer has type_is(p2) and unit. Inner inside the
+! type_is(p2) block has a nested type_is(p2)/unit pair.
+! CHECK-LABEL: func.func @_QMselect_type_lower_testPselect_type14
+! CHECK:         fir.select_type %{{.*}} : !fir.class<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>
+! CHECK-SAME:    [#fir.type_is<!fir.type<_QMselect_type_lower_testTp2
+! CHECK-SAME:     unit
+! CHECK:         fir.select_type %{{.*}} : !fir.class<!fir.type<_QMselect_type_lower_testTp1{a:i32,b:i32}>>
+! CHECK-SAME:    [#fir.type_is<!fir.type<_QMselect_type_lower_testTp2
+! CHECK-SAME:     unit
 
   subroutine select_type15(a)
     class(p5) :: a
@@ -385,14 +698,23 @@ subroutine select_type15(a)
     end select
   end subroutine
 
+! Selector is the result of an overloaded unary minus implemented as the
+! type-bound function negate. The result is a class<heap<p5>> allocated
+! by the dispatched function and stored into a fir.alloca .result tmp.
 ! CHECK-LABEL: func.func @_QMselect_type_lower_testPselect_type15(
-! CHECK-SAME: %[[ARG0:.*]]: !fir.class<!fir.type<_QMselect_type_lower_testTp5{a:i32}>>
-! CHECK: %[[RES:.*]] = fir.alloca !fir.class<!fir.heap<!fir.type<_QMselect_type_lower_testTp5{a:i32}>>>
-! CHECK: %[[ADECL:.*]]:2 = hlfir.declare %[[ARG0]]
-! CHECK: %[[TMP_RES:.*]] = fir.dispatch "negate"(%[[ADECL]]#0
-! CHECK: fir.save_result %[[TMP_RES]] to %{{.*}}
-! CHECK: %[[LOAD_RES:.*]] = fir.load %{{.*}}
-! CHECK: fir.select_type %{{.*}}
+! CHECK-SAME:    %[[ARG0:.*]]: !fir.class<!fir.type<_QMselect_type_lower_testTp5{a:i32}>>
+! CHECK:         %[[RES:.*]] = fir.alloca !fir.class<!fir.heap<!fir.type<_QMselect_type_lower_testTp5{a:i32}>>> {bindc_name = ".result"}
+! CHECK:         %[[A:.*]]:2 = hlfir.declare %[[ARG0]]
+! CHECK:         %[[CALL:.*]] = fir.dispatch "negate"(%[[A]]#0 : !fir.class<!fir.type<_QMselect_type_lower_testTp5{a:i32}>>) (%[[A]]#0 : !fir.class<!fir.type<_QMselect_type_lower_testTp5{a:i32}>>) -> !fir.class<!fir.heap<!fir.type<_QMselect_type_lower_testTp5{a:i32}>>> {pass_arg_pos = 0 : i32}
+! CHECK:         fir.save_result %[[CALL]] to %[[RES]]
+! CHECK:         %[[LOAD:.*]] = fir.load %{{.*}}
+! CHECK:         fir.select_type %{{.*}} : !fir.class<!fir.type<_QMselect_type_lower_testTp5{a:i32}>>
+! CHECK-SAME:    [#fir.type_is<!fir.type<_QMselect_type_lower_testTp5{a:i32}>>, ^bb[[T:[0-9]+]],
+! CHECK-SAME:     unit, ^bb[[D:[0-9]+]]]
+! CHECK:       ^bb[[T]]:
+! CHECK:         fir.box_addr %{{.*}} : (!fir.class<{{.*}}>) -> !fir.ref<!fir.type<_QMselect_type_lower_testTp5{a:i32}>>
+! CHECK:         hlfir.declare %{{.*}}{{.*}}"_QMselect_type_lower_testFselect_type15Ex"
+! CHECK:         hlfir.designate %{{.*}}{"a"}
 
 end module
 



More information about the flang-commits mailing list