summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target
diff options
context:
space:
mode:
authorMartin Storsjo <martin@martin.st>2018-08-22 20:34:12 +0000
committerMartin Storsjo <martin@martin.st>2018-08-22 20:34:12 +0000
commit5ab1d107bb247db7e802e7041c4314bc6afcaa05 (patch)
tree6af75e2e14035cf758a004c17306a95973d48a7d /llvm/lib/Target
parentd3b29223a8d36bdddb5d8c24cf3f81d0a989f955 (diff)
downloadbcm5719-llvm-5ab1d107bb247db7e802e7041c4314bc6afcaa05.tar.gz
bcm5719-llvm-5ab1d107bb247db7e802e7041c4314bc6afcaa05.zip
[ARM] Avoid injecting constant islands in movw+movt pairs on Windows
On Windows, movw+movt pairs with relocations are handled with a single relocation that covers them both. Therefore we can't inject anything between these instructions, otherwise the relocation (which in LLVM only is treated as the movw instruction's relocation, while the movt instruction's relocation is dropped) will end up bogus. These instructions are bundled up until right before the constant islands pass, making this effectively the only place that can split them apart. Differential Revision: https://reviews.llvm.org/D51032 llvm-svn: 340451
Diffstat (limited to 'llvm/lib/Target')
-rw-r--r--llvm/lib/Target/ARM/ARMConstantIslandPass.cpp16
1 files changed, 16 insertions, 0 deletions
diff --git a/llvm/lib/Target/ARM/ARMConstantIslandPass.cpp b/llvm/lib/Target/ARM/ARMConstantIslandPass.cpp
index 2c4738d3cb7..5e97c4cb35e 100644
--- a/llvm/lib/Target/ARM/ARMConstantIslandPass.cpp
+++ b/llvm/lib/Target/ARM/ARMConstantIslandPass.cpp
@@ -1420,6 +1420,22 @@ void ARMConstantIslands::createNewWater(unsigned CPUserIndex,
MI = LastIT;
}
+ // Avoid splitting a MOVW+MOVT pair with a relocation on Windows.
+ // On Windows, this instruction pair is covered by one single
+ // IMAGE_REL_ARM_MOV32T relocation which covers both instructions. If a
+ // constant island is injected inbetween them, the relocation will clobber
+ // the instruction and fail to update the MOVT instruction.
+ // (These instructions are bundled up until right before the ConstantIslands
+ // pass.)
+ if (STI->isTargetWindows() && isThumb && MI->getOpcode() == ARM::t2MOVTi16 &&
+ (MI->getOperand(2).getTargetFlags() & ARMII::MO_OPTION_MASK) ==
+ ARMII::MO_HI16) {
+ --MI;
+ assert(MI->getOpcode() == ARM::t2MOVi16 &&
+ (MI->getOperand(1).getTargetFlags() & ARMII::MO_OPTION_MASK) ==
+ ARMII::MO_LO16);
+ }
+
// We really must not split an IT block.
LLVM_DEBUG(unsigned PredReg; assert(
!isThumb || getITInstrPredicate(*MI, PredReg) == ARMCC::AL));
OpenPOWER on IntegriCloud