summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorChandler Carruth <chandlerc@gmail.com>2018-02-07 23:59:14 +0000
committerChandler Carruth <chandlerc@gmail.com>2018-02-07 23:59:14 +0000
commit0be0cfa65b0197be7501efd04c49098e013c1a58 (patch)
treeb43ec874d9133dc964cb248b14e984d95366b704 /llvm/lib
parent1a78ae3c895d0520bbb8ad2f154e737d52fe7ae2 (diff)
downloadbcm5719-llvm-0be0cfa65b0197be7501efd04c49098e013c1a58.tar.gz
bcm5719-llvm-0be0cfa65b0197be7501efd04c49098e013c1a58.zip
[x86] Fix nasty bug in the x86 backend that is essentially impossible to
hit from IR but creates a minefield for MI passes. The x86 backend has fairly powerful logic to try and fold loads that feed register operands to instructions into a memory operand on the instruction. This is almost always a good thing, but there are specific relocated loads that are only allowed to appear in specific instructions. Notably, R_X86_64_GOTTPOFF is only allowed in `movq` and `addq`. This patch blocks folding of memory operands using this relocation unless the target is in fact `addq`. The particular relocation indicates why we simply don't hit this under normal circumstances. This relocation is only used for TLS, and it gets used in very specific ways in conjunction with %fs-relative addressing. The result is that loads using this relocation are essentially never eligible for folding into an instruction's memory operands. Unless, of course, you have an MI pass that inserts usage of such a load. I have exactly such an MI pass and was greeted by truly mysterious miscompiles where the linker replaced my instruction with a completely garbage byte sequence. Go team. This is the only such relocation I'm aware of in x86, but there may be others that need to be similarly restricted. Fixes PR36165. Differential Revision: https://reviews.llvm.org/D42732 llvm-svn: 324546
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Target/X86/X86InstrInfo.cpp8
1 files changed, 8 insertions, 0 deletions
diff --git a/llvm/lib/Target/X86/X86InstrInfo.cpp b/llvm/lib/Target/X86/X86InstrInfo.cpp
index 19e9f30c91d..ab6ea1e06bc 100644
--- a/llvm/lib/Target/X86/X86InstrInfo.cpp
+++ b/llvm/lib/Target/X86/X86InstrInfo.cpp
@@ -8535,6 +8535,14 @@ MachineInstr *X86InstrInfo::foldMemoryOperandImpl(
MI.getOperand(2).getTargetFlags() == X86II::MO_GOT_ABSOLUTE_ADDRESS)
return nullptr;
+ // GOTTPOFF relocation loads can only be folded into add instructions.
+ // FIXME: Need to exclude other relocations that only support specific
+ // instructions.
+ if (MOs.size() == X86::AddrNumOperands &&
+ MOs[X86::AddrDisp].getTargetFlags() == X86II::MO_GOTTPOFF &&
+ MI.getOpcode() != X86::ADD64rr)
+ return nullptr;
+
MachineInstr *NewMI = nullptr;
// Attempt to fold any custom cases we have.
OpenPOWER on IntegriCloud