[llvm] db35789 - Infer dereferenceability from malloc and friends

Philip Reames via llvm-commits llvm-commits at lists.llvm.org
Thu Apr 1 11:33:44 PDT 2021


Author: Philip Reames
Date: 2021-04-01T11:33:35-07:00
New Revision: db357891f0cf76253be3cd75f682b68544a411da

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

LOG: Infer dereferenceability from malloc and friends

Hookup TLI when inferring object size from allocation calls. This allows the analysis to prove dereferenceability for known allocation functions (such as malloc/new/etc) in addition to those marked explicitly with the allocsize attribute.

This is a follow up to 0129cd5 now that the bug fixed by e2c6621e6 is resolved.

As noted in the test, this relies on being able to prove that there is no free between allocation and context (e.g. hoist location). At the moment, this is handled conservatively. I'm working strengthening out ability to reason about no-free regions separately.

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

Added: 
    

Modified: 
    llvm/lib/Analysis/Loads.cpp
    llvm/test/Transforms/LICM/hoist-alloc.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Analysis/Loads.cpp b/llvm/lib/Analysis/Loads.cpp
index 771c9e4f1311..9a0211fd50e3 100644
--- a/llvm/lib/Analysis/Loads.cpp
+++ b/llvm/lib/Analysis/Loads.cpp
@@ -162,8 +162,7 @@ static bool isDereferenceableAndAlignedPointer(
     Opts.RoundToAlign = false;
     Opts.NullIsUnknownSize = true;
     uint64_t ObjSize;
-    // TODO: Plumb through TLI so that malloc routines and such work.
-    if (getObjectSize(V, ObjSize, DL, nullptr, Opts)) {
+    if (getObjectSize(V, ObjSize, DL, TLI, Opts)) {
       APInt KnownDerefBytes(Size.getBitWidth(), ObjSize);
       if (KnownDerefBytes.getBoolValue() && KnownDerefBytes.uge(Size) &&
           isKnownNonZero(V, DL, 0, nullptr, CtxI, DT) && !V->canBeFreed()) {

diff  --git a/llvm/test/Transforms/LICM/hoist-alloc.ll b/llvm/test/Transforms/LICM/hoist-alloc.ll
index 9eb9c8f9aa8a..04992c993686 100644
--- a/llvm/test/Transforms/LICM/hoist-alloc.ll
+++ b/llvm/test/Transforms/LICM/hoist-alloc.ll
@@ -130,7 +130,8 @@ for.end:
   ret i8 %res
 }
 
-; TODO: We can hoist the load in this case.
+; TODO: We can hoist the load in this case, but only once we have
+; some form of context sensitive free analysis.
 define i8 @test_hoist_malloc() {
 ; CHECK-LABEL: @test_hoist_malloc(
 ; CHECK-NEXT:  entry:
@@ -171,18 +172,17 @@ for.end:
   ret i8 %res
 }
 
-; TODO: We can hoist the load in this case.
-define i8 @test_hoist_malloc_leak() {
+define i8 @test_hoist_malloc_leak() nofree nosync {
 ; CHECK-LABEL: @test_hoist_malloc_leak(
 ; CHECK-NEXT:  entry:
 ; CHECK-NEXT:    [[A_RAW:%.*]] = call nonnull i8* @malloc(i64 32)
 ; CHECK-NEXT:    call void @init(i8* [[A_RAW]])
 ; CHECK-NEXT:    [[ADDR:%.*]] = getelementptr i8, i8* [[A_RAW]], i32 31
+; CHECK-NEXT:    [[RES:%.*]] = load i8, i8* [[ADDR]], align 1
 ; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
 ; CHECK:       for.body:
 ; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ [[IV_NEXT:%.*]], [[FOR_BODY]] ], [ 0, [[ENTRY:%.*]] ]
 ; CHECK-NEXT:    call void @unknown()
-; CHECK-NEXT:    [[RES:%.*]] = load i8, i8* [[ADDR]], align 1
 ; CHECK-NEXT:    call void @use(i8 [[RES]])
 ; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
 ; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp eq i64 [[IV_NEXT]], 200


        


More information about the llvm-commits mailing list