diff options
-rw-r--r-- | llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp | 27 | ||||
-rw-r--r-- | llvm/test/Transforms/InstCombine/objsize.ll | 2 | ||||
-rw-r--r-- | llvm/test/Transforms/InstCombine/strndup.ll | 2 |
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 |