Skip to content

nuw nsw not deduced for add 1 inbounds of range-restricted length #87854

Closed
@scottmcm

Description

@scottmcm

(Context: I tried adding assumes to slice lengths in rust -- rust-lang/rust#122926 -- and was surprised that certain things didn't optimize away that I would have expected to. The example here is basically if i < slice.len() { do_something_with(i + 1); }).)

I tried the following: https://llvm.godbolt.org/z/qM5bnMxxj

define noundef i64 @src(i64 noundef %x.1, i64 noundef %i) unnamed_addr #0 {
start:
  %0 = icmp sge i64 %x.1, 0
  tail call void @llvm.assume(i1 %0)
  %inbounds = icmp ult i64 %i, %x.1
  br i1 %inbounds, label %do_something, label %done

do_something:
  %next = add i64 %i, 1  ;  <-- look here
  br label %done

done:
  %r = phi i64 [ %next, %do_something ], [-1, %start ]
  ret i64 %r
}

expecting to see the add become add nuw nsw because of the range restriction on %x.1, but it doesn't.

Alive proof that it would be ok to do so here: https://alive2.llvm.org/ce/z/3jHXNu

Activity

self-assigned this
on Apr 6, 2024
dtcxzyw

dtcxzyw commented on Apr 7, 2024

@dtcxzyw
Member

It has been supported by CVP: https://godbolt.org/z/ezdrzn4Yv.

Did you mean: https://alive2.llvm.org/ce/z/xNoymj

define i32 @src(i32 %x.1, i32 noundef %i) {
  %cond = icmp sgt i32 %x.1, -1
  tail call void @llvm.assume(i1 %cond)
  %inbounds = icmp ult i32 %i, %x.1
  %next = add i32 %i, 1
  %spec.select = select i1 %inbounds, i32 %next, i32 -1
  ret i32 %spec.select
}

define i32 @tgt(i32 %x.1, i32 noundef %i) {
  %cond = icmp sgt i32 %x.1, -1
  tail call void @llvm.assume(i1 %cond)
  %inbounds = icmp ult i32 %i, %x.1
  %next = add nuw nsw i32 %i, 1
  %spec.select = select i1 %inbounds, i32 %next, i32 -1
  ret i32 %spec.select
}
scottmcm

scottmcm commented on Apr 7, 2024

@scottmcm
Author

Did you mean

I guess so? I don't know enough about phase ordering to say confidently whether CVP can actually handle the scenario I was hitting, just that running the normal O3 passes on the provided source IR doesn't give me an output with add nuw nsw.

added a commit that references this issue on Apr 13, 2024
dtcxzyw

dtcxzyw commented on Jul 27, 2024

@dtcxzyw
Member

Closed as there is little benefit to use block value in CVP.

diff --git a/llvm/lib/Analysis/LazyValueInfo.cpp b/llvm/lib/Analysis/LazyValueInfo.cpp
index 4c023ed5ed8f..a35d250608ea 100644
--- a/llvm/lib/Analysis/LazyValueInfo.cpp
+++ b/llvm/lib/Analysis/LazyValueInfo.cpp
@@ -1531,7 +1531,7 @@ ValueLatticeElement LazyValueInfoImpl::getValueInBlock(Value *V, BasicBlock *BB,
   LLVM_DEBUG(dbgs() << "LVI Getting block end value " << *V << " at '"
                     << BB->getName() << "'\n");
 
-  assert(BlockValueStack.empty() && BlockValueSet.empty());
+  // assert(BlockValueStack.empty() && BlockValueSet.empty());
   std::optional<ValueLatticeElement> OptResult = getBlockValue(V, BB, CxtI);
   if (!OptResult) {
     solve();
@@ -1601,12 +1601,12 @@ ValueLatticeElement LazyValueInfoImpl::getValueAtUse(const Use &U) {
         break;
       if (CurrU->getOperandNo() == 1)
         CondVal =
-            *getValueFromCondition(V, SI->getCondition(), /*IsTrueDest*/ true,
-                                   /*UseBlockValue*/ false);
+            getValueFromCondition(V, SI->getCondition(), /*IsTrueDest=*/true,
+                                   /*UseBlockValue=*/true);
       else if (CurrU->getOperandNo() == 2)
         CondVal =
-            *getValueFromCondition(V, SI->getCondition(), /*IsTrueDest*/ false,
-                                   /*UseBlockValue*/ false);
+            getValueFromCondition(V, SI->getCondition(), /*IsTrueDest=*/false,
+                                   /*UseBlockValue=*/true);
     } else if (auto *PHI = dyn_cast<PHINode>(CurrI)) {
       // TODO: Use non-local query?
       CondVal = *getEdgeValueLocal(V, PHI->getIncomingBlock(*CurrU),
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

    Development

    No branches or pull requests

      Participants

      @dtcxzyw@scottmcm

      Issue actions

        `nuw nsw` not deduced for `add 1` inbounds of range-restricted length · Issue #87854 · llvm/llvm-project