[SLC] Transform strncpy(dst, "text", C) to memcpy(dst, "text\0\0\0", C) for C <=...
authorDávid Bolvanský <david.bolvansky@gmail.com>
Fri, 14 Aug 2020 23:49:02 +0000 (01:49 +0200)
committerDávid Bolvanský <david.bolvansky@gmail.com>
Fri, 14 Aug 2020 23:53:32 +0000 (01:53 +0200)
Transformation creates big strings for big C values, so bail out for C > 128.

Reviewed By: efriedma

Differential Revision: https://reviews.llvm.org/D86004

llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
llvm/test/Transforms/InstCombine/strncpy-3.ll

index 1a76549..db7078b 100644 (file)
@@ -610,12 +610,16 @@ Value *LibCallSimplifier::optimizeStrNCpy(CallInst *CI, IRBuilderBase &B) {
 
   // strncpy(a, "a", 4) - > memcpy(a, "a\0\0\0", 4)
   if (Len > SrcLen + 1) {
-    StringRef Str;
-    if (!getConstantStringInfo(Src, Str))
+    if (Len <= 128) {
+      StringRef Str;
+      if (!getConstantStringInfo(Src, Str))
+        return nullptr;
+      std::string SrcStr = Str.str();
+      SrcStr.resize(Len, '\0');
+      Src = B.CreateGlobalString(SrcStr, "str");
+    } else {
       return nullptr;
-    std::string SrcStr = Str.str();
-    SrcStr.resize(Len, '\0');
-    Src = B.CreateGlobalString(SrcStr, "str");
+    }
   }
 
   Type *PT = Callee->getFunctionType()->getParamType(0);
index 744f1e4..28d27a4 100644 (file)
@@ -38,3 +38,21 @@ define void @fill_with_zeros3(i8* %dst) {
   tail call i8* @strncpy(i8* %dst, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @str3, i64 0, i64 0), i64 4)
   ret void
 }
+
+define void @fill_with_zeros4(i8* %dst) {
+; CHECK-LABEL: @fill_with_zeros4(
+; CHECK-NEXT:    call void @llvm.memcpy.p0i8.p0i8.i64(i8* nonnull align 1 dereferenceable(128) [[DST:%.*]], i8* nonnull align 1 dereferenceable(128) getelementptr inbounds ([129 x i8], [129 x i8]* @str.2, i64 0, i64 0), i64 128, i1 false)
+; CHECK-NEXT:    ret void
+;
+  tail call i8* @strncpy(i8* %dst, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @str3, i64 0, i64 0), i64 128)
+  ret void
+}
+
+define void @no_simplify(i8* %dst) {
+; CHECK-LABEL: @no_simplify(
+; CHECK-NEXT:    [[TMP1:%.*]] = tail call i8* @strncpy(i8* nonnull dereferenceable(1) [[DST:%.*]], i8* nonnull dereferenceable(5) getelementptr inbounds ([4 x i8], [4 x i8]* @str3, i64 0, i64 0), i64 129)
+; CHECK-NEXT:    ret void
+;
+  tail call i8* @strncpy(i8* %dst, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @str3, i64 0, i64 0), i64 129)
+  ret void
+}