diff options
author | Martin Storsjo <martin@martin.st> | 2018-08-22 20:34:12 +0000 |
---|---|---|
committer | Martin Storsjo <martin@martin.st> | 2018-08-22 20:34:12 +0000 |
commit | 5ab1d107bb247db7e802e7041c4314bc6afcaa05 (patch) | |
tree | 6af75e2e14035cf758a004c17306a95973d48a7d /llvm/lib/Target | |
parent | d3b29223a8d36bdddb5d8c24cf3f81d0a989f955 (diff) | |
download | bcm5719-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.cpp | 16 |
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)); |