aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Kramer <benny.kra@googlemail.com>2009-11-05 17:44:22 +0000
committerBenjamin Kramer <benny.kra@googlemail.com>2009-11-05 17:44:22 +0000
commit992a63729706355c2a6b8221709fc0aa100a1e79 (patch)
tree214145f9a8152732e03af0193e20a8d1e3d035bc
parentf626167e69d08f500805d209ff80720240adde3f (diff)
Teach SimplifyLibCalls to fold memcmp calls with constant arguments.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@86141 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Transforms/Scalar/SimplifyLibCalls.cpp15
-rw-r--r--test/Transforms/SimplifyLibCalls/memcmp.ll4
2 files changed, 15 insertions, 4 deletions
diff --git a/lib/Transforms/Scalar/SimplifyLibCalls.cpp b/lib/Transforms/Scalar/SimplifyLibCalls.cpp
index 575c93b9dd..ecca3c73b9 100644
--- a/lib/Transforms/Scalar/SimplifyLibCalls.cpp
+++ b/lib/Transforms/Scalar/SimplifyLibCalls.cpp
@@ -955,6 +955,17 @@ struct MemCmpOpt : public LibCallOptimization {
return B.CreateZExt(B.CreateXor(LHSV, RHSV, "shortdiff"), CI->getType());
}
+ // Constant folding: memcmp(x, y, l) -> cnst (all arguments are constant)
+ std::string LHSStr, RHSStr;
+ if (GetConstantStringInfo(LHS, LHSStr) &&
+ GetConstantStringInfo(RHS, RHSStr)) {
+ // Make sure we're not reading out-of-bounds memory.
+ if (Len > LHSStr.length() || Len > RHSStr.length())
+ return 0;
+ uint64_t Ret = memcmp(LHSStr.data(), RHSStr.data(), Len);
+ return ConstantInt::get(CI->getType(), Ret);
+ }
+
return 0;
}
};
@@ -2479,10 +2490,6 @@ bool SimplifyLibCalls::doInitialization(Module &M) {
// lround, lroundf, lroundl:
// * lround(cnst) -> cnst'
//
-// memcmp:
-// * memcmp(x,y,l) -> cnst
-// (if all arguments are constant and strlen(x) <= l and strlen(y) <= l)
-//
// pow, powf, powl:
// * pow(exp(x),y) -> exp(x*y)
// * pow(sqrt(x),y) -> pow(x,y*0.5)
diff --git a/test/Transforms/SimplifyLibCalls/memcmp.ll b/test/Transforms/SimplifyLibCalls/memcmp.ll
index 700873627e..ed7bcac467 100644
--- a/test/Transforms/SimplifyLibCalls/memcmp.ll
+++ b/test/Transforms/SimplifyLibCalls/memcmp.ll
@@ -17,6 +17,10 @@ define void @test(i8* %P, i8* %Q, i32 %N, i32* %IP, i1* %BP) {
%D = call i32 @memcmp( i8* %P, i8* %Q, i32 2 ) ; <i32> [#uses=1]
%E = icmp eq i32 %D, 0 ; <i1> [#uses=1]
volatile store i1 %E, i1* %BP
+ %F = call i32 @memcmp(i8* getelementptr ([4 x i8]* @hel, i32 0, i32 0),
+ i8* getelementptr ([8 x i8]* @hello_u, i32 0, i32 0),
+ i32 3)
+ volatile store i32 %F, i32* %IP
ret void
}