[llvm] dc817b2 - [InstCombine] Deduce attributes for aligned_alloc in InstCombine

Uday Bondhugula via llvm-commits llvm-commits at lists.llvm.org
Tue Mar 31 10:48:00 PDT 2020


Author: Uday Bondhugula
Date: 2020-03-31T23:17:28+05:30
New Revision: dc817b2dea9f28e22470d1d74956f404fcec4e01

URL: https://github.com/llvm/llvm-project/commit/dc817b2dea9f28e22470d1d74956f404fcec4e01
DIFF: https://github.com/llvm/llvm-project/commit/dc817b2dea9f28e22470d1d74956f404fcec4e01.diff

LOG: [InstCombine] Deduce attributes for aligned_alloc in InstCombine

Make InstCombine aware of the aligned_alloc library function.

Signed-off-by: Uday Bondhugula <uday at polymagelabs.com>

Depends on D76970.

Differential Revision: https://reviews.llvm.org/D76971

Added: 
    

Modified: 
    llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
    llvm/test/Transforms/InstCombine/deref-alloc-fns.ll
    llvm/test/Transforms/InstCombine/malloc-free-delete.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
index abbc878f106c..4ad0f8d80ac3 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
@@ -4441,7 +4441,8 @@ static void annotateAnyAllocSite(CallBase &Call, const TargetLibraryInfo *TLI) {
   ConstantInt *Op0C = dyn_cast<ConstantInt>(Call.getOperand(0));
   ConstantInt *Op1C =
       (NumArgs == 1) ? nullptr : dyn_cast<ConstantInt>(Call.getOperand(1));
-  // Bail out if the allocation size is zero.
+  // Bail out if the allocation size is zero (or an invalid alignment of zero
+  // with aligned_alloc).
   if ((Op0C && Op0C->isNullValue()) || (Op1C && Op1C->isNullValue()))
     return;
 
@@ -4454,6 +4455,18 @@ static void annotateAnyAllocSite(CallBase &Call, const TargetLibraryInfo *TLI) {
       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()));
+    // Add alignment attribute if alignment is a power of two constant.
+    if (Op0C) {
+      uint64_t AlignmentVal = Op0C->getZExtValue();
+      if (llvm::isPowerOf2_64(AlignmentVal))
+        Call.addAttribute(AttributeList::ReturnIndex,
+                          Attribute::getWithAlignment(Call.getContext(),
+                                                      Align(AlignmentVal)));
+    }
   } 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
index efaf1cd1604d..9d9964de2e00 100644
--- a/llvm/test/Transforms/InstCombine/deref-alloc-fns.ll
+++ b/llvm/test/Transforms/InstCombine/deref-alloc-fns.ll
@@ -7,6 +7,7 @@ declare noalias i8* @realloc(i8* nocapture, i64)
 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,31 @@ define noalias i8* @malloc_constant_size() {
   ret i8* %call
 }
 
+define noalias i8* @aligned_alloc_constant_size() {
+; CHECK-LABEL: @aligned_alloc_constant_size(
+; CHECK-NEXT:    [[CALL:%.*]] = tail call noalias align 32 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
+}
+
+declare noalias i8* @foo(i8*, i8*, i8*)
+
+define noalias i8* @aligned_alloc_dynamic_args(i64 %align, i64 %size) {
+; CHECK-LABEL: @aligned_alloc_dynamic_args(
+; CHECK-NEXT:    tail call noalias dereferenceable_or_null(1024) i8* @aligned_alloc(i64 %{{.*}}, i64 1024)
+; CHECK-NEXT:    tail call noalias i8* @aligned_alloc(i64 0, i64 1024)
+; CHECK-NEXT:    tail call noalias i8* @aligned_alloc(i64 32, i64 %{{.*}})
+;
+  %call = tail call noalias i8* @aligned_alloc(i64 %align, i64 1024)
+  %call_1 = tail call noalias i8* @aligned_alloc(i64 0, i64 1024)
+  %call_2 = tail call noalias i8* @aligned_alloc(i64 32, i64 %size)
+
+  call i8* @foo(i8* %call, i8* %call_1, i8* %call_2)
+  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 +72,6 @@ define noalias i8* @malloc_constant_size3() {
   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
index 7f6d7b4b2832..2f4447b65118 100644
--- a/llvm/test/Transforms/InstCombine/malloc-free-delete.ll
+++ b/llvm/test/Transforms/InstCombine/malloc-free-delete.ll
@@ -13,8 +13,19 @@ define i32 @main(i32 %argc, i8** %argv) {
   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() {


        


More information about the llvm-commits mailing list