Skip to content

[AArch64][GlobalISel] Legalize G_VECREDUCE_{MIN/MAX} #69461

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Nov 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions llvm/include/llvm/Target/GlobalISel/SelectionDAGCompat.td
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,10 @@ def : GINodeEquiv<G_VECREDUCE_FMAX, vecreduce_fmax>;
def : GINodeEquiv<G_VECREDUCE_FMIN, vecreduce_fmin>;
def : GINodeEquiv<G_VECREDUCE_FMAXIMUM, vecreduce_fmaximum>;
def : GINodeEquiv<G_VECREDUCE_FMINIMUM, vecreduce_fminimum>;
def : GINodeEquiv<G_VECREDUCE_UMIN, vecreduce_umin>;
def : GINodeEquiv<G_VECREDUCE_UMAX, vecreduce_umax>;
def : GINodeEquiv<G_VECREDUCE_SMIN, vecreduce_smin>;
def : GINodeEquiv<G_VECREDUCE_SMAX, vecreduce_smax>;

def : GINodeEquiv<G_STRICT_FADD, strict_fadd>;
def : GINodeEquiv<G_STRICT_FSUB, strict_fsub>;
Expand Down
37 changes: 37 additions & 0 deletions llvm/lib/Target/AArch64/AArch64InstrInfo.td
Original file line number Diff line number Diff line change
Expand Up @@ -6702,6 +6702,43 @@ defm : SIMDAcrossLanesUnsignedIntrinsic<"UMINV", AArch64uminv>;
def : Pat<(v2i32 (AArch64uminv (v2i32 V64:$Rn))),
(UMINPv2i32 V64:$Rn, V64:$Rn)>;

// For vecreduce_{opc} used by GlobalISel, not SDAG at the moment
// because GlobalISel allows us to specify the return register to be a FPR
multiclass SIMDAcrossLanesVecReductionIntrinsic<string baseOpc,
SDPatternOperator opNode> {
def : Pat<(i8 (opNode (v8i8 FPR64:$Rn))),
(!cast<Instruction>(!strconcat(baseOpc, "v8i8v")) FPR64:$Rn)>;

def : Pat<(i8 (opNode (v16i8 FPR128:$Rn))),
(!cast<Instruction>(!strconcat(baseOpc, "v16i8v")) FPR128:$Rn)>;

def : Pat<(i16 (opNode (v4i16 FPR64:$Rn))),
(!cast<Instruction>(!strconcat(baseOpc, "v4i16v")) FPR64:$Rn)>;

def : Pat<(i16 (opNode (v8i16 FPR128:$Rn))),
(!cast<Instruction>(!strconcat(baseOpc, "v8i16v")) FPR128:$Rn)>;

def : Pat<(i32 (opNode (v4i32 V128:$Rn))),
(!cast<Instruction>(!strconcat(baseOpc, "v4i32v")) V128:$Rn)>;
}

// For v2i32 source type, the pairwise instruction can be used instead
defm : SIMDAcrossLanesVecReductionIntrinsic<"UMINV", vecreduce_umin>;
def : Pat<(i32 (vecreduce_umin (v2i32 V64:$Rn))),
(i32 (EXTRACT_SUBREG (UMINPv2i32 V64:$Rn, V64:$Rn), ssub))>;

defm : SIMDAcrossLanesVecReductionIntrinsic<"UMAXV", vecreduce_umax>;
def : Pat<(i32 (vecreduce_umax (v2i32 V64:$Rn))),
(i32 (EXTRACT_SUBREG (UMAXPv2i32 V64:$Rn, V64:$Rn), ssub))>;

defm : SIMDAcrossLanesVecReductionIntrinsic<"SMINV", vecreduce_smin>;
def : Pat<(i32 (vecreduce_smin (v2i32 V64:$Rn))),
(i32 (EXTRACT_SUBREG (SMINPv2i32 V64:$Rn, V64:$Rn), ssub))>;

defm : SIMDAcrossLanesVecReductionIntrinsic<"SMAXV", vecreduce_smax>;
def : Pat<(i32 (vecreduce_smax (v2i32 V64:$Rn))),
(i32 (EXTRACT_SUBREG (SMAXPv2i32 V64:$Rn, V64:$Rn), ssub))>;

