Skip to content
This repository has been archived by the owner on Jan 1, 2023. It is now read-only.

Commit

Permalink
IR: Add immarg attribute
Browse files Browse the repository at this point in the history
This indicates an intrinsic parameter is required to be a constant,
and should not be replaced with a non-constant value.

Add the attribute to all AMDGPU and generic intrinsics that comments
indicate it should apply to. I scanned other target intrinsics, but I
don't see any obvious comments indicating which arguments are intended
to be only immediates.

This breaks one questionable testcase for the autoupgrade. I'm unclear
on whether the autoupgrade is supposed to really handle declarations
which were never valid. The verifier fails because the attributes now
refer to a parameter past the end of the argument list.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@355981 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
arsenm committed Mar 12, 2019
1 parent 9e6583c commit 5375d14
Show file tree
Hide file tree
Showing 49 changed files with 1,545 additions and 667 deletions.
7 changes: 7 additions & 0 deletions docs/LangRef.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1178,6 +1178,13 @@ Currently, only the following parameter attributes are defined:
does not alias any other memory visible within a function and that a
``swifterror`` alloca passed as an argument does not escape.

``immarg``
This indicates the parameter is required to be an immediate
value. This must be a trivial immediate integer or floating-point
constant. Undef or constant expressions are not valid. This is
only valid on intrinsic declarations and cannot be applied to a
call site or arbitrary function.

.. _gc:

Garbage Collector Strategy Names
Expand Down
4 changes: 4 additions & 0 deletions docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,10 @@ Non-comprehensive list of changes in this release
Changes to the LLVM IR
----------------------

* Added ``immarg`` parameter attribute. This indicates an intrinsic
parameter is required to be a simple constant. This annotation must
be accurate to avoid possible miscompiles.


Changes to the ARM Backend
--------------------------
Expand Down
1 change: 1 addition & 0 deletions include/llvm/Bitcode/LLVMBitCodes.h
Original file line number Diff line number Diff line change
Expand Up @@ -605,6 +605,7 @@ enum AttributeKindCodes {
ATTR_KIND_OPT_FOR_FUZZING = 57,
ATTR_KIND_SHADOWCALLSTACK = 58,
ATTR_KIND_SPECULATIVE_LOAD_HARDENING = 59,
ATTR_KIND_IMMARG = 60
};

