Skip to content

Commit 451bc3e

Browse files
authored
[AArch64][GlobalISel] Legalize G_VECREDUCE_{MIN/MAX} (#69461)
Legalizes G_VECREDUCE_{MIN/MAX} and selects instructions for vecreduce_{min/max}
1 parent 7ac8486 commit 451bc3e

File tree

6 files changed

+2119
-171
lines changed

6 files changed

+2119
-171
lines changed

llvm/include/llvm/Target/GlobalISel/SelectionDAGCompat.td

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,10 @@ def : GINodeEquiv<G_VECREDUCE_FMAX, vecreduce_fmax>;
173173
def : GINodeEquiv<G_VECREDUCE_FMIN, vecreduce_fmin>;
174174
def : GINodeEquiv<G_VECREDUCE_FMAXIMUM, vecreduce_fmaximum>;
175175
def : GINodeEquiv<G_VECREDUCE_FMINIMUM, vecreduce_fminimum>;
176+
def : GINodeEquiv<G_VECREDUCE_UMIN, vecreduce_umin>;
177+
def : GINodeEquiv<G_VECREDUCE_UMAX, vecreduce_umax>;
178+
def : GINodeEquiv<G_VECREDUCE_SMIN, vecreduce_smin>;
179+
def : GINodeEquiv<G_VECREDUCE_SMAX, vecreduce_smax>;
176180

177181
def : GINodeEquiv<G_STRICT_FADD, strict_fadd>;
178182
def : GINodeEquiv<G_STRICT_FSUB, strict_fsub>;

llvm/lib/Target/AArch64/AArch64InstrInfo.td

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6702,6 +6702,43 @@ defm : SIMDAcrossLanesUnsignedIntrinsic<"UMINV", AArch64uminv>;
67026702
def : Pat<(v2i32 (AArch64uminv (v2i32 V64:$Rn))),
67036703
(UMINPv2i32 V64:$Rn, V64:$Rn)>;
67046704

6705+
// For vecreduce_{opc} used by GlobalISel, not SDAG at the moment
6706+
// because GlobalISel allows us to specify the return register to be a FPR
6707+
multiclass SIMDAcrossLanesVecReductionIntrinsic<string baseOpc,
6708+
SDPatternOperator opNode> {
6709+
def : Pat<(i8 (opNode (v8i8 FPR64:$Rn))),
6710+
(!cast<Instruction>(!strconcat(baseOpc, "v8i8v")) FPR64:$Rn)>;
6711+
6712+
def : Pat<(i8 (opNode (v16i8 FPR128:$Rn))),
6713+
(!cast<Instruction>(!strconcat(baseOpc, "v16i8v")) FPR128:$Rn)>;
6714+
6715+
def : Pat<(i16 (opNode (v4i16 FPR64:$Rn))),
6716+
(!cast<Instruction>(!strconcat(baseOpc, "v4i16v")) FPR64:$Rn)>;
6717+
6718+
def : Pat<(i16 (opNode (v8i16 FPR128:$Rn))),
6719+
(!cast<Instruction>(!strconcat(baseOpc, "v8i16v")) FPR128:$Rn)>;
6720+
6721+
def : Pat<(i32 (opNode (v4i32 V128:$Rn))),
6722+
(!cast<Instruction>(!strconcat(baseOpc, "v4i32v")) V128:$Rn)>;
6723+
}
6724+
6725+
// For v2i32 source type, the pairwise instruction can be used instead
6726+
defm : SIMDAcrossLanesVecReductionIntrinsic<"UMINV", vecreduce_umin>;
6727+
def : Pat<(i32 (vecreduce_umin (v2i32 V64:$Rn))),
6728+
(i32 (EXTRACT_SUBREG (UMINPv2i32 V64:$Rn, V64:$Rn), ssub))>;
6729+
6730+
defm : SIMDAcrossLanesVecReductionIntrinsic<"UMAXV", vecreduce_umax>;
6731+
def : Pat<(i32 (vecreduce_umax (v2i32 V64:$Rn))),
6732+
(i32 (EXTRACT_SUBREG (UMAXPv2i32 V64:$Rn, V64:$Rn), ssub))>;
6733+
6734+
defm : SIMDAcrossLanesVecReductionIntrinsic<"SMINV", vecreduce_smin>;
6735+
def : Pat<(i32 (vecreduce_smin (v2i32 V64:$Rn))),
6736+
(i32 (EXTRACT_SUBREG (SMINPv2i32 V64:$Rn, V64:$Rn), ssub))>;
6737+
6738+
defm : SIMDAcrossLanesVecReductionIntrinsic<"SMAXV", vecreduce_smax>;
6739+
def : Pat<(i32 (vecreduce_smax (v2i32 V64:$Rn))),
6740+
(i32 (EXTRACT_SUBREG (SMAXPv2i32 V64:$Rn, V64:$Rn), ssub))>;
6741+
67056742
multiclass SIMDAcrossLanesSignedLongIntrinsic<string baseOpc, Intrinsic intOp> {
67066743
def : Pat<(i32 (intOp (v8i8 V64:$Rn))),
67076744
(i32 (SMOVvi16to32

llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -990,6 +990,21 @@ AArch64LegalizerInfo::AArch64LegalizerInfo(const AArch64Subtarget &ST)
990990
.scalarize(1)
991991
.lower();
992992

993+
getActionDefinitionsBuilder(
994+
{G_VECREDUCE_SMIN, G_VECREDUCE_SMAX, G_VECREDUCE_UMIN, G_VECREDUCE_UMAX})
995+
.legalFor({{s8, v8s8},
996+
{s8, v16s8},
997+
{s16, v4s16},
998+
{s16, v8s16},
999+
{s32, v2s32},
1000+
{s32, v4s32}})
1001+
.clampMaxNumElements(1, s64, 2)
1002+
.clampMaxNumElements(1, s32, 4)
1003+
.clampMaxNumElements(1, s16, 8)
1004+
.clampMaxNumElements(1, s8, 16)
1005+
.scalarize(1)
1006+
.lower();
1007+
9931008
getActionDefinitionsBuilder(
9941009
{G_VECREDUCE_OR, G_VECREDUCE_AND, G_VECREDUCE_XOR})
9951010
// Try to break down into smaller vectors as long as they're at least 64

llvm/test/CodeGen/AArch64/GlobalISel/legalizer-info-validation.mir

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -769,17 +769,20 @@
769769
# DEBUG-NEXT: .. type index coverage check SKIPPED: user-defined predicate detected
770770
# DEBUG-NEXT: .. imm index coverage check SKIPPED: user-defined predicate detected
771771
# DEBUG-NEXT: G_VECREDUCE_SMAX (opcode {{[0-9]+}}): 2 type indices, 0 imm indices
772-
# DEBUG-NEXT: .. type index coverage check SKIPPED: no rules defined
773-
# DEBUG-NEXT: .. imm index coverage check SKIPPED: no rules defined
772+
# DEBUG-NEXT: .. opcode {{[0-9]+}} is aliased to {{[0-9]+}}
773+
# DEBUG-NEXT: .. type index coverage check SKIPPED: user-defined predicate detected
774+
# DEBUG-NEXT: .. imm index coverage check SKIPPED: user-defined predicate detected
774775
# DEBUG-NEXT: G_VECREDUCE_SMIN (opcode {{[0-9]+}}): 2 type indices, 0 imm indices
775-
# DEBUG-NEXT: .. type index coverage check SKIPPED: no rules defined
776-
# DEBUG-NEXT: .. imm index coverage check SKIPPED: no rules defined
776+
# DEBUG-NEXT: .. type index coverage check SKIPPED: user-defined predicate detected
777+
# DEBUG-NEXT: .. imm index coverage check SKIPPED: user-defined predicate detected
777778
# DEBUG-NEXT: G_VECREDUCE_UMAX (opcode {{[0-9]+}}): 2 type indices, 0 imm indices
778-
# DEBUG-NEXT: .. type index coverage check SKIPPED: no rules defined
779-
# DEBUG-NEXT: .. imm index coverage check SKIPPED: no rules defined
779+
# DEBUG-NEXT: .. opcode {{[0-9]+}} is aliased to {{[0-9]+}}
780+
# DEBUG-NEXT: .. type index coverage check SKIPPED: user-defined predicate detected
781+
# DEBUG-NEXT: .. imm index coverage check SKIPPED: user-defined predicate detected
780782
# DEBUG-NEXT: G_VECREDUCE_UMIN (opcode {{[0-9]+}}): 2 type indices, 0 imm indices
781-
# DEBUG-NEXT: .. type index coverage check SKIPPED: no rules defined
782-
# DEBUG-NEXT: .. imm index coverage check SKIPPED: no rules defined
783+
# DEBUG-NEXT: .. opcode {{[0-9]+}} is aliased to {{[0-9]+}}
784+
# DEBUG-NEXT: .. type index coverage check SKIPPED: user-defined predicate detected
785+
# DEBUG-NEXT: .. imm index coverage check SKIPPED: user-defined predicate detected
783786
# DEBUG-NEXT: G_SBFX (opcode {{[0-9]+}}): 2 type indices, 0 imm indices
784787
# DEBUG-NEXT: .. the first uncovered type index: 2, OK
785788
# DEBUG-NEXT: .. the first uncovered imm index: 0, OK

0 commit comments

Comments
 (0)