[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