summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
diff options
context:
space:
mode:
authorClement Courbet <courbet@google.com>2019-03-08 09:07:45 +0000
committerClement Courbet <courbet@google.com>2019-03-08 09:07:45 +0000
commit8e16d73346f8091461319a7dfc4ddd18eedcff13 (patch)
tree834ddc2069d1bcdb9214a794b89c7570156a6046 /llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
parent1a98dc184044768dd672c54b3b9557a05dd082f1 (diff)
downloadbcm5719-llvm-8e16d73346f8091461319a7dfc4ddd18eedcff13.tar.gz
bcm5719-llvm-8e16d73346f8091461319a7dfc4ddd18eedcff13.zip
[SelectionDAG] Allow the user to specify a memeq function.
Summary: Right now, when we encounter a string equality check, e.g. `if (memcmp(a, b, s) == 0)`, we try to expand to a comparison if `s` is a small compile-time constant, and fall back on calling `memcmp()` else. This is sub-optimal because memcmp has to compute much more than equality. This patch replaces `memcmp(a, b, s) == 0` by `bcmp(a, b, s) == 0` on platforms that support `bcmp`. `bcmp` can be made much more efficient than `memcmp` because equality compare is trivially parallel while lexicographic ordering has a chain dependency. Subscribers: fedor.sergeev, jyknight, ckennelly, gchatelet, llvm-commits Differential Revision: https://reviews.llvm.org/D56593 llvm-svn: 355672
Diffstat (limited to 'llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp')
-rw-r--r--llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp41
1 files changed, 27 insertions, 14 deletions
diff --git a/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp b/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
index da368b2d863..86df9339874 100644
--- a/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
+++ b/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
@@ -831,18 +831,9 @@ Value *LibCallSimplifier::optimizeMemChr(CallInst *CI, IRBuilder<> &B) {
return B.CreateGEP(B.getInt8Ty(), SrcStr, B.getInt64(I), "memchr");
}
-Value *LibCallSimplifier::optimizeMemCmp(CallInst *CI, IRBuilder<> &B) {
- Value *LHS = CI->getArgOperand(0), *RHS = CI->getArgOperand(1);
-
- if (LHS == RHS) // memcmp(s,s,x) -> 0
- return Constant::getNullValue(CI->getType());
-
- // Make sure we have a constant length.
- ConstantInt *LenC = dyn_cast<ConstantInt>(CI->getArgOperand(2));
- if (!LenC)
- return nullptr;
-
- uint64_t Len = LenC->getZExtValue();
+static Value *optimizeMemCmpConstantSize(CallInst *CI, Value *LHS, Value *RHS,
+ uint64_t Len, IRBuilder<> &B,
+ const DataLayout &DL) {
if (Len == 0) // memcmp(s1,s2,0) -> 0
return Constant::getNullValue(CI->getType());
@@ -912,6 +903,28 @@ Value *LibCallSimplifier::optimizeMemCmp(CallInst *CI, IRBuilder<> &B) {
Ret = 1;
return ConstantInt::get(CI->getType(), Ret);
}
+ return nullptr;
+}
+
+Value *LibCallSimplifier::optimizeMemCmp(CallInst *CI, IRBuilder<> &B) {
+ Value *LHS = CI->getArgOperand(0), *RHS = CI->getArgOperand(1);
+ Value *Size = CI->getArgOperand(2);
+
+ if (LHS == RHS) // memcmp(s,s,x) -> 0
+ return Constant::getNullValue(CI->getType());
+
+ // Handle constant lengths.
+ if (ConstantInt *LenC = dyn_cast<ConstantInt>(Size))
+ if (Value *Res = optimizeMemCmpConstantSize(CI, LHS, RHS,
+ LenC->getZExtValue(), B, DL))
+ return Res;
+
+ // memcmp(x, y, Len) == 0 -> bcmp(x, y, Len) == 0
+ // `bcmp` can be more efficient than memcmp because it only has to know that
+ // there is a difference, not where is is.
+ if (isOnlyUsedInZeroEqualityComparison(CI) && TLI->has(LibFunc_bcmp)) {
+ return emitBCmp(LHS, RHS, Size, B, DL, TLI);
+ }
return nullptr;
}
@@ -1137,10 +1150,10 @@ static Value *optimizeTrigReflections(CallInst *Call, LibFunc Func,
IRBuilder<> &B) {
if (!isa<FPMathOperator>(Call))
return nullptr;
-
+
IRBuilder<>::FastMathFlagGuard Guard(B);
B.setFastMathFlags(Call->getFastMathFlags());
-
+
// TODO: Can this be shared to also handle LLVM intrinsics?
Value *X;
switch (Func) {
OpenPOWER on IntegriCloud