Skip to content

[Transform] Clean up strlen loop idiom #132421

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Mar 21, 2025
Merged

Conversation

mustartt
Copy link
Member

@mustartt mustartt commented Mar 21, 2025

We should bailout of modifying the CFG if the library functions are not emittable or disabled.

Address buildbot failure in https://lab.llvm.org/buildbot/#/builders/187/builds/4958 with expensive check enabled.

@llvmbot
Copy link
Member

llvmbot commented Mar 21, 2025

@llvm/pr-subscribers-llvm-transforms

Author: Henry Jiang (mustartt)

Changes

Address buildbot failure in https://lab.llvm.org/buildbot/#/builders/187/builds/4958 with expensive check enabled.

We should bailout of modifying the CFG if the library functions are not emittable or disabled.


Full diff: https://github.com/llvm/llvm-project/pull/132421.diff

5 Files Affected:

  • (modified) llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp (+15-24)
  • (modified) llvm/test/Transforms/LoopIdiom/strlen-not-emittable.ll (+1-1)
  • (modified) llvm/test/Transforms/LoopIdiom/strlen.ll (+1-1)
  • (modified) llvm/test/Transforms/LoopIdiom/wcslen16.ll (+1-1)
  • (modified) llvm/test/Transforms/LoopIdiom/wcslen32.ll (+1-1)
diff --git a/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp b/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp
index b91cdc0748581..7f92f5f65a972 100644
--- a/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp
+++ b/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp
@@ -1515,16 +1515,6 @@ bool LoopIdiomRecognize::runOnNoncountableLoop() {
          recognizeShiftUntilLessThan() || recognizeAndInsertStrLen();
 }
 
-/// Check if a Value is either a nullptr or a constant int zero
-static bool isZeroConstant(const Value *Val) {
-  if (isa<ConstantPointerNull>(Val))
-    return true;
-  const ConstantInt *CmpZero = dyn_cast<ConstantInt>(Val);
-  if (!CmpZero || !CmpZero->isZero())
-    return false;
-  return true;
-}
-
 /// Check if the given conditional branch is based on the comparison between
 /// a variable and zero, and if the variable is non-zero or zero (JmpOnZero is
 /// true), the control yields to the loop entry. If the branch matches the
