diff options
author | Peter Collingbourne <peter@pcc.me.uk> | 2016-04-22 21:18:02 +0000 |
---|---|---|
committer | Peter Collingbourne <peter@pcc.me.uk> | 2016-04-22 21:18:02 +0000 |
commit | 7dd8dbf48652dfddd08cb7a6de0f2b079be45ea8 (patch) | |
tree | 5dfcc400c31a3efdcb20c300d9d24cdb262ac16c /llvm/include | |
parent | b29465fe478b92e896e7d1de5d48fcc35f115a5e (diff) | |
download | bcm5719-llvm-7dd8dbf48652dfddd08cb7a6de0f2b079be45ea8.tar.gz bcm5719-llvm-7dd8dbf48652dfddd08cb7a6de0f2b079be45ea8.zip |
Introduce llvm.load.relative intrinsic.
This intrinsic takes two arguments, ``%ptr`` and ``%offset``. It loads
a 32-bit value from the address ``%ptr + %offset``, adds ``%ptr`` to that
value and returns it. The constant folder specifically recognizes the form of
this intrinsic and the constant initializers it may load from; if a loaded
constant initializer is known to have the form ``i32 trunc(x - %ptr)``,
the intrinsic call is folded to ``x``.
LLVM provides that the calculation of such a constant initializer will
not overflow at link time under the medium code model if ``x`` is an
``unnamed_addr`` function. However, it does not provide this guarantee for
a constant initializer folded into a function body. This intrinsic can be
used to avoid the possibility of overflows when loading from such a constant.
Differential Revision: http://reviews.llvm.org/D18367
llvm-svn: 267223
Diffstat (limited to 'llvm/include')
-rw-r--r-- | llvm/include/llvm/CodeGen/Passes.h | 5 | ||||
-rw-r--r-- | llvm/include/llvm/IR/Intrinsics.td | 3 | ||||
-rw-r--r-- | llvm/include/llvm/InitializePasses.h | 1 |
3 files changed, 9 insertions, 0 deletions
diff --git a/llvm/include/llvm/CodeGen/Passes.h b/llvm/include/llvm/CodeGen/Passes.h index 30630dcf644..589c0500a41 100644 --- a/llvm/include/llvm/CodeGen/Passes.h +++ b/llvm/include/llvm/CodeGen/Passes.h @@ -680,6 +680,11 @@ namespace llvm { /// ModulePass *createLowerEmuTLSPass(const TargetMachine *TM); + /// This pass lowers the @llvm.load.relative intrinsic to instructions. + /// This is unsafe to do earlier because a pass may combine the constant + /// initializer into the load, which may result in an overflowing evaluation. + ModulePass *createPreISelIntrinsicLoweringPass(); + /// GlobalMerge - This pass merges internal (by default) globals into structs /// to enable reuse of a base pointer by indexed addressing modes. /// It can also be configured to focus on size optimizations only. diff --git a/llvm/include/llvm/IR/Intrinsics.td b/llvm/include/llvm/IR/Intrinsics.td index e49872043fd..f245df4ff91 100644 --- a/llvm/include/llvm/IR/Intrinsics.td +++ b/llvm/include/llvm/IR/Intrinsics.td @@ -669,6 +669,9 @@ def int_masked_scatter: Intrinsic<[], def int_bitset_test : Intrinsic<[llvm_i1_ty], [llvm_ptr_ty, llvm_metadata_ty], [IntrNoMem]>; +def int_load_relative: Intrinsic<[llvm_ptr_ty], [llvm_ptr_ty, llvm_anyint_ty], + [IntrReadMem, IntrArgMemOnly]>; + //===----------------------------------------------------------------------===// // Target-specific intrinsics //===----------------------------------------------------------------------===// diff --git a/llvm/include/llvm/InitializePasses.h b/llvm/include/llvm/InitializePasses.h index 638071fb11d..557f927a656 100644 --- a/llvm/include/llvm/InitializePasses.h +++ b/llvm/include/llvm/InitializePasses.h @@ -246,6 +246,7 @@ void initializePostOrderFunctionAttrsLegacyPassPass(PassRegistry&); void initializePostRAHazardRecognizerPass(PassRegistry&); void initializePostRASchedulerPass(PassRegistry&); void initializePostMachineSchedulerPass(PassRegistry&); +void initializePreISelIntrinsicLoweringPass(PassRegistry&); void initializePrintFunctionPassWrapperPass(PassRegistry&); void initializePrintModulePassWrapperPass(PassRegistry&); void initializePrintBasicBlockPassPass(PassRegistry&); |