diff options
| author | Eli Friedman <eli.friedman@gmail.com> | 2011-10-05 22:27:16 +0000 | 
|---|---|---|
| committer | Eli Friedman <eli.friedman@gmail.com> | 2011-10-05 22:27:16 +0000 | 
| commit | 3e3aecbc2cd760b958e38a163f5162f939405f14 (patch) | |
| tree | 9a2156212d22b124226d7a68d863492360d6a30f /llvm/lib/Transforms | |
| parent | 267f323d28aad590ccde7806bf35f11511760a58 (diff) | |
| download | bcm5719-llvm-3e3aecbc2cd760b958e38a163f5162f939405f14.tar.gz bcm5719-llvm-3e3aecbc2cd760b958e38a163f5162f939405f14.zip | |
PR11061: Make simplifylibcalls fold strcmp("", x) correctly.
While I'm here, fix the related issue with strncmp, add some actual tests for strcmp and strncmp, and start using StringRef::compare for constant folding instead of using strcmp/strncmp so that the optimized IR isn't dependent on the host's implementation of strcmp.
llvm-svn: 141227
Diffstat (limited to 'llvm/lib/Transforms')
| -rw-r--r-- | llvm/lib/Transforms/Scalar/SimplifyLibCalls.cpp | 31 | 
1 files changed, 18 insertions, 13 deletions
| diff --git a/llvm/lib/Transforms/Scalar/SimplifyLibCalls.cpp b/llvm/lib/Transforms/Scalar/SimplifyLibCalls.cpp index e433e30ea82..fbb9465743c 100644 --- a/llvm/lib/Transforms/Scalar/SimplifyLibCalls.cpp +++ b/llvm/lib/Transforms/Scalar/SimplifyLibCalls.cpp @@ -338,16 +338,17 @@ struct StrCmpOpt : public LibCallOptimization {      bool HasStr1 = GetConstantStringInfo(Str1P, Str1);      bool HasStr2 = GetConstantStringInfo(Str2P, Str2); -    if (HasStr1 && Str1.empty()) // strcmp("", x) -> *x -      return B.CreateZExt(B.CreateLoad(Str2P, "strcmpload"), CI->getType()); - -    if (HasStr2 && Str2.empty()) // strcmp(x,"") -> *x -      return B.CreateZExt(B.CreateLoad(Str1P, "strcmpload"), CI->getType()); -      // strcmp(x, y)  -> cnst  (if both x and y are constant strings)      if (HasStr1 && HasStr2)        return ConstantInt::get(CI->getType(), -                                     strcmp(Str1.c_str(),Str2.c_str())); +                              StringRef(Str1).compare(Str2)); + +    if (HasStr1 && Str1.empty()) // strcmp("", x) -> -*x +      return B.CreateNeg(B.CreateZExt(B.CreateLoad(Str2P, "strcmpload"), +                                      CI->getType())); + +    if (HasStr2 && Str2.empty()) // strcmp(x,"") -> *x +      return B.CreateZExt(B.CreateLoad(Str1P, "strcmpload"), CI->getType());      // strcmp(P, "x") -> memcmp(P, "x", 2)      uint64_t Len1 = GetStringLength(Str1P); @@ -400,16 +401,20 @@ struct StrNCmpOpt : public LibCallOptimization {      bool HasStr1 = GetConstantStringInfo(Str1P, Str1);      bool HasStr2 = GetConstantStringInfo(Str2P, Str2); -    if (HasStr1 && Str1.empty())  // strncmp("", x, n) -> *x -      return B.CreateZExt(B.CreateLoad(Str2P, "strcmpload"), CI->getType()); +    // strncmp(x, y)  -> cnst  (if both x and y are constant strings) +    if (HasStr1 && HasStr2) { +      StringRef SubStr1 = StringRef(Str1).substr(0, Length); +      StringRef SubStr2 = StringRef(Str2).substr(0, Length); +      return ConstantInt::get(CI->getType(), SubStr1.compare(SubStr2)); +    } + +    if (HasStr1 && Str1.empty())  // strncmp("", x, n) -> -*x +      return B.CreateNeg(B.CreateZExt(B.CreateLoad(Str2P, "strcmpload"), +                                      CI->getType()));      if (HasStr2 && Str2.empty())  // strncmp(x, "", n) -> *x        return B.CreateZExt(B.CreateLoad(Str1P, "strcmpload"), CI->getType()); -    // strncmp(x, y)  -> cnst  (if both x and y are constant strings) -    if (HasStr1 && HasStr2) -      return ConstantInt::get(CI->getType(), -                              strncmp(Str1.c_str(), Str2.c_str(), Length));      return 0;    }  }; | 

