diff options
author | Sam Parker <sam.parker@arm.com> | 2020-01-14 11:02:32 +0000 |
---|---|---|
committer | Sam Parker <sam.parker@arm.com> | 2020-01-14 11:41:17 +0000 |
commit | e73b20c57dc7a8c847ebadeb7e19c08ec84f5bd7 (patch) | |
tree | 676fcee3e00876793f546d9b2fd621411c56b5ef /llvm/lib/Target/ARM | |
parent | d6ea8ff0d74bfe5cd181ccfe91c2c300c5f7a35d (diff) | |
download | bcm5719-llvm-e73b20c57dc7a8c847ebadeb7e19c08ec84f5bd7.tar.gz bcm5719-llvm-e73b20c57dc7a8c847ebadeb7e19c08ec84f5bd7.zip |
[ARM][MVE] Disallow VPSEL for tail predication
Due to the current way that we collect predicated instructions, we
can't easily handle vpsel in tail predicated loops. There are a
couple of issues:
1) It will use the VPR as a predicate operand, but doesn't have to be
instead a VPT block, which means we can assert while building up
the VPT block because we don't find another VPST to being a new
one.
2) VPSEL still requires a VPR operand even after tail predicating,
which means we can't remove it unless there is another
instruction, such as vcmp, that can provide the VPR def.
The first issue should be a relatively simple fix in the logic of the
LowOverheadLoops pass, whereas the second will require us to
represent the 'implicit' tail predication with an explicit value.
Differential Revision: https://reviews.llvm.org/D72629
Diffstat (limited to 'llvm/lib/Target/ARM')
-rw-r--r-- | llvm/lib/Target/ARM/ARMInstrMVE.td | 1 | ||||
-rw-r--r-- | llvm/lib/Target/ARM/ARMLowOverheadLoops.cpp | 19 |
2 files changed, 16 insertions, 4 deletions
diff --git a/llvm/lib/Target/ARM/ARMInstrMVE.td b/llvm/lib/Target/ARM/ARMInstrMVE.td index 2b454b4186a..325c9153491 100644 --- a/llvm/lib/Target/ARM/ARMInstrMVE.td +++ b/llvm/lib/Target/ARM/ARMInstrMVE.td @@ -5712,7 +5712,6 @@ def MVE_VPSEL : MVE_p<(outs MQPR:$Qd), (ins MQPR:$Qn, MQPR:$Qm), NoItinerary, let Inst{4} = 0b0; let Inst{3-1} = Qm{2-0}; let Inst{0} = 0b1; - let validForTailPredication = 1; } foreach suffix = ["s8", "s16", "s32", "u8", "u16", "u32", diff --git a/llvm/lib/Target/ARM/ARMLowOverheadLoops.cpp b/llvm/lib/Target/ARM/ARMLowOverheadLoops.cpp index 34757df3a79..066b385ed91 100644 --- a/llvm/lib/Target/ARM/ARMLowOverheadLoops.cpp +++ b/llvm/lib/Target/ARM/ARMLowOverheadLoops.cpp @@ -485,6 +485,9 @@ void LowOverheadLoop::CheckLegality(ARMBasicBlockUtils *BBUtils, } bool LowOverheadLoop::RecordVPTBlocks(MachineInstr* MI) { + if (CannotTailPredicate) + return false; + // Only support a single vctp. if (isVCTP(MI) && VCTP) return false; @@ -494,10 +497,20 @@ bool LowOverheadLoop::RecordVPTBlocks(MachineInstr* MI) { VPTBlocks.emplace_back(MI, CurrentPredicate); CurrentBlock = &VPTBlocks.back(); return true; - } - - if (isVCTP(MI)) + } else if (isVCTP(MI)) VCTP = MI; + else if (MI->getOpcode() == ARM::MVE_VPSEL || + MI->getOpcode() == ARM::MVE_VPNOT) + return false; + + // TODO: Allow VPSEL and VPNOT, we currently cannot because: + // 1) It will use the VPR as a predicate operand, but doesn't have to be + // instead a VPT block, which means we can assert while building up + // the VPT block because we don't find another VPST to being a new + // one. + // 2) VPSEL still requires a VPR operand even after tail predicating, + // which means we can't remove it unless there is another + // instruction, such as vcmp, that can provide the VPR def. unsigned VPROpNum = MI->getNumOperands() - 1; bool IsUse = false; |