Skip to content

Commit be2487a

Browse files
[InstCombine] Annotate strdup with deref_or_null
llvm-svn: 372098
1 parent 3a3dddd commit be2487a

File tree

5 files changed

+42
-3
lines changed

5 files changed

+42
-3
lines changed

llvm/include/llvm/Analysis/MemoryBuiltins.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,11 @@ bool isReallocLikeFn(const Function *F, const TargetLibraryInfo *TLI);
104104
bool isOpNewLikeFn(const Value *V, const TargetLibraryInfo *TLI,
105105
bool LookThroughBitCast = false);
106106

107+
/// Tests if a value is a call or invoke to a library function that
108+
/// allocates memory (strdup, strndup).
109+
bool isStrdupLikeFn(const Value *V, const TargetLibraryInfo *TLI,
110+
bool LookThroughBitCast = false);
111+
107112
//===----------------------------------------------------------------------===//
108113
// malloc Call Utility Functions.
109114
//

llvm/lib/Analysis/MemoryBuiltins.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,13 @@ bool llvm::isOpNewLikeFn(const Value *V, const TargetLibraryInfo *TLI,
307307
return getAllocationData(V, OpNewLike, TLI, LookThroughBitCast).hasValue();
308308
}
309309

310+
/// Tests if a value is a call or invoke to a library function that
311+
/// allocates memory (strdup, strndup).
312+
bool llvm::isStrdupLikeFn(const Value *V, const TargetLibraryInfo *TLI,
313+
bool LookThroughBitCast) {
314+
return getAllocationData(V, StrDupLike, TLI, LookThroughBitCast).hasValue();
315+
}
316+
310317
/// extractMallocCall - Returns the corresponding CallInst if the instruction
311318
/// is a malloc call. Since CallInst::CreateMalloc() only creates calls, we
312319
/// ignore InvokeInst here.

llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4208,6 +4208,12 @@ static void annotateAnyAllocSite(CallBase &Call, const TargetLibraryInfo *TLI) {
42084208
Call.addAttribute(AttributeList::ReturnIndex,
42094209
Attribute::getWithDereferenceableOrNullBytes(
42104210
Call.getContext(), Size.getZExtValue()));
4211+
} else if (isStrdupLikeFn(&Call, TLI) && Call.getNumArgOperands() == 1) {
4212+
// TODO: handle strndup
4213+
if (uint64_t Len = GetStringLength(Call.getOperand(0)))
4214+
Call.addAttribute(
4215+
AttributeList::ReturnIndex,
4216+
Attribute::getWithDereferenceableOrNullBytes(Call.getContext(), Len));
42114217
}
42124218
}
42134219

llvm/test/Transforms/InstCombine/deref-alloc-fns.ll

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ declare noalias i8* @calloc(i64, i64)
66
declare noalias i8* @realloc(i8* nocapture, i64)
77
declare noalias nonnull i8* @_Znam(i64) ; throwing version of 'new'
88
declare noalias nonnull i8* @_Znwm(i64) ; throwing version of 'new'
9+
declare noalias i8* @strdup(i8*)
10+
11+
@.str = private unnamed_addr constant [6 x i8] c"hello\00", align 1
912

1013
define noalias i8* @malloc_nonconstant_size(i64 %n) {
1114
; CHECK-LABEL: @malloc_nonconstant_size(
@@ -206,3 +209,21 @@ define noalias i8* @op_new_constant_zero_size() {
206209
%call = tail call i8* @_Znam(i64 0)
207210
ret i8* %call
208211
}
212+
213+
define noalias i8* @strdup_constant_str() {
214+
; CHECK-LABEL: @strdup_constant_str(
215+
; CHECK-NEXT: [[CALL:%.*]] = tail call noalias dereferenceable_or_null(6) i8* @strdup(i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str, i64 0, i64 0))
216+
; CHECK-NEXT: ret i8* [[CALL]]
217+
;
218+
%call = tail call noalias i8* @strdup(i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str, i64 0, i64 0))
219+
ret i8* %call
220+
}
221+
222+
define noalias i8* @strdup_notconstant_str(i8 * %str) {
223+
; CHECK-LABEL: @strdup_notconstant_str(
224+
; CHECK-NEXT: [[CALL:%.*]] = tail call noalias i8* @strdup(i8* [[STR:%.*]])
225+
; CHECK-NEXT: ret i8* [[CALL]]
226+
;
227+
%call = tail call noalias i8* @strdup(i8* %str)
228+
ret i8* %call
229+
}

llvm/test/Transforms/InstCombine/objsize.ll

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ define i32 @test4(i8** %esc) nounwind ssp {
141141
; CHECK-NEXT: entry:
142142
; CHECK-NEXT: [[TMP0:%.*]] = alloca [[STRUCT_DATA:%.*]], align 8
143143
; CHECK-NEXT: [[TMP1:%.*]] = bitcast %struct.data* [[TMP0]] to i8*
144-
; CHECK-NEXT: call void @llvm.memset.p0i8.i32(i8* nonnull align 8 dereferenceable(1824) [[TMP1]], i8 0, i32 1824, i1 false)
144+
; CHECK-NEXT: call void @llvm.memset.p0i8.i32(i8* nonnull align 8 dereferenceable(1824) [[TMP1]], i8 0, i32 1824, i1 false) #0
145145
; CHECK-NEXT: [[TMP2:%.*]] = bitcast i8** [[ESC:%.*]] to %struct.data**
146146
; CHECK-NEXT: store %struct.data* [[TMP0]], %struct.data** [[TMP2]], align 4
147147
; CHECK-NEXT: ret i32 0
@@ -163,7 +163,7 @@ define i8* @test5(i32 %n) nounwind ssp {
163163
; CHECK-NEXT: entry:
164164
; CHECK-NEXT: [[TMP0:%.*]] = tail call noalias dereferenceable_or_null(20) i8* @malloc(i32 20) #0
165165
; CHECK-NEXT: [[TMP1:%.*]] = load i8*, i8** @s, align 8
166-
; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* nonnull align 1 dereferenceable(10) [[TMP0]], i8* nonnull align 1 dereferenceable(10) [[TMP1]], i32 10, i1 false)
166+
; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* nonnull align 1 dereferenceable(10) [[TMP0]], i8* nonnull align 1 dereferenceable(10) [[TMP1]], i32 10, i1 false) #0
167167
; CHECK-NEXT: ret i8* [[TMP0]]
168168
;
169169
entry:
@@ -227,7 +227,7 @@ declare noalias i8* @strndup(i8* nocapture, i32) nounwind
227227

228228
define i32 @test9(i8** %esc) {
229229
; CHECK-LABEL: @test9(
230-
; CHECK-NEXT: [[CALL:%.*]] = tail call i8* @strdup(i8* getelementptr inbounds ([8 x i8], [8 x i8]* @.str, i32 0, i32 0)) #0
230+
; CHECK-NEXT: [[CALL:%.*]] = tail call dereferenceable_or_null(8) i8* @strdup(i8* getelementptr inbounds ([8 x i8], [8 x i8]* @.str, i32 0, i32 0)) #0
231231
; CHECK-NEXT: store i8* [[CALL]], i8** [[ESC:%.*]], align 8
232232
; CHECK-NEXT: ret i32 8
233233
;

0 commit comments

Comments
 (0)