Skip to content

Commit 6b94870

Browse files
authored
[AggressiveInstCombine] Inline strcmp/strncmp (#89371)
Inline calls to strcmp(s1, s2) and strncmp(s1, s2, N), where N and exactly one of s1 and s2 are constant. For example: ```c int res = strcmp(s, "ab"); ``` is converted to ```c int res = (int)s[0] - (int)'a'; if (res != 0) goto END; res = (int)s[1] - (int)'b'; if (res != 0) goto END; res = (int)s[2] - (int)'\0'; END: ``` Ported from a similar gcc feature [Inline strcmp with small constant strings](https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78809).
1 parent b62c45c commit 6b94870

File tree

7 files changed

+616
-243
lines changed

7 files changed

+616
-243
lines changed

llvm/include/llvm/Analysis/ValueTracking.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,8 @@ bool isKnownToBeAPowerOfTwo(const Value *V, const DataLayout &DL,
117117
const DominatorTree *DT = nullptr,
118118
bool UseInstrInfo = true);
119119

120+
bool isOnlyUsedInZeroComparison(const Instruction *CxtI);
121+
120122
bool isOnlyUsedInZeroEqualityComparison(const Instruction *CxtI);
121123

122124
/// Return true if the given value is known to be non-zero when defined. For

llvm/include/llvm/Transforms/AggressiveInstCombine/AggressiveInstCombine.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
/// \file
99
///
1010
/// AggressiveInstCombiner - Combine expression patterns to form expressions
11-
/// with fewer, simple instructions. This pass does not modify the CFG.
11+
/// with fewer, simple instructions.
1212
///
1313
//===----------------------------------------------------------------------===//
1414

llvm/lib/Analysis/ValueTracking.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,13 @@ bool llvm::haveNoCommonBitsSet(const WithCache<const Value *> &LHSCache,
252252
RHSCache.getKnownBits(SQ));
253253
}
254254

255+
bool llvm::isOnlyUsedInZeroComparison(const Instruction *I) {
256+
return !I->user_empty() && all_of(I->users(), [](const User *U) {
257+
ICmpInst::Predicate P;
258+
return match(U, m_ICmp(P, m_Value(), m_Zero()));
259+
});
260+
}
261+
255262
bool llvm::isOnlyUsedInZeroEqualityComparison(const Instruction *I) {
256263
return !I->user_empty() && all_of(I->users(), [](const User *U) {
257264
ICmpInst::Predicate P;

0 commit comments

Comments
 (0)