summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/ARM/ARMLowOverheadLoops.cpp
diff options
context:
space:
mode:
authorSam Parker <sam.parker@arm.com>2019-07-11 09:56:15 +0000
committerSam Parker <sam.parker@arm.com>2019-07-11 09:56:15 +0000
commit08b4a8da07aa2335c44a40aa5a9951c2ee909e6b (patch)
treec8b0d7b8083cf8ede5d20306a2022f362f635418 /llvm/lib/Target/ARM/ARMLowOverheadLoops.cpp
parentad54935c7781008d3ad780767aec309f28360ff9 (diff)
downloadbcm5719-llvm-08b4a8da07aa2335c44a40aa5a9951c2ee909e6b.tar.gz
bcm5719-llvm-08b4a8da07aa2335c44a40aa5a9951c2ee909e6b.zip
[ARM][LowOverheadLoops] Correct offset checking
This patch addresses a couple of problems: 1) The maximum supported offset of LE is -4094. 2) The offset of WLS also needs to be checked, this uses a maximum positive offset of 4094. The use of BasicBlockUtils has been changed because the block offsets weren't being initialised, but the isBBInRange checks both positive and negative offsets. ARMISelLowering has been tweaked because the test case presented another pattern that we weren't supporting. llvm-svn: 365749
Diffstat (limited to 'llvm/lib/Target/ARM/ARMLowOverheadLoops.cpp')
-rw-r--r--llvm/lib/Target/ARM/ARMLowOverheadLoops.cpp16
1 files changed, 13 insertions, 3 deletions
diff --git a/llvm/lib/Target/ARM/ARMLowOverheadLoops.cpp b/llvm/lib/Target/ARM/ARMLowOverheadLoops.cpp
index a790ab0f852..cedf3bd3c74 100644
--- a/llvm/lib/Target/ARM/ARMLowOverheadLoops.cpp
+++ b/llvm/lib/Target/ARM/ARMLowOverheadLoops.cpp
@@ -91,6 +91,7 @@ bool ARMLowOverheadLoops::runOnMachineFunction(MachineFunction &MF) {
MF.getSubtarget().getInstrInfo());
BBUtils = std::unique_ptr<ARMBasicBlockUtils>(new ARMBasicBlockUtils(MF));
BBUtils->computeAllBlockSizes();
+ BBUtils->adjustBBOffsetsAfter(&MF.front());
bool Changed = false;
for (auto ML : MLI) {
@@ -200,9 +201,18 @@ bool ARMLowOverheadLoops::ProcessLoop(MachineLoop *ML) {
End->getOperand(1).getMBB() != ML->getHeader())
report_fatal_error("Expected LoopEnd to target Loop Header");
- // The LE instructions has 12-bits for the label offset.
- if (!BBUtils->isBBInRange(End, ML->getHeader(), 4096)) {
- LLVM_DEBUG(dbgs() << "ARM Loops: Too large for a low-overhead loop!\n");
+ // The WLS and LE instructions have 12-bits for the label offset. WLS
+ // requires a positive offset, while LE uses negative.
+ if (BBUtils->getOffsetOf(End) < BBUtils->getOffsetOf(ML->getHeader()) ||
+ !BBUtils->isBBInRange(End, ML->getHeader(), 4094)) {
+ LLVM_DEBUG(dbgs() << "ARM Loops: LE offset is out-of-range\n");
+ Revert = true;
+ }
+ if (Start->getOpcode() == ARM::t2WhileLoopStart &&
+ (BBUtils->getOffsetOf(Start) >
+ BBUtils->getOffsetOf(Start->getOperand(1).getMBB()) ||
+ !BBUtils->isBBInRange(Start, Start->getOperand(1).getMBB(), 4094))) {
+ LLVM_DEBUG(dbgs() << "ARM Loops: WLS offset is out-of-range!\n");
Revert = true;
}
OpenPOWER on IntegriCloud