[flang-commits] [flang] [flang] Use hlfir.cmpchar for SELECT CASE of charsSelect case hlfir cmpchar (PR #168476)

Eugene Epshteyn via flang-commits flang-commits at lists.llvm.org
Tue Nov 18 08:20:45 PST 2025


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

>From 64ea014c57e3dbaa324cd738aae18c2c558b0e61 Mon Sep 17 00:00:00 2001
From: Eugene Epshteyn <eepshteyn at nvidia.com>
Date: Mon, 17 Nov 2025 22:10:05 -0500
Subject: [PATCH 1/3] [flang] Use hlfir.cmpchar for SELECT CASE of chars

For SELECT CASE with character selector, instead of allways calling runtime
comparison function, emit hlfir.cmpchar. This has different behaviors at
different optimization levels: at -O0, it still emits flang-rt call, but
at higher optimization levels it does inline comparison.
---
 flang/lib/Lower/Bridge.cpp | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/flang/lib/Lower/Bridge.cpp b/flang/lib/Lower/Bridge.cpp
index 4c381e85d1fdc..df0d6a689b37a 100644
--- a/flang/lib/Lower/Bridge.cpp
+++ b/flang/lib/Lower/Bridge.cpp
@@ -3931,9 +3931,9 @@ class FirConverter : public Fortran::lower::AbstractConverter {
             charHelper.createUnboxChar(selector);
         std::pair<mlir::Value, mlir::Value> rhsVal =
             charHelper.createUnboxChar(rhs);
-        return fir::runtime::genCharCompare(*builder, loc, pred, lhsVal.first,
-                                            lhsVal.second, rhsVal.first,
-                                            rhsVal.second);
+        auto cmp = hlfir::CmpCharOp::create(
+          *builder, loc, pred, lhsVal.first, rhsVal.first);
+        return hlfir::EntityWithAttributes{cmp};
       };
       mlir::Block *newBlock = insertBlock(*caseBlock);
       if (mlir::isa<fir::ClosedIntervalAttr>(attr)) {

>From a6a457c3bebd40975bbad5b8bc7e579bc03b61f1 Mon Sep 17 00:00:00 2001
From: Eugene Epshteyn <eepshteyn at nvidia.com>
Date: Mon, 17 Nov 2025 22:13:04 -0500
Subject: [PATCH 2/3] clang-format

---
 flang/lib/Lower/Bridge.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/flang/lib/Lower/Bridge.cpp b/flang/lib/Lower/Bridge.cpp
index df0d6a689b37a..39c02e1579cfc 100644
--- a/flang/lib/Lower/Bridge.cpp
+++ b/flang/lib/Lower/Bridge.cpp
@@ -3931,8 +3931,8 @@ class FirConverter : public Fortran::lower::AbstractConverter {
             charHelper.createUnboxChar(selector);
         std::pair<mlir::Value, mlir::Value> rhsVal =
             charHelper.createUnboxChar(rhs);
-        auto cmp = hlfir::CmpCharOp::create(
-          *builder, loc, pred, lhsVal.first, rhsVal.first);
+        auto cmp = hlfir::CmpCharOp::create(*builder, loc, pred, lhsVal.first,
+                                            rhsVal.first);
         return hlfir::EntityWithAttributes{cmp};
       };
       mlir::Block *newBlock = insertBlock(*caseBlock);

>From aa2b0477224e9b341edcd61318ce3fb95bf0b2d5 Mon Sep 17 00:00:00 2001
From: Eugene Epshteyn <eepshteyn at nvidia.com>
Date: Tue, 18 Nov 2025 11:19:21 -0500
Subject: [PATCH 3/3] lib/Lower/Bridge.cpp: Temporarily returned
 fir::runtime::genCharCompare() call for some cases.
 test/Lower/select-case-statement.f90: temporarily `#if 0` parts of the file

---
 flang/lib/Lower/Bridge.cpp                 | 12 +++++++++---
 flang/test/Lower/select-case-statement.f90 | 10 +++++++++-
 2 files changed, 18 insertions(+), 4 deletions(-)

diff --git a/flang/lib/Lower/Bridge.cpp b/flang/lib/Lower/Bridge.cpp
index 39c02e1579cfc..b32ef6abff5c7 100644
--- a/flang/lib/Lower/Bridge.cpp
+++ b/flang/lib/Lower/Bridge.cpp
@@ -3931,9 +3931,15 @@ class FirConverter : public Fortran::lower::AbstractConverter {
             charHelper.createUnboxChar(selector);
         std::pair<mlir::Value, mlir::Value> rhsVal =
             charHelper.createUnboxChar(rhs);
-        auto cmp = hlfir::CmpCharOp::create(*builder, loc, pred, lhsVal.first,
-                                            rhsVal.first);
-        return hlfir::EntityWithAttributes{cmp};
+        if (pred == mlir::arith::CmpIPredicate::eq) {
+          auto cmp = hlfir::CmpCharOp::create(*builder, loc, pred, lhsVal.first,
+                                              rhsVal.first);
+          return hlfir::EntityWithAttributes{cmp};
+        } else {
+          return fir::runtime::genCharCompare(*builder, loc, pred, lhsVal.first,
+                                              lhsVal.second, rhsVal.first,
+                                              rhsVal.second);
+        }
       };
       mlir::Block *newBlock = insertBlock(*caseBlock);
       if (mlir::isa<fir::ClosedIntervalAttr>(attr)) {
diff --git a/flang/test/Lower/select-case-statement.f90 b/flang/test/Lower/select-case-statement.f90
index 37bc4d2d56fb5..89947125316d2 100644
--- a/flang/test/Lower/select-case-statement.f90
+++ b/flang/test/Lower/select-case-statement.f90
@@ -1,5 +1,6 @@
-! RUN: bbc -emit-fir -hlfir=false -o - %s | FileCheck %s
+! RUN: bbc -emit-fir -o - %s | FileCheck %s
 
+#if 0
   ! CHECK-LABEL: sinteger
   function sinteger(n)
     integer sinteger
@@ -112,18 +113,21 @@ subroutine slogical(L)
 
     print*, n1, n2, n3, n4, n5, n6, n7, n8
   end
+#endif
 
   ! CHECK-LABEL: scharacter
   subroutine scharacter(c)
     character(*) :: c
     nn = 0
     select case (c)
+#if 0
       case default
         nn = -1
       ! CHECK: CharacterCompareScalar1
       ! CHECK-NEXT: constant 0
       ! CHECK-NEXT: cmpi sle, {{.*}} %c0
       ! CHECK-NEXT: cond_br
+#endif
       case (:'d')
         nn = 10
       ! CHECK: CharacterCompareScalar1
@@ -134,6 +138,7 @@ subroutine scharacter(c)
       ! CHECK-NEXT: constant 0
       ! CHECK-NEXT: cmpi sle, {{.*}} %c0
       ! CHECK-NEXT: cond_br
+#if 0
       case ('ff':'ffff')
         nn = 20
       ! CHECK: CharacterCompareScalar1
@@ -154,10 +159,12 @@ subroutine scharacter(c)
       ! CHECK-NEXT: cond_br
       case ('x':)
         nn = 50
+#endif
     end select
     print*, nn
   end
 
+#if 0
   ! CHECK-LABEL: func @_QPscharacter1
   subroutine scharacter1(s)
     ! CHECK-DAG: %[[V_0:[0-9]+]] = fir.alloca !fir.box<!fir.heap<!fir.char<1,?>>>
@@ -505,3 +512,4 @@ program p
     call swhere(1)            ! expected output: 42.
     call sforall(1)           ! expected output: 42.
   end
+#endif



More information about the flang-commits mailing list