[llvm] [InstCombine] Pull extract through broadcast (PR #143380)
via llvm-commits
llvm-commits at lists.llvm.org
Tue Jun 10 07:59:42 PDT 2025
https://github.com/agorenstein-nvidia updated https://github.com/llvm/llvm-project/pull/143380
>From 34c1222e9119655c5d5286bd01be13752f300bbd Mon Sep 17 00:00:00 2001
From: Aaron Gorenstein <agorenstein at nvidia.com>
Date: Fri, 6 Jun 2025 09:55:52 -0400
Subject: [PATCH 1/8] Initial changes
---
.../Transforms/InstCombine/InstCombineVectorOps.cpp | 6 ++++++
.../InstCombine/vec_extract_through_broadcast.ll | 12 ++++++++++++
2 files changed, 18 insertions(+)
create mode 100644 llvm/test/Transforms/InstCombine/vec_extract_through_broadcast.ll
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp b/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp
index f946c3856948b..f2fb26c3ffae8 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp
@@ -542,6 +542,12 @@ Instruction *InstCombinerImpl::visitExtractElementInst(ExtractElementInst &EI) {
}
}
} else if (auto *SVI = dyn_cast<ShuffleVectorInst>(I)) {
+ // extractelt (shufflevector %v1, %v2, zeroinitializer) ->
+ // extractelt %v1, 0
+ if (isa<FixedVectorType>(SVI->getType()))
+ if (all_of(SVI->getShuffleMask(), [](int Elt) { return Elt == 0; }))
+ return ExtractElementInst::Create(SVI->getOperand(0), Builder.getInt64(0));
+
// If this is extracting an element from a shufflevector, figure out where
// it came from and extract from the appropriate input element instead.
// Restrict the following transformation to fixed-length vector.
diff --git a/llvm/test/Transforms/InstCombine/vec_extract_through_broadcast.ll b/llvm/test/Transforms/InstCombine/vec_extract_through_broadcast.ll
new file mode 100644
index 0000000000000..ec80fbf01a3c9
--- /dev/null
+++ b/llvm/test/Transforms/InstCombine/vec_extract_through_broadcast.ll
@@ -0,0 +1,12 @@
+; RUN: opt -passes=instcombine -S < %s | FileCheck %s
+
+define float @extract_from_zero_init_shuffle(<2 x float> %1, i64 %idx) {
+; CHECK-LABEL: @extract_from_zero_init_shuffle(
+; CHECK-NEXT: [[TMP1:%.*]] = extractelement <2 x float> [[W:%.*]], i64 0
+; CHECK-NEXT: ret float [[TMP1]]
+;
+ %3 = shufflevector <2 x float> %1, <2 x float> poison, <4 x i32> zeroinitializer
+ %4 = extractelement <4 x float> %3, i64 %idx
+ ret float %4
+}
+
>From e315c89001f13dabea489e2531621cd4f9eadd75 Mon Sep 17 00:00:00 2001
From: Aaron Gorenstein <agorenstein at nvidia.com>
Date: Mon, 9 Jun 2025 11:51:26 -0400
Subject: [PATCH 2/8] PR feedback 1
---
.../InstCombine/InstCombineVectorOps.cpp | 12 +++---
.../vec_extract_through_broadcast.ll | 37 +++++++++++++++++++
2 files changed, 44 insertions(+), 5 deletions(-)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp b/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp
index f2fb26c3ffae8..36f61fad0d887 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp
@@ -542,11 +542,13 @@ Instruction *InstCombinerImpl::visitExtractElementInst(ExtractElementInst &EI) {
}
}
} else if (auto *SVI = dyn_cast<ShuffleVectorInst>(I)) {
- // extractelt (shufflevector %v1, %v2, zeroinitializer) ->
- // extractelt %v1, 0
- if (isa<FixedVectorType>(SVI->getType()))
- if (all_of(SVI->getShuffleMask(), [](int Elt) { return Elt == 0; }))
- return ExtractElementInst::Create(SVI->getOperand(0), Builder.getInt64(0));
+ // extractelt (shufflevector %v1, %v2, splat-mask) idx ->
+ // extractelt %v1, splat-mask[0]
+ if (isa<VectorType>(SVI->getType())) {
+ auto mask = SVI->getShuffleMask();
+ if (mask[0] != -1 && all_equal(mask))
+ return ExtractElementInst::Create(SVI->getOperand(0), Builder.getInt64(mask[0]));
+ }
// If this is extracting an element from a shufflevector, figure out where
// it came from and extract from the appropriate input element instead.
diff --git a/llvm/test/Transforms/InstCombine/vec_extract_through_broadcast.ll b/llvm/test/Transforms/InstCombine/vec_extract_through_broadcast.ll
index ec80fbf01a3c9..7afe6015779dd 100644
--- a/llvm/test/Transforms/InstCombine/vec_extract_through_broadcast.ll
+++ b/llvm/test/Transforms/InstCombine/vec_extract_through_broadcast.ll
@@ -10,3 +10,40 @@ define float @extract_from_zero_init_shuffle(<2 x float> %1, i64 %idx) {
ret float %4
}
+
+define float @extract_from_general_splat(<2 x float> %1, i64 %idx) {
+; CHECK-LABEL: @extract_from_general_splat(
+; CHECK-NEXT: [[TMP1:%.*]] = extractelement <2 x float> [[W:%.*]], i64 1
+; CHECK-NEXT: ret float [[TMP1]]
+;
+ %3 = shufflevector <2 x float> %1, <2 x float> poison, <4 x i32> <i32 1, i32 1, i32 1, i32 1>
+ %4 = extractelement <4 x float> %3, i64 %idx
+ ret float %4
+}
+
+define float @extract_from_general_scalable_splat(<vscale x 2 x float> %1, i64 %idx) {
+; CHECK-LABEL: @extract_from_general_scalable_splat(
+; CHECK-NEXT: [[TMP1:%.*]] = extractelement <vscale x 2 x float> [[W:%.*]], i64 0
+; CHECK-NEXT: ret float [[TMP1]]
+;
+ %3 = shufflevector <vscale x 2 x float> %1, <vscale x 2 x float> poison, <vscale x 4 x i32> zeroinitializer
+ %4 = extractelement <vscale x 4 x float> %3, i64 %idx
+ ret float %4
+}
+
+define float @no_extract_from_general_no_splat_0(<2 x float> %1, i64 %idx) {
+ %3 = shufflevector <2 x float> %1, <2 x float> poison, <4 x i32> <i32 undef, i32 1, i32 1, i32 1>
+ %4 = extractelement <4 x float> %3, i64 %idx
+ ret float %4
+}
+
+define float @no_extract_from_general_no_splat_1(<2 x float> %1, i64 %idx) {
+; CHECK-LABEL: @no_extract_from_general_no_splat_0(
+; CHECK-NEXT: [[TMP1:%.*]] = shufflevector <2 x float> [[W:%.*]], <2 x float> poison, <4 x i32> <i32 poison, i32 1, i32 1, i32 1>
+; CHECK-NEXT: [[TMP2:%.*]] = extractelement <4 x float> [[TMP1]], i64 %idx
+; CHECK-NEXT: ret float [[TMP2]]
+;
+ %3 = shufflevector <2 x float> %1, <2 x float> poison, <4 x i32> <i32 1, i32 undef, i32 1, i32 1>
+ %4 = extractelement <4 x float> %3, i64 %idx
+ ret float %4
+}
>From 274cec9375c0220abaea446243f64ef9f73027f8 Mon Sep 17 00:00:00 2001
From: Aaron Gorenstein <agorenstein at nvidia.com>
Date: Mon, 9 Jun 2025 12:02:57 -0400
Subject: [PATCH 3/8] clang-format
---
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 36f61fad0d887..1f2aef985524f 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp
@@ -547,7 +547,8 @@ Instruction *InstCombinerImpl::visitExtractElementInst(ExtractElementInst &EI) {
if (isa<VectorType>(SVI->getType())) {
auto mask = SVI->getShuffleMask();
if (mask[0] != -1 && all_equal(mask))
- return ExtractElementInst::Create(SVI->getOperand(0), Builder.getInt64(mask[0]));
+ return ExtractElementInst::Create(SVI->getOperand(0),
+ Builder.getInt64(mask[0]));
}
// If this is extracting an element from a shufflevector, figure out where
>From 4fda162dc315044fe9a0aa38d5db89be7c1a4a9e Mon Sep 17 00:00:00 2001
From: Aaron Gorenstein <agorenstein at nvidia.com>
Date: Mon, 9 Jun 2025 12:09:09 -0400
Subject: [PATCH 4/8] Fixing edit damage in test file
---
.../InstCombine/vec_extract_through_broadcast.ll | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/llvm/test/Transforms/InstCombine/vec_extract_through_broadcast.ll b/llvm/test/Transforms/InstCombine/vec_extract_through_broadcast.ll
index 7afe6015779dd..e14bf14cfa387 100644
--- a/llvm/test/Transforms/InstCombine/vec_extract_through_broadcast.ll
+++ b/llvm/test/Transforms/InstCombine/vec_extract_through_broadcast.ll
@@ -32,14 +32,19 @@ define float @extract_from_general_scalable_splat(<vscale x 2 x float> %1, i64 %
}
define float @no_extract_from_general_no_splat_0(<2 x float> %1, i64 %idx) {
+; CHECK-LABEL: @no_extract_from_general_no_splat_0(
+; CHECK-NEXT: [[TMP1:%.*]] = shufflevector <2 x float> [[W:%.*]], <2 x float> poison, <4 x i32> <i32 poison, i32 1, i32 1, i32 1>
+; CHECK-NEXT: [[TMP2:%.*]] = extractelement <4 x float> [[TMP1]], i64 %idx
+; CHECK-NEXT: ret float [[TMP2]]
+;
%3 = shufflevector <2 x float> %1, <2 x float> poison, <4 x i32> <i32 undef, i32 1, i32 1, i32 1>
%4 = extractelement <4 x float> %3, i64 %idx
ret float %4
}
define float @no_extract_from_general_no_splat_1(<2 x float> %1, i64 %idx) {
-; CHECK-LABEL: @no_extract_from_general_no_splat_0(
-; CHECK-NEXT: [[TMP1:%.*]] = shufflevector <2 x float> [[W:%.*]], <2 x float> poison, <4 x i32> <i32 poison, i32 1, i32 1, i32 1>
+; CHECK-LABEL: @no_extract_from_general_no_splat_1(
+; CHECK-NEXT: [[TMP1:%.*]] = shufflevector <2 x float> [[W:%.*]], <2 x float> poison, <4 x i32> <i32 1, i32 poison, i32 1, i32 1>
; CHECK-NEXT: [[TMP2:%.*]] = extractelement <4 x float> [[TMP1]], i64 %idx
; CHECK-NEXT: ret float [[TMP2]]
;
>From 5d9e4d98bb5b116c0323e5229f54fd98bb44671e Mon Sep 17 00:00:00 2001
From: Aaron Gorenstein <agorenstein at nvidia.com>
Date: Mon, 9 Jun 2025 12:14:51 -0400
Subject: [PATCH 5/8] Removed unneeded check
---
.../Transforms/InstCombine/InstCombineVectorOps.cpp | 10 ++++------
1 file changed, 4 insertions(+), 6 deletions(-)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp b/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp
index 1f2aef985524f..789ceaa0be0f4 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp
@@ -544,12 +544,10 @@ Instruction *InstCombinerImpl::visitExtractElementInst(ExtractElementInst &EI) {
} else if (auto *SVI = dyn_cast<ShuffleVectorInst>(I)) {
// extractelt (shufflevector %v1, %v2, splat-mask) idx ->
// extractelt %v1, splat-mask[0]
- if (isa<VectorType>(SVI->getType())) {
- auto mask = SVI->getShuffleMask();
- if (mask[0] != -1 && all_equal(mask))
- return ExtractElementInst::Create(SVI->getOperand(0),
- Builder.getInt64(mask[0]));
- }
+ auto mask = SVI->getShuffleMask();
+ if (mask[0] != -1 && all_equal(mask))
+ return ExtractElementInst::Create(SVI->getOperand(0),
+ Builder.getInt64(mask[0]));
// If this is extracting an element from a shufflevector, figure out where
// it came from and extract from the appropriate input element instead.
>From a1aec2eb38245a397917c9daf1fc02f6ab8ff504 Mon Sep 17 00:00:00 2001
From: Aaron Gorenstein <agorenstein at nvidia.com>
Date: Mon, 9 Jun 2025 12:35:06 -0400
Subject: [PATCH 6/8] Improve undef/poison usage in test (per PR automation
failure), and using meaningful global instead of magic constant for
shufflemask poison-indicator
---
llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp | 2 +-
.../Transforms/InstCombine/vec_extract_through_broadcast.ll | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp b/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp
index 789ceaa0be0f4..946c8cd09bb6f 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp
@@ -545,7 +545,7 @@ Instruction *InstCombinerImpl::visitExtractElementInst(ExtractElementInst &EI) {
// extractelt (shufflevector %v1, %v2, splat-mask) idx ->
// extractelt %v1, splat-mask[0]
auto mask = SVI->getShuffleMask();
- if (mask[0] != -1 && all_equal(mask))
+ if (mask[0] != PoisonMaskElem && all_equal(mask))
return ExtractElementInst::Create(SVI->getOperand(0),
Builder.getInt64(mask[0]));
diff --git a/llvm/test/Transforms/InstCombine/vec_extract_through_broadcast.ll b/llvm/test/Transforms/InstCombine/vec_extract_through_broadcast.ll
index e14bf14cfa387..b93b4d017918a 100644
--- a/llvm/test/Transforms/InstCombine/vec_extract_through_broadcast.ll
+++ b/llvm/test/Transforms/InstCombine/vec_extract_through_broadcast.ll
@@ -37,7 +37,7 @@ define float @no_extract_from_general_no_splat_0(<2 x float> %1, i64 %idx) {
; CHECK-NEXT: [[TMP2:%.*]] = extractelement <4 x float> [[TMP1]], i64 %idx
; CHECK-NEXT: ret float [[TMP2]]
;
- %3 = shufflevector <2 x float> %1, <2 x float> poison, <4 x i32> <i32 undef, i32 1, i32 1, i32 1>
+ %3 = shufflevector <2 x float> %1, <2 x float> poison, <4 x i32> <i32 poison, i32 1, i32 1, i32 1>
%4 = extractelement <4 x float> %3, i64 %idx
ret float %4
}
@@ -48,7 +48,7 @@ define float @no_extract_from_general_no_splat_1(<2 x float> %1, i64 %idx) {
; CHECK-NEXT: [[TMP2:%.*]] = extractelement <4 x float> [[TMP1]], i64 %idx
; CHECK-NEXT: ret float [[TMP2]]
;
- %3 = shufflevector <2 x float> %1, <2 x float> poison, <4 x i32> <i32 1, i32 undef, i32 1, i32 1>
+ %3 = shufflevector <2 x float> %1, <2 x float> poison, <4 x i32> <i32 1, i32 poison, i32 1, i32 1>
%4 = extractelement <4 x float> %3, i64 %idx
ret float %4
}
>From 70d3c0124b9593202eb494be0fd46d422b50ef3b Mon Sep 17 00:00:00 2001
From: Aaron Gorenstein <agorenstein at nvidia.com>
Date: Mon, 9 Jun 2025 12:58:46 -0400
Subject: [PATCH 7/8] Fixed varname convention per PR feedback; on reflection
from PR feedback removing negative tests
---
.../InstCombine/InstCombineVectorOps.cpp | 6 ++---
.../vec_extract_through_broadcast.ll | 22 -------------------
2 files changed, 3 insertions(+), 25 deletions(-)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp b/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp
index 946c8cd09bb6f..5519855a85054 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp
@@ -544,10 +544,10 @@ Instruction *InstCombinerImpl::visitExtractElementInst(ExtractElementInst &EI) {
} else if (auto *SVI = dyn_cast<ShuffleVectorInst>(I)) {
// extractelt (shufflevector %v1, %v2, splat-mask) idx ->
// extractelt %v1, splat-mask[0]
- auto mask = SVI->getShuffleMask();
- if (mask[0] != PoisonMaskElem && all_equal(mask))
+ auto Mask = SVI->getShuffleMask();
+ if (Mask[0] != PoisonMaskElem && all_equal(Mask))
return ExtractElementInst::Create(SVI->getOperand(0),
- Builder.getInt64(mask[0]));
+ Builder.getInt64(Mask[0]));
// If this is extracting an element from a shufflevector, figure out where
// it came from and extract from the appropriate input element instead.
diff --git a/llvm/test/Transforms/InstCombine/vec_extract_through_broadcast.ll b/llvm/test/Transforms/InstCombine/vec_extract_through_broadcast.ll
index b93b4d017918a..5ed837eb22760 100644
--- a/llvm/test/Transforms/InstCombine/vec_extract_through_broadcast.ll
+++ b/llvm/test/Transforms/InstCombine/vec_extract_through_broadcast.ll
@@ -30,25 +30,3 @@ define float @extract_from_general_scalable_splat(<vscale x 2 x float> %1, i64 %
%4 = extractelement <vscale x 4 x float> %3, i64 %idx
ret float %4
}
-
-define float @no_extract_from_general_no_splat_0(<2 x float> %1, i64 %idx) {
-; CHECK-LABEL: @no_extract_from_general_no_splat_0(
-; CHECK-NEXT: [[TMP1:%.*]] = shufflevector <2 x float> [[W:%.*]], <2 x float> poison, <4 x i32> <i32 poison, i32 1, i32 1, i32 1>
-; CHECK-NEXT: [[TMP2:%.*]] = extractelement <4 x float> [[TMP1]], i64 %idx
-; CHECK-NEXT: ret float [[TMP2]]
-;
- %3 = shufflevector <2 x float> %1, <2 x float> poison, <4 x i32> <i32 poison, i32 1, i32 1, i32 1>
- %4 = extractelement <4 x float> %3, i64 %idx
- ret float %4
-}
-
-define float @no_extract_from_general_no_splat_1(<2 x float> %1, i64 %idx) {
-; CHECK-LABEL: @no_extract_from_general_no_splat_1(
-; CHECK-NEXT: [[TMP1:%.*]] = shufflevector <2 x float> [[W:%.*]], <2 x float> poison, <4 x i32> <i32 1, i32 poison, i32 1, i32 1>
-; CHECK-NEXT: [[TMP2:%.*]] = extractelement <4 x float> [[TMP1]], i64 %idx
-; CHECK-NEXT: ret float [[TMP2]]
-;
- %3 = shufflevector <2 x float> %1, <2 x float> poison, <4 x i32> <i32 1, i32 poison, i32 1, i32 1>
- %4 = extractelement <4 x float> %3, i64 %idx
- ret float %4
-}
>From 52f5c4b3f12225b0f27b78fb0d212d65e157fadc Mon Sep 17 00:00:00 2001
From: Aaron Gorenstein <agorenstein at nvidia.com>
Date: Tue, 10 Jun 2025 10:20:15 -0400
Subject: [PATCH 8/8] Restore old tests, reframe optimization as extension of
existing one.
---
.../InstCombine/InstCombineVectorOps.cpp | 60 ++++++++++---------
.../vec_extract_through_broadcast.ll | 20 +++++++
.../InstCombine/vec_shuffle-inseltpoison.ll | 3 +-
.../Transforms/InstCombine/vec_shuffle.ll | 3 +-
.../vscale_extractelement-inseltpoison.ll | 10 +---
.../InstCombine/vscale_extractelement.ll | 10 +---
6 files changed, 59 insertions(+), 47 deletions(-)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp b/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp
index 5519855a85054..e06f08bc19ead 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp
@@ -542,34 +542,40 @@ Instruction *InstCombinerImpl::visitExtractElementInst(ExtractElementInst &EI) {
}
}
} else if (auto *SVI = dyn_cast<ShuffleVectorInst>(I)) {
- // extractelt (shufflevector %v1, %v2, splat-mask) idx ->
- // extractelt %v1, splat-mask[0]
- auto Mask = SVI->getShuffleMask();
- if (Mask[0] != PoisonMaskElem && all_equal(Mask))
- return ExtractElementInst::Create(SVI->getOperand(0),
- Builder.getInt64(Mask[0]));
-
- // If this is extracting an element from a shufflevector, figure out where
- // it came from and extract from the appropriate input element instead.
- // Restrict the following transformation to fixed-length vector.
- if (isa<FixedVectorType>(SVI->getType()) && isa<ConstantInt>(Index)) {
- int SrcIdx =
- SVI->getMaskValue(cast<ConstantInt>(Index)->getZExtValue());
- Value *Src;
- unsigned LHSWidth = cast<FixedVectorType>(SVI->getOperand(0)->getType())
- ->getNumElements();
-
- if (SrcIdx < 0)
- return replaceInstUsesWith(EI, PoisonValue::get(EI.getType()));
- if (SrcIdx < (int)LHSWidth)
- Src = SVI->getOperand(0);
- else {
- SrcIdx -= LHSWidth;
- Src = SVI->getOperand(1);
+ int SplatIndex = getSplatIndex(SVI->getShuffleMask());
+ // We know such a splat must be reading from the first operand, even
+ // in the case of scalable vectors (vscale is always > 0).
+ if (SplatIndex == 0)
+ return ExtractElementInst::Create(SVI->getOperand(0), Builder.getInt64(0));
+ // Restrict the non-zero index case to fixed-length vectors
+ if (isa<FixedVectorType>(SVI->getType())) {
+
+ // getSplatIndex doesn't distinguish between the all-poison splat and
+ // a non-splat mask. However, if Index is -1, we still want to propagate
+ // that poison value.
+ int SrcIdx = -2;
+ if (SplatIndex != PoisonMaskElem)
+ SrcIdx = SplatIndex;
+ else if (ConstantInt* CI = dyn_cast<ConstantInt>(Index))
+ SrcIdx = SVI->getMaskValue(CI->getZExtValue());
+
+ if (SrcIdx != -2) {
+ Value *Src;
+ unsigned LHSWidth = cast<FixedVectorType>(SVI->getOperand(0)->getType())
+ ->getNumElements();
+
+ if (SrcIdx < 0)
+ return replaceInstUsesWith(EI, PoisonValue::get(EI.getType()));
+ if (SrcIdx < (int)LHSWidth)
+ Src = SVI->getOperand(0);
+ else {
+ SrcIdx -= LHSWidth;
+ Src = SVI->getOperand(1);
+ }
+ Type *Int64Ty = Type::getInt64Ty(EI.getContext());
+ return ExtractElementInst::Create(
+ Src, ConstantInt::get(Int64Ty, SrcIdx, false));
}
- Type *Int64Ty = Type::getInt64Ty(EI.getContext());
- return ExtractElementInst::Create(
- Src, ConstantInt::get(Int64Ty, SrcIdx, false));
}
} else if (auto *CI = dyn_cast<CastInst>(I)) {
// Canonicalize extractelement(cast) -> cast(extractelement).
diff --git a/llvm/test/Transforms/InstCombine/vec_extract_through_broadcast.ll b/llvm/test/Transforms/InstCombine/vec_extract_through_broadcast.ll
index 5ed837eb22760..a51b6db877ff4 100644
--- a/llvm/test/Transforms/InstCombine/vec_extract_through_broadcast.ll
+++ b/llvm/test/Transforms/InstCombine/vec_extract_through_broadcast.ll
@@ -30,3 +30,23 @@ define float @extract_from_general_scalable_splat(<vscale x 2 x float> %1, i64 %
%4 = extractelement <vscale x 4 x float> %3, i64 %idx
ret float %4
}
+
+define float @extract_from_splat_with_poison_0(<2 x float> %1, i64 %idx) {
+; CHECK-LABEL: @extract_from_splat_with_poison_0(
+; CHECK-NEXT: [[TMP2:%.*]] = extractelement <2 x float> [[TMP1:%.*]], i64 1
+; CHECK-NEXT: ret float [[TMP2]]
+;
+ %3 = shufflevector <2 x float> %1, <2 x float> poison, <4 x i32> <i32 poison, i32 1, i32 1, i32 1>
+ %4 = extractelement <4 x float> %3, i64 %idx
+ ret float %4
+}
+
+define float @extract_from_splat_with_poison_1(<2 x float> %1, i64 %idx) {
+; CHECK-LABEL: @extract_from_splat_with_poison_1(
+; CHECK-NEXT: [[TMP2:%.*]] = extractelement <2 x float> [[TMP1:%.*]], i64 1
+; CHECK-NEXT: ret float [[TMP2]]
+;
+ %3 = shufflevector <2 x float> %1, <2 x float> poison, <4 x i32> <i32 1, i32 poison, i32 1, i32 1>
+ %4 = extractelement <4 x float> %3, i64 %idx
+ ret float %4
+}
diff --git a/llvm/test/Transforms/InstCombine/vec_shuffle-inseltpoison.ll b/llvm/test/Transforms/InstCombine/vec_shuffle-inseltpoison.ll
index 9aa050e8cd500..cc8ecd9aefb1c 100644
--- a/llvm/test/Transforms/InstCombine/vec_shuffle-inseltpoison.ll
+++ b/llvm/test/Transforms/InstCombine/vec_shuffle-inseltpoison.ll
@@ -61,8 +61,7 @@ define float @test6(<4 x float> %X) {
define float @testvscale6(<vscale x 4 x float> %X) {
; CHECK-LABEL: @testvscale6(
-; CHECK-NEXT: [[T2:%.*]] = shufflevector <vscale x 4 x float> [[X:%.*]], <vscale x 4 x float> poison, <vscale x 4 x i32> zeroinitializer
-; CHECK-NEXT: [[R:%.*]] = extractelement <vscale x 4 x float> [[T2]], i64 0
+; CHECK-NEXT: [[R:%.*]] = extractelement <vscale x 4 x float> [[X:%.*]], i64 0
; CHECK-NEXT: ret float [[R]]
;
%X1 = bitcast <vscale x 4 x float> %X to <vscale x 4 x i32>
diff --git a/llvm/test/Transforms/InstCombine/vec_shuffle.ll b/llvm/test/Transforms/InstCombine/vec_shuffle.ll
index 83919e743d384..f4ee0e7f2eb95 100644
--- a/llvm/test/Transforms/InstCombine/vec_shuffle.ll
+++ b/llvm/test/Transforms/InstCombine/vec_shuffle.ll
@@ -67,8 +67,7 @@ define float @test6(<4 x float> %X) {
define float @testvscale6(<vscale x 4 x float> %X) {
; CHECK-LABEL: @testvscale6(
-; CHECK-NEXT: [[T2:%.*]] = shufflevector <vscale x 4 x float> [[X:%.*]], <vscale x 4 x float> poison, <vscale x 4 x i32> zeroinitializer
-; CHECK-NEXT: [[R:%.*]] = extractelement <vscale x 4 x float> [[T2]], i64 0
+; CHECK-NEXT: [[R:%.*]] = extractelement <vscale x 4 x float> [[X:%.*]], i64 0
; CHECK-NEXT: ret float [[R]]
;
%X1 = bitcast <vscale x 4 x float> %X to <vscale x 4 x i32>
diff --git a/llvm/test/Transforms/InstCombine/vscale_extractelement-inseltpoison.ll b/llvm/test/Transforms/InstCombine/vscale_extractelement-inseltpoison.ll
index 2655c20354607..58613dc14e0fe 100644
--- a/llvm/test/Transforms/InstCombine/vscale_extractelement-inseltpoison.ll
+++ b/llvm/test/Transforms/InstCombine/vscale_extractelement-inseltpoison.ll
@@ -91,10 +91,7 @@ define i8 @extractelement_bitcast_insert_extra_use_bitcast(<vscale x 2 x i32> %a
define i32 @extractelement_shuffle_maybe_out_of_range(i32 %v) {
; CHECK-LABEL: @extractelement_shuffle_maybe_out_of_range(
-; CHECK-NEXT: [[IN:%.*]] = insertelement <vscale x 4 x i32> poison, i32 [[V:%.*]], i64 0
-; CHECK-NEXT: [[SPLAT:%.*]] = shufflevector <vscale x 4 x i32> [[IN]], <vscale x 4 x i32> poison, <vscale x 4 x i32> zeroinitializer
-; CHECK-NEXT: [[R:%.*]] = extractelement <vscale x 4 x i32> [[SPLAT]], i64 4
-; CHECK-NEXT: ret i32 [[R]]
+; CHECK-NEXT: ret i32 [[V:%.*]]
;
%in = insertelement <vscale x 4 x i32> poison, i32 %v, i32 0
%splat = shufflevector <vscale x 4 x i32> %in, <vscale x 4 x i32> poison, <vscale x 4 x i32> zeroinitializer
@@ -104,10 +101,7 @@ define i32 @extractelement_shuffle_maybe_out_of_range(i32 %v) {
define i32 @extractelement_shuffle_invalid_index(i32 %v) {
; CHECK-LABEL: @extractelement_shuffle_invalid_index(
-; CHECK-NEXT: [[IN:%.*]] = insertelement <vscale x 4 x i32> poison, i32 [[V:%.*]], i64 0
-; CHECK-NEXT: [[SPLAT:%.*]] = shufflevector <vscale x 4 x i32> [[IN]], <vscale x 4 x i32> poison, <vscale x 4 x i32> zeroinitializer
-; CHECK-NEXT: [[R:%.*]] = extractelement <vscale x 4 x i32> [[SPLAT]], i64 4294967295
-; CHECK-NEXT: ret i32 [[R]]
+; CHECK-NEXT: ret i32 [[V:%.*]]
;
%in = insertelement <vscale x 4 x i32> poison, i32 %v, i32 0
%splat = shufflevector <vscale x 4 x i32> %in, <vscale x 4 x i32> poison, <vscale x 4 x i32> zeroinitializer
diff --git a/llvm/test/Transforms/InstCombine/vscale_extractelement.ll b/llvm/test/Transforms/InstCombine/vscale_extractelement.ll
index 07090e9099ae1..3da9aaf02e798 100644
--- a/llvm/test/Transforms/InstCombine/vscale_extractelement.ll
+++ b/llvm/test/Transforms/InstCombine/vscale_extractelement.ll
@@ -55,10 +55,7 @@ define i8 @extractelement_bitcast_useless_insert(<vscale x 2 x i32> %a, i32 %x)
define i32 @extractelement_shuffle_maybe_out_of_range(i32 %v) {
; CHECK-LABEL: @extractelement_shuffle_maybe_out_of_range(
-; CHECK-NEXT: [[IN:%.*]] = insertelement <vscale x 4 x i32> undef, i32 [[V:%.*]], i64 0
-; CHECK-NEXT: [[SPLAT:%.*]] = shufflevector <vscale x 4 x i32> [[IN]], <vscale x 4 x i32> poison, <vscale x 4 x i32> zeroinitializer
-; CHECK-NEXT: [[R:%.*]] = extractelement <vscale x 4 x i32> [[SPLAT]], i64 4
-; CHECK-NEXT: ret i32 [[R]]
+; CHECK-NEXT: ret i32 [[V:%.*]]
;
%in = insertelement <vscale x 4 x i32> undef, i32 %v, i32 0
%splat = shufflevector <vscale x 4 x i32> %in, <vscale x 4 x i32> undef, <vscale x 4 x i32> zeroinitializer
@@ -68,10 +65,7 @@ define i32 @extractelement_shuffle_maybe_out_of_range(i32 %v) {
define i32 @extractelement_shuffle_invalid_index(i32 %v) {
; CHECK-LABEL: @extractelement_shuffle_invalid_index(
-; CHECK-NEXT: [[IN:%.*]] = insertelement <vscale x 4 x i32> undef, i32 [[V:%.*]], i64 0
-; CHECK-NEXT: [[SPLAT:%.*]] = shufflevector <vscale x 4 x i32> [[IN]], <vscale x 4 x i32> poison, <vscale x 4 x i32> zeroinitializer
-; CHECK-NEXT: [[R:%.*]] = extractelement <vscale x 4 x i32> [[SPLAT]], i64 4294967295
-; CHECK-NEXT: ret i32 [[R]]
+; CHECK-NEXT: ret i32 [[V:%.*]]
;
%in = insertelement <vscale x 4 x i32> undef, i32 %v, i32 0
%splat = shufflevector <vscale x 4 x i32> %in, <vscale x 4 x i32> undef, <vscale x 4 x i32> zeroinitializer
More information about the llvm-commits
mailing list