[llvm] [LLVM][LangRef] Redefine out-of-range stepvector values as being truncated. (PR #173494)
Paul Walker via llvm-commits
llvm-commits at lists.llvm.org
Wed Dec 24 06:33:47 PST 2025
https://github.com/paulwalker-arm updated https://github.com/llvm/llvm-project/pull/173494
>From c8f48b5bc34a82c6d6eab03794d8d6ee79a1a0dd Mon Sep 17 00:00:00 2001
From: Paul Walker <paul.walker at arm.com>
Date: Wed, 24 Dec 2025 13:47:51 +0000
Subject: [PATCH 1/2] [LLVM][LangRef] Redefine out-of-range stepvector values
as being truncated.
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.
---
llvm/docs/LangRef.rst | 2 +-
llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp | 2 +-
llvm/test/Transforms/InstCombine/vscale_extractelement.ll | 7 +++++--
3 files changed, 7 insertions(+), 4 deletions(-)
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()
>From 1f351807a9616182d64b62cd4db28c9da64a79c1 Mon Sep 17 00:00:00 2001
From: Paul Walker <paul.walker at arm.com>
Date: Wed, 24 Dec 2025 14:33:00 +0000
Subject: [PATCH 2/2] Update comment removing reference to out-of-range values
being undefined.
---
llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp b/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp
index f5e8d341e3493..4dcd9751ad0f5 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp
@@ -444,7 +444,8 @@ Instruction *InstCombinerImpl::visitExtractElementInst(ExtractElementInst &EI) {
unsigned BitWidth = Ty->getIntegerBitWidth();
Value *Idx;
// Return index when its value does not exceed the allowed limit
- // for the element type of the vector, otherwise return undefined.
+ // for the element type of the vector.
+ // TODO: Truncate out-of-range values.
if (IndexC->getValue().getActiveBits() <= BitWidth)
Idx = ConstantInt::get(Ty, IndexC->getValue().zextOrTrunc(BitWidth));
else
More information about the llvm-commits
mailing list