multiclass SIMDAcrossLanesSignedLongIntrinsic<string baseOpc, Intrinsic intOp> {
def : Pat<(i32 (intOp (v8i8 V64:$Rn))),
(i32 (SMOVvi16to32
Expand Down
15 changes: 15 additions & 0 deletions llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -990,6 +990,21 @@ AArch64LegalizerInfo::AArch64LegalizerInfo(const AArch64Subtarget &ST)
.scalarize(1)
.lower();

getActionDefinitionsBuilder(
{G_VECREDUCE_SMIN, G_VECREDUCE_SMAX, G_VECREDUCE_UMIN, G_VECREDUCE_UMAX})
.legalFor({{s8, v8s8},
{s8, v16s8},
{s16, v4s16},
{s16, v8s16},
{s32, v2s32},
{s32, v4s32}})
.clampMaxNumElements(1, s64, 2)
.clampMaxNumElements(1, s32, 4)
.clampMaxNumElements(1, s16, 8)
.clampMaxNumElements(1, s8, 16)
.scalarize(1)
.lower();

getActionDefinitionsBuilder(
{G_VECREDUCE_OR, G_VECREDUCE_AND, G_VECREDUCE_XOR})
// Try to break down into smaller vectors as long as they're at least 64
Expand Down
19 changes: 11 additions & 8 deletions llvm/test/CodeGen/AArch64/GlobalISel/legalizer-info-validation.mir
Original file line number Diff line number Diff line change
Expand Up @@ -769,17 +769,20 @@
# DEBUG-NEXT: .. type index coverage check SKIPPED: user-defined predicate detected
# DEBUG-NEXT: .. imm index coverage check SKIPPED: user-defined predicate detected
# DEBUG-NEXT: G_VECREDUCE_SMAX (opcode {{[0-9]+}}): 2 type indices, 0 imm indices
# DEBUG-NEXT: .. type index coverage check SKIPPED: no rules defined
# DEBUG-NEXT: .. imm index coverage check SKIPPED: no rules defined
# DEBUG-NEXT: .. opcode {{[0-9]+}} is aliased to {{[0-9]+}}
# DEBUG-NEXT: .. type index coverage check SKIPPED: user-defined predicate detected
# DEBUG-NEXT: .. imm index coverage check SKIPPED: user-defined predicate detected
# DEBUG-NEXT: G_VECREDUCE_SMIN (opcode {{[0-9]+}}): 2 type indices, 0 imm indices
# DEBUG-NEXT: .. type index coverage check SKIPPED: no rules defined
# DEBUG-NEXT: .. imm index coverage check SKIPPED: no rules defined
# DEBUG-NEXT: .. type index coverage check SKIPPED: user-defined predicate detected
# DEBUG-NEXT: .. imm index coverage check SKIPPED: user-defined predicate detected
# DEBUG-NEXT: G_VECREDUCE_UMAX (opcode {{[0-9]+}}): 2 type indices, 0 imm indices
# DEBUG-NEXT: .. type index coverage check SKIPPED: no rules defined
# DEBUG-NEXT: .. imm index coverage check SKIPPED: no rules defined
# DEBUG-NEXT: .. opcode {{[0-9]+}} is aliased to {{[0-9]+}}
# DEBUG-NEXT: .. type index coverage check SKIPPED: user-defined predicate detected
# DEBUG-NEXT: .. imm index coverage check SKIPPED: user-defined predicate detected
# DEBUG-NEXT: G_VECREDUCE_UMIN (opcode {{[0-9]+}}): 2 type indices, 0 imm indices
# DEBUG-NEXT: .. type index coverage check SKIPPED: no rules defined
# DEBUG-NEXT: .. imm index coverage check SKIPPED: no rules defined
# DEBUG-NEXT: .. opcode {{[0-9]+}} is aliased to {{[0-9]+}}
# DEBUG-NEXT: .. type index coverage check SKIPPED: user-defined predicate detected
# DEBUG-NEXT: .. imm index coverage check SKIPPED: user-defined predicate detected
# DEBUG-NEXT: G_SBFX (opcode {{[0-9]+}}): 2 type indices, 0 imm indices
# DEBUG-NEXT: .. the first uncovered type index: 2, OK
# DEBUG-NEXT: .. the first uncovered imm index: 0, OK
Expand Down
Loading