[llvm] 5859ae6 - [Attributor][FIX] Use maximal access for dereferenceability deduction

Johannes Doerfert via llvm-commits llvm-commits at lists.llvm.org
Sun Mar 6 19:29:24 PST 2022


Author: Johannes Doerfert
Date: 2022-03-06T21:28:38-06:00
New Revision: 5859ae6a5dbe341cd5fae963644ce40ad083e592

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

LOG: [Attributor][FIX] Use maximal access for dereferenceability deduction

While we can use range information when we derive dereferenceability we
must make sure to pick he right end of the range. Before we always went
with the minimal offset, which is not correct if we want to combine
the base dereferenceability with some offset. In that case it's the
maximum that gives the correct result.

Added: 
    

Modified: 
    llvm/lib/Transforms/IPO/AttributorAttributes.cpp
    llvm/test/Transforms/Attributor/dereferenceable-1.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/IPO/AttributorAttributes.cpp b/llvm/lib/Transforms/IPO/AttributorAttributes.cpp
index 00b953a7e3711..1910500aa30f7 100644
--- a/llvm/lib/Transforms/IPO/AttributorAttributes.cpp
+++ b/llvm/lib/Transforms/IPO/AttributorAttributes.cpp
@@ -440,10 +440,11 @@ bool AA::getAssumedUnderlyingObjects(Attributor &A, const Value &Ptr,
   return true;
 }
 
-const Value *stripAndAccumulateMinimalOffsets(
-    Attributor &A, const AbstractAttribute &QueryingAA, const Value *Val,
-    const DataLayout &DL, APInt &Offset, bool AllowNonInbounds,
-    bool UseAssumed = false) {
+static const Value *
+stripAndAccumulateOffsets(Attributor &A, const AbstractAttribute &QueryingAA,
+                          const Value *Val, const DataLayout &DL, APInt &Offset,
+                          bool GetMinOffset, bool AllowNonInbounds,
+                          bool UseAssumed = false) {
 
   auto AttributorAnalysis = [&](Value &V, APInt &ROffset) -> bool {
     const IRPosition &Pos = IRPosition::value(V);
@@ -456,12 +457,15 @@ const Value *stripAndAccumulateMinimalOffsets(
                                      : ValueConstantRangeAA.getKnown();
     // We can only use the lower part of the range because the upper part can
     // be higher than what the value can really be.
-    ROffset = Range.getSignedMin();
+    if (GetMinOffset)
+      ROffset = Range.getSignedMin();
+    else
+      ROffset = Range.getSignedMax();
     return true;
   };
 
   return Val->stripAndAccumulateConstantOffsets(DL, Offset, AllowNonInbounds,
-                                                /* AllowInvariant */ false,
+                                                /* AllowInvariant */ true,
                                                 AttributorAnalysis);
 }
 
@@ -470,8 +474,9 @@ getMinimalBaseOfPointer(Attributor &A, const AbstractAttribute &QueryingAA,
                         const Value *Ptr, int64_t &BytesOffset,
                         const DataLayout &DL, bool AllowNonInbounds = false) {
   APInt OffsetAPInt(DL.getIndexTypeSizeInBits(Ptr->getType()), 0);
-  const Value *Base = stripAndAccumulateMinimalOffsets(
-      A, QueryingAA, Ptr, DL, OffsetAPInt, AllowNonInbounds);
+  const Value *Base =
+      stripAndAccumulateOffsets(A, QueryingAA, Ptr, DL, OffsetAPInt,
+                                /* GetMinOffset */ true, AllowNonInbounds);
 
   BytesOffset = OffsetAPInt.getSExtValue();
   return Base;
@@ -4274,8 +4279,9 @@ struct AADereferenceableFloating : AADereferenceableImpl {
       unsigned IdxWidth =
           DL.getIndexSizeInBits(V.getType()->getPointerAddressSpace());
       APInt Offset(IdxWidth, 0);
-      const Value *Base =
-          stripAndAccumulateMinimalOffsets(A, *this, &V, DL, Offset, false);
+      const Value *Base = stripAndAccumulateOffsets(
+          A, *this, &V, DL, Offset, /* GetMinOffset */ false,
+          /* AllowNonInbounds */ true);
 
       const auto &AA = A.getAAFor<AADereferenceable>(
           *this, IRPosition::value(*Base), DepClassTy::REQUIRED);

diff  --git a/llvm/test/Transforms/Attributor/dereferenceable-1.ll b/llvm/test/Transforms/Attributor/dereferenceable-1.ll
index b0a2195a44cfb..df88b174c9413 100644
--- a/llvm/test/Transforms/Attributor/dereferenceable-1.ll
+++ b/llvm/test/Transforms/Attributor/dereferenceable-1.ll
@@ -10,6 +10,9 @@ declare void @deref_phi_user(i32* %a);
 ; TEST 1
 ; take mininimum of return values
 ;
+;.
+; CHECK: @[[G:[a-zA-Z0-9_$"\\.-]+]] = global i64 0
+;.
 define i32* @test1(i32* dereferenceable(4) %0, double* dereferenceable(8) %1, i1 zeroext %2) local_unnamed_addr {
 ; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
 ; CHECK-LABEL: define {{[^@]+}}@test1
@@ -915,6 +918,32 @@ declare void @unknown_use8(i8*) willreturn nounwind
 declare void @unknown_use32(i32*) willreturn nounwind
 declare void @llvm.assume(i1)
 
+ at g = global i64 0
+define void @max_offset(i1 %c) {
+; CHECK: Function Attrs: nounwind willreturn
+; CHECK-LABEL: define {{[^@]+}}@max_offset
+; CHECK-SAME: (i1 [[C:%.*]]) #[[ATTR1]] {
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
+; CHECK:       t:
+; CHECK-NEXT:    br label [[F]]
+; CHECK:       f:
+; CHECK-NEXT:    [[PHI:%.*]] = phi i8* [ getelementptr (i8, i8* bitcast (i64* @g to i8*), i64 2), [[T]] ], [ bitcast (i64* @g to i8*), [[ENTRY:%.*]] ]
+; CHECK-NEXT:    call void @unknown_use8(i8* noundef align 2 dereferenceable_or_null(6) [[PHI]]) #[[ATTR1]]
+; CHECK-NEXT:    ret void
+;
+entry:
+  %bc = bitcast i64* @g to i8*
+  br i1 %c, label %t, label %f
+t:
+  %gep = getelementptr i8, i8* %bc, i64 2
+  br label %f
+f:
+  %phi = phi i8* [%gep, %t], [%bc, %entry]
+  call void @unknown_use8(i8* %phi)
+  ret void
+}
+
 !0 = !{i64 10, i64 100}
 
 ;.


        


More information about the llvm-commits mailing list