Skip to content

Commit b0cc47c

Browse files
[InstCombine] Remove scalable vector extracts to and from the same type (llvm#69702)
visitCallInst already looks for fixed width vector extracts where number of elements in the source and destination types are equal. This patch modifies the function to also identify scalable extracts which can be removed.
1 parent dc53410 commit b0cc47c

File tree

2 files changed

+21
-8
lines changed

2 files changed

+21
-8
lines changed

llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp

+11-8
Original file line numberDiff line numberDiff line change
@@ -2997,24 +2997,27 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) {
29972997
return replaceOperand(CI, 0, InsertTuple);
29982998
}
29992999

3000-
auto *DstTy = dyn_cast<FixedVectorType>(ReturnType);
3001-
auto *VecTy = dyn_cast<FixedVectorType>(Vec->getType());
3000+
auto *DstTy = dyn_cast<VectorType>(ReturnType);
3001+
auto *VecTy = dyn_cast<VectorType>(Vec->getType());
30023002

3003-
// Only canonicalize if the destination vector and Vec are fixed
3004-
// vectors.
30053003
if (DstTy && VecTy) {
3006-
unsigned DstNumElts = DstTy->getNumElements();
3007-
unsigned VecNumElts = VecTy->getNumElements();
3004+
auto DstEltCnt = DstTy->getElementCount();
3005+
auto VecEltCnt = VecTy->getElementCount();
30083006
unsigned IdxN = cast<ConstantInt>(Idx)->getZExtValue();
30093007

30103008
// Extracting the entirety of Vec is a nop.
3011-
if (VecNumElts == DstNumElts) {
3009+
if (DstEltCnt == VecTy->getElementCount()) {
30123010
replaceInstUsesWith(CI, Vec);
30133011
return eraseInstFromFunction(CI);
30143012
}
30153013

3014+
// Only canonicalize to shufflevector if the destination vector and
3015+
// Vec are fixed vectors.
3016+
if (VecEltCnt.isScalable() || DstEltCnt.isScalable())
3017+
break;
3018+
30163019
SmallVector<int, 8> Mask;
3017-
for (unsigned i = 0; i != DstNumElts; ++i)
3020+
for (unsigned i = 0; i != DstEltCnt.getKnownMinValue(); ++i)
30183021
Mask.push_back(IdxN + i);
30193022

30203023
Value *Shuffle = Builder.CreateShuffleVector(Vec, Mask);

llvm/test/Transforms/InstCombine/canonicalize-vector-extract.ll

+10
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ declare <3 x i32> @llvm.vector.extract.v3i32.v8i32(<8 x i32> %vec, i64 %idx)
1010
declare <4 x i32> @llvm.vector.extract.v4i32.nxv4i32(<vscale x 4 x i32> %vec, i64 %idx)
1111
declare <4 x i32> @llvm.vector.extract.v4i32.v8i32(<8 x i32> %vec, i64 %idx)
1212
declare <8 x i32> @llvm.vector.extract.v8i32.v8i32(<8 x i32> %vec, i64 %idx)
13+
declare <vscale x 8 x i32> @llvm.vector.extract.nxv8i32.nxv8i32(<vscale x 8 x i32> %vec, i64 %idx)
1314

1415
; ============================================================================ ;
1516
; Trivial cases
@@ -24,6 +25,15 @@ define <8 x i32> @trivial_nop(<8 x i32> %vec) {
2425
ret <8 x i32> %1
2526
}
2627

28+
define <vscale x 8 x i32> @trivial_nop_scalable(<vscale x 8 x i32> %vec) {
29+
; CHECK-LABEL: define <vscale x 8 x i32> @trivial_nop_scalable(
30+
; CHECK-SAME: <vscale x 8 x i32> [[VEC:%.*]]) {
31+
; CHECK-NEXT: ret <vscale x 8 x i32> [[VEC]]
32+
;
33+
%ext = call <vscale x 8 x i32> @llvm.vector.extract.nxv8i32.nxv8i32(<vscale x 8 x i32> %vec, i64 0)
34+
ret <vscale x 8 x i32> %ext
35+
}
36+
2737
; ============================================================================ ;
2838
; Valid canonicalizations
2939
; ============================================================================ ;

0 commit comments

Comments
 (0)