[PATCH] D45344: Fold malloc + memset to calloc even for llvm.memset

Dávid Bolvanský via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Fri Apr 6 01:11:21 PDT 2018


xbolva00 updated this revision to Diff 141289.
xbolva00 marked an inline comment as done.
xbolva00 added a comment.

Fixed previous test, now it passes


https://reviews.llvm.org/D45344

Files:
  lib/Transforms/Utils/SimplifyLibCalls.cpp
  test/Transforms/InstCombine/memset-1.ll


Index: test/Transforms/InstCombine/memset-1.ll
===================================================================
--- test/Transforms/InstCombine/memset-1.ll
+++ test/Transforms/InstCombine/memset-1.ll
@@ -26,6 +26,17 @@
 ; CHECK-NEXT:  ret i8* %calloc
 }
 
+
+define i8* @malloc_llvmmemset_fold_calloc(i32 %n) #0 {
+  %call = call i8* @malloc(i32 %n)
+  call void @llvm.memset.p0i8.i32(i8* %call, i8 0, i32 %n, i32 1, i1 false)
+  ret i8* %call
+
+; CHECK-LABEL: @malloc_llvmmemset_fold_calloc(
+; CHECK-NEXT:  %calloc = call i8* @calloc(i32 1, i32 %n)
+; CHECK-NEXT:  ret i8* %calloc
+}
+
 ; This should not create a calloc and not crash the compiler.
 ; CHECK-LABEL: @notmalloc_memset
 ; CHECK-NOT: @calloc
@@ -53,12 +64,11 @@
 
 ; CHECK-LABEL: @pr25892(
 ; CHECK:       entry:
-; CHECK-NEXT:    %call = tail call i8* @malloc(i32 %size) #1
-; CHECK-NEXT:    %cmp = icmp eq i8* %call, null
+; CHECK-NEXT:    %calloc = call i8* @calloc(i32 1, i32 %size)
+; CHECK-NEXT:    %cmp = icmp eq i8* %calloc, null
 ; CHECK-NEXT:    br i1 %cmp, label %cleanup, label %if.end
 ; CHECK:       if.end: 
-; CHECK-NEXT:    %bc = bitcast i8* %call to float*
-; CHECK-NEXT:    call void @llvm.memset.p0i8.i32(i8* nonnull align 1 %call, i8 0, i32 %size, i1 false)
+; CHECK-NEXT:    %bc = bitcast i8* %calloc to float*
 ; CHECK-NEXT:    br label %cleanup
 ; CHECK:       cleanup:
 ; CHECK-NEXT:    %retval.0 = phi float* [ %bc, %if.end ], [ null, %entry ]
@@ -67,6 +77,8 @@
 
 declare noalias i8* @malloc(i32) #1
 declare i64 @llvm.objectsize.i64.p0i8(i8*, i1) #2
+declare void @llvm.memset.p0i8.i32(i8* nocapture writeonly, i8, i32, i32, i1) #3
+declare i8* @calloc(i32, i32) #4
 
 attributes #0 = { nounwind ssp uwtable }
 attributes #1 = { nounwind }
Index: lib/Transforms/Utils/SimplifyLibCalls.cpp
===================================================================
--- lib/Transforms/Utils/SimplifyLibCalls.cpp
+++ lib/Transforms/Utils/SimplifyLibCalls.cpp
@@ -840,12 +840,8 @@
   if (!FillValue || FillValue->getZExtValue() != 0)
     return nullptr;
 
-  // TODO: We should handle the case where the malloc has more than one use.
-  // This is necessary to optimize common patterns such as when the result of
-  // the malloc is checked against null or when a memset intrinsic is used in
-  // place of a memset library call.
   auto *Malloc = dyn_cast<CallInst>(Memset->getArgOperand(0));
-  if (!Malloc || !Malloc->hasOneUse())
+  if (!Malloc)
     return nullptr;
 
   // Is the inner call really malloc()?
@@ -2219,7 +2215,8 @@
       return optimizeLog(CI, Builder);
     case Intrinsic::sqrt:
       return optimizeSqrt(CI, Builder);
-    // TODO: Use foldMallocMemset() with memset intrinsic.
+    case Intrinsic::memset:
+      return foldMallocMemset(CI, Builder, *TLI);
     default:
       return nullptr;
     }
@@ -2393,7 +2390,8 @@
 
 Value *FortifiedLibCallSimplifier::optimizeMemSetChk(CallInst *CI,
                                                      IRBuilder<> &B) {
-  // TODO: Try foldMallocMemset() here.
+  if (auto *Calloc = foldMallocMemset(CI, B, *TLI))
+    return Calloc;
 
   if (isFortifiedCallFoldable(CI, 3, 2, false)) {
     Value *Val = B.CreateIntCast(CI->getArgOperand(1), B.getInt8Ty(), false);


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D45344.141289.patch
Type: text/x-patch
Size: 3225 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20180406/bd6b9495/attachment.bin>


More information about the llvm-commits mailing list