mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-22 02:33:06 +01:00
[GlobalISel] Add combine for merge(unmerge) and use AArch64 postlegal-combiner.
Differential Revision: https://reviews.llvm.org/D106761
This commit is contained in:
parent
cd521f45d9
commit
b09f2e63d9
@ -264,6 +264,9 @@ public:
|
|||||||
void applyCombineShlOfExtend(MachineInstr &MI,
|
void applyCombineShlOfExtend(MachineInstr &MI,
|
||||||
const RegisterImmPair &MatchData);
|
const RegisterImmPair &MatchData);
|
||||||
|
|
||||||
|
/// Fold away a merge of an unmerge of the corresponding values.
|
||||||
|
bool matchCombineMergeUnmerge(MachineInstr &MI, Register &MatchInfo);
|
||||||
|
|
||||||
/// Reduce a shift by a constant to an unmerge and a shift on a half sized
|
/// Reduce a shift by a constant to an unmerge and a shift on a half sized
|
||||||
/// type. This will not produce a shift smaller than \p TargetShiftSize.
|
/// type. This will not produce a shift smaller than \p TargetShiftSize.
|
||||||
bool matchCombineShiftToUnmerge(MachineInstr &MI, unsigned TargetShiftSize,
|
bool matchCombineShiftToUnmerge(MachineInstr &MI, unsigned TargetShiftSize,
|
||||||
|
@ -490,6 +490,14 @@ def unmerge_merge : GICombineRule<
|
|||||||
(apply [{ Helper.applyCombineUnmergeMergeToPlainValues(*${d}, ${info}); }])
|
(apply [{ Helper.applyCombineUnmergeMergeToPlainValues(*${d}, ${info}); }])
|
||||||
>;
|
>;
|
||||||
|
|
||||||
|
// Fold merge(unmerge).
|
||||||
|
def merge_unmerge : GICombineRule<
|
||||||
|
(defs root:$d, register_matchinfo:$matchinfo),
|
||||||
|
(match (wip_match_opcode G_MERGE_VALUES):$d,
|
||||||
|
[{ return Helper.matchCombineMergeUnmerge(*${d}, ${matchinfo}); }]),
|
||||||
|
(apply [{ Helper.replaceSingleDefInstWithReg(*${d}, ${matchinfo}); }])
|
||||||
|
>;
|
||||||
|
|
||||||
// Fold (fabs (fabs x)) -> (fabs x).
|
// Fold (fabs (fabs x)) -> (fabs x).
|
||||||
def fabs_fabs_fold: GICombineRule<
|
def fabs_fabs_fold: GICombineRule<
|
||||||
(defs root:$root, register_matchinfo:$matchinfo),
|
(defs root:$root, register_matchinfo:$matchinfo),
|
||||||
@ -694,7 +702,7 @@ def all_combines : GICombineGroup<[trivial_combines, insert_vec_elt_combines,
|
|||||||
known_bits_simplifications, ext_ext_fold,
|
known_bits_simplifications, ext_ext_fold,
|
||||||
not_cmp_fold, opt_brcond_by_inverting_cond,
|
not_cmp_fold, opt_brcond_by_inverting_cond,
|
||||||
unmerge_merge, fabs_fabs_fold, unmerge_cst, unmerge_dead_to_trunc,
|
unmerge_merge, fabs_fabs_fold, unmerge_cst, unmerge_dead_to_trunc,
|
||||||
unmerge_zext_to_zext, trunc_ext_fold, trunc_shl,
|
unmerge_zext_to_zext, merge_unmerge, trunc_ext_fold, trunc_shl,
|
||||||
const_combines, xor_of_and_with_same_reg, ptr_add_with_zero,
|
const_combines, xor_of_and_with_same_reg, ptr_add_with_zero,
|
||||||
shift_immed_chain, shift_of_shifted_logic_chain, load_or_combine,
|
shift_immed_chain, shift_of_shifted_logic_chain, load_or_combine,
|
||||||
div_rem_to_divrem, funnel_shift_combines, form_bitfield_extract]>;
|
div_rem_to_divrem, funnel_shift_combines, form_bitfield_extract]>;
|
||||||
|
@ -2014,6 +2014,25 @@ void CombinerHelper::applyCombineShlOfExtend(MachineInstr &MI,
|
|||||||
MI.eraseFromParent();
|
MI.eraseFromParent();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CombinerHelper::matchCombineMergeUnmerge(MachineInstr &MI,
|
||||||
|
Register &MatchInfo) {
|
||||||
|
GMerge &Merge = cast<GMerge>(MI);
|
||||||
|
SmallVector<Register, 16> MergedValues;
|
||||||
|
for (unsigned I = 0; I < Merge.getNumSources(); ++I)
|
||||||
|
MergedValues.emplace_back(Merge.getSourceReg(I));
|
||||||
|
|
||||||
|
auto *Unmerge = getOpcodeDef<GUnmerge>(MergedValues[0], MRI);
|
||||||
|
if (!Unmerge || Unmerge->getNumDefs() != Merge.getNumSources())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
for (unsigned I = 0; I < MergedValues.size(); ++I)
|
||||||
|
if (MergedValues[I] != Unmerge->getReg(I))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
MatchInfo = Unmerge->getSourceReg();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static Register peekThroughBitcast(Register Reg,
|
static Register peekThroughBitcast(Register Reg,
|
||||||
const MachineRegisterInfo &MRI) {
|
const MachineRegisterInfo &MRI) {
|
||||||
while (mi_match(Reg, MRI, m_GBitcast(m_Reg(Reg))))
|
while (mi_match(Reg, MRI, m_GBitcast(m_Reg(Reg))))
|
||||||
|
@ -203,6 +203,6 @@ def AArch64PostLegalizerCombinerHelper
|
|||||||
extractvecelt_pairwise_add, redundant_or,
|
extractvecelt_pairwise_add, redundant_or,
|
||||||
mul_const, redundant_sext_inreg,
|
mul_const, redundant_sext_inreg,
|
||||||
form_bitfield_extract, rotate_out_of_range,
|
form_bitfield_extract, rotate_out_of_range,
|
||||||
icmp_to_true_false_known_bits]> {
|
icmp_to_true_false_known_bits, merge_unmerge]> {
|
||||||
let DisableRuleOption = "aarch64postlegalizercombiner-disable-rule";
|
let DisableRuleOption = "aarch64postlegalizercombiner-disable-rule";
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,70 @@
|
|||||||
|
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
|
||||||
|
# RUN: llc -mtriple aarch64 -run-pass=aarch64-postlegalizer-combiner -verify-machineinstrs %s -o - | FileCheck %s
|
||||||
|
|
||||||
|
---
|
||||||
|
name: merge_unmerge
|
||||||
|
alignment: 4
|
||||||
|
legalized: true
|
||||||
|
liveins:
|
||||||
|
- { reg: '$w0' }
|
||||||
|
body: |
|
||||||
|
bb.1.entry:
|
||||||
|
liveins: $x0
|
||||||
|
|
||||||
|
; CHECK-LABEL: name: merge_unmerge
|
||||||
|
; CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY $x0
|
||||||
|
; CHECK: $x0 = COPY [[COPY]](s64)
|
||||||
|
; CHECK: RET_ReallyLR implicit $x0
|
||||||
|
%0:_(s64) = COPY $x0
|
||||||
|
%a:_(s32), %b:_(s32) = G_UNMERGE_VALUES %0
|
||||||
|
%merge:_(s64) = G_MERGE_VALUES %a, %b
|
||||||
|
$x0 = COPY %merge(s64)
|
||||||
|
RET_ReallyLR implicit $x0
|
||||||
|
|
||||||
|
...
|
||||||
|
---
|
||||||
|
name: merge_unmerge_mismatched_order
|
||||||
|
alignment: 4
|
||||||
|
legalized: true
|
||||||
|
liveins:
|
||||||
|
- { reg: '$w0' }
|
||||||
|
body: |
|
||||||
|
bb.1.entry:
|
||||||
|
liveins: $x0
|
||||||
|
|
||||||
|
; CHECK-LABEL: name: merge_unmerge_mismatched_order
|
||||||
|
; CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY $x0
|
||||||
|
; CHECK: %b:_(s32), %a:_(s32) = G_UNMERGE_VALUES [[COPY]](s64)
|
||||||
|
; CHECK: %merge:_(s64) = G_MERGE_VALUES %a(s32), %b(s32)
|
||||||
|
; CHECK: $x0 = COPY %merge(s64)
|
||||||
|
; CHECK: RET_ReallyLR implicit $x0
|
||||||
|
%0:_(s64) = COPY $x0
|
||||||
|
%b:_(s32), %a:_(s32) = G_UNMERGE_VALUES %0
|
||||||
|
%merge:_(s64) = G_MERGE_VALUES %a, %b
|
||||||
|
$x0 = COPY %merge(s64)
|
||||||
|
RET_ReallyLR implicit $x0
|
||||||
|
|
||||||
|
...
|
||||||
|
---
|
||||||
|
name: merge_unmerge_mismatched_num_defs
|
||||||
|
alignment: 4
|
||||||
|
legalized: true
|
||||||
|
liveins:
|
||||||
|
- { reg: '$w0' }
|
||||||
|
body: |
|
||||||
|
bb.1.entry:
|
||||||
|
liveins: $q0
|
||||||
|
|
||||||
|
; CHECK-LABEL: name: merge_unmerge_mismatched_num_defs
|
||||||
|
; CHECK: [[COPY:%[0-9]+]]:_(s128) = COPY $q0
|
||||||
|
; CHECK: %a:_(s32), %b:_(s32), %c:_(s32), %d:_(s32) = G_UNMERGE_VALUES [[COPY]](s128)
|
||||||
|
; CHECK: %merge:_(s64) = G_MERGE_VALUES %a(s32), %b(s32)
|
||||||
|
; CHECK: $x0 = COPY %merge(s64)
|
||||||
|
; CHECK: RET_ReallyLR implicit $x0
|
||||||
|
%0:_(s128) = COPY $q0
|
||||||
|
%a:_(s32), %b:_(s32), %c:_(s32), %d:_(s32) = G_UNMERGE_VALUES %0
|
||||||
|
%merge:_(s64) = G_MERGE_VALUES %a, %b
|
||||||
|
$x0 = COPY %merge(s64)
|
||||||
|
RET_ReallyLR implicit $x0
|
||||||
|
|
||||||
|
...
|
Loading…
Reference in New Issue
Block a user