[llvm] [LLVM][LangRef] Redefine out-of-range stepvector values as being truncated. (PR #173494)

via llvm-commits llvm-commits at lists.llvm.org
Wed Dec 24 06:15:46 PST 2025


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-llvm-transforms

Author: Paul Walker (paulwalker-arm)

<details>
<summary>Changes</summary>

The LangRef current defines out-of-range stepvector values as poison. This property is at odds with both the expansion used for fixed-length vectors and the equivalent ISD node, both of which implicitly truncate out-of-range values.

NOTE: In order to keep the PR mostly NFC I would like to defer the follow extensions to seperate PRs.

1) The new definition means the "8-bit" restriction can be lifted
   because that only existed due to problematic cases like
   `<vscale x n x i1> stepvector()`, which by definition is mostly poison.
   Defering because I'm unsure of the code generation support for
   smaller types, as a minimum we're missing test coverage.

2) The instcombine can fire in many more case, and the current constant
   handling can be a simplification rather than a combine.

---
Full diff: https://github.com/llvm/llvm-project/pull/173494.diff


3 Files Affected:

- (modified) llvm/docs/LangRef.rst (+1-1) 
- (modified) llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp (+1-1) 
- (modified) llvm/test/Transforms/InstCombine/vscale_extractelement.ll (+5-2) 


``````````diff
diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst
index d99280f05e73f..5b462b87acb0f 100644
--- a/llvm/docs/LangRef.rst
+++ b/llvm/docs/LangRef.rst
@@ -20828,7 +20828,7 @@ of integers whose elements contain a linear sequence of values starting from 0
 with a step of 1. This intrinsic can only be used for vectors with integer
 elements that are at least 8 bits in size. If the sequence value exceeds
 the allowed limit for the element type then the result for that lane is
-a poison value.
+truncated.
 
 These intrinsics work for both fixed and scalable vectors. While this intrinsic
 supports all vector types, the recommended way to express this operation for
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp b/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp
index 98e2d9ebe4fc2..f5e8d341e3493 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp
@@ -448,7 +448,7 @@ Instruction *InstCombinerImpl::visitExtractElementInst(ExtractElementInst &EI) {
         if (IndexC->getValue().getActiveBits() <= BitWidth)
           Idx = ConstantInt::get(Ty, IndexC->getValue().zextOrTrunc(BitWidth));
         else
-          Idx = PoisonValue::get(Ty);
+          return nullptr;
         return replaceInstUsesWith(EI, Idx);
       }
     }
diff --git a/llvm/test/Transforms/InstCombine/vscale_extractelement.ll b/llvm/test/Transforms/InstCombine/vscale_extractelement.ll
index 9ac8a92abb689..ec58307a253d1 100644
--- a/llvm/test/Transforms/InstCombine/vscale_extractelement.ll
+++ b/llvm/test/Transforms/InstCombine/vscale_extractelement.ll
@@ -214,12 +214,15 @@ entry:
   ret i64 %1
 }
 
-; Check that poison is returned when the extracted element has wrapped.
+; TODO: stepvector now wraps rather than poisons elements when the value does
+; not fit, so this should return 0.
 
 define i8 @ext_lane256_from_stepvec() {
 ; CHECK-LABEL: @ext_lane256_from_stepvec(
 ; CHECK-NEXT:  entry:
-; CHECK-NEXT:    ret i8 poison
+; CHECK-NEXT:    [[TMP0:%.*]] = call <vscale x 512 x i8> @llvm.stepvector.nxv512i8()
+; CHECK-NEXT:    [[TMP1:%.*]] = extractelement <vscale x 512 x i8> [[TMP0]], i64 256
+; CHECK-NEXT:    ret i8 [[TMP1]]
 ;
 entry:
   %0 = call <vscale x 512 x i8> @llvm.stepvector.nxv512i8()

``````````

</details>


https://github.com/llvm/llvm-project/pull/173494


More information about the llvm-commits mailing list