[llvm] [ConstantTime][LLVM] Add llvm.ct.select intrinsic with generic SelectionDAG lowering (PR #166702)

Akshay K via llvm-commits llvm-commits at lists.llvm.org
Tue Jul 14 19:17:13 PDT 2026


================
@@ -16303,6 +16303,134 @@ Example:
         call void @llvm.call.preallocated.teardown(token %cs)
         ret void
 
+Constant-Time Intrinsics
+-------------------------
+
+These intrinsics are provided to support constant-time operations for
+security-sensitive code. Constant-time operations execute in time independent
+of secret data values, preventing timing side-channel leaks.
+
+.. _int_ct_select:
+
+'``llvm.ct.select.*``' Intrinsic
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Syntax:
+"""""""
+
+This is an overloaded intrinsic. You can use ``llvm.ct.select`` on any
+integer or floating-point type, pointer types, or vectors types.
+
+::
+
+      declare i32 @llvm.ct.select.i32(i1 <cond>, i32 <val1>, i32 <val2>)
+      declare i64 @llvm.ct.select.i64(i1 <cond>, i64 <val1>, i64 <val2>)
+      declare float @llvm.ct.select.f32(i1 <cond>, float <val1>, float <val2>)
+      declare double @llvm.ct.select.f64(i1 <cond>, double <val1>, double <val2>)
+      declare ptr @llvm.ct.select.p0(i1 <cond>, ptr <val1>, ptr <val2>)
+
+      ; 128-bit vectors
+      declare <4 x i32> @llvm.ct.select.v4i32(i1 <cond>, <4 x i32> <val1>, <4 x i32> <val2>)
+      declare <2 x i64> @llvm.ct.select.v2i64(i1 <cond>, <2 x i64> <val1>, <2 x i64> <val2>)
+      declare <4 x float> @llvm.ct.select.v4f32(i1 <cond>, <4 x float> <val1>, <4 x float> <val2>)
+      declare <2 x double> @llvm.ct.select.v2f64(i1 <cond>, <2 x double> <val1>, <2 x double> <val2>)
+
+      ; 256-bit vectors
+      declare <8 x i32> @llvm.ct.select.v8i32(i1 <cond>, <8 x i32> <val1>, <8 x i32> <val2>)
+      declare <8 x float> @llvm.ct.select.v8f32(i1 <cond>, <8 x float> <val1>, <8 x float> <val2>)
+      declare <4 x double> @llvm.ct.select.v4f64(i1 <cond>, <4 x double> <val1>, <4 x double> <val2>)
+
+Overview:
+"""""""""
+
+The '``llvm.ct.select``' family of intrinsic functions selects one of two
+values based on a condition, with the guarantee that the operation executes
+in constant time. Unlike the standard :ref:`select <i_select>` instruction,
+``llvm.ct.select`` ensures that the execution time and observable behavior
+do not depend on the condition value, preventing timing-based side-channel
+leaks.
+
+Arguments:
+""""""""""
+
+The '``llvm.ct.select``' intrinsic requires three arguments:
+
+1. The condition, which must be a scalar value of type 'i1'. Unlike
+   :ref:`select <i_select>` which accepts both scalar 'i1' and vector
+   '<N x i1>' conditions, ``llvm.ct.select`` only accepts a scalar 'i1'
+   condition. Vector conditions are not supported.
+2. The first value argument of any :ref:`first class <t_firstclass>` type.
+   This can be a scalar or vector type.
+3. The second value argument, which must have the same type as the first
+   value argument.
+
+Semantics:
+""""""""""
+
+If the condition evaluates to true, the intrinsic returns the first value
+argument; otherwise, it returns the second value argument.
+
+The key semantic difference from :ref:`select <i_select>` is the constant-time
+code generation guarantee: the intrinsic must be lowered to machine code that:
+
+* Does not introduce data-dependent control flow based on the condition value
+* Executes the same sequence of instructions regardless of the condition value
+* Computes both value arguments before performing the selection
+
+**Platform Requirements:** The constant-time guarantee is conditional on
+platform support for data-independent timing, such as ARM DIT (Data Independent
+Timing) or x86 DOIT (Data Operand Independent Timing). Without such hardware
----------------
kumarak wrote:

You are right. Zkt and Zvkt are machine architecture features that provide hardware guarantees that a subset of instructions is constant time. I will go ahead and update the Platform requirements to include Zkt and Zvkt as well. 

https://github.com/llvm/llvm-project/pull/166702


More information about the llvm-commits mailing list