enum ComdatSelectionKindCodes {
Expand Down
3 changes: 3 additions & 0 deletions include/llvm/IR/Attributes.td
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,9 @@ def ReadOnly : EnumAttr<"readonly">;
/// Return value is always equal to this argument.
def Returned : EnumAttr<"returned">;

/// Parameter is required to be a trivial constant.
def ImmArg : EnumAttr<"immarg">;

/// Function can return twice.
def ReturnsTwice : EnumAttr<"returns_twice">;

Expand Down
67 changes: 39 additions & 28 deletions include/llvm/IR/Intrinsics.td
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,11 @@ class Returned<int argNo> : IntrinsicProperty {
int ArgNo = argNo;
}

// ImmArg - The specified argument must be an immediate.
class ImmArg<int argNo> : IntrinsicProperty {
int ArgNo = argNo;
}

// ReadOnly - The specified argument pointer is not written to through the
// pointer by the intrinsic.
class ReadOnly<int argNo> : IntrinsicProperty {
Expand Down Expand Up @@ -397,9 +402,9 @@ def int_objc_arc_annotation_bottomup_bbend : Intrinsic<[],

//===--------------------- Code Generator Intrinsics ----------------------===//
//
def int_returnaddress : Intrinsic<[llvm_ptr_ty], [llvm_i32_ty], [IntrNoMem]>;
def int_returnaddress : Intrinsic<[llvm_ptr_ty], [llvm_i32_ty], [IntrNoMem, ImmArg<0>]>;
def int_addressofreturnaddress : Intrinsic<[llvm_ptr_ty], [], [IntrNoMem]>;
def int_frameaddress : Intrinsic<[llvm_ptr_ty], [llvm_i32_ty], [IntrNoMem]>;
def int_frameaddress : Intrinsic<[llvm_ptr_ty], [llvm_i32_ty], [IntrNoMem, ImmArg<0>]>;
def int_sponentry : Intrinsic<[llvm_ptr_ty], [], [IntrNoMem]>;
def int_read_register : Intrinsic<[llvm_anyint_ty], [llvm_metadata_ty],
[IntrReadMem], "llvm.read_register">;
Expand All @@ -417,7 +422,7 @@ def int_localescape : Intrinsic<[], [llvm_vararg_ty]>;
// to an escaped allocation indicated by the index.
def int_localrecover : Intrinsic<[llvm_ptr_ty],
[llvm_ptr_ty, llvm_ptr_ty, llvm_i32_ty],
[IntrNoMem]>;
[IntrNoMem, ImmArg<2>]>;

// Given the frame pointer passed into an SEH filter function, returns a
// pointer to the local variable area suitable for use with llvm.localrecover.
Expand All @@ -443,7 +448,8 @@ def int_thread_pointer : Intrinsic<[llvm_ptr_ty], [], [IntrNoMem]>,
// memory while not impeding optimization.
def int_prefetch
: Intrinsic<[], [ llvm_ptr_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty ],
[ IntrInaccessibleMemOrArgMemOnly, ReadOnly<0>, NoCapture<0> ]>;
[ IntrInaccessibleMemOrArgMemOnly, ReadOnly<0>, NoCapture<0>,
ImmArg<1>, ImmArg<2>]>;
def int_pcmarker : Intrinsic<[], [llvm_i32_ty]>;

def int_readcyclecounter : Intrinsic<[llvm_i64_ty]>;
Expand Down Expand Up @@ -484,16 +490,17 @@ def int_memcpy : Intrinsic<[],
[llvm_anyptr_ty, llvm_anyptr_ty, llvm_anyint_ty,
llvm_i1_ty],
[IntrArgMemOnly, NoCapture<0>, NoCapture<1>,
WriteOnly<0>, ReadOnly<1>]>;
WriteOnly<0>, ReadOnly<1>, ImmArg<3>]>;
def int_memmove : Intrinsic<[],
[llvm_anyptr_ty, llvm_anyptr_ty, llvm_anyint_ty,
llvm_i1_ty],
[IntrArgMemOnly, NoCapture<0>, NoCapture<1>,
ReadOnly<1>]>;
ReadOnly<1>, ImmArg<3>]>;
def int_memset : Intrinsic<[],
[llvm_anyptr_ty, llvm_i8_ty, llvm_anyint_ty,
llvm_i1_ty],
[IntrArgMemOnly, NoCapture<0>, WriteOnly<0>]>;
[IntrArgMemOnly, NoCapture<0>, WriteOnly<0>,
ImmArg<3>]>;

// FIXME: Add version of these floating point intrinsics which allow non-default
// rounding modes and FP exception handling.
Expand Down Expand Up @@ -560,7 +567,7 @@ def int_siglongjmp : Intrinsic<[], [llvm_ptr_ty, llvm_i32_ty], [IntrNoReturn]>;
def int_objectsize : Intrinsic<[llvm_anyint_ty],
[llvm_anyptr_ty, llvm_i1_ty,
llvm_i1_ty, llvm_i1_ty],
[IntrNoMem, IntrSpeculatable]>,
[IntrNoMem, IntrSpeculatable, ImmArg<1>, ImmArg<2>, ImmArg<3>]>,
GCCBuiltin<"__builtin_object_size">;

