summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/ARM
diff options
context:
space:
mode:
authorSam Parker <sam.parker@arm.com>2020-01-14 11:02:32 +0000
committerSam Parker <sam.parker@arm.com>2020-01-14 11:41:17 +0000
commite73b20c57dc7a8c847ebadeb7e19c08ec84f5bd7 (patch)
tree676fcee3e00876793f546d9b2fd621411c56b5ef /llvm/lib/Target/ARM
parentd6ea8ff0d74bfe5cd181ccfe91c2c300c5f7a35d (diff)
downloadbcm5719-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.td1
-rw-r--r--llvm/lib/Target/ARM/ARMLowOverheadLoops.cpp19
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;
OpenPOWER on IntegriCloud