[PATCH] D45344: [SimplifyLibcalls] Fold malloc + memset to calloc even for llvm.memset
Dávid Bolvanský via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Sat Apr 7 10:56:09 PDT 2018
xbolva00 updated this revision to Diff 141495.
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
@@ -102,6 +102,16 @@
ret i8* %memset
}
+define i8* @memset_intristic_malloc(i32 %n) #0 {
+; CHECK-LABEL: @memset_intristic_malloc(
+; CHECK-NEXT: [[CALLOC:%.*]] = call i8* @calloc(i32 1, i32 [[N:%.*]])
+; CHECK-NEXT: ret i8* [[CALLOC]]
+;
+ %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
+}
+
attributes #0 = { nounwind ssp uwtable }
attributes #1 = { nounwind }
attributes #2 = { nounwind readnone }
Index: lib/Transforms/Utils/SimplifyLibCalls.cpp
===================================================================
--- lib/Transforms/Utils/SimplifyLibCalls.cpp
+++ lib/Transforms/Utils/SimplifyLibCalls.cpp
@@ -835,19 +835,33 @@
/// Fold memset[_chk](malloc(n), 0, n) --> calloc(1, n).
static Value *foldMallocMemset(CallInst *Memset, IRBuilder<> &B,
const TargetLibraryInfo &TLI) {
+ auto Src = Memset->getArgOperand(1);
// This has to be a memset of zeros (bzero).
- auto *FillValue = dyn_cast<ConstantInt>(Memset->getArgOperand(1));
+ auto *FillValue = dyn_cast<ConstantInt>(Src);
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;
+ if (!Malloc->hasOneUse()) {
+ Instruction *I = Malloc->getNextNode();
+ while (I) {
+ auto *Call = dyn_cast<CallInst>(I);
+ if (Call && Call == Memset)
+ break;
+
+ for (unsigned i = 0; i < I->getNumOperands(); ++i) {
+ if (Src == I->getOperand(i)) {
+ return nullptr;
+ }
+ }
+
+ I = I->getNextNode();
+ }
+ }
+
// Is the inner call really malloc()?
Function *InnerCallee = Malloc->getCalledFunction();
if (!InnerCallee)
@@ -883,6 +897,10 @@
if (auto *Calloc = foldMallocMemset(CI, B, *TLI))
return Calloc;
+ if (CI->getCalledFunction()->isIntrinsic()) {
+ return nullptr;
+ }
+
// memset(p, v, n) -> llvm.memset(align 1 p, v, n)
Value *Val = B.CreateIntCast(CI->getArgOperand(1), B.getInt8Ty(), false);
B.CreateMemSet(CI->getArgOperand(0), Val, CI->getArgOperand(2), 1);
@@ -2219,7 +2237,8 @@
return optimizeLog(CI, Builder);
case Intrinsic::sqrt:
return optimizeSqrt(CI, Builder);
- // TODO: Use foldMallocMemset() with memset intrinsic.
+ case Intrinsic::memset:
+ return optimizeMemSet(CI, Builder);
default:
return nullptr;
}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D45344.141495.patch
Type: text/x-patch
Size: 2998 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20180407/6ee8e09d/attachment.bin>
More information about the llvm-commits
mailing list