Skip to content

Commit 7c52886

Browse files
authored
[Transform] Clean up strlen loop idiom (#132421)
We should bailout of modifying the CFG if the library functions are not emittable or disabled.
1 parent 98dc8bb commit 7c52886

File tree

5 files changed

+20
-33
lines changed

5 files changed

+20
-33
lines changed

llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp

Lines changed: 16 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1515,16 +1515,6 @@ bool LoopIdiomRecognize::runOnNoncountableLoop() {
15151515
recognizeShiftUntilLessThan() || recognizeAndInsertStrLen();
15161516
}
15171517

1518-
/// Check if a Value is either a nullptr or a constant int zero
1519-
static bool isZeroConstant(const Value *Val) {
1520-
if (isa<ConstantPointerNull>(Val))
1521-
return true;
1522-
const ConstantInt *CmpZero = dyn_cast<ConstantInt>(Val);
1523-
if (!CmpZero || !CmpZero->isZero())
1524-
return false;
1525-
return true;
1526-
}
1527-
15281518
/// Check if the given conditional branch is based on the comparison between
15291519
/// a variable and zero, and if the variable is non-zero or zero (JmpOnZero is
15301520
/// true), the control yields to the loop entry. If the branch matches the
@@ -1540,7 +1530,8 @@ static Value *matchCondition(BranchInst *BI, BasicBlock *LoopEntry,
15401530
if (!Cond)
15411531
return nullptr;
15421532

1543-
if (!isZeroConstant(Cond->getOperand(1)))
1533+
auto *CmpZero = dyn_cast<ConstantInt>(Cond->getOperand(1));
1534+
if (!CmpZero || !CmpZero->isZero())
15441535
return nullptr;
15451536

15461537
BasicBlock *TrueSucc = BI->getSuccessor(0);
@@ -1611,11 +1602,7 @@ class StrlenVerifier {
16111602
return false;
16121603
LoadBaseEv = LoadEv->getStart();
16131604

1614-
LLVM_DEBUG({
1615-
dbgs() << "pointer load scev: ";
1616-
LoadEv->print(outs());
1617-
dbgs() << "\n";
1618-
});
1605+
LLVM_DEBUG(dbgs() << "pointer load scev: " << *LoadEv << "\n");
16191606

16201607
const SCEVConstant *Step =
16211608
dyn_cast<SCEVConstant>(LoadEv->getStepRecurrence(*SE));
@@ -1656,11 +1643,7 @@ class StrlenVerifier {
16561643
if (!Ev)
16571644
return false;
16581645

1659-
LLVM_DEBUG({
1660-
dbgs() << "loop exit phi scev: ";
1661-
Ev->print(dbgs());
1662-
dbgs() << "\n";
1663-
});
1646+
LLVM_DEBUG(dbgs() << "loop exit phi scev: " << *Ev << "\n");
16641647

16651648
// Since we verified that the loop trip count will be a valid strlen
16661649
// idiom, we can expand all lcssa phi with {n,+,1} as (n + strlen) and use
@@ -1763,6 +1746,18 @@ bool LoopIdiomRecognize::recognizeAndInsertStrLen() {
17631746
BasicBlock *Preheader = CurLoop->getLoopPreheader();
17641747
BasicBlock *LoopExitBB = CurLoop->getExitBlock();
17651748

1749+
if (Verifier.OpWidth == 8) {
1750+
if (DisableLIRP::Strlen)
1751+
return false;
1752+
if (!isLibFuncEmittable(Preheader->getModule(), TLI, LibFunc_strlen))
1753+
return false;
1754+
} else {
1755+
if (DisableLIRP::Wcslen)
1756+
return false;
1757+
if (!isLibFuncEmittable(Preheader->getModule(), TLI, LibFunc_wcslen))
1758+
return false;
1759+
}
1760+
17661761
IRBuilder<> Builder(Preheader->getTerminator());
17671762
SCEVExpander Expander(*SE, Preheader->getModule()->getDataLayout(),
17681763
"strlen_idiom");
@@ -1772,16 +1767,8 @@ bool LoopIdiomRecognize::recognizeAndInsertStrLen() {
17721767

17731768
Value *StrLenFunc = nullptr;
17741769
if (Verifier.OpWidth == 8) {
1775-
if (DisableLIRP::Strlen)
1776-
return false;
1777-
if (!isLibFuncEmittable(Preheader->getModule(), TLI, LibFunc_strlen))
1778-
return false;
17791770
StrLenFunc = emitStrLen(MaterialzedBase, Builder, *DL, TLI);
17801771
} else {
1781-
if (DisableLIRP::Wcslen)
1782-
return false;
1783-
if (!isLibFuncEmittable(Preheader->getModule(), TLI, LibFunc_wcslen))
1784-
return false;
17851772
StrLenFunc = emitWcsLen(MaterialzedBase, Builder, *DL, TLI);
17861773
}
17871774
assert(StrLenFunc && "Failed to emit strlen function.");

llvm/test/Transforms/LoopIdiom/strlen-not-emittable.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
; RUN: opt -passes='loop(loop-idiom),verify' < %s -S | FileCheck %s
1+
; RUN: opt -passes='loop(loop-idiom)' < %s -S | FileCheck %s
22

33
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"
44
target triple = "x86_64-unknown-linux-gnu"

llvm/test/Transforms/LoopIdiom/strlen.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
2-
; RUN: opt -passes='loop(loop-idiom),verify' < %s -S | FileCheck %s
2+
; RUN: opt -passes='loop(loop-idiom)' < %s -S | FileCheck %s
33

44
declare void @other()
55
declare void @use(ptr)

llvm/test/Transforms/LoopIdiom/wcslen16.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
2-
; RUN: opt -passes='loop(loop-idiom),verify' < %s -S | FileCheck %s
2+
; RUN: opt -passes='loop(loop-idiom)' < %s -S | FileCheck %s
33

44
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"
55
target triple = "x86_64-unknown-linux-gnu"

llvm/test/Transforms/LoopIdiom/wcslen32.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
2-
; RUN: opt -passes='loop(loop-idiom),verify' < %s -S | FileCheck %s
2+
; RUN: opt -passes='loop(loop-idiom)' < %s -S | FileCheck %s
33

44
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"
55
target triple = "x86_64-unknown-linux-gnu"

0 commit comments

Comments
 (0)