Skip to content

Commit da15b8f

Browse files
authored
[AArch64][GlobalISel] Add a constant funnel shift post-legalizer combine. (#151912)
We want to be able to produce extr instructions post-legalization. They are legal for scalars, acting as a funnel shift with a constant shift amount. Unfortunately I'm not sure if there is a way currently to represent that in the legalization rules, but it might be useful for several operations - to be able to treat and test operands with constant operands as legal or not. This adds a change to the existing matchOrShiftToFunnelShift so that AArch64 can generate such instructions post-legalization providing that the operation is scalar and the shift amount is constant.
1 parent 04e78b4 commit da15b8f

File tree

9 files changed

+703
-919
lines changed

9 files changed

+703
-919
lines changed

llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -640,7 +640,8 @@ class CombinerHelper {
640640
/// This variant does not erase \p MI after calling the build function.
641641
void applyBuildFnNoErase(MachineInstr &MI, BuildFnTy &MatchInfo) const;
642642

643-
bool matchOrShiftToFunnelShift(MachineInstr &MI, BuildFnTy &MatchInfo) const;
643+
bool matchOrShiftToFunnelShift(MachineInstr &MI, bool AllowScalarConstants,
644+
BuildFnTy &MatchInfo) const;
644645
bool matchFunnelShiftToRotate(MachineInstr &MI) const;
645646
void applyFunnelShiftToRotate(MachineInstr &MI) const;
646647
bool matchRotateOutOfRange(MachineInstr &MI) const;

llvm/include/llvm/Target/GlobalISel/Combine.td

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1013,10 +1013,18 @@ def extract_vec_elt_combines : GICombineGroup<[
10131013
def funnel_shift_from_or_shift : GICombineRule<
10141014
(defs root:$root, build_fn_matchinfo:$info),
10151015
(match (wip_match_opcode G_OR):$root,
1016-
[{ return Helper.matchOrShiftToFunnelShift(*${root}, ${info}); }]),
1016+
[{ return Helper.matchOrShiftToFunnelShift(*${root}, false, ${info}); }]),
10171017
(apply [{ Helper.applyBuildFn(*${root}, ${info}); }])
10181018
>;
10191019

1020+
def funnel_shift_from_or_shift_constants_are_legal : GICombineRule<
1021+
(defs root:$root, build_fn_matchinfo:$info),
1022+
(match (wip_match_opcode G_OR):$root,
1023+
[{ return Helper.matchOrShiftToFunnelShift(*${root}, true, ${info}); }]),
1024+
(apply [{ Helper.applyBuildFn(*${root}, ${info}); }])
1025+
>;
1026+
1027+
10201028
def funnel_shift_to_rotate : GICombineRule<
10211029
(defs root:$root),
10221030
(match (wip_match_opcode G_FSHL, G_FSHR):$root,

llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4425,6 +4425,7 @@ void CombinerHelper::applyBuildFnNoErase(
44254425
}
44264426

44274427
bool CombinerHelper::matchOrShiftToFunnelShift(MachineInstr &MI,
4428+
bool AllowScalarConstants,
44284429
BuildFnTy &MatchInfo) const {
44294430
assert(MI.getOpcode() == TargetOpcode::G_OR);
44304431

@@ -4444,31 +4445,29 @@ bool CombinerHelper::matchOrShiftToFunnelShift(MachineInstr &MI,
44444445

44454446
// Given constants C0 and C1 such that C0 + C1 is bit-width:
44464447
// (or (shl x, C0), (lshr y, C1)) -> (fshl x, y, C0) or (fshr x, y, C1)
4447-
int64_t CstShlAmt, CstLShrAmt;
4448+
int64_t CstShlAmt = 0, CstLShrAmt;
44484449
if (mi_match(ShlAmt, MRI, m_ICstOrSplat(CstShlAmt)) &&
44494450
mi_match(LShrAmt, MRI, m_ICstOrSplat(CstLShrAmt)) &&
44504451
CstShlAmt + CstLShrAmt == BitWidth) {
44514452
FshOpc = TargetOpcode::G_FSHR;
44524453
Amt = LShrAmt;
4453-
44544454
} else if (mi_match(LShrAmt, MRI,
44554455
m_GSub(m_SpecificICstOrSplat(BitWidth), m_Reg(Amt))) &&
44564456
ShlAmt == Amt) {
44574457
// (or (shl x, amt), (lshr y, (sub bw, amt))) -> (fshl x, y, amt)
44584458
FshOpc = TargetOpcode::G_FSHL;
4459-
44604459
} else if (mi_match(ShlAmt, MRI,
44614460
m_GSub(m_SpecificICstOrSplat(BitWidth), m_Reg(Amt))) &&
44624461
LShrAmt == Amt) {
44634462
// (or (shl x, (sub bw, amt)), (lshr y, amt)) -> (fshr x, y, amt)
44644463
FshOpc = TargetOpcode::G_FSHR;
4465-
44664464
} else {
44674465
return false;
44684466
}
44694467

44704468
LLT AmtTy = MRI.getType(Amt);
4471-
if (!isLegalOrBeforeLegalizer({FshOpc, {Ty, AmtTy}}))
4469+
if (!isLegalOrBeforeLegalizer({FshOpc, {Ty, AmtTy}}) &&
4470+
(!AllowScalarConstants || CstShlAmt == 0 || !Ty.isScalar()))
44724471
return false;
44734472

44744473
MatchInfo = [=](MachineIRBuilder &B) {

llvm/lib/Target/AArch64/AArch64Combine.td

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -366,6 +366,7 @@ def AArch64PostLegalizerCombiner
366366
select_to_minmax, or_to_bsp, combine_concat_vector,
367367
commute_constant_to_rhs, extract_vec_elt_combines,
368368
push_freeze_to_prevent_poison_from_propagating,
369-
combine_mul_cmlt, combine_use_vector_truncate,
370-
extmultomull, truncsat_combines, lshr_of_trunc_of_lshr]> {
369+
combine_mul_cmlt, combine_use_vector_truncate,
370+
extmultomull, truncsat_combines, lshr_of_trunc_of_lshr,
371+
funnel_shift_from_or_shift_constants_are_legal]> {
371372
}

0 commit comments

Comments
 (0)