//===--------------- Constrained Floating Point Intrinsics ----------------===//
Expand Down Expand Up @@ -687,8 +694,8 @@ let IntrProperties = [IntrInaccessibleMemOnly] in {

//===------------------------- Expect Intrinsics --------------------------===//
//
def int_expect : Intrinsic<[llvm_anyint_ty], [LLVMMatchType<0>,
LLVMMatchType<0>], [IntrNoMem]>;
def int_expect : Intrinsic<[llvm_anyint_ty],
[LLVMMatchType<0>, LLVMMatchType<0>], [IntrNoMem, ImmArg<1>]>;

//===-------------------- Bit Manipulation Intrinsics ---------------------===//
//
Expand All @@ -697,15 +704,18 @@ def int_expect : Intrinsic<[llvm_anyint_ty], [LLVMMatchType<0>,
let IntrProperties = [IntrNoMem, IntrSpeculatable] in {
def int_bswap: Intrinsic<[llvm_anyint_ty], [LLVMMatchType<0>]>;
def int_ctpop: Intrinsic<[llvm_anyint_ty], [LLVMMatchType<0>]>;
def int_ctlz : Intrinsic<[llvm_anyint_ty], [LLVMMatchType<0>, llvm_i1_ty]>;
def int_cttz : Intrinsic<[llvm_anyint_ty], [LLVMMatchType<0>, llvm_i1_ty]>;
def int_bitreverse : Intrinsic<[llvm_anyint_ty], [LLVMMatchType<0>]>;
def int_fshl : Intrinsic<[llvm_anyint_ty],
[LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>]>;
def int_fshr : Intrinsic<[llvm_anyint_ty],
[LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>]>;
}

let IntrProperties = [IntrNoMem, IntrSpeculatable, ImmArg<1>] in {
def int_ctlz : Intrinsic<[llvm_anyint_ty], [LLVMMatchType<0>, llvm_i1_ty]>;
def int_cttz : Intrinsic<[llvm_anyint_ty], [LLVMMatchType<0>, llvm_i1_ty]>;
}

//===------------------------ Debugger Intrinsics -------------------------===//
//

Expand Down Expand Up @@ -848,27 +858,27 @@ def int_usub_sat : Intrinsic<[llvm_anyint_ty],
//
def int_smul_fix : Intrinsic<[llvm_anyint_ty],
[LLVMMatchType<0>, LLVMMatchType<0>, llvm_i32_ty],
[IntrNoMem, IntrSpeculatable, Commutative]>;
[IntrNoMem, IntrSpeculatable, Commutative, ImmArg<2>]>;

def int_umul_fix : Intrinsic<[llvm_anyint_ty],
[LLVMMatchType<0>, LLVMMatchType<0>, llvm_i32_ty],
[IntrNoMem, IntrSpeculatable, Commutative]>;
[IntrNoMem, IntrSpeculatable, Commutative, ImmArg<2>]>;

//===------------------------- Memory Use Markers -------------------------===//
//
def int_lifetime_start : Intrinsic<[],
[llvm_i64_ty, llvm_anyptr_ty],
[IntrArgMemOnly, NoCapture<1>]>;
[IntrArgMemOnly, NoCapture<1>, ImmArg<0>]>;
def int_lifetime_end : Intrinsic<[],
[llvm_i64_ty, llvm_anyptr_ty],
[IntrArgMemOnly, NoCapture<1>]>;
[IntrArgMemOnly, NoCapture<1>, ImmArg<0>]>;
def int_invariant_start : Intrinsic<[llvm_descriptor_ty],
[llvm_i64_ty, llvm_anyptr_ty],
[IntrArgMemOnly, NoCapture<1>]>;
[IntrArgMemOnly, NoCapture<1>, ImmArg<0>]>;
def int_invariant_end : Intrinsic<[],
[llvm_descriptor_ty, llvm_i64_ty,
llvm_anyptr_ty],
[IntrArgMemOnly, NoCapture<2>]>;
[IntrArgMemOnly, NoCapture<2>, ImmArg<1>]>;

// launder.invariant.group can't be marked with 'readnone' (IntrNoMem),
// because it would cause CSE of two barriers with the same argument.
Expand Down Expand Up @@ -915,13 +925,13 @@ def int_experimental_gc_statepoint : Intrinsic<[llvm_token_ty],
[llvm_i64_ty, llvm_i32_ty,
llvm_anyptr_ty, llvm_i32_ty,
llvm_i32_ty, llvm_vararg_ty],
[Throws]>;
[Throws, ImmArg<0>, ImmArg<1>, ImmArg<3>, ImmArg<4>]>;

def int_experimental_gc_result : Intrinsic<[llvm_any_ty], [llvm_token_ty],
[IntrReadMem]>;
def int_experimental_gc_relocate : Intrinsic<[llvm_any_ty],
[llvm_token_ty, llvm_i32_ty, llvm_i32_ty],
[IntrReadMem]>;
[IntrReadMem, ImmArg<1>, ImmArg<2>]>;

//===------------------------ Coroutine Intrinsics ---------------===//
// These are documented in docs/Coroutines.rst
Expand Down Expand Up @@ -1018,23 +1028,24 @@ def int_masked_store : Intrinsic<[], [llvm_anyvector_ty,
LLVMAnyPointerType<LLVMMatchType<0>>,
llvm_i32_ty,
LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>],
[IntrArgMemOnly]>;
[IntrArgMemOnly, ImmArg<2>]>;

def int_masked_load : Intrinsic<[llvm_anyvector_ty],
[LLVMAnyPointerType<LLVMMatchType<0>>, llvm_i32_ty,
LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>, LLVMMatchType<0>],
[IntrReadMem, IntrArgMemOnly]>;
[IntrReadMem, IntrArgMemOnly, ImmArg<1>]>;

def int_masked_gather: Intrinsic<[llvm_anyvector_ty],
[LLVMVectorOfAnyPointersToElt<0>, llvm_i32_ty,
LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
LLVMMatchType<0>],
[IntrReadMem]>;
[IntrReadMem, ImmArg<1>]>;

def int_masked_scatter: Intrinsic<[],
[llvm_anyvector_ty,
LLVMVectorOfAnyPointersToElt<0>, llvm_i32_ty,
LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>]>;
LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>],
[ImmArg<2>]>;

def int_masked_expandload: Intrinsic<[llvm_anyvector_ty],
[LLVMPointerToElt<0>,
Expand Down Expand Up @@ -1065,7 +1076,7 @@ def int_load_relative: Intrinsic<[llvm_ptr_ty], [llvm_ptr_ty, llvm_anyint_ty],
[IntrReadMem, IntrArgMemOnly]>;

def int_hwasan_check_memaccess :
Intrinsic<[], [llvm_ptr_ty, llvm_ptr_ty, llvm_i32_ty], [IntrInaccessibleMemOnly]>;
Intrinsic<[], [llvm_ptr_ty, llvm_ptr_ty, llvm_i32_ty], [IntrInaccessibleMemOnly, ImmArg<2>]>;

// Xray intrinsics
//===----------------------------------------------------------------------===//
Expand All @@ -1090,7 +1101,7 @@ def int_memcpy_element_unordered_atomic
],
[
IntrArgMemOnly, NoCapture<0>, NoCapture<1>, WriteOnly<0>,
ReadOnly<1>
ReadOnly<1>, ImmArg<3>
]>;

// @llvm.memmove.element.unordered.atomic.*(dest, src, length, elementsize)
Expand All @@ -1101,13 +1112,13 @@ def int_memmove_element_unordered_atomic
],
[
IntrArgMemOnly, NoCapture<0>, NoCapture<1>, WriteOnly<0>,
ReadOnly<1>
ReadOnly<1>, ImmArg<3>
]>;

// @llvm.memset.element.unordered.atomic.*(dest, value, length, elementsize)
def int_memset_element_unordered_atomic
: Intrinsic<[], [ llvm_anyptr_ty, llvm_i8_ty, llvm_anyint_ty, llvm_i32_ty ],
[ IntrArgMemOnly, NoCapture<0>, WriteOnly<0> ]>;
[ IntrArgMemOnly, NoCapture<0>, WriteOnly<0>, ImmArg<3> ]>;

//===------------------------ Reduction Intrinsics ------------------------===//
//
Expand Down
Loading

0 comments on commit 5375d14

Please sign in to comment.