diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst --- a/llvm/docs/LangRef.rst +++ b/llvm/docs/LangRef.rst @@ -14871,6 +14871,169 @@ %r2 = call float @llvm.fmuladd.f32(float %a, float %b, float %c) ; yields float:r2 = (a * b) + c +Hardware-Loop Intrinsics +------------------------ + +LLVM support several intrinsics to mark a loop as a hardware-loop. They are +hints to the backend which are required to lower these intrinsics further to target +specific instructions, or revert the hardware-loop to a normal loop if target +specific restriction are not met and a hardware-loop can't be generated. + +These intrinsics may be modified in the future and are not intended to be used +outside the backend. Thus, front-end and mid-level optimizations should not be +generating these intrinsics. + + +'``llvm.set.loop.iterations.*``' Intrinsic +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Syntax: +""""""" + +This is an overloaded intrinsic. + +:: + + declare void @llvm.set.loop.iterations.i32(i32) + declare void @llvm.set.loop.iterations.i64(i64) + +Overview: +""""""""" + +The '``llvm.set.loop.iterations.*``' intrinsics are used to specify the +hardware-loop trip count. They are placed in the loop preheader basic block and +are marked as ``IntrNoDuplicate`` to avoid optimizers duplicating these +instructions. + +Arguments: +"""""""""" + +The integer operand is the loop trip count of the hardware-loop, and thus +not e.g. the loop back-edge taken count. + +Semantics: +"""""""""" + +The '``llvm.set.loop.iterations.*``' intrinsics do not perform any arithmetic +on their operand. It's a hint to the backend that can use this to set up the +hardware-loop count with a target specific instruction, usually a move of this +value to a special register or a hardware-loop instruction. + +'``llvm.test.set.loop.iterations.*``' Intrinsic +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Syntax: +""""""" + +This is an overloaded intrinsic. + +:: + + declare void @llvm.test.set.loop.iterations.i32(i32) + declare void @llvm.test.set.loop.iterations.i64(i64) + +Overview: +""""""""" + +The '``llvm.test.set.loop.iterations.*``' intrinsics are used to specify the +the loop trip count, and also test that the given count is not zero, allowing +it to control entry to a while-loop. They are placed in the loop preheader's +predecessor basic block, and are marked as ``IntrNoDuplicate`` to avoid +optimizers duplicating these instructions. + +Arguments: +"""""""""" + +The integer operand is the loop trip count of the hardware-loop, and thus +not e.g. the loop back-edge taken count. + +Semantics: +"""""""""" + +The '``llvm.test.set.loop.iterations.*``' intrinsics do not perform any +arithmetic on their operand. It's a hint to the backend that can use this to +set up the hardware-loop count with a target specific instruction, usually a +move of this value to a special register or a hardware-loop instruction. + +'``llvm.loop.decrement.reg.*``' Intrinsic +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Syntax: +""""""" + +This is an overloaded intrinsic. + +:: + + declare i32 @llvm.loop.decrement.reg.i32(i32, i32) + declare i64 @llvm.loop.decrement.reg.i64(i64, i64) + +Overview: +""""""""" + +The '``llvm.loop.decrement.reg.*``' intrinsics are used to lower the loop +iteration counter and return an updated value that will be used in the next +loop test check. + +Arguments: +"""""""""" + +Both arguments must have identical integer types. The first operand is the +loop iteration counter. The second operand is the maximum number of elements +processed in an iteration. + +Semantics: +"""""""""" + +The '``llvm.loop.decrement.reg.*``' intrinsics do an integer ``SUB`` of its +two operands, which is not allowed to wrap. They return the remaining number of +iterations still to be executed, and can be used together with a ``PHI``, +``ICMP`` and ``BR`` to control the number of loop iterations executed. Any +optimisations are allowed to treat it is a ``SUB``, and it is supported by +SCEV, so it's the backends responsibility to handle cases where it may be +optimised. These intrinsics are marked as ``IntrNoDuplicate`` to avoid +optimizers duplicating these instructions. + + +'``llvm.loop.decrement.*``' Intrinsic +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Syntax: +""""""" + +This is an overloaded intrinsic. + +:: + + declare i1 @llvm.loop.decrement.i32(i32) + declare i1 @llvm.loop.decrement.i64(i64) + +Overview: +""""""""" + +The HardwareLoops pass allows the loop decrement value to be specified with an +option. It defaults to a loop decrement value of 1, but it can be an unsigned +integer value provided by this option. The '``llvm.loop.decrement.*``' +intrinsics decrement the loop iteration counter with this value, and return a +false predicate if the loop should exit, and true otherwise. +This is emitted if the loop counter is not updated via a ``PHI`` node, which +can also be controlled with an option. + +Arguments: +"""""""""" + +The integer argument is the loop decrement value used to decrement the loop +iteration counter. + +Semantics: +"""""""""" + +The '``llvm.loop.decrement.*``' intrinsics do a ``SUB`` of the loop iteration +counter with the given loop decrement value, and return false if the loop +should exit, this ``SUB`` is not allowed to wrap. The result is a condition +that is used by the conditional branch controlling the loop. + + Experimental Vector Reduction Intrinsics ----------------------------------------