diff --git a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp index 534a1a82e0d2..101534105116 100644 --- a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp +++ b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp @@ -594,6 +594,50 @@ bool CombinerHelper::tryCombineShuffleVector(MachineInstr &MI) { return true; } + // {n/2, n/2+1, ..., n, 0, 1, ..., n/2-1} + GeneratorType FirstHalf = adderGenerator(0, SrcNumElts / 2, 1); + GeneratorType SecondHalf = adderGenerator(SrcNumElts / 2, SrcNumElts, 1); + GeneratorType Reverse = + concatGenerators(SmallVector{FirstHalf, SecondHalf}); + + if (matchCombineShuffleVector(MI, Reverse, SrcNumElts)) { + // The shuffle is concatenating multiple vectors together. + // Collect the different operands for that. + Register UndefReg; + const Register Src1 = MI.getOperand(1).getReg(); + const Register Src2 = MI.getOperand(2).getReg(); + const ArrayRef Mask = MI.getOperand(3).getShuffleMask(); + + // The destination can be longer than the source, so we separate them into + // equal blocks and check them separately to see if one of the blocks can be + // copied whole. + unsigned NumConcat = DstNumElts / SrcNumElts; + unsigned Index = 0; + for (unsigned Concat = 0; Concat < NumConcat; Concat++) { + unsigned Target = (Concat + 1) * SrcNumElts; + while (Index < Target) { + int MaskElt = Mask[Index]; + if (MaskElt >= 0) { + Ops.push_back((MaskElt < (int)SrcNumElts) ? Src1 : Src2); + break; + } + Index++; + } + + if (Index == Target) { + if (!UndefReg) { + Builder.setInsertPt(*MI.getParent(), MI); + UndefReg = Builder.buildUndef(SrcTy).getReg(0); + } + Ops.push_back(UndefReg); + } + + Index = Target; + } + applyCombineShuffleVector(MI, {Ops[1], Ops[0]}); + return true; + } + return false; } diff --git a/llvm/test/CodeGen/AIE/aie2/GlobalISel/prelegalizercombiner-shufflevector.mir b/llvm/test/CodeGen/AIE/aie2/GlobalISel/prelegalizercombiner-shufflevector.mir index 5b8e73165623..5089018c5a9c 100644 --- a/llvm/test/CodeGen/AIE/aie2/GlobalISel/prelegalizercombiner-shufflevector.mir +++ b/llvm/test/CodeGen/AIE/aie2/GlobalISel/prelegalizercombiner-shufflevector.mir @@ -682,3 +682,172 @@ body: | %3:_(<128 x s8>) = G_SHUFFLE_VECTOR %1:_(<128 x s8>), %2:_(<128 x s8>), shufflemask(128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63) PseudoRET implicit $lr, implicit %3 ... + +--- +name: concat_vector_reverse_32_512 +legalized: false +body: | + bb.1.entry: + liveins: $wl2, $wl4 + ; CHECK-LABEL: name: concat_vector_reverse_32_512 + ; CHECK: liveins: $wl2, $wl4 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<8 x s32>) = COPY $wl2 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<8 x s32>) = COPY $wl4 + ; CHECK-NEXT: [[CONCAT_VECTORS:%[0-9]+]]:_(<16 x s32>) = G_CONCAT_VECTORS [[COPY1]](<8 x s32>), [[COPY]](<8 x s32>) + ; CHECK-NEXT: $x0 = COPY [[CONCAT_VECTORS]](<16 x s32>) + ; CHECK-NEXT: PseudoRET implicit $lr, implicit $x0 + %1:_(<8 x s32>) = COPY $wl2 + %2:_(<8 x s32>) = COPY $wl4 + %0:_(<16 x s32>) = G_SHUFFLE_VECTOR %1:_(<8 x s32>), %2:_, shufflemask(8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7) + $x0 = COPY %0:_(<16 x s32>) + PseudoRET implicit $lr, implicit $x0 +... + +--- +name: concat_vector_reverse_32_512_undef_start_first +legalized: false +body: | + bb.1.entry: + liveins: $wl2, $wl4 + ; CHECK-LABEL: name: concat_vector_reverse_32_512_undef_start_first + ; CHECK: liveins: $wl2, $wl4 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<8 x s32>) = COPY $wl2 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<8 x s32>) = COPY $wl4 + ; CHECK-NEXT: [[CONCAT_VECTORS:%[0-9]+]]:_(<16 x s32>) = G_CONCAT_VECTORS [[COPY1]](<8 x s32>), [[COPY]](<8 x s32>) + ; CHECK-NEXT: $x0 = COPY [[CONCAT_VECTORS]](<16 x s32>) + ; CHECK-NEXT: PseudoRET implicit $lr, implicit $x0 + %1:_(<8 x s32>) = COPY $wl2 + %2:_(<8 x s32>) = COPY $wl4 + %0:_(<16 x s32>) = G_SHUFFLE_VECTOR %1:_(<8 x s32>), %2:_, shufflemask(-1, -1, -1, -1, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7) + $x0 = COPY %0:_(<16 x s32>) + PseudoRET implicit $lr, implicit $x0 +... + +--- +name: concat_vector_reverse_32_512_start_end +legalized: false +body: | + bb.1.entry: + liveins: $wl2, $wl4 + ; CHECK-LABEL: name: concat_vector_reverse_32_512_start_end + ; CHECK: liveins: $wl2, $wl4 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<8 x s32>) = COPY $wl2 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<8 x s32>) = COPY $wl4 + ; CHECK-NEXT: [[CONCAT_VECTORS:%[0-9]+]]:_(<16 x s32>) = G_CONCAT_VECTORS [[COPY1]](<8 x s32>), [[COPY]](<8 x s32>) + ; CHECK-NEXT: $x0 = COPY [[CONCAT_VECTORS]](<16 x s32>) + ; CHECK-NEXT: PseudoRET implicit $lr, implicit $x0 + %1:_(<8 x s32>) = COPY $wl2 + %2:_(<8 x s32>) = COPY $wl4 + %0:_(<16 x s32>) = G_SHUFFLE_VECTOR %1:_(<8 x s32>), %2:_, shufflemask(8, 9, 10, 11, 12, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7) + $x0 = COPY %0:_(<16 x s32>) + PseudoRET implicit $lr, implicit $x0 +... + +--- +name: concat_vector_reverse_32_512_end_start +legalized: false +body: | + bb.1.entry: + liveins: $wl2, $wl4 + ; CHECK-LABEL: name: concat_vector_reverse_32_512_end_start + ; CHECK: liveins: $wl2, $wl4 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<8 x s32>) = COPY $wl2 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<8 x s32>) = COPY $wl4 + ; CHECK-NEXT: [[CONCAT_VECTORS:%[0-9]+]]:_(<16 x s32>) = G_CONCAT_VECTORS [[COPY1]](<8 x s32>), [[COPY]](<8 x s32>) + ; CHECK-NEXT: $x0 = COPY [[CONCAT_VECTORS]](<16 x s32>) + ; CHECK-NEXT: PseudoRET implicit $lr, implicit $x0 + %1:_(<8 x s32>) = COPY $wl2 + %2:_(<8 x s32>) = COPY $wl4 + %0:_(<16 x s32>) = G_SHUFFLE_VECTOR %1:_(<8 x s32>), %2:_, shufflemask(8, 9, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, 4, 5, 6, 7) + $x0 = COPY %0:_(<16 x s32>) + PseudoRET implicit $lr, implicit $x0 +... + +--- +name: concat_vector_reverse_32_512_end_end +legalized: false +body: | + bb.1.entry: + liveins: $wl2, $wl4 + ; CHECK-LABEL: name: concat_vector_reverse_32_512_end_end + ; CHECK: liveins: $wl2, $wl4 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<8 x s32>) = COPY $wl2 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<8 x s32>) = COPY $wl4 + ; CHECK-NEXT: [[CONCAT_VECTORS:%[0-9]+]]:_(<16 x s32>) = G_CONCAT_VECTORS [[COPY1]](<8 x s32>), [[COPY]](<8 x s32>) + ; CHECK-NEXT: $x0 = COPY [[CONCAT_VECTORS]](<16 x s32>) + ; CHECK-NEXT: PseudoRET implicit $lr, implicit $x0 + %1:_(<8 x s32>) = COPY $wl2 + %2:_(<8 x s32>) = COPY $wl4 + %0:_(<16 x s32>) = G_SHUFFLE_VECTOR %1:_(<8 x s32>), %2:_, shufflemask(8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, -1, -1, -1, -1) + $x0 = COPY %0:_(<16 x s32>) + PseudoRET implicit $lr, implicit $x0 +... + +--- +name: concat_vector_reverse_32_512_first_block +legalized: false +body: | + bb.1.entry: + liveins: $wl2, $wl4 + ; CHECK-LABEL: name: concat_vector_reverse_32_512_first_block + ; CHECK: liveins: $wl2, $wl4 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<8 x s32>) = COPY $wl2 + ; CHECK-NEXT: [[DEF:%[0-9]+]]:_(<8 x s32>) = G_IMPLICIT_DEF + ; CHECK-NEXT: [[DEF1:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF + ; CHECK-NEXT: [[CONCAT_VECTORS:%[0-9]+]]:_(<16 x s32>) = G_CONCAT_VECTORS [[DEF]](<8 x s32>), [[COPY]](<8 x s32>) + ; CHECK-NEXT: $x0 = COPY [[CONCAT_VECTORS]](<16 x s32>) + ; CHECK-NEXT: PseudoRET implicit $lr, implicit $x0 + %1:_(<8 x s32>) = COPY $wl2 + %2:_(<8 x s32>) = COPY $wl4 + %0:_(<16 x s32>) = G_SHUFFLE_VECTOR %1:_(<8 x s32>), %2:_, shufflemask(-1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7) + $x0 = COPY %0:_(<16 x s32>) + PseudoRET implicit $lr, implicit $x0 +... + +--- +name: concat_vector_reverse_32_512_second_block +legalized: false +body: | + bb.1.entry: + liveins: $wl2, $wl4 + ; CHECK-LABEL: name: concat_vector_reverse_32_512_second_block + ; CHECK: liveins: $wl2, $wl4 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<8 x s32>) = COPY $wl4 + ; CHECK-NEXT: [[DEF:%[0-9]+]]:_(<8 x s32>) = G_IMPLICIT_DEF + ; CHECK-NEXT: [[CONCAT_VECTORS:%[0-9]+]]:_(<16 x s32>) = G_CONCAT_VECTORS [[COPY]](<8 x s32>), [[DEF]](<8 x s32>) + ; CHECK-NEXT: $x0 = COPY [[CONCAT_VECTORS]](<16 x s32>) + ; CHECK-NEXT: PseudoRET implicit $lr, implicit $x0 + %1:_(<8 x s32>) = COPY $wl2 + %2:_(<8 x s32>) = COPY $wl4 + %0:_(<16 x s32>) = G_SHUFFLE_VECTOR %1:_(<8 x s32>), %2:_, shufflemask(8, 9, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1) + $x0 = COPY %0:_(<16 x s32>) + PseudoRET implicit $lr, implicit $x0 +... + +--- +name: concat_vector_reverse_32_512_random +legalized: false +body: | + bb.1.entry: + liveins: $wl2, $wl4 + ; CHECK-LABEL: name: concat_vector_reverse_32_512_random + ; CHECK: liveins: $wl2, $wl4 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<8 x s32>) = COPY $wl2 + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<8 x s32>) = COPY $wl4 + ; CHECK-NEXT: [[CONCAT_VECTORS:%[0-9]+]]:_(<16 x s32>) = G_CONCAT_VECTORS [[COPY1]](<8 x s32>), [[COPY]](<8 x s32>) + ; CHECK-NEXT: $x0 = COPY [[CONCAT_VECTORS]](<16 x s32>) + ; CHECK-NEXT: PseudoRET implicit $lr, implicit $x0 + %1:_(<8 x s32>) = COPY $wl2 + %2:_(<8 x s32>) = COPY $wl4 + %0:_(<16 x s32>) = G_SHUFFLE_VECTOR %1:_(<8 x s32>), %2:_, shufflemask(8, 9, -1, 11, 12, 13, -1, 15, 0, 1, -1, 3, 4, 5, -1, 7) + $x0 = COPY %0:_(<16 x s32>) + PseudoRET implicit $lr, implicit $x0 +...