[Attributor] Only non-exact accesses require a uniform bit-pattern (=0)
authorJohannes Doerfert <johannes@jdoerfert.de>
Sun, 10 Jul 2022 18:46:42 +0000 (13:46 -0500)
committerJohannes Doerfert <johannes@jdoerfert.de>
Wed, 20 Jul 2022 22:34:50 +0000 (17:34 -0500)
If we only have exact accesses we should never require the bit-pattern
to be uniform (in this case 0). Only a non-exact access should force us
to require only 0 values.

llvm/lib/Transforms/IPO/Attributor.cpp
llvm/test/Transforms/Attributor/value-simplify-gpu.ll

index aaaadf9..952c188 100644 (file)
@@ -378,13 +378,13 @@ static bool getPotentialCopiesOfMemoryValue(
 
     bool NullOnly = true;
     bool NullRequired = false;
-    auto CheckForNullOnlyAndUndef = [&](Optional<Value *> V) {
+    auto CheckForNullOnlyAndUndef = [&](Optional<Value *> V, bool IsExact) {
       if (!V || *V == nullptr)
         NullOnly = false;
       else if (isa<UndefValue>(*V))
         /* No op */;
       else if (isa<Constant>(*V) && cast<Constant>(*V)->isNullValue())
-        NullRequired = true;
+        NullRequired = !IsExact;
       else
         NullOnly = false;
     };
@@ -395,7 +395,7 @@ static bool getPotentialCopiesOfMemoryValue(
         LLVM_DEBUG(dbgs() << "Failed to get initial value: " << *Obj << "\n");
         return false;
       }
-      CheckForNullOnlyAndUndef(InitialValue);
+      CheckForNullOnlyAndUndef(InitialValue, /* IsExact */ true);
       NewCopies.push_back(InitialValue);
       NewCopyOrigins.push_back(nullptr);
     }
@@ -405,7 +405,7 @@ static bool getPotentialCopiesOfMemoryValue(
         return true;
       if (IsLoad && Acc.isWrittenValueYetUndetermined())
         return true;
-      CheckForNullOnlyAndUndef(Acc.getContent());
+      CheckForNullOnlyAndUndef(Acc.getContent(), IsExact);
       if (OnlyExact && !IsExact && !NullOnly &&
           !isa_and_nonnull<UndefValue>(Acc.getWrittenValue())) {
         LLVM_DEBUG(dbgs() << "Non exact access " << *Acc.getRemoteInst()
index 0ef99fc..fa19fe6 100644 (file)
@@ -288,7 +288,7 @@ define internal void @level2a(i32* %addr) {
 ; IS__TUNIT____-NEXT:  entry:
 ; IS__TUNIT____-NEXT:    [[TMP0:%.*]] = load i32, i32* addrspacecast (i32 addrspace(3)* @ReachableNonKernel to i32*), align 4
 ; IS__TUNIT____-NEXT:    [[TMP1:%.*]] = load i32, i32* addrspacecast (i32 addrspace(3)* @UnreachableNonKernel to i32*), align 4
-; IS__TUNIT____-NEXT:    call void @use(i32 [[TMP0]], i32 [[TMP1]], i32 17) #[[ATTR6]]
+; IS__TUNIT____-NEXT:    call void @use(i32 noundef [[TMP0]], i32 noundef [[TMP1]], i32 17) #[[ATTR6]]
 ; IS__TUNIT____-NEXT:    ret void
 ;
 ; IS__CGSCC____: Function Attrs: nosync nounwind
@@ -298,7 +298,7 @@ define internal void @level2a(i32* %addr) {
 ; IS__CGSCC____-NEXT:    [[TMP0:%.*]] = load i32, i32* addrspacecast (i32 addrspace(3)* @ReachableNonKernel to i32*), align 4
 ; IS__CGSCC____-NEXT:    [[TMP1:%.*]] = load i32, i32* addrspacecast (i32 addrspace(3)* @UnreachableNonKernel to i32*), align 4
 ; IS__CGSCC____-NEXT:    [[QQQQ2:%.*]] = load i32, i32* [[ADDR]], align 4
-; IS__CGSCC____-NEXT:    call void @use(i32 [[TMP0]], i32 [[TMP1]], i32 [[QQQQ2]]) #[[ATTR4]]
+; IS__CGSCC____-NEXT:    call void @use(i32 noundef [[TMP0]], i32 noundef [[TMP1]], i32 [[QQQQ2]]) #[[ATTR4]]
 ; IS__CGSCC____-NEXT:    ret void
 ;
 entry:
@@ -316,7 +316,7 @@ define internal void @level2b(i32* %addr) {
 ; IS__TUNIT____-NEXT:  entry:
 ; IS__TUNIT____-NEXT:    [[TMP0:%.*]] = load i32, i32* addrspacecast (i32 addrspace(3)* @ReachableNonKernel to i32*), align 4
 ; IS__TUNIT____-NEXT:    [[TMP1:%.*]] = load i32, i32* addrspacecast (i32 addrspace(3)* @UnreachableNonKernel to i32*), align 4
-; IS__TUNIT____-NEXT:    call void @use(i32 [[TMP0]], i32 [[TMP1]], i32 17) #[[ATTR6]]
+; IS__TUNIT____-NEXT:    call void @use(i32 noundef [[TMP0]], i32 noundef [[TMP1]], i32 17) #[[ATTR6]]
 ; IS__TUNIT____-NEXT:    ret void
 ;
 ; IS__CGSCC____: Function Attrs: nosync nounwind
@@ -326,7 +326,7 @@ define internal void @level2b(i32* %addr) {
 ; IS__CGSCC____-NEXT:    [[TMP0:%.*]] = load i32, i32* addrspacecast (i32 addrspace(3)* @ReachableNonKernel to i32*), align 4
 ; IS__CGSCC____-NEXT:    [[TMP1:%.*]] = load i32, i32* addrspacecast (i32 addrspace(3)* @UnreachableNonKernel to i32*), align 4
 ; IS__CGSCC____-NEXT:    [[TMP2:%.*]] = load i32, i32* [[ADDR]], align 4
-; IS__CGSCC____-NEXT:    call void @use(i32 [[TMP0]], i32 [[TMP1]], i32 [[TMP2]]) #[[ATTR4]]
+; IS__CGSCC____-NEXT:    call void @use(i32 noundef [[TMP0]], i32 noundef [[TMP1]], i32 [[TMP2]]) #[[ATTR4]]
 ; IS__CGSCC____-NEXT:    ret void
 ;
 entry: