diff --git a/flang-rt/lib/runtime/character.cpp b/flang-rt/lib/runtime/character.cpp index c890fd0e4ddcd..d1152ee1caefb 100644 --- a/flang-rt/lib/runtime/character.cpp +++ b/flang-rt/lib/runtime/character.cpp @@ -14,6 +14,7 @@ #include "flang/Common/uint128.h" #include "flang/Runtime/character.h" #include "flang/Runtime/cpp-type.h" +#include "flang/Runtime/freestanding-tools.h" #include #include @@ -293,6 +294,24 @@ 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]}; + if constexpr (std::is_same_v) { + if (auto pos{reinterpret_cast( + Fortran::runtime::memchr(x, ch, xLen))}) { + return pos - x + 1; + } + } else { + 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},