[Attributor] Handle special case when offset equals zero in nonnull deduction
authorHideto Ueno <uenoku.tokotoko@gmail.com>
Wed, 27 Nov 2019 14:41:12 +0000 (14:41 +0000)
committerHideto Ueno <uenoku.tokotoko@gmail.com>
Wed, 27 Nov 2019 14:45:16 +0000 (14:45 +0000)
llvm/lib/Transforms/IPO/Attributor.cpp
llvm/test/Transforms/FunctionAttrs/align.ll

index 366c347..faf0cdf 100644 (file)
@@ -308,15 +308,16 @@ static const Value *getPointerOperand(const Instruction *I) {
 
   return nullptr;
 }
-static const Value *getBasePointerOfAccessPointerOperand(const Instruction *I,
-                                                         int64_t &BytesOffset,
-                                                         const DataLayout &DL) {
+static const Value *
+getBasePointerOfAccessPointerOperand(const Instruction *I, int64_t &BytesOffset,
+                                     const DataLayout &DL,
+                                     bool AllowNonInbounds = false) {
   const Value *Ptr = getPointerOperand(I);
   if (!Ptr)
     return nullptr;
 
   return GetPointerBaseWithConstantOffset(Ptr, BytesOffset, DL,
-                                          /*AllowNonInbounds*/ false);
+                                          AllowNonInbounds);
 }
 
 ChangeStatus AbstractAttribute::update(Attributor &A) {
@@ -1702,8 +1703,7 @@ static int64_t getKnownNonNullAndDerefBytesForUse(
     return 0;
   }
   if (auto *GEP = dyn_cast<GetElementPtrInst>(I))
-    if (GEP->hasAllZeroIndices() ||
-        (GEP->isInBounds() && GEP->hasAllConstantIndices())) {
+    if (GEP->hasAllConstantIndices()) {
       TrackUse = true;
       return 0;
     }
@@ -1718,6 +1718,18 @@ static int64_t getKnownNonNullAndDerefBytesForUse(
       return std::max(int64_t(0), DerefBytes);
     }
   }
+
+  /// Corner case when an offset is 0.
+  if (const Value *Base = getBasePointerOfAccessPointerOperand(
+          I, Offset, DL, /*AllowNonInbounds*/ true)) {
+    if (Offset == 0 && Base == &AssociatedValue &&
+        getPointerOperand(I) == UseV) {
+      int64_t DerefBytes =
+          (int64_t)DL.getTypeStoreSize(PtrTy->getPointerElementType());
+      IsNonNull |= !NullPointerIsDefined;
+      return std::max(int64_t(0), DerefBytes);
+    }
+  }
   if (const Value *Base =
           GetPointerBaseWithConstantOffset(UseV, Offset, DL,
                                            /*AllowNonInbounds*/ false)) {
index b8817a4..a5bf919 100644 (file)
@@ -351,8 +351,7 @@ define i64 @test12-1(i32* align 4 %p) {
   ret i64 %ret
 }
 
-; FXIME: %p should have nonnull
-; ATTRIBUTOR: define i64 @test12-2(i32* nocapture nofree readonly align 16 %p)
+; ATTRIBUTOR: define i64 @test12-2(i32* nocapture nofree nonnull readonly align 16 dereferenceable(8) %p)
 define i64 @test12-2(i32* align 4 %p) {
   %p-cast = bitcast i32* %p to i64*
   %arrayidx0 = getelementptr i64, i64* %p-cast, i64 0
@@ -370,8 +369,7 @@ define void @test12-3(i32* align 4 %p) {
   ret void 
 }
 
-; FXIME: %p should have nonnull
-; ATTRIBUTOR: define void @test12-4(i32* nocapture nofree writeonly align 16 %p)
+; ATTRIBUTOR: define void @test12-4(i32* nocapture nofree nonnull writeonly align 16 dereferenceable(8) %p)
 define void @test12-4(i32* align 4 %p) {
   %p-cast = bitcast i32* %p to i64*
   %arrayidx0 = getelementptr i64, i64* %p-cast, i64 0