Skip to content

Commit

Permalink
InstCombine: Fold shufflevector(select) and shufflevector(phi) (#113746)
Browse files Browse the repository at this point in the history
- Transform `shufflevector(select(c, x, y), C)` to
  `select(c, shufflevector(x, C), shufflevector(y, C))` by re-using
  the `FoldOpIntoSelect` helper.
- Transform `shufflevector(phi(x, y), C)` to
  `phi(shufflevector(x, C), shufflevector(y, C))` by re-using the
  `foldOpInotPhi` helper.
  • Loading branch information
MatzeB authored Oct 28, 2024
1 parent 36c1194 commit 5903c6a
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 0 deletions.
11 changes: 11 additions & 0 deletions llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2900,6 +2900,17 @@ Instruction *InstCombinerImpl::visitShuffleVectorInst(ShuffleVectorInst &SVI) {
if (Instruction *I = foldIdentityPaddedShuffles(SVI))
return I;

if (match(RHS, m_Constant())) {
if (auto *SI = dyn_cast<SelectInst>(LHS)) {
if (Instruction *I = FoldOpIntoSelect(SVI, SI))
return I;
}
if (auto *PN = dyn_cast<PHINode>(LHS)) {
if (Instruction *I = foldOpIntoPhi(SVI, PN))
return I;
}
}

if (match(RHS, m_Poison()) && canEvaluateShuffled(LHS, Mask)) {
Value *V = evaluateInDifferentElementOrder(LHS, Mask, Builder);
return replaceInstUsesWith(SVI, V);
Expand Down
44 changes: 44 additions & 0 deletions llvm/test/Transforms/InstCombine/vec_shuffle.ll
Original file line number Diff line number Diff line change
Expand Up @@ -2377,3 +2377,47 @@ define <2 x i32> @not_splat_shuffle2(i32 %x) {
%shuf = shufflevector <2 x i32> %vec, <2 x i32> undef, <2 x i32> <i32 1, i32 3>
ret <2 x i32> %shuf
}
define <2 x i32> @foldselect0(i1 %c) {
; CHECK-LABEL: @foldselect0(
; CHECK-NEXT: [[SHUF:%.*]] = select i1 [[C:%.*]], <2 x i32> <i32 7, i32 42>, <2 x i32> <i32 1, i32 0>
; CHECK-NEXT: ret <2 x i32> [[SHUF]]
;
%sel = select i1 %c, <2 x i32> <i32 42, i32 7>, <2 x i32> <i32 0, i32 1>
%shuf = shufflevector <2 x i32> %sel, <2 x i32> poison, <2 x i32> <i32 1, i32 0>
ret <2 x i32> %shuf
}

declare i1 @cond()
declare <4 x i32> @value()

define <4 x i32> @foldphi1() {
; CHECK-LABEL: @foldphi1(
; CHECK-NEXT: entry:
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
; CHECK-NEXT: [[V:%.*]] = phi <4 x i32> [ zeroinitializer, [[ENTRY:%.*]] ], [ [[XOR:%.*]], [[LOOP]] ]
; CHECK-NEXT: [[VAL:%.*]] = call <4 x i32> @value()
; CHECK-NEXT: [[XOR]] = xor <4 x i32> [[V]], [[VAL]]
; CHECK-NEXT: [[C:%.*]] = call i1 @cond()
; CHECK-NEXT: br i1 [[C]], label [[LOOP]], label [[EXIT:%.*]]
; CHECK: exit:
; CHECK-NEXT: [[SHUF1:%.*]] = shufflevector <4 x i32> [[XOR]], <4 x i32> poison, <4 x i32> <i32 3, i32 0, i32 1, i32 2>
; CHECK-NEXT: ret <4 x i32> [[SHUF1]]
;
entry:
br label %loop

loop:
%v = phi <4 x i32> [zeroinitializer, %entry], [%shuf1, %loop]

%shuf0 = shufflevector <4 x i32> %v, <4 x i32> poison, <4 x i32> <i32 1, i32 2, i32 3, i32 0>
%val = call <4 x i32> @value()
%xor = xor <4 x i32> %shuf0, %val
%shuf1 = shufflevector <4 x i32> %xor, <4 x i32> poison, <4 x i32> <i32 3, i32 0, i32 1, i32 2>

%c = call i1 @cond()
br i1 %c, label %loop, label %exit

exit:
ret <4 x i32> %shuf1
}

0 comments on commit 5903c6a

Please sign in to comment.