Use branch funnels for virtual calls when retpoline mitigation is enabled.
authorPeter Collingbourne <peter@pcc.me.uk>
Fri, 9 Mar 2018 19:11:44 +0000 (19:11 +0000)
committerPeter Collingbourne <peter@pcc.me.uk>
Fri, 9 Mar 2018 19:11:44 +0000 (19:11 +0000)
commit2974856ad4326989052f04299affaa516985e77a
tree9be1d673e3f12d12980c7a093f7c12554c44ace4
parentdee18b82c23c1637bdfad001bfe8c62bdf8c5955
Use branch funnels for virtual calls when retpoline mitigation is enabled.

The retpoline mitigation for variant 2 of CVE-2017-5715 inhibits the
branch predictor, and as a result it can lead to a measurable loss of
performance. We can reduce the performance impact of retpolined virtual
calls by replacing them with a special construct known as a branch
funnel, which is an instruction sequence that implements virtual calls
to a set of known targets using a binary tree of direct branches. This
allows the processor to speculately execute valid implementations of the
virtual function without allowing for speculative execution of of calls
to arbitrary addresses.

This patch extends the whole-program devirtualization pass to replace
certain virtual calls with calls to branch funnels, which are
represented using a new llvm.icall.jumptable intrinsic. It also extends
the LowerTypeTests pass to recognize the new intrinsic, generate code
for the branch funnels (x86_64 only for now) and lay out virtual tables
as required for each branch funnel.

The implementation supports full LTO as well as ThinLTO, and extends the
ThinLTO summary format used for whole-program devirtualization to
support branch funnels.

For more details see RFC:
http://lists.llvm.org/pipermail/llvm-dev/2018-January/120672.html

Differential Revision: https://reviews.llvm.org/D42453

llvm-svn: 327163
18 files changed:
compiler-rt/test/cfi/simple-pass.cpp
llvm/include/llvm/ADT/PointerUnion.h
llvm/include/llvm/CodeGen/TargetOpcodes.def
llvm/include/llvm/IR/Intrinsics.td
llvm/include/llvm/IR/ModuleSummaryIndex.h
llvm/include/llvm/IR/ModuleSummaryIndexYAML.h
llvm/include/llvm/Target/Target.td
llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
llvm/lib/IR/Verifier.cpp
llvm/lib/Target/X86/X86ExpandPseudo.cpp
llvm/lib/Transforms/IPO/LowerTypeTests.cpp
llvm/lib/Transforms/IPO/WholeProgramDevirt.cpp
llvm/test/CodeGen/X86/icall-branch-funnel.ll [new file with mode: 0644]
llvm/test/Transforms/LowerTypeTests/icall-branch-funnel.ll [new file with mode: 0644]
llvm/test/Transforms/WholeProgramDevirt/Inputs/import-branch-funnel.yaml [new file with mode: 0644]
llvm/test/Transforms/WholeProgramDevirt/Inputs/import-vcp-branch-funnel.yaml [new file with mode: 0644]
llvm/test/Transforms/WholeProgramDevirt/branch-funnel.ll [new file with mode: 0644]
llvm/test/Transforms/WholeProgramDevirt/import.ll