diff options
Diffstat (limited to 'include/llvm/IR/Intrinsics.td')
| -rw-r--r-- | include/llvm/IR/Intrinsics.td | 227 |
1 files changed, 160 insertions, 67 deletions
diff --git a/include/llvm/IR/Intrinsics.td b/include/llvm/IR/Intrinsics.td index 64603d8ea030..d660f8278437 100644 --- a/include/llvm/IR/Intrinsics.td +++ b/include/llvm/IR/Intrinsics.td @@ -1,9 +1,8 @@ //===- Intrinsics.td - Defines all LLVM intrinsics ---------*- tablegen -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -70,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 { @@ -90,6 +94,8 @@ class ReadNone<int argNo> : IntrinsicProperty { def IntrNoReturn : IntrinsicProperty; +def IntrWillReturn : IntrinsicProperty; + // IntrCold - Calls to this intrinsic are cold. // Parallels the cold attribute on LLVM IR functions. def IntrCold : IntrinsicProperty; @@ -157,13 +163,19 @@ class LLVMMatchType<int num> // the intrinsic is overloaded, so the matched type should be declared as iAny. class LLVMExtendedType<int num> : LLVMMatchType<num>; class LLVMTruncatedType<int num> : LLVMMatchType<num>; -class LLVMVectorSameWidth<int num, LLVMType elty> - : LLVMMatchType<num> { + +// Match the scalar/vector of another intrinsic parameter but with a different +// element type. Either both are scalars or both are vectors with the same +// number of elements. +class LLVMScalarOrSameVectorWidth<int idx, LLVMType elty> + : LLVMMatchType<idx> { ValueType ElTy = elty.VT; } + class LLVMPointerTo<int num> : LLVMMatchType<num>; class LLVMPointerToElt<int num> : LLVMMatchType<num>; class LLVMVectorOfAnyPointersToElt<int num> : LLVMMatchType<num>; +class LLVMVectorElementType<int num> : LLVMMatchType<num>; // Match the type of another intrinsic parameter that is expected to be a // vector type, but change the element count to be half as many @@ -251,6 +263,7 @@ def llvm_v2f32_ty : LLVMType<v2f32>; // 2 x float def llvm_v4f32_ty : LLVMType<v4f32>; // 4 x float def llvm_v8f32_ty : LLVMType<v8f32>; // 8 x float def llvm_v16f32_ty : LLVMType<v16f32>; // 16 x float +def llvm_v32f32_ty : LLVMType<v32f32>; // 32 x float def llvm_v1f64_ty : LLVMType<v1f64>; // 1 x double def llvm_v2f64_ty : LLVMType<v2f64>; // 2 x double def llvm_v4f64_ty : LLVMType<v4f64>; // 4 x double @@ -393,9 +406,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">; @@ -413,7 +426,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. @@ -439,7 +452,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]>; @@ -480,16 +494,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. @@ -527,6 +542,11 @@ let IntrProperties = [IntrNoMem, IntrSpeculatable] in { def int_round : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>; def int_canonicalize : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem]>; + + def int_lround : Intrinsic<[llvm_anyint_ty], [llvm_anyfloat_ty]>; + def int_llround : Intrinsic<[llvm_anyint_ty], [llvm_anyfloat_ty]>; + def int_lrint : Intrinsic<[llvm_anyint_ty], [llvm_anyfloat_ty]>; + def int_llrint : Intrinsic<[llvm_anyint_ty], [llvm_anyfloat_ty]>; } def int_minnum : Intrinsic<[llvm_anyfloat_ty], @@ -554,8 +574,9 @@ def int_siglongjmp : Intrinsic<[], [llvm_ptr_ty, llvm_i32_ty], [IntrNoReturn]>; // Internal interface for object size checking def int_objectsize : Intrinsic<[llvm_anyint_ty], - [llvm_anyptr_ty, llvm_i1_ty, llvm_i1_ty], - [IntrNoMem, IntrSpeculatable]>, + [llvm_anyptr_ty, llvm_i1_ty, + llvm_i1_ty, llvm_i1_ty], + [IntrNoMem, IntrSpeculatable, ImmArg<1>, ImmArg<2>, ImmArg<3>]>, GCCBuiltin<"__builtin_object_size">; //===--------------- Constrained Floating Point Intrinsics ----------------===// @@ -595,6 +616,15 @@ let IntrProperties = [IntrInaccessibleMemOnly] in { llvm_metadata_ty, llvm_metadata_ty ]>; + def int_experimental_constrained_fptrunc : Intrinsic<[ llvm_anyfloat_ty ], + [ llvm_anyfloat_ty, + llvm_metadata_ty, + llvm_metadata_ty ]>; + + def int_experimental_constrained_fpext : Intrinsic<[ llvm_anyfloat_ty ], + [ llvm_anyfloat_ty, + llvm_metadata_ty ]>; + // These intrinsics are sensitive to the rounding mode so we need constrained // versions of each of them. When strict rounding and exception control are // not required the non-constrained versions of these intrinsics should be @@ -676,14 +706,12 @@ let IntrProperties = [IntrInaccessibleMemOnly] in { llvm_metadata_ty, llvm_metadata_ty ]>; } -// FIXME: Add intrinsics for fcmp, fptrunc, fpext, fptoui and fptosi. -// FIXME: Add intrinsics for fabs and copysign? - +// FIXME: Add intrinsics for fcmp, fptoui and fptosi. //===------------------------- 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]>; //===-------------------- Bit Manipulation Intrinsics ---------------------===// // @@ -692,8 +720,6 @@ 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>]>; @@ -701,6 +727,11 @@ let IntrProperties = [IntrNoMem, IntrSpeculatable] in { [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 -------------------------===// // @@ -797,24 +828,30 @@ def int_adjust_trampoline : Intrinsic<[llvm_ptr_ty], [llvm_ptr_ty], // // Expose the carry flag from add operations on two integrals. -def int_sadd_with_overflow : Intrinsic<[llvm_anyint_ty, llvm_i1_ty], +def int_sadd_with_overflow : Intrinsic<[llvm_anyint_ty, + LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>], [LLVMMatchType<0>, LLVMMatchType<0>], [IntrNoMem, IntrSpeculatable]>; -def int_uadd_with_overflow : Intrinsic<[llvm_anyint_ty, llvm_i1_ty], +def int_uadd_with_overflow : Intrinsic<[llvm_anyint_ty, + LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>], [LLVMMatchType<0>, LLVMMatchType<0>], [IntrNoMem, IntrSpeculatable]>; -def int_ssub_with_overflow : Intrinsic<[llvm_anyint_ty, llvm_i1_ty], +def int_ssub_with_overflow : Intrinsic<[llvm_anyint_ty, + LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>], [LLVMMatchType<0>, LLVMMatchType<0>], [IntrNoMem, IntrSpeculatable]>; -def int_usub_with_overflow : Intrinsic<[llvm_anyint_ty, llvm_i1_ty], +def int_usub_with_overflow : Intrinsic<[llvm_anyint_ty, + LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>], [LLVMMatchType<0>, LLVMMatchType<0>], [IntrNoMem, IntrSpeculatable]>; -def int_smul_with_overflow : Intrinsic<[llvm_anyint_ty, llvm_i1_ty], +def int_smul_with_overflow : Intrinsic<[llvm_anyint_ty, + LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>], [LLVMMatchType<0>, LLVMMatchType<0>], [IntrNoMem, IntrSpeculatable]>; -def int_umul_with_overflow : Intrinsic<[llvm_anyint_ty, llvm_i1_ty], +def int_umul_with_overflow : Intrinsic<[llvm_anyint_ty, + LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>], [LLVMMatchType<0>, LLVMMatchType<0>], [IntrNoMem, IntrSpeculatable]>; @@ -837,23 +874,33 @@ 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, ImmArg<2>]>; + +//===------------------- Fixed Point Saturation Arithmetic Intrinsics ----------------===// +// +def int_smul_fix_sat : Intrinsic<[llvm_anyint_ty], + [LLVMMatchType<0>, LLVMMatchType<0>, llvm_i32_ty], + [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. @@ -900,13 +947,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 @@ -996,41 +1043,41 @@ def int_clear_cache : Intrinsic<[], [llvm_ptr_ty, llvm_ptr_ty], // Intrinsic to detect whether its argument is a constant. def int_is_constant : Intrinsic<[llvm_i1_ty], [llvm_any_ty], [IntrNoMem], "llvm.is.constant">; - //===-------------------------- Masked Intrinsics -------------------------===// // def int_masked_store : Intrinsic<[], [llvm_anyvector_ty, LLVMAnyPointerType<LLVMMatchType<0>>, llvm_i32_ty, - LLVMVectorSameWidth<0, llvm_i1_ty>], - [IntrArgMemOnly]>; + LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>], + [IntrArgMemOnly, ImmArg<2>]>; def int_masked_load : Intrinsic<[llvm_anyvector_ty], [LLVMAnyPointerType<LLVMMatchType<0>>, llvm_i32_ty, - LLVMVectorSameWidth<0, llvm_i1_ty>, LLVMMatchType<0>], - [IntrReadMem, IntrArgMemOnly]>; + LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>, LLVMMatchType<0>], + [IntrReadMem, IntrArgMemOnly, ImmArg<1>]>; def int_masked_gather: Intrinsic<[llvm_anyvector_ty], [LLVMVectorOfAnyPointersToElt<0>, llvm_i32_ty, - LLVMVectorSameWidth<0, llvm_i1_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, - LLVMVectorSameWidth<0, llvm_i1_ty>]>; + LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>], + [ImmArg<2>]>; def int_masked_expandload: Intrinsic<[llvm_anyvector_ty], [LLVMPointerToElt<0>, - LLVMVectorSameWidth<0, llvm_i1_ty>, + LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>, LLVMMatchType<0>], [IntrReadMem]>; def int_masked_compressstore: Intrinsic<[], [llvm_anyvector_ty, LLVMPointerToElt<0>, - LLVMVectorSameWidth<0, llvm_i1_ty>], + LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>], [IntrArgMemOnly]>; // Test whether a pointer is associated with a type metadata identifier. @@ -1049,6 +1096,9 @@ def int_icall_branch_funnel : Intrinsic<[], [llvm_vararg_ty], []>; 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, ImmArg<2>]>; + // Xray intrinsics //===----------------------------------------------------------------------===// // Custom event logging for x-ray. @@ -1072,7 +1122,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) @@ -1083,62 +1133,105 @@ 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 ------------------------===// // -def int_experimental_vector_reduce_fadd : Intrinsic<[llvm_anyfloat_ty], - [llvm_anyfloat_ty, - llvm_anyvector_ty], - [IntrNoMem]>; -def int_experimental_vector_reduce_fmul : Intrinsic<[llvm_anyfloat_ty], - [llvm_anyfloat_ty, - llvm_anyvector_ty], - [IntrNoMem]>; -def int_experimental_vector_reduce_add : Intrinsic<[llvm_anyint_ty], +def int_experimental_vector_reduce_v2_fadd : Intrinsic<[llvm_anyfloat_ty], + [LLVMMatchType<0>, + llvm_anyvector_ty], + [IntrNoMem]>; +def int_experimental_vector_reduce_v2_fmul : Intrinsic<[llvm_anyfloat_ty], + [LLVMMatchType<0>, + llvm_anyvector_ty], + [IntrNoMem]>; +def int_experimental_vector_reduce_add : Intrinsic<[LLVMVectorElementType<0>], [llvm_anyvector_ty], [IntrNoMem]>; -def int_experimental_vector_reduce_mul : Intrinsic<[llvm_anyint_ty], +def int_experimental_vector_reduce_mul : Intrinsic<[LLVMVectorElementType<0>], [llvm_anyvector_ty], [IntrNoMem]>; -def int_experimental_vector_reduce_and : Intrinsic<[llvm_anyint_ty], +def int_experimental_vector_reduce_and : Intrinsic<[LLVMVectorElementType<0>], [llvm_anyvector_ty], [IntrNoMem]>; -def int_experimental_vector_reduce_or : Intrinsic<[llvm_anyint_ty], +def int_experimental_vector_reduce_or : Intrinsic<[LLVMVectorElementType<0>], [llvm_anyvector_ty], [IntrNoMem]>; -def int_experimental_vector_reduce_xor : Intrinsic<[llvm_anyint_ty], +def int_experimental_vector_reduce_xor : Intrinsic<[LLVMVectorElementType<0>], [llvm_anyvector_ty], [IntrNoMem]>; -def int_experimental_vector_reduce_smax : Intrinsic<[llvm_anyint_ty], +def int_experimental_vector_reduce_smax : Intrinsic<[LLVMVectorElementType<0>], [llvm_anyvector_ty], [IntrNoMem]>; -def int_experimental_vector_reduce_smin : Intrinsic<[llvm_anyint_ty], +def int_experimental_vector_reduce_smin : Intrinsic<[LLVMVectorElementType<0>], [llvm_anyvector_ty], [IntrNoMem]>; -def int_experimental_vector_reduce_umax : Intrinsic<[llvm_anyint_ty], +def int_experimental_vector_reduce_umax : Intrinsic<[LLVMVectorElementType<0>], [llvm_anyvector_ty], [IntrNoMem]>; -def int_experimental_vector_reduce_umin : Intrinsic<[llvm_anyint_ty], +def int_experimental_vector_reduce_umin : Intrinsic<[LLVMVectorElementType<0>], [llvm_anyvector_ty], [IntrNoMem]>; -def int_experimental_vector_reduce_fmax : Intrinsic<[llvm_anyfloat_ty], +def int_experimental_vector_reduce_fmax : Intrinsic<[LLVMVectorElementType<0>], [llvm_anyvector_ty], [IntrNoMem]>; -def int_experimental_vector_reduce_fmin : Intrinsic<[llvm_anyfloat_ty], +def int_experimental_vector_reduce_fmin : Intrinsic<[LLVMVectorElementType<0>], [llvm_anyvector_ty], [IntrNoMem]>; +//===---------- Intrinsics to control hardware supported loops ----------===// + +// Specify that the value given is the number of iterations that the next loop +// will execute. +def int_set_loop_iterations : + Intrinsic<[], [llvm_anyint_ty], [IntrNoDuplicate]>; + +// Specify that the value given is the number of iterations that the next loop +// will execute. Also test that the given count is not zero, allowing it to +// control entry to a 'while' loop. +def int_test_set_loop_iterations : + Intrinsic<[llvm_i1_ty], [llvm_anyint_ty], [IntrNoDuplicate]>; + +// Decrement loop counter by the given argument. Return false if the loop +// should exit. +def int_loop_decrement : + Intrinsic<[llvm_i1_ty], [llvm_anyint_ty], [IntrNoDuplicate]>; + +// Decrement the first operand (the loop counter) by the second operand (the +// maximum number of elements processed in an iteration). Return the remaining +// number of iterations still to be executed. This is effectively a sub which +// can be used with a phi, icmp and br to control the number of iterations +// executed, as usual. +def int_loop_decrement_reg : + Intrinsic<[llvm_anyint_ty], + [llvm_anyint_ty, llvm_anyint_ty], [IntrNoDuplicate]>; + //===----- Intrinsics that are used to provide predicate information -----===// def int_ssa_copy : Intrinsic<[llvm_any_ty], [LLVMMatchType<0>], [IntrNoMem, Returned<0>]>; + +//===------- Intrinsics that are used to preserve debug information -------===// + +def int_preserve_array_access_index : Intrinsic<[llvm_anyptr_ty], + [llvm_anyptr_ty, llvm_i32_ty, + llvm_i32_ty], + [IntrNoMem, ImmArg<1>, ImmArg<2>]>; +def int_preserve_union_access_index : Intrinsic<[llvm_anyptr_ty], + [llvm_anyptr_ty, llvm_i32_ty], + [IntrNoMem, ImmArg<1>]>; +def int_preserve_struct_access_index : Intrinsic<[llvm_anyptr_ty], + [llvm_anyptr_ty, llvm_i32_ty, + llvm_i32_ty], + [IntrNoMem, ImmArg<1>, + ImmArg<2>]>; + //===----------------------------------------------------------------------===// // Target-specific intrinsics //===----------------------------------------------------------------------===// |