@@ -1540,7 +1530,8 @@ static Value *matchCondition(BranchInst *BI, BasicBlock *LoopEntry,
   if (!Cond)
     return nullptr;
 
-  if (!isZeroConstant(Cond->getOperand(1)))
+  const ConstantInt *CmpZero = dyn_cast<ConstantInt>(Cond->getOperand(1));
+  if (!CmpZero || !CmpZero->isZero())
     return nullptr;
 
   BasicBlock *TrueSucc = BI->getSuccessor(0);
@@ -1656,11 +1647,7 @@ class StrlenVerifier {
       if (!Ev)
         return false;
 
-      LLVM_DEBUG({
-        dbgs() << "loop exit phi scev: ";
-        Ev->print(dbgs());
-        dbgs() << "\n";
-      });
+      LLVM_DEBUG(dbgs() << "loop exit phi scev: " << *Ev << "\n");
 
       // Since we verified that the loop trip count will be a valid strlen
       // idiom, we can expand all lcssa phi with {n,+,1} as (n + strlen) and use
@@ -1763,6 +1750,18 @@ bool LoopIdiomRecognize::recognizeAndInsertStrLen() {
   BasicBlock *Preheader = CurLoop->getLoopPreheader();
   BasicBlock *LoopExitBB = CurLoop->getExitBlock();
 
+  if (Verifier.OpWidth == 8) {
+    if (DisableLIRP::Strlen)
+      return false;
+    if (!isLibFuncEmittable(Preheader->getModule(), TLI, LibFunc_strlen))
+      return false;
+  } else {
+    if (DisableLIRP::Wcslen)
+      return false;
+    if (!isLibFuncEmittable(Preheader->getModule(), TLI, LibFunc_wcslen))
+      return false;
+  }
+
   IRBuilder<> Builder(Preheader->getTerminator());
   SCEVExpander Expander(*SE, Preheader->getModule()->getDataLayout(),
                         "strlen_idiom");
@@ -1772,16 +1771,8 @@ bool LoopIdiomRecognize::recognizeAndInsertStrLen() {
 
   Value *StrLenFunc = nullptr;
   if (Verifier.OpWidth == 8) {
-    if (DisableLIRP::Strlen)
-      return false;
-    if (!isLibFuncEmittable(Preheader->getModule(), TLI, LibFunc_strlen))
-      return false;
     StrLenFunc = emitStrLen(MaterialzedBase, Builder, *DL, TLI);
   } else {
-    if (DisableLIRP::Wcslen)
-      return false;
-    if (!isLibFuncEmittable(Preheader->getModule(), TLI, LibFunc_wcslen))
-      return false;
     StrLenFunc = emitWcsLen(MaterialzedBase, Builder, *DL, TLI);
   }
   assert(StrLenFunc && "Failed to emit strlen function.");
diff --git a/llvm/test/Transforms/LoopIdiom/strlen-not-emittable.ll b/llvm/test/Transforms/LoopIdiom/strlen-not-emittable.ll
index 0be76cbd42a72..00fbe89846a30 100644
--- a/llvm/test/Transforms/LoopIdiom/strlen-not-emittable.ll
+++ b/llvm/test/Transforms/LoopIdiom/strlen-not-emittable.ll
@@ -1,4 +1,4 @@
-; RUN: opt -passes='loop(loop-idiom),verify' < %s -S | FileCheck %s
+; RUN: opt -passes='loop(loop-idiom)' < %s -S | FileCheck %s
 
 target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
 target triple = "x86_64-unknown-linux-gnu"
diff --git a/llvm/test/Transforms/LoopIdiom/strlen.ll b/llvm/test/Transforms/LoopIdiom/strlen.ll
index 137a17f541cd4..c1141177c659f 100644
--- a/llvm/test/Transforms/LoopIdiom/strlen.ll
+++ b/llvm/test/Transforms/LoopIdiom/strlen.ll
@@ -1,5 +1,5 @@
 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
-; RUN: opt -passes='loop(loop-idiom),verify' < %s -S | FileCheck %s
+; RUN: opt -passes='loop(loop-idiom)' < %s -S | FileCheck %s
 
 declare void @other()
 declare void @use(ptr)
diff --git a/llvm/test/Transforms/LoopIdiom/wcslen16.ll b/llvm/test/Transforms/LoopIdiom/wcslen16.ll
index d3b0b8d208cd8..8be51869f1f2e 100644
--- a/llvm/test/Transforms/LoopIdiom/wcslen16.ll
+++ b/llvm/test/Transforms/LoopIdiom/wcslen16.ll
@@ -1,5 +1,5 @@
 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
-; RUN: opt -passes='loop(loop-idiom),verify' < %s -S | FileCheck %s
+; RUN: opt -passes='loop(loop-idiom)' < %s -S | FileCheck %s
 
 target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
 target triple = "x86_64-unknown-linux-gnu"
diff --git a/llvm/test/Transforms/LoopIdiom/wcslen32.ll b/llvm/test/Transforms/LoopIdiom/wcslen32.ll
index 488afff86c245..2c7ceb4d187e6 100644
--- a/llvm/test/Transforms/LoopIdiom/wcslen32.ll
+++ b/llvm/test/Transforms/LoopIdiom/wcslen32.ll
@@ -1,5 +1,5 @@
 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
-; RUN: opt -passes='loop(loop-idiom),verify' < %s -S | FileCheck %s
+; RUN: opt -passes='loop(loop-idiom)' < %s -S | FileCheck %s
 
 target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
 target triple = "x86_64-unknown-linux-gnu"

@@ -1,4 +1,4 @@
; RUN: opt -passes='loop(loop-idiom),verify' < %s -S | FileCheck %s
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why removing the verify?

Copy link
Member Author

@mustartt mustartt Mar 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Its redundant:
#131412 (comment)

I also verified that verify is already scheduled at the end of the pipeline.

@mustartt mustartt requested a review from maryammo March 21, 2025 19:16
@mustartt mustartt force-pushed the cleanup-strlen-idiom branch from b1f81d0 to 5316f36 Compare March 21, 2025 19:50
@mustartt
Copy link
Member Author

Rebased onto fa4bf3a because of the failing LLDB Tests

@@ -1540,7 +1530,8 @@ static Value *matchCondition(BranchInst *BI, BasicBlock *LoopEntry,
if (!Cond)
return nullptr;

if (!isZeroConstant(Cond->getOperand(1)))
const ConstantInt *CmpZero = dyn_cast<ConstantInt>(Cond->getOperand(1));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
const ConstantInt *CmpZero = dyn_cast<ConstantInt>(Cond->getOperand(1));
auto *CmpZero = dyn_cast<ConstantInt>(Cond->getOperand(1));

Prefer auto with dyn_cast.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated to use auto.

@mustartt mustartt merged commit 7c52886 into llvm:main Mar 21, 2025
6 of 10 checks passed
@mustartt mustartt deleted the cleanup-strlen-idiom branch March 21, 2025 23:10
@llvm-ci
Copy link
Collaborator

llvm-ci commented Mar 21, 2025

LLVM Buildbot has detected a new failure on builder lldb-arm-ubuntu running on linaro-lldb-arm-ubuntu while building llvm at step 6 "test".

Full details are available at: https://lab.llvm.org/buildbot/#/builders/18/builds/13320

Here is the relevant piece of the build log for the reference
Step 6 (test) failure: build (failure)
...
PASS: lldb-api :: lang/cpp/printf/TestPrintf.py (838 of 2928)
PASS: lldb-api :: lang/cpp/preferred_name/TestPreferredName.py (839 of 2928)
PASS: lldb-api :: lang/cpp/rvalue-references/TestRvalueReferences.py (840 of 2928)
PASS: lldb-api :: lang/cpp/scope/TestCppScope.py (841 of 2928)
UNSUPPORTED: lldb-api :: lang/cpp/standards/cpp20/TestCPP20Standard.py (842 of 2928)
PASS: lldb-api :: lang/cpp/sizeof/TestCPPSizeof.py (843 of 2928)
PASS: lldb-api :: lang/cpp/signed_types/TestSignedTypes.py (844 of 2928)
PASS: lldb-api :: lang/cpp/static_member_type_depending_on_parent_size/TestStaticMemberTypeDependingOnParentSize.py (845 of 2928)
UNSUPPORTED: lldb-api :: lang/cpp/std-function-recognizer/TestStdFunctionRecognizer.py (846 of 2928)
UNSUPPORTED: lldb-api :: lang/cpp/std-function-step-into-callable/TestStdFunctionStepIntoCallable.py (847 of 2928)
FAIL: lldb-api :: lang/cpp/static_methods/TestCPPStaticMethods.py (848 of 2928)
******************** TEST 'lldb-api :: lang/cpp/static_methods/TestCPPStaticMethods.py' FAILED ********************
Script:
--
/usr/bin/python3.10 /home/tcwg-buildbot/worker/lldb-arm-ubuntu/llvm-project/lldb/test/API/dotest.py -u CXXFLAGS -u CFLAGS --env LLVM_LIBS_DIR=/home/tcwg-buildbot/worker/lldb-arm-ubuntu/build/./lib --env LLVM_INCLUDE_DIR=/home/tcwg-buildbot/worker/lldb-arm-ubuntu/build/include --env LLVM_TOOLS_DIR=/home/tcwg-buildbot/worker/lldb-arm-ubuntu/build/./bin --arch armv8l --build-dir /home/tcwg-buildbot/worker/lldb-arm-ubuntu/build/lldb-test-build.noindex --lldb-module-cache-dir /home/tcwg-buildbot/worker/lldb-arm-ubuntu/build/lldb-test-build.noindex/module-cache-lldb/lldb-api --clang-module-cache-dir /home/tcwg-buildbot/worker/lldb-arm-ubuntu/build/lldb-test-build.noindex/module-cache-clang/lldb-api --executable /home/tcwg-buildbot/worker/lldb-arm-ubuntu/build/./bin/lldb --compiler /home/tcwg-buildbot/worker/lldb-arm-ubuntu/build/./bin/clang --dsymutil /home/tcwg-buildbot/worker/lldb-arm-ubuntu/build/./bin/dsymutil --make /usr/bin/gmake --llvm-tools-dir /home/tcwg-buildbot/worker/lldb-arm-ubuntu/build/./bin --lldb-obj-root /home/tcwg-buildbot/worker/lldb-arm-ubuntu/build/tools/lldb --lldb-libs-dir /home/tcwg-buildbot/worker/lldb-arm-ubuntu/build/./lib /home/tcwg-buildbot/worker/lldb-arm-ubuntu/llvm-project/lldb/test/API/lang/cpp/static_methods -p TestCPPStaticMethods.py
--
Exit Code: -11

Command Output (stdout):
--
lldb version 21.0.0git (https://github.com/llvm/llvm-project.git revision 7c52886700a5a70d873400ec022a99d7dce8b03b)
  clang revision 7c52886700a5a70d873400ec022a99d7dce8b03b
  llvm revision 7c52886700a5a70d873400ec022a99d7dce8b03b
Skipping the following test categories: ['libc++', 'dsym', 'gmodules', 'debugserver', 'objc']

--
Command Output (stderr):
--
UNSUPPORTED: LLDB (/home/tcwg-buildbot/worker/lldb-arm-ubuntu/build/bin/clang-arm) :: test_with_run_command_dsym (TestCPPStaticMethods.CPPStaticMethodsTestCase) (test case does not fall in any category of interest for this run) 
PASS: LLDB (/home/tcwg-buildbot/worker/lldb-arm-ubuntu/build/bin/clang-arm) :: test_with_run_command_dwarf (TestCPPStaticMethods.CPPStaticMethodsTestCase)
PASS: LLDB (/home/tcwg-buildbot/worker/lldb-arm-ubuntu/build/bin/clang-arm) :: test_with_run_command_dwo (TestCPPStaticMethods.CPPStaticMethodsTestCase)
----------------------------------------------------------------------
Ran 3 tests in 0.954s

OK (skipped=1)

--

********************
PASS: lldb-api :: lang/cpp/scratch-context-merging/structs/TestCppScratchContextMergingStructs.py (849 of 2928)
PASS: lldb-api :: lang/cpp/step-through-trampoline/TestStepThroughTrampoline.py (850 of 2928)
PASS: lldb-api :: lang/cpp/struct_with_keyword_name/TestStructWithKeywordName.py (851 of 2928)
UNSUPPORTED: lldb-api :: lang/cpp/structured-binding/TestStructuredBinding.py (852 of 2928)
PASS: lldb-api :: lang/cpp/subst_template_type_param/TestSubstTemplateTypeParam.py (853 of 2928)
PASS: lldb-api :: lang/cpp/static_members/TestCPPStaticMembers.py (854 of 2928)
PASS: lldb-api :: lang/cpp/template-arguments/TestCppTemplateArguments.py (855 of 2928)
PASS: lldb-api :: lang/cpp/symbols/TestSymbols.py (856 of 2928)
PASS: lldb-api :: lang/cpp/template-specialization-type/TestTemplateSpecializationType.py (857 of 2928)
PASS: lldb-api :: lang/cpp/stl/TestSTL.py (858 of 2928)

mstorsjo added a commit that referenced this pull request Mar 22, 2025
This reverts commit 7c52886.

Reverting this as I have to revert another preceding commit,
ac9049d.
mustartt added a commit to mustartt/llvm-project that referenced this pull request Mar 22, 2025
We should bailout of modifying the CFG if the library functions are not
emittable or disabled.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants