[llvm] 7f8dcfa - [LVI] Do not walk past cross-lane ops while determining value range (#207711)

via llvm-commits llvm-commits at lists.llvm.org
Mon Jul 6 06:06:07 PDT 2026


Author: Antonio Frighetto
Date: 2026-07-06T15:06:03+02:00
New Revision: 7f8dcfacbbcd77a8ddf512fa31589af1bf1f6ef4

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

LOG: [LVI] Do not walk past cross-lane ops while determining value range (#207711)

While walking the one-use chain to find a constraining select
in `getValueAtUse`, do not look through cross-lane operations,
as they may move wrapping lanes into positions where the select
condition is true, and inferring nowrap flags would be unsound.

Fixes: https://github.com/llvm/llvm-project/issues/207619.

Added: 
    

Modified: 
    llvm/lib/Analysis/LazyValueInfo.cpp
    llvm/test/Transforms/CorrelatedValuePropagation/vectors.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Analysis/LazyValueInfo.cpp b/llvm/lib/Analysis/LazyValueInfo.cpp
index f092f7c5913b5..053144c42341f 100644
--- a/llvm/lib/Analysis/LazyValueInfo.cpp
+++ b/llvm/lib/Analysis/LazyValueInfo.cpp
@@ -1889,6 +1889,11 @@ ValueLatticeElement LazyValueInfoImpl::getValueAtUse(const Use &U) {
         !isSafeToSpeculativelyExecuteWithVariableReplaced(
             CurrI, /*IgnoreUBImplyingAttrs=*/false))
       break;
+    // Also stop walking at cross-lane operations, since they may rearrange
+    // lanes so that a later select per-lane condition might no longer
+    // correspond to the original value's lanes.
+    if (V->getType()->isVectorTy() && !isNotCrossLaneOperation(CurrI))
+      break;
     CurrU = &*CurrI->use_begin();
   }
   return VL;

diff  --git a/llvm/test/Transforms/CorrelatedValuePropagation/vectors.ll b/llvm/test/Transforms/CorrelatedValuePropagation/vectors.ll
index b3a5fb6bcbc23..1873ab0cd30a6 100644
--- a/llvm/test/Transforms/CorrelatedValuePropagation/vectors.ll
+++ b/llvm/test/Transforms/CorrelatedValuePropagation/vectors.ll
@@ -390,3 +390,44 @@ define <2 x i16> @insertelement_constexpr() {
   %ins = insertelement <2 x i16> poison, i16 ptrtoint (ptr @g to i16), i32 0
   ret <2 x i16> %ins
 }
+
+; Cannot infer nowrap flags, as shufflevector moves the wrapping lane (0 - 1) to a position
+; where the select condition is true.
+define <2 x i16> @select_of_shufflevector() {
+; CHECK-LABEL: define <2 x i16> @select_of_shufflevector() {
+; CHECK-NEXT:  [[ENTRY:.*:]]
+; CHECK-NEXT:    [[V:%.*]] = bitcast <1 x i32> splat (i32 1) to <2 x i16>
+; CHECK-NEXT:    [[CMP:%.*]] = icmp eq <2 x i16> [[V]], zeroinitializer
+; CHECK-NEXT:    [[NEG:%.*]] = sub <2 x i16> zeroinitializer, [[V]]
+; CHECK-NEXT:    [[SHUFFLE:%.*]] = shufflevector <2 x i16> [[NEG]], <2 x i16> zeroinitializer, <2 x i32> <i32 1, i32 0>
+; CHECK-NEXT:    [[SELECT:%.*]] = select <2 x i1> [[CMP]], <2 x i16> [[SHUFFLE]], <2 x i16> zeroinitializer
+; CHECK-NEXT:    ret <2 x i16> [[SELECT]]
+;
+entry:
+  %v = bitcast <1 x i32> <i32 1> to <2 x i16>
+  %cmp = icmp eq <2 x i16> %v, zeroinitializer
+  %neg = sub <2 x i16> zeroinitializer, %v
+  %shuffle = shufflevector <2 x i16> %neg, <2 x i16> zeroinitializer, <2 x i32> <i32 1, i32 0>
+  %select = select <2 x i1> %cmp, <2 x i16> %shuffle, <2 x i16> zeroinitializer
+  ret <2 x i16> %select
+}
+
+; Could infer nowrap flags, as shufflevector reads the non-wrapping lane, yet conservatively do not.
+define <2 x i16> @select_of_shufflevector_2() {
+; CHECK-LABEL: define <2 x i16> @select_of_shufflevector_2() {
+; CHECK-NEXT:  [[ENTRY:.*:]]
+; CHECK-NEXT:    [[V:%.*]] = bitcast <1 x i32> splat (i32 1) to <2 x i16>
+; CHECK-NEXT:    [[CMP:%.*]] = icmp eq <2 x i16> [[V]], zeroinitializer
+; CHECK-NEXT:    [[NEG:%.*]] = sub <2 x i16> zeroinitializer, [[V]]
+; CHECK-NEXT:    [[SHUFFLE:%.*]] = shufflevector <2 x i16> [[NEG]], <2 x i16> zeroinitializer, <2 x i32> <i32 1, i32 0>
+; CHECK-NEXT:    [[SELECT:%.*]] = select <2 x i1> [[CMP]], <2 x i16> [[SHUFFLE]], <2 x i16> zeroinitializer
+; CHECK-NEXT:    ret <2 x i16> [[SELECT]]
+;
+entry:
+  %v = bitcast <1 x i32> <i32 1> to <2 x i16>
+  %cmp = icmp eq <2 x i16> %v, zeroinitializer
+  %neg = sub <2 x i16> zeroinitializer, %v
+  %shuffle = shufflevector <2 x i16> %neg, <2 x i16> zeroinitializer, <2 x i32> <i32 1, i32 0>
+  %select = select <2 x i1> %cmp, <2 x i16> %shuffle, <2 x i16> zeroinitializer
+  ret <2 x i16> %select
+}


        


More information about the llvm-commits mailing list