[flang-commits] [flang] [flang] Enumeration Type: (PR 4/5) Lowering (PR #193571)

via flang-commits flang-commits at lists.llvm.org
Thu Oct 1 19:49:57 PDT 2026


================
@@ -0,0 +1,542 @@
+! Test lowering of enumeration types to HLFIR/FIR.
+! Enumeration types lower to i32 values representing 1-based ordinal positions.
+! RUN: %flang_fc1 -fenumeration-type -emit-hlfir %s -o - | FileCheck %s
+
+module enum_mod
+  enumeration type :: color
+    enumerator :: red, green, blue
+  end enumeration type
+end module
+
+! -----------------------------------------------------------------------------
+!            Test enumeration type maps to i32 (not fir.type)
+! -----------------------------------------------------------------------------
+
+! CHECK-LABEL: func.func @_QPtest_enum_variable()
+subroutine test_enum_variable()
+  use enum_mod
+  type(color) :: c
+  ! CHECK: %[[ALLOC:.*]] = fir.alloca i32
+  ! CHECK: hlfir.declare %[[ALLOC]]
+  c = red
+end subroutine
+
+! -----------------------------------------------------------------------------
+!            Test enumerator constants lower to i32 constants
+! -----------------------------------------------------------------------------
+
+! CHECK-LABEL: func.func @_QPtest_enumerator_constants()
+subroutine test_enumerator_constants()
+  use enum_mod
+  type(color) :: c
+  ! CHECK: %[[RED:.*]] = arith.constant 1 : i32
+  ! CHECK: hlfir.assign %[[RED]]
+  c = red
+  ! CHECK: %[[GREEN:.*]] = arith.constant 2 : i32
+  ! CHECK: hlfir.assign %[[GREEN]]
+  c = green
+  ! CHECK: %[[BLUE:.*]] = arith.constant 3 : i32
+  ! CHECK: hlfir.assign %[[BLUE]]
+  c = blue
+end subroutine
+
+! -----------------------------------------------------------------------------
+!            Test enumeration constructor — color(n) → i32 constant
+! -----------------------------------------------------------------------------
+
+! CHECK-LABEL: func.func @_QPtest_constructor()
+subroutine test_constructor()
+  use enum_mod
+  type(color) :: c
+  ! CHECK: %[[C2:.*]] = arith.constant 2 : i32
+  ! CHECK: hlfir.assign %[[C2]]
+  ! Constant argument is range-checked at compile time (semantics), so no
+  ! runtime range check is emitted here.
+  ! CHECK-NOT: fir.call @{{.*}}ReportFatalUserError
+  c = color(2)
+end subroutine
+
+! -----------------------------------------------------------------------------
+!            Test enumeration constructor — color(i) runtime range check
+! -----------------------------------------------------------------------------
+
+! A non-constant argument cannot be range-checked at compile time, so lowering
+! emits an always-on runtime check (1 <= i <= enumeratorCount) with fatal
+! error termination (F2023 7.6.2 para 5).
+
+! CHECK-LABEL: func.func @_QPtest_constructor_runtime(
+! CHECK-SAME: %[[ARG:.*]]: !fir.ref<i32>
+subroutine test_constructor_runtime(i)
+  use enum_mod
+  integer, intent(in) :: i
+  type(color) :: c
+  ! CHECK: %[[ORD:.*]] = fir.load %{{.*}} : !fir.ref<i32>
+  ! CHECK-DAG: %[[ONE:.*]] = arith.constant 1 : i32
+  ! CHECK-DAG: %[[MAX:.*]] = arith.constant 3 : i32
+  ! CHECK: %[[LOW:.*]] = arith.cmpi slt, %[[ORD]], %[[ONE]] : i32
+  ! CHECK: %[[HIGH:.*]] = arith.cmpi sgt, %[[ORD]], %[[MAX]] : i32
+  ! CHECK: %[[OOR:.*]] = arith.ori %[[LOW]], %[[HIGH]] : i1
+  ! CHECK: fir.if %[[OOR]] {
+  ! CHECK:   fir.call @{{.*}}ReportFatalUserError
+  ! CHECK: }
+  ! CHECK: hlfir.assign %[[ORD]]
+  c = color(i)
+end subroutine
+
+! -----------------------------------------------------------------------------
+!            Test enumeration comparisons (relational operators)
+! -----------------------------------------------------------------------------
+
+! CHECK-LABEL: func.func @_QPtest_comparisons(
+! CHECK-SAME: %[[ARG0:.*]]: !fir.ref<i32>{{.*}}, %[[ARG1:.*]]: !fir.ref<i32>{{.*}})
+subroutine test_comparisons(c1, c2)
+  use enum_mod
+  type(color), intent(in) :: c1, c2
+  logical :: l
+  ! CHECK: %[[V1:.*]] = fir.load %{{.*}} : !fir.ref<i32>
+  ! CHECK: %[[V2:.*]] = fir.load %{{.*}} : !fir.ref<i32>
+  ! CHECK: arith.cmpi eq, %[[V1]], %[[V2]] : i32
+  l = (c1 == c2)
+  ! CHECK: arith.cmpi slt
+  l = (c1 < c2)
+  ! CHECK: arith.cmpi sle
+  l = (c1 <= c2)
+  ! CHECK: arith.cmpi sgt
+  l = (c1 > c2)
+  ! CHECK: arith.cmpi sge
+  l = (c1 >= c2)
+  ! CHECK: arith.cmpi ne
+  l = (c1 /= c2)
+end subroutine
+
+! -----------------------------------------------------------------------------
+!            Test INT() conversion of enumeration values
+! -----------------------------------------------------------------------------
+
+! CHECK-LABEL: func.func @_QPtest_int_conversion()
+subroutine test_int_conversion()
+  use enum_mod
+  integer :: i
+  ! CHECK: %[[C1:.*]] = arith.constant 1 : i32
+  i = int(red)
----------------
MattPD wrote:

Variable INT and KIND=8 now have direct lowering coverage and return the expected ordinals.

https://github.com/llvm/llvm-project/pull/193571


More information about the flang-commits mailing list