Skip to content

Commit b5c4524

Browse files
committed
[AArch64][GlobalISel] Add a constant funnel shift post-legalizer combine.
We want to be able to produce extr instructions post-legalization. They are legal for scalars, acting as a funnel shifts 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. It doesn't feel like the best solution - any thoughts on alternatives?
1 parent 342f212 commit b5c4524

File tree

8 files changed

+340
-392
lines changed

8 files changed

+340
-392
lines changed

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

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

630-
bool matchOrShiftToFunnelShift(MachineInstr &MI, BuildFnTy &MatchInfo) const;
630+
bool matchOrShiftToFunnelShift(MachineInstr &MI, bool ScalarConstantsAreLegal,
631+
BuildFnTy &MatchInfo) const;
631632
bool matchFunnelShiftToRotate(MachineInstr &MI) const;
632633
void applyFunnelShiftToRotate(MachineInstr &MI) const;
633634
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
@@ -1000,10 +1000,18 @@ def extract_vec_elt_combines : GICombineGroup<[
10001000
def funnel_shift_from_or_shift : GICombineRule<
10011001
(defs root:$root, build_fn_matchinfo:$info),
10021002
(match (wip_match_opcode G_OR):$root,
1003-
[{ return Helper.matchOrShiftToFunnelShift(*${root}, ${info}); }]),
1003+
[{ return Helper.matchOrShiftToFunnelShift(*${root}, false, ${info}); }]),
10041004
(apply [{ Helper.applyBuildFn(*${root}, ${info}); }])
10051005
>;
10061006

1007+
def funnel_shift_from_or_shift_constants_are_legal : GICombineRule<
1008+
(defs root:$root, build_fn_matchinfo:$info),
1009+
(match (wip_match_opcode G_OR):$root,
1010+
[{ return Helper.matchOrShiftToFunnelShift(*${root}, true, ${info}); }]),
1011+
(apply [{ Helper.applyBuildFn(*${root}, ${info}); }])
1012+
>;
1013+
1014+
10071015
def funnel_shift_to_rotate : GICombineRule<
10081016
(defs root:$root),
10091017
(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
@@ -4390,6 +4390,7 @@ void CombinerHelper::applyBuildFnNoErase(
43904390
}
43914391

43924392
bool CombinerHelper::matchOrShiftToFunnelShift(MachineInstr &MI,
4393+
bool ScalarConstantsAreLegal,
43934394
BuildFnTy &MatchInfo) const {
43944395
assert(MI.getOpcode() == TargetOpcode::G_OR);
43954396

@@ -4409,31 +4410,29 @@ bool CombinerHelper::matchOrShiftToFunnelShift(MachineInstr &MI,
44094410

44104411
// Given constants C0 and C1 such that C0 + C1 is bit-width:
44114412
// (or (shl x, C0), (lshr y, C1)) -> (fshl x, y, C0) or (fshr x, y, C1)
4412-
int64_t CstShlAmt, CstLShrAmt;
4413+
int64_t CstShlAmt = 0, CstLShrAmt;
44134414
if (mi_match(ShlAmt, MRI, m_ICstOrSplat(CstShlAmt)) &&
44144415
mi_match(LShrAmt, MRI, m_ICstOrSplat(CstLShrAmt)) &&
44154416
CstShlAmt + CstLShrAmt == BitWidth) {
44164417
FshOpc = TargetOpcode::G_FSHR;
44174418
Amt = LShrAmt;
4418-
44194419
} else if (mi_match(LShrAmt, MRI,
44204420
m_GSub(m_SpecificICstOrSplat(BitWidth), m_Reg(Amt))) &&
44214421
ShlAmt == Amt) {
44224422
// (or (shl x, amt), (lshr y, (sub bw, amt))) -> (fshl x, y, amt)
44234423
FshOpc = TargetOpcode::G_FSHL;
4424-
44254424
} else if (mi_match(ShlAmt, MRI,
44264425
m_GSub(m_SpecificICstOrSplat(BitWidth), m_Reg(Amt))) &&
44274426
LShrAmt == Amt) {
44284427
// (or (shl x, (sub bw, amt)), (lshr y, amt)) -> (fshr x, y, amt)
44294428
FshOpc = TargetOpcode::G_FSHR;
4430-
44314429
} else {
44324430
return false;
44334431
}
44344432

44354433
LLT AmtTy = MRI.getType(Amt);
4436-
if (!isLegalOrBeforeLegalizer({FshOpc, {Ty, AmtTy}}))
4434+
if (!isLegalOrBeforeLegalizer({FshOpc, {Ty, AmtTy}}) &&
4435+
(!ScalarConstantsAreLegal || CstShlAmt == 0 || !Ty.isScalar()))
44374436
return false;
44384437

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

llvm/lib/Target/AArch64/AArch64Combine.td

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -367,5 +367,6 @@ def AArch64PostLegalizerCombiner
367367
select_to_minmax, or_to_bsp, combine_concat_vector,
368368
commute_constant_to_rhs, extract_vec_elt_combines,
369369
push_freeze_to_prevent_poison_from_propagating,
370-
combine_mul_cmlt, combine_use_vector_truncate, extmultomull]> {
370+
combine_mul_cmlt, combine_use_vector_truncate, extmultomull,
371+
funnel_shift_from_or_shift_constants_are_legal]> {
371372
}

llvm/test/CodeGen/AArch64/adc.ll

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -71,9 +71,8 @@ define i128 @test_shifted(i128 %a, i128 %b) {
7171
;
7272
; CHECK-GI-LABEL: test_shifted:
7373
; CHECK-GI: ; %bb.0:
74-
; CHECK-GI-NEXT: lsr x8, x2, #19
74+
; CHECK-GI-NEXT: extr x8, x3, x2, #19
7575
; CHECK-GI-NEXT: adds x0, x0, x2, lsl #45
76-
; CHECK-GI-NEXT: orr x8, x8, x3, lsl #45
7776
; CHECK-GI-NEXT: adc x1, x1, x8
7877
; CHECK-GI-NEXT: ret
7978
%rhs = shl i128 %b, 45
@@ -108,8 +107,7 @@ define i128 @test_extended(i128 %a, i16 %b) {
108107
; CHECK-GI-NEXT: sxth x8, w2
109108
; CHECK-GI-NEXT: adds x0, x0, w2, sxth #3
110109
; CHECK-GI-NEXT: asr x9, x8, #63
111-
; CHECK-GI-NEXT: lsr x8, x8, #61
112-
; CHECK-GI-NEXT: orr x8, x8, x9, lsl #3
110+
; CHECK-GI-NEXT: extr x8, x9, x8, #61
113111
; CHECK-GI-NEXT: adc x1, x1, x8
114112
; CHECK-GI-NEXT: ret
115113
%ext = sext i16 %b to i128

0 commit comments

Comments
 (0)