Skip to content

Commit 01cf1dc

Browse files
yurai007hyp
authored andcommitted
[SimplifyLibCalls][NFC] Clean up LibCallSimplifier from 'memset + malloc into calloc' transformation
FoldMallocMemset can be safely removed because since https://reviews.llvm.org/D103009 such transformation is already performed in DSE. Differential Revision: https://reviews.llvm.org/D103451 (cherry picked from commit f8cdde7)
1 parent 94da50f commit 01cf1dc

File tree

3 files changed

+8
-56
lines changed

3 files changed

+8
-56
lines changed

llvm/include/llvm/Transforms/Utils/SimplifyLibCalls.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -132,8 +132,6 @@ class LibCallSimplifier {
132132
eraseFromParent(I);
133133
}
134134

135-
Value *foldMallocMemset(CallInst *Memset, IRBuilderBase &B);
136-
137135
public:
138136
LibCallSimplifier(
139137
const DataLayout &DL, const TargetLibraryInfo *TLI,

llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp

Lines changed: 0 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1156,59 +1156,12 @@ Value *LibCallSimplifier::optimizeMemMove(CallInst *CI, IRBuilderBase &B) {
11561156
return CI->getArgOperand(0);
11571157
}
11581158

1159-
/// Fold memset[_chk](malloc(n), 0, n) --> calloc(1, n).
1160-
Value *LibCallSimplifier::foldMallocMemset(CallInst *Memset, IRBuilderBase &B) {
1161-
// This has to be a memset of zeros (bzero).
1162-
auto *FillValue = dyn_cast<ConstantInt>(Memset->getArgOperand(1));
1163-
if (!FillValue || FillValue->getZExtValue() != 0)
1164-
return nullptr;
1165-
1166-
// TODO: We should handle the case where the malloc has more than one use.
1167-
// This is necessary to optimize common patterns such as when the result of
1168-
// the malloc is checked against null or when a memset intrinsic is used in
1169-
// place of a memset library call.
1170-
auto *Malloc = dyn_cast<CallInst>(Memset->getArgOperand(0));
1171-
if (!Malloc || !Malloc->hasOneUse())
1172-
return nullptr;
1173-
1174-
// Is the inner call really malloc()?
1175-
Function *InnerCallee = Malloc->getCalledFunction();
1176-
if (!InnerCallee)
1177-
return nullptr;
1178-
1179-
LibFunc Func;
1180-
if (!TLI->getLibFunc(*InnerCallee, Func) || !TLI->has(Func) ||
1181-
Func != LibFunc_malloc)
1182-
return nullptr;
1183-
1184-
// The memset must cover the same number of bytes that are malloc'd.
1185-
if (Memset->getArgOperand(2) != Malloc->getArgOperand(0))
1186-
return nullptr;
1187-
1188-
// Replace the malloc with a calloc. We need the data layout to know what the
1189-
// actual size of a 'size_t' parameter is.
1190-
B.SetInsertPoint(Malloc->getParent(), ++Malloc->getIterator());
1191-
const DataLayout &DL = Malloc->getModule()->getDataLayout();
1192-
IntegerType *SizeType = DL.getIntPtrType(B.GetInsertBlock()->getContext());
1193-
if (Value *Calloc = emitCalloc(ConstantInt::get(SizeType, 1),
1194-
Malloc->getArgOperand(0),
1195-
Malloc->getAttributes(), B, *TLI)) {
1196-
substituteInParent(Malloc, Calloc);
1197-
return Calloc;
1198-
}
1199-
1200-
return nullptr;
1201-
}
1202-
12031159
Value *LibCallSimplifier::optimizeMemSet(CallInst *CI, IRBuilderBase &B) {
12041160
Value *Size = CI->getArgOperand(2);
12051161
annotateNonNullAndDereferenceable(CI, 0, Size, DL);
12061162
if (isa<IntrinsicInst>(CI))
12071163
return nullptr;
12081164

1209-
if (auto *Calloc = foldMallocMemset(CI, B))
1210-
return Calloc;
1211-
12121165
// memset(p, v, n) -> llvm.memset(align 1 p, v, n)
12131166
Value *Val = B.CreateIntCast(CI->getArgOperand(1), B.getInt8Ty(), false);
12141167
CallInst *NewCI = B.CreateMemSet(CI->getArgOperand(0), Val, Size, Align(1));
@@ -3066,7 +3019,6 @@ Value *LibCallSimplifier::optimizeCall(CallInst *CI, IRBuilderBase &Builder) {
30663019
return optimizeLog(CI, Builder);
30673020
case Intrinsic::sqrt:
30683021
return optimizeSqrt(CI, Builder);
3069-
// TODO: Use foldMallocMemset() with memset intrinsic.
30703022
case Intrinsic::memset:
30713023
return optimizeMemSet(CI, Builder);
30723024
case Intrinsic::memcpy:
@@ -3289,8 +3241,6 @@ Value *FortifiedLibCallSimplifier::optimizeMemMoveChk(CallInst *CI,
32893241

32903242
Value *FortifiedLibCallSimplifier::optimizeMemSetChk(CallInst *CI,
32913243
IRBuilderBase &B) {
3292-
// TODO: Try foldMallocMemset() here.
3293-
32943244
if (isFortifiedCallFoldable(CI, 3, 2)) {
32953245
Value *Val = B.CreateIntCast(CI->getArgOperand(1), B.getInt8Ty(), false);
32963246
CallInst *NewCI = B.CreateMemSet(CI->getArgOperand(0), Val,

llvm/test/Transforms/InstCombine/memset-1.ll

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,17 +21,20 @@ define i8* @test_simplify1(i8* %mem, i32 %val, i32 %size) {
2121
ret i8* %ret
2222
}
2323

24+
; Malloc + memset pattern is now handled by DSE in a more general way.
25+
2426
define i8* @pr25892_lite(i32 %size) #0 {
2527
; CHECK-LABEL: @pr25892_lite(
26-
; CHECK-NEXT: [[CALLOC:%.*]] = call i8* @calloc(i32 1, i32 [[SIZE:%.*]])
27-
; CHECK-NEXT: ret i8* [[CALLOC]]
28+
; CHECK-NEXT: [[CALL:%.*]] = call i8* @malloc(i32 [[SIZE:%.*]])
29+
; CHECK-NEXT: call void @llvm.memset.p0i8.i32(i8* align 1 [[CALL]], i8 0, i32 [[SIZE]], i1 false)
2830
;
2931
%call1 = call i8* @malloc(i32 %size) #1
3032
%call2 = call i8* @memset(i8* %call1, i32 0, i32 %size) #1
3133
ret i8* %call2
3234
}
3335

34-
; FIXME: A memset intrinsic should be handled similarly to a memset() libcall.
36+
; A memset intrinsic should be handled similarly to a memset() libcall.
37+
; Notice that malloc + memset pattern is now handled by DSE in a more general way.
3538

3639
define i8* @malloc_and_memset_intrinsic(i32 %n) #0 {
3740
; CHECK-LABEL: @malloc_and_memset_intrinsic(
@@ -45,6 +48,7 @@ define i8* @malloc_and_memset_intrinsic(i32 %n) #0 {
4548
}
4649

4750
; This should not create a calloc and should not crash the compiler.
51+
; Notice that malloc + memset pattern is now handled by DSE in a more general way.
4852

4953
define i8* @notmalloc_memset(i32 %size, i8*(i32)* %notmalloc) {
5054
; CHECK-LABEL: @notmalloc_memset(
@@ -57,8 +61,8 @@ define i8* @notmalloc_memset(i32 %size, i8*(i32)* %notmalloc) {
5761
ret i8* %call2
5862
}
5963

60-
; FIXME: memset(malloc(x), 0, x) -> calloc(1, x)
6164
; This doesn't fire currently because the malloc has more than one use.
65+
; Notice that malloc + memset pattern is now handled by DSE in a more general way.
6266

6367
define float* @pr25892(i32 %size) #0 {
6468
; CHECK-LABEL: @pr25892(

0 commit comments

Comments
 (0)