[llvm] [flang-rt] Simplify INDEX with len-1 SUBSTRING. (PR #137889)

Slava Zakharin via llvm-commits llvm-commits at lists.llvm.org
Tue Apr 29 15:59:57 PDT 2025


https://github.com/vzakhari created https://github.com/llvm/llvm-project/pull/137889

The len-1 case is noticeably slower than gfortran's straightforward
implementation https://github.com/gcc-mirror/gcc/blob/075611b646e5554ae02b2622061ea1614bf16ead/libgfortran/intrinsics/string_intrinsics_inc.c#L253
This change speeds up a simple microkernel by 37% on icelake.


>From 31e7881c6c274c7f2e858cb82e33adb686465046 Mon Sep 17 00:00:00 2001
From: Slava Zakharin <szakharin at nvidia.com>
Date: Tue, 29 Apr 2025 15:31:06 -0700
Subject: [PATCH] [flang-rt] Simplify INDEX with len-1 SUBSTRING.

The len-1 case is noticeably slower than gfortran's straightforward
implementation https://github.com/gcc-mirror/gcc/blob/075611b646e5554ae02b2622061ea1614bf16ead/libgfortran/intrinsics/string_intrinsics_inc.c#L253
This change speeds up a simple microkernel by 37% on icelake.
---
 flang-rt/lib/runtime/character.cpp           | 11 +++++++++++
 flang-rt/unittests/Runtime/CharacterTest.cpp |  1 +
 2 files changed, 12 insertions(+)

diff --git a/flang-rt/lib/runtime/character.cpp b/flang-rt/lib/runtime/character.cpp
index c890fd0e4ddcd..89be9fc2fbf6a 100644
--- a/flang-rt/lib/runtime/character.cpp
+++ b/flang-rt/lib/runtime/character.cpp
@@ -293,6 +293,17 @@ inline RT_API_ATTRS std::size_t Index(const CHAR *x, std::size_t xLen,
     }
     return 0;
   }
+  if (wantLen == 1) {
+    // Trivial case for single character lookup.
+    // We can use simple forward search.
+    CHAR ch = want[0];
+    for (std::size_t at = 0; at < xLen; ++at) {
+      if (x[at] == ch) {
+        return at + 1;
+      }
+    }
+    return 0;
+  }
   // Non-trivial forward substring search: use a simplified form of
   // Boyer-Moore substring searching.
   for (std::size_t at{1}; at + wantLen - 1 <= xLen;) {
diff --git a/flang-rt/unittests/Runtime/CharacterTest.cpp b/flang-rt/unittests/Runtime/CharacterTest.cpp
index c158e0cb31f18..0f28e883671bc 100644
--- a/flang-rt/unittests/Runtime/CharacterTest.cpp
+++ b/flang-rt/unittests/Runtime/CharacterTest.cpp
@@ -354,6 +354,7 @@ TYPED_TEST(SearchTests, IndexTests) {
       {"", "a", true, 0},
       {"aa", "a", false, 1},
       {"aa", "a", true, 2},
+      {"aAA", "A", false, 2},
       {"Fortran that I ran", "that I ran", false, 9},
       {"Fortran that I ran", "that I ran", true, 9},
       {"Fortran that you ran", "that I ran", false, 0},



More information about the llvm-commits mailing list