summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp27
-rw-r--r--llvm/test/Transforms/InstCombine/objsize.ll2
-rw-r--r--llvm/test/Transforms/InstCombine/strndup.ll2
3 files changed, 20 insertions, 11 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
index bf9917dbab0..0b4e9e9af3c 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
@@ -4179,10 +4179,10 @@ static IntrinsicInst *findInitTrampoline(Value *Callee) {
}
static void annotateAnyAllocSite(CallBase &Call, const TargetLibraryInfo *TLI) {
+ unsigned NumArgs = Call.getNumArgOperands();
ConstantInt *Op0C = dyn_cast<ConstantInt>(Call.getOperand(0));
- ConstantInt *Op1C = (Call.getNumArgOperands() == 1)
- ? nullptr
- : dyn_cast<ConstantInt>(Call.getOperand(1));
+ ConstantInt *Op1C =
+ (NumArgs == 1) ? nullptr : dyn_cast<ConstantInt>(Call.getOperand(1));
// Bail out if the allocation size is zero.
if ((Op0C && Op0C->isNullValue()) || (Op1C && Op1C->isNullValue()))
return;
@@ -4208,12 +4208,21 @@ static void annotateAnyAllocSite(CallBase &Call, const TargetLibraryInfo *TLI) {
Call.addAttribute(AttributeList::ReturnIndex,
Attribute::getWithDereferenceableOrNullBytes(
Call.getContext(), Size.getZExtValue()));
- } else if (isStrdupLikeFn(&Call, TLI) && Call.getNumArgOperands() == 1) {
- // TODO: handle strndup
- if (uint64_t Len = GetStringLength(Call.getOperand(0)))
- Call.addAttribute(
- AttributeList::ReturnIndex,
- Attribute::getWithDereferenceableOrNullBytes(Call.getContext(), Len));
+ } else if (isStrdupLikeFn(&Call, TLI)) {
+ uint64_t Len = GetStringLength(Call.getOperand(0));
+ if (Len) {
+ // strdup
+ if (NumArgs == 1)
+ Call.addAttribute(AttributeList::ReturnIndex,
+ Attribute::getWithDereferenceableOrNullBytes(
+ Call.getContext(), Len));
+ // strndup
+ else if (NumArgs == 2 && Op1C)
+ Call.addAttribute(
+ AttributeList::ReturnIndex,
+ Attribute::getWithDereferenceableOrNullBytes(
+ Call.getContext(), std::min(Len, Op1C->getZExtValue() + 1)));
+ }
}
}
diff --git a/llvm/test/Transforms/InstCombine/objsize.ll b/llvm/test/Transforms/InstCombine/objsize.ll
index f00f5970af1..15f6b44a3a0 100644
--- a/llvm/test/Transforms/InstCombine/objsize.ll
+++ b/llvm/test/Transforms/InstCombine/objsize.ll
@@ -239,7 +239,7 @@ define i32 @test9(i8** %esc) {
define i32 @test10(i8** %esc) {
; CHECK-LABEL: @test10(
-; CHECK-NEXT: [[CALL:%.*]] = tail call i8* @strndup(i8* dereferenceable(8) getelementptr inbounds ([8 x i8], [8 x i8]* @.str, i32 0, i32 0), i32 3) #0
+; CHECK-NEXT: [[CALL:%.*]] = tail call dereferenceable_or_null(4) i8* @strndup(i8* dereferenceable(8) getelementptr inbounds ([8 x i8], [8 x i8]* @.str, i32 0, i32 0), i32 3) #0
; CHECK-NEXT: store i8* [[CALL]], i8** [[ESC:%.*]], align 8
; CHECK-NEXT: ret i32 4
;
diff --git a/llvm/test/Transforms/InstCombine/strndup.ll b/llvm/test/Transforms/InstCombine/strndup.ll
index 0861535e9dd..b3f927934a7 100644
--- a/llvm/test/Transforms/InstCombine/strndup.ll
+++ b/llvm/test/Transforms/InstCombine/strndup.ll
@@ -18,7 +18,7 @@ define i8* @test1() {
define i8* @test2() {
; CHECK-LABEL: @test2(
-; CHECK-NEXT: [[RET:%.*]] = call i8* @strndup(i8* dereferenceable(6) getelementptr inbounds ([6 x i8], [6 x i8]* @hello, i64 0, i64 0), i32 4)
+; CHECK-NEXT: [[RET:%.*]] = call dereferenceable_or_null(5) i8* @strndup(i8* dereferenceable(6) getelementptr inbounds ([6 x i8], [6 x i8]* @hello, i64 0, i64 0), i32 4)
; CHECK-NEXT: ret i8* [[RET]]
;
%src = getelementptr [6 x i8], [6 x i8]* @hello, i32 0, i32 0
OpenPOWER on IntegriCloud