diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp --- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp @@ -4193,7 +4193,7 @@ return replaceOperand(*II, 2, ConstantInt::get(OpIntTy, GCR.getBasePtrIndex())); } - + // Translate facts known about a pointer before relocating into // facts about the relocate value, while being careful to // preserve relocation semantics. @@ -4439,6 +4439,10 @@ Call.addAttribute(AttributeList::ReturnIndex, Attribute::getWithDereferenceableOrNullBytes( Call.getContext(), Op0C->getZExtValue())); + } else if (isAlignedAllocLikeFn(&Call, TLI) && Op1C) { + Call.addAttribute(AttributeList::ReturnIndex, + Attribute::getWithDereferenceableOrNullBytes( + Call.getContext(), Op1C->getZExtValue())); } else if (isReallocLikeFn(&Call, TLI) && Op1C) { Call.addAttribute(AttributeList::ReturnIndex, Attribute::getWithDereferenceableOrNullBytes( diff --git a/llvm/test/Transforms/InstCombine/deref-alloc-fns.ll b/llvm/test/Transforms/InstCombine/deref-alloc-fns.ll --- a/llvm/test/Transforms/InstCombine/deref-alloc-fns.ll +++ b/llvm/test/Transforms/InstCombine/deref-alloc-fns.ll @@ -7,6 +7,7 @@ declare noalias nonnull i8* @_Znam(i64) ; throwing version of 'new' declare noalias nonnull i8* @_Znwm(i64) ; throwing version of 'new' declare noalias i8* @strdup(i8*) +declare noalias i8* @aligned_alloc(i64, i64) @.str = private unnamed_addr constant [6 x i8] c"hello\00", align 1 @@ -28,6 +29,15 @@ ret i8* %call } +define noalias i8* @aligned_alloc_constant_size() { +; CHECK-LABEL: @aligned_alloc_constant_size( +; CHECK-NEXT: [[CALL:%.*]] = tail call noalias dereferenceable_or_null(512) i8* @aligned_alloc(i64 32, i64 512) +; CHECK-NEXT: ret i8* [[CALL]] +; + %call = tail call noalias i8* @aligned_alloc(i64 32, i64 512) + ret i8* %call +} + define noalias i8* @malloc_constant_size2() { ; CHECK-LABEL: @malloc_constant_size2( ; CHECK-NEXT: [[CALL:%.*]] = tail call noalias dereferenceable_or_null(80) i8* @malloc(i64 40) @@ -46,7 +56,6 @@ ret i8* %call } - define noalias i8* @malloc_constant_zero_size() { ; CHECK-LABEL: @malloc_constant_zero_size( ; CHECK-NEXT: [[CALL:%.*]] = tail call noalias i8* @malloc(i64 0) diff --git a/llvm/test/Transforms/InstCombine/malloc-free-delete.ll b/llvm/test/Transforms/InstCombine/malloc-free-delete.ll --- a/llvm/test/Transforms/InstCombine/malloc-free-delete.ll +++ b/llvm/test/Transforms/InstCombine/malloc-free-delete.ll @@ -13,8 +13,19 @@ ret i32 0 } +define i32 @dead_aligned_alloc(i32 %size, i32 %alignment, i8 %value) { +; CHECK-LABEL: @dead_aligned_alloc( +; CHECK-NEXT: ret i32 0 +; + %aligned_allocation = tail call i8* @aligned_alloc(i32 %alignment, i32 %size) + store i8 %value, i8* %aligned_allocation + tail call void @free(i8* %aligned_allocation) + ret i32 0 +} + declare noalias i8* @calloc(i32, i32) nounwind declare noalias i8* @malloc(i32) +declare noalias i8* @aligned_alloc(i32, i32) declare void @free(i8*) define i1 @foo() {