If capturing groups are used, the regex matcher handles something like (.*)suffix by first doing a maximal match of .*, trying to match suffix afterward, and then reducing the maximal stop position one by one until this finally succeeds. This makes the match quadratic in the length of the line (with large constant factors).
This is particularly problematic because regexes of this form are ubiquitous in FileCheck (something like [[VAR:%.*]] = ... falls in this category), making FileCheck executions much slower than they have any right to be.
This implements a very crude optimization that checks if suffix starts with a fixed character, and steps back to the last occurrence of that character, instead of stepping back by one character at the time. This drops FileCheck time on clang/test/CodeGen/RISCV/rvv-intrinsics/vloxseg_mask.c from 7.3 seconds to 2.7 seconds.
An obvious further improvement would be to check more than one character (once again, this is particularly relevant for FileCheck, because the next character is usually a space, which happens to have many occurrences).
This should help with https://github.com/llvm/llvm-project/issues/54821.