[PATCH] D137934: [InstCombine] Fold extractelt with select of constants
Thomas Symalla via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Mon Nov 14 04:11:40 PST 2022
tsymalla created this revision.
Herald added a subscriber: hiraditya.
Herald added a project: All.
tsymalla requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.
An extractelt with a constant index which extracts an element from the
two vector operands of a select can be directly folded into a select.
extractelt (select %cond, <vec1>, <vec2>), %c1, %c2 ->
select %cond, <vec1>[c1], <vec2>[c2]
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D137934
Files:
llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp
llvm/test/Transforms/InstCombine/extractelement.ll
Index: llvm/test/Transforms/InstCombine/extractelement.ll
===================================================================
--- llvm/test/Transforms/InstCombine/extractelement.ll
+++ llvm/test/Transforms/InstCombine/extractelement.ll
@@ -785,8 +785,7 @@
define i32 @extelt_select_const_operand_vector(i1 %c) {
; ANY-LABEL: @extelt_select_const_operand_vector(
-; ANY-NEXT: [[S:%.*]] = select i1 [[C:%.*]], <3 x i32> <i32 poison, i32 poison, i32 4>, <3 x i32> <i32 poison, i32 poison, i32 7>
-; ANY-NEXT: [[R:%.*]] = extractelement <3 x i32> [[S]], i64 2
+; ANY-NEXT: [[R:%.*]] = select i1 [[C:%.*]], i32 4, i32 7
; ANY-NEXT: ret i32 [[R]]
;
%s = select i1 %c, <3 x i32> <i32 2, i32 3, i32 4>, <3 x i32> <i32 5, i32 6, i32 7>
Index: llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp
===================================================================
--- llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp
+++ llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp
@@ -391,6 +391,35 @@
IndexC->getValue().zextOrTrunc(64));
}
+static SelectInst *foldExtractElementConstSelect(ExtractElementInst &EI,
+ Value *Vec, ConstantInt *Idx) {
+ if (!EI.hasOneUse())
+ return nullptr;
+
+ if (auto *Select = dyn_cast<SelectInst>(Vec);
+ Select != nullptr && Select->hasOneUse()) {
+ auto *TrueVal = dyn_cast<ConstantVector>(Select->getTrueValue());
+ auto *FalseVal = dyn_cast<ConstantVector>(Select->getFalseValue());
+ if (TrueVal && FalseVal) {
+ const uint64_t IndexVal = Idx->getValue().getZExtValue();
+ const uint64_t NumElements = TrueVal->getType()->getNumElements();
+
+ if (IndexVal < NumElements) {
+ auto *TrueConst =
+ dyn_cast<ConstantInt>(TrueVal->getAggregateElement(IndexVal));
+ auto *FalseConst =
+ dyn_cast<ConstantInt>(FalseVal->getAggregateElement(IndexVal));
+
+ if (TrueConst && FalseConst)
+ return SelectInst::Create(Select->getCondition(), TrueConst,
+ FalseConst);
+ }
+ }
+ }
+
+ return nullptr;
+}
+
Instruction *InstCombinerImpl::visitExtractElementInst(ExtractElementInst &EI) {
Value *SrcVec = EI.getVectorOperand();
Value *Index = EI.getIndexOperand();
@@ -402,6 +431,11 @@
// find a previously computed scalar that was inserted into the vector.
auto *IndexC = dyn_cast<ConstantInt>(Index);
if (IndexC) {
+ // extractelt (select %cond, <vec1>, <vec2>), %c1, %c2 ->
+ // select %cond, <vec1>[c1], <vec2>[c2]
+ if (auto *Select = foldExtractElementConstSelect(EI, SrcVec, IndexC))
+ return Select;
+
// Canonicalize type of constant indices to i64 to simplify CSE
if (auto *NewIdx = getPreferredVectorIndex(IndexC))
return replaceOperand(EI, 1, NewIdx);
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D137934.475102.patch
Type: text/x-patch
Size: 2869 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20221114/5d1d4d8a/attachment.bin>
More information about the llvm-commits
mailing list