Skip to content

Commit f1e2bc1

Browse files
committed
InstCombine: Order shufflevector operands by complexity
As shufflevector is effectively commutative we should apply the same logic as other commutative operations where we order the inputs by their `getComplexity()` value. This will put things like `undef`, `poison` and constants on the right hand side where possible. We had a rule moving `undef` to the right hand side that is superseded by this.
1 parent 5c47d3e commit f1e2bc1

File tree

8 files changed

+68
-24
lines changed

8 files changed

+68
-24
lines changed

llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2248,13 +2248,15 @@ Instruction *InstCombinerImpl::foldSelectShuffle(ShuffleVectorInst &Shuf) {
22482248
if (!Shuf.isSelect())
22492249
return nullptr;
22502250

2251+
Value *Op0 = Shuf.getOperand(0);
2252+
Value *Op1 = Shuf.getOperand(1);
2253+
22512254
// Canonicalize to choose from operand 0 first unless operand 1 is undefined.
2252-
// Commuting undef to operand 0 conflicts with another canonicalization.
2255+
// Only do so when the operand have the same complexity to avoid conflict with
2256+
// complexity normalization.
22532257
unsigned NumElts = cast<FixedVectorType>(Shuf.getType())->getNumElements();
2254-
if (!match(Shuf.getOperand(1), m_Undef()) &&
2255-
Shuf.getMaskValue(0) >= (int)NumElts) {
2256-
// TODO: Can we assert that both operands of a shuffle-select are not undef
2257-
// (otherwise, it would have been folded by instsimplify?
2258+
if (Shuf.getMaskValue(0) >= (int)NumElts &&
2259+
getComplexity(Op0) == getComplexity(Op1)) {
22582260
Shuf.commute();
22592261
return &Shuf;
22602262
}
@@ -2267,8 +2269,7 @@ Instruction *InstCombinerImpl::foldSelectShuffle(ShuffleVectorInst &Shuf) {
22672269
return I;
22682270

22692271
BinaryOperator *B0, *B1;
2270-
if (!match(Shuf.getOperand(0), m_BinOp(B0)) ||
2271-
!match(Shuf.getOperand(1), m_BinOp(B1)))
2272+
if (!match(Op0, m_BinOp(B0)) || !match(Op1, m_BinOp(B1)))
22722273
return nullptr;
22732274

22742275
// If one operand is "0 - X", allow that to be viewed as "X * -1"
@@ -2791,6 +2792,16 @@ Instruction *InstCombinerImpl::simplifyBinOpSplats(ShuffleVectorInst &SVI) {
27912792
Instruction *InstCombinerImpl::visitShuffleVectorInst(ShuffleVectorInst &SVI) {
27922793
Value *LHS = SVI.getOperand(0);
27932794
Value *RHS = SVI.getOperand(1);
2795+
2796+
unsigned LHSComplexity = getComplexity(LHS);
2797+
unsigned RHSComplexity = getComplexity(RHS);
2798+
// Order operands from most complex to least complex so for example
2799+
// constants or poison end up on RHS.
2800+
if (LHSComplexity < RHSComplexity) {
2801+
SVI.commute();
2802+
return &SVI;
2803+
}
2804+
27942805
SimplifyQuery ShufQuery = SQ.getWithInstruction(&SVI);
27952806
if (auto *V = simplifyShuffleVectorInst(LHS, RHS, SVI.getShuffleMask(),
27962807
SVI.getType(), ShufQuery))
@@ -2858,12 +2869,6 @@ Instruction *InstCombinerImpl::visitShuffleVectorInst(ShuffleVectorInst &SVI) {
28582869
return new ShuffleVectorInst(LHS, createUnaryMask(Mask, LHSWidth));
28592870
}
28602871

2861-
// shuffle undef, x, mask --> shuffle x, undef, mask'
2862-
if (match(LHS, m_Undef())) {
2863-
SVI.commute();
2864-
return &SVI;
2865-
}
2866-
28672872
if (Instruction *I = canonicalizeInsertSplat(SVI, Builder))
28682873
return I;
28692874

llvm/test/Analysis/ValueTracking/knownbits-x86-hadd-hsub.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,7 @@ define <4 x i1> @hadd_shuffle_4th_negative_v4i32(<4 x i32> %x, <4 x i32> %y) {
240240
; CHECK-NEXT: [[TMP0:%.*]] = and <4 x i32> [[X]], <i32 3, i32 3, i32 3, i32 3>
241241
; CHECK-NEXT: [[TMP1:%.*]] = and <4 x i32> [[Y]], <i32 3, i32 3, i32 -1, i32 -1>
242242
; CHECK-NEXT: [[TMP2:%.*]] = tail call <4 x i32> @llvm.x86.ssse3.phadd.d.128(<4 x i32> [[TMP0]], <4 x i32> [[TMP1]])
243-
; CHECK-NEXT: [[TMP3:%.*]] = shufflevector <4 x i32> <i32 0, i32 0, i32 0, i32 poison>, <4 x i32> [[TMP2]], <4 x i32> <i32 0, i32 1, i32 2, i32 7>
243+
; CHECK-NEXT: [[TMP3:%.*]] = shufflevector <4 x i32> [[TMP2]], <4 x i32> <i32 0, i32 0, i32 0, i32 poison>, <4 x i32> <i32 4, i32 5, i32 6, i32 3>
244244
; CHECK-NEXT: [[RET:%.*]] = icmp ne <4 x i32> [[TMP3]], <i32 8, i32 8, i32 8, i32 8>
245245
; CHECK-NEXT: ret <4 x i1> [[RET]]
246246
;

llvm/test/Transforms/InstCombine/insert-extract-shuffle-inseltpoison.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ define <8 x float> @widen_extract4(<8 x float> %ins, <2 x float> %ext) {
8787
define <8 x i16> @pr26015(<4 x i16> %t0) {
8888
; CHECK-LABEL: @pr26015(
8989
; CHECK-NEXT: [[TMP1:%.*]] = shufflevector <4 x i16> [[T0:%.*]], <4 x i16> poison, <8 x i32> <i32 poison, i32 poison, i32 2, i32 3, i32 poison, i32 poison, i32 poison, i32 poison>
90-
; CHECK-NEXT: [[T5:%.*]] = shufflevector <8 x i16> <i16 0, i16 0, i16 0, i16 poison, i16 0, i16 0, i16 0, i16 poison>, <8 x i16> [[TMP1]], <8 x i32> <i32 0, i32 1, i32 2, i32 10, i32 4, i32 5, i32 6, i32 11>
90+
; CHECK-NEXT: [[T5:%.*]] = shufflevector <8 x i16> [[TMP1]], <8 x i16> <i16 0, i16 0, i16 0, i16 poison, i16 0, i16 0, i16 0, i16 poison>, <8 x i32> <i32 8, i32 9, i32 10, i32 2, i32 12, i32 13, i32 14, i32 3>
9191
; CHECK-NEXT: ret <8 x i16> [[T5]]
9292
;
9393
%t1 = extractelement <4 x i16> %t0, i32 2
@@ -267,7 +267,7 @@ define <4 x i32> @extractelt_insertion(<2 x i32> %x, i32 %y) {
267267
; CHECK-LABEL: @extractelt_insertion(
268268
; CHECK-NEXT: entry:
269269
; CHECK-NEXT: [[TMP0:%.*]] = shufflevector <2 x i32> [[X:%.*]], <2 x i32> poison, <4 x i32> <i32 0, i32 1, i32 poison, i32 poison>
270-
; CHECK-NEXT: [[B:%.*]] = shufflevector <4 x i32> <i32 0, i32 poison, i32 poison, i32 poison>, <4 x i32> [[TMP0]], <4 x i32> <i32 0, i32 0, i32 0, i32 5>
270+
; CHECK-NEXT: [[B:%.*]] = shufflevector <4 x i32> [[TMP0]], <4 x i32> <i32 0, i32 poison, i32 poison, i32 poison>, <4 x i32> <i32 4, i32 4, i32 4, i32 1>
271271
; CHECK-NEXT: [[C:%.*]] = add i32 [[Y:%.*]], 3
272272
; CHECK-NEXT: [[D:%.*]] = extractelement <4 x i32> [[TMP0]], i32 [[C]]
273273
; CHECK-NEXT: [[E:%.*]] = icmp eq i32 [[D]], 0

llvm/test/Transforms/InstCombine/insert-extract-shuffle.ll

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ define <8 x float> @widen_extract4(<8 x float> %ins, <2 x float> %ext) {
8787
define <8 x i16> @pr26015(<4 x i16> %t0) {
8888
; CHECK-LABEL: @pr26015(
8989
; CHECK-NEXT: [[TMP1:%.*]] = shufflevector <4 x i16> [[T0:%.*]], <4 x i16> poison, <8 x i32> <i32 poison, i32 poison, i32 2, i32 3, i32 poison, i32 poison, i32 poison, i32 poison>
90-
; CHECK-NEXT: [[T5:%.*]] = shufflevector <8 x i16> <i16 0, i16 0, i16 0, i16 poison, i16 0, i16 0, i16 0, i16 poison>, <8 x i16> [[TMP1]], <8 x i32> <i32 0, i32 1, i32 2, i32 10, i32 4, i32 5, i32 6, i32 11>
90+
; CHECK-NEXT: [[T5:%.*]] = shufflevector <8 x i16> [[TMP1]], <8 x i16> <i16 0, i16 0, i16 0, i16 poison, i16 0, i16 0, i16 0, i16 poison>, <8 x i32> <i32 8, i32 9, i32 10, i32 2, i32 12, i32 13, i32 14, i32 3>
9191
; CHECK-NEXT: ret <8 x i16> [[T5]]
9292
;
9393
%t1 = extractelement <4 x i16> %t0, i32 2
@@ -267,7 +267,7 @@ define <4 x i32> @extractelt_insertion(<2 x i32> %x, i32 %y) {
267267
; CHECK-LABEL: @extractelt_insertion(
268268
; CHECK-NEXT: entry:
269269
; CHECK-NEXT: [[TMP0:%.*]] = shufflevector <2 x i32> [[X:%.*]], <2 x i32> poison, <4 x i32> <i32 0, i32 1, i32 poison, i32 poison>
270-
; CHECK-NEXT: [[B:%.*]] = shufflevector <4 x i32> <i32 0, i32 poison, i32 poison, i32 poison>, <4 x i32> [[TMP0]], <4 x i32> <i32 0, i32 0, i32 0, i32 5>
270+
; CHECK-NEXT: [[B:%.*]] = shufflevector <4 x i32> [[TMP0]], <4 x i32> <i32 0, i32 poison, i32 poison, i32 poison>, <4 x i32> <i32 4, i32 4, i32 4, i32 1>
271271
; CHECK-NEXT: [[C:%.*]] = add i32 [[Y:%.*]], 3
272272
; CHECK-NEXT: [[D:%.*]] = extractelement <4 x i32> [[TMP0]], i32 [[C]]
273273
; CHECK-NEXT: [[E:%.*]] = icmp eq i32 [[D]], 0
@@ -795,7 +795,7 @@ define <4 x i32> @infloop_D151807(<4 x float> %arg) {
795795
; CHECK-NEXT: [[I:%.*]] = shufflevector <4 x float> [[ARG:%.*]], <4 x float> poison, <2 x i32> <i32 2, i32 poison>
796796
; CHECK-NEXT: [[I1:%.*]] = bitcast <2 x float> [[I]] to <2 x i32>
797797
; CHECK-NEXT: [[TMP1:%.*]] = shufflevector <2 x i32> [[I1]], <2 x i32> poison, <4 x i32> <i32 0, i32 poison, i32 poison, i32 poison>
798-
; CHECK-NEXT: [[I4:%.*]] = shufflevector <4 x i32> <i32 0, i32 poison, i32 poison, i32 poison>, <4 x i32> [[TMP1]], <4 x i32> <i32 4, i32 0, i32 0, i32 0>
798+
; CHECK-NEXT: [[I4:%.*]] = shufflevector <4 x i32> [[TMP1]], <4 x i32> <i32 0, i32 poison, i32 poison, i32 poison>, <4 x i32> <i32 0, i32 4, i32 4, i32 4>
799799
; CHECK-NEXT: ret <4 x i32> [[I4]]
800800
;
801801
%i = shufflevector <4 x float> %arg, <4 x float> poison, <2 x i32> <i32 2, i32 poison>

llvm/test/Transforms/InstCombine/vec_shuffle-inseltpoison.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1346,7 +1346,7 @@ define <2 x float> @frem_splat_constant1(<2 x float> %x) {
13461346

13471347
define <2 x i1> @PR40734(<1 x i1> %x, <4 x i1> %y) {
13481348
; CHECK-LABEL: @PR40734(
1349-
; CHECK-NEXT: [[WIDEN:%.*]] = shufflevector <1 x i1> zeroinitializer, <1 x i1> [[X:%.*]], <2 x i32> <i32 0, i32 1>
1349+
; CHECK-NEXT: [[WIDEN:%.*]] = shufflevector <1 x i1> [[X:%.*]], <1 x i1> zeroinitializer, <2 x i32> <i32 1, i32 0>
13501350
; CHECK-NEXT: [[NARROW:%.*]] = shufflevector <4 x i1> [[Y:%.*]], <4 x i1> poison, <2 x i32> <i32 0, i32 1>
13511351
; CHECK-NEXT: [[R:%.*]] = and <2 x i1> [[WIDEN]], [[NARROW]]
13521352
; CHECK-NEXT: ret <2 x i1> [[R]]

llvm/test/Transforms/InstCombine/vec_shuffle.ll

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1351,7 +1351,7 @@ define <2 x float> @frem_splat_constant1(<2 x float> %x) {
13511351

13521352
define <2 x i1> @PR40734(<1 x i1> %x, <4 x i1> %y) {
13531353
; CHECK-LABEL: @PR40734(
1354-
; CHECK-NEXT: [[WIDEN:%.*]] = shufflevector <1 x i1> zeroinitializer, <1 x i1> [[X:%.*]], <2 x i32> <i32 0, i32 1>
1354+
; CHECK-NEXT: [[WIDEN:%.*]] = shufflevector <1 x i1> [[X:%.*]], <1 x i1> zeroinitializer, <2 x i32> <i32 1, i32 0>
13551355
; CHECK-NEXT: [[NARROW:%.*]] = shufflevector <4 x i1> [[Y:%.*]], <4 x i1> poison, <2 x i32> <i32 0, i32 1>
13561356
; CHECK-NEXT: [[R:%.*]] = and <2 x i1> [[WIDEN]], [[NARROW]]
13571357
; CHECK-NEXT: ret <2 x i1> [[R]]
@@ -2335,7 +2335,7 @@ define <2 x float> @uitofp_shuf_narrow(<4 x i32> %x, <4 x i32> %y) {
23352335
define <4 x i16> @blend_elements_from_load(ptr align 8 %_0) {
23362336
; CHECK-LABEL: @blend_elements_from_load(
23372337
; CHECK-NEXT: [[LOAD:%.*]] = load <3 x i16>, ptr [[_0:%.*]], align 8
2338-
; CHECK-NEXT: [[RV:%.*]] = shufflevector <3 x i16> <i16 0, i16 undef, i16 poison>, <3 x i16> [[LOAD]], <4 x i32> <i32 0, i32 1, i32 3, i32 5>
2338+
; CHECK-NEXT: [[RV:%.*]] = shufflevector <3 x i16> [[LOAD]], <3 x i16> <i16 0, i16 undef, i16 poison>, <4 x i32> <i32 3, i32 4, i32 0, i32 2>
23392339
; CHECK-NEXT: ret <4 x i16> [[RV]]
23402340
;
23412341
%load = load <3 x i16>, ptr %_0, align 8
@@ -2377,3 +2377,42 @@ define <2 x i32> @not_splat_shuffle2(i32 %x) {
23772377
%shuf = shufflevector <2 x i32> %vec, <2 x i32> undef, <2 x i32> <i32 1, i32 3>
23782378
ret <2 x i32> %shuf
23792379
}
2380+
2381+
define <2 x i32> @commutative0(<2 x i32> %x) {
2382+
; CHECK-LABEL: @commutative0(
2383+
; CHECK-NEXT: [[SHUF:%.*]] = shufflevector <2 x i32> [[X:%.*]], <2 x i32> poison, <2 x i32> <i32 poison, i32 1>
2384+
; CHECK-NEXT: ret <2 x i32> [[SHUF]]
2385+
;
2386+
%shuf = shufflevector <2 x i32> poison, <2 x i32> %x, <2 x i32> <i32 0, i32 3>
2387+
ret <2 x i32> %shuf
2388+
}
2389+
2390+
define <2 x i32> @commutative1(<2 x i32> %x) {
2391+
; CHECK-LABEL: @commutative1(
2392+
; CHECK-NEXT: [[SHUF1:%.*]] = insertelement <2 x i32> [[X:%.*]], i32 undef, i64 0
2393+
; CHECK-NEXT: ret <2 x i32> [[SHUF1]]
2394+
;
2395+
%shuf = shufflevector <2 x i32> undef, <2 x i32> %x, <2 x i32> <i32 0, i32 3>
2396+
ret <2 x i32> %shuf
2397+
}
2398+
2399+
define <4 x i32> @commutative2(<4 x i32> %x) {
2400+
; CHECK-LABEL: @commutative2(
2401+
; CHECK-NEXT: [[SHUF:%.*]] = shufflevector <4 x i32> [[X:%.*]], <4 x i32> <i32 7, i32 poison, i32 -1, i32 poison>, <4 x i32> <i32 4, i32 1, i32 6, i32 3>
2402+
; CHECK-NEXT: ret <4 x i32> [[SHUF]]
2403+
;
2404+
%shuf = shufflevector <4 x i32> <i32 7, i32 42, i32 -1, i32 3>, <4 x i32> %x, <4 x i32> <i32 0, i32 5, i32 2, i32 7>
2405+
ret <4 x i32> %shuf
2406+
}
2407+
2408+
define <2 x i32> @commutative3(<2 x i32> %x, <2 x i16> %y) {
2409+
; CHECK-LABEL: @commutative3(
2410+
; CHECK-NEXT: [[ZX:%.*]] = zext <2 x i16> [[Y:%.*]] to <2 x i32>
2411+
; CHECK-NEXT: [[SHUF:%.*]] = shufflevector <2 x i32> [[X:%.*]], <2 x i32> [[ZX]], <2 x i32> <i32 2, i32 1>
2412+
; CHECK-NEXT: ret <2 x i32> [[SHUF]]
2413+
;
2414+
2415+
%zx = zext <2 x i16> %y to <2 x i32>
2416+
%shuf = shufflevector <2 x i32> %zx, <2 x i32> %x, <2 x i32> <i32 0, i32 3>
2417+
ret <2 x i32> %shuf
2418+
}

llvm/test/Transforms/SLPVectorizer/X86/alternate-cast-inseltpoison.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ define <8 x float> @fneg_fabs(<8 x float> %a) {
7878
; CHECK-LABEL: @fneg_fabs(
7979
; CHECK-NEXT: [[TMP1:%.*]] = fneg <8 x float> [[A:%.*]]
8080
; CHECK-NEXT: [[TMP2:%.*]] = call <8 x float> @llvm.fabs.v8f32(<8 x float> [[A]])
81-
; CHECK-NEXT: [[DOTUNCASTED:%.*]] = shufflevector <8 x float> [[TMP1]], <8 x float> [[TMP2]], <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 12, i32 13, i32 14, i32 15>
81+
; CHECK-NEXT: [[DOTUNCASTED:%.*]] = shufflevector <8 x float> [[TMP2]], <8 x float> [[TMP1]], <8 x i32> <i32 8, i32 9, i32 10, i32 11, i32 4, i32 5, i32 6, i32 7>
8282
; CHECK-NEXT: ret <8 x float> [[DOTUNCASTED]]
8383
;
8484
%a0 = extractelement <8 x float> %a, i32 0

llvm/test/Transforms/SLPVectorizer/X86/alternate-cast.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ define <8 x float> @fneg_fabs(<8 x float> %a) {
7878
; CHECK-LABEL: @fneg_fabs(
7979
; CHECK-NEXT: [[TMP1:%.*]] = fneg <8 x float> [[A:%.*]]
8080
; CHECK-NEXT: [[TMP2:%.*]] = call <8 x float> @llvm.fabs.v8f32(<8 x float> [[A]])
81-
; CHECK-NEXT: [[DOTUNCASTED:%.*]] = shufflevector <8 x float> [[TMP1]], <8 x float> [[TMP2]], <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 12, i32 13, i32 14, i32 15>
81+
; CHECK-NEXT: [[DOTUNCASTED:%.*]] = shufflevector <8 x float> [[TMP2]], <8 x float> [[TMP1]], <8 x i32> <i32 8, i32 9, i32 10, i32 11, i32 4, i32 5, i32 6, i32 7>
8282
; CHECK-NEXT: ret <8 x float> [[DOTUNCASTED]]
8383
;
8484
%a0 = extractelement <8 x float> %a, i32 0

0 commit comments

Comments
 (0)