[llvm-branch-commits] [llvm] 311b24c - Revert "[LangRef][ConstantTime] Add documentation for llvm.ct.select.* consta…"
via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Thu Feb 12 08:21:36 PST 2026
Author: Nikita Popov
Date: 2026-02-12T17:21:31+01:00
New Revision: 311b24c0b88dd0009f0ff87fc84369f4df37acd8
URL: https://github.com/llvm/llvm-project/commit/311b24c0b88dd0009f0ff87fc84369f4df37acd8
DIFF: https://github.com/llvm/llvm-project/commit/311b24c0b88dd0009f0ff87fc84369f4df37acd8.diff
LOG: Revert "[LangRef][ConstantTime] Add documentation for llvm.ct.select.* consta…"
This reverts commit 64a23815683718b12b9e8877057755aeb7a3b1e4.
Added:
Modified:
llvm/docs/LangRef.rst
llvm/test/CodeGen/X86/ctselect.ll
Removed:
################################################################################
diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst
index 98bfc325625e0..00a4a00c5bf95 100644
--- a/llvm/docs/LangRef.rst
+++ b/llvm/docs/LangRef.rst
@@ -15904,132 +15904,6 @@ 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.
-
-When the value arguments are vectors, the scalar condition is broadcast to
-all vector elements (i.e., all elements are selected from the same source
-vector based on the single condition).
-
-Semantics:
-""""""""""
-
-If the condition evaluates to 1, the intrinsic returns the first value
-argument; otherwise, it returns the second value argument.
-
-The key semantic
diff erence 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
-
-The typical implementation uses bitwise operations to blend the two values
-based on a mask derived from the condition:
-
-::
-
- mask = sext(cond) ; sign-extend condition to all 1s or all 0s
- result = val2 ^ ((val1 ^ val2) & mask)
-
-Targets with native constant-time select support use target-specific
-instructions to generate optimized bitwise operations with stronger guarantees.
-Targets without native support lower the intrinsic to a sequence of generic
-bitwise operations as shown above, structured to resist pattern recognition
-and preserve the constant-time property through optimization passes.
-
-Optimizations must preserve the constant-time code generation semantics.
-Transforms that would introduce data-dependent control flow are not permitted.
-This includes converting to conditional branches, using predicated instructions
-with data-dependent timing, or optimizing away either value argument before the
-selection completes (both paths must be computed).
-
-Examples:
-"""""""""
-
-.. code-block:: llvm
-
- ; Constant-time integer selection
- %x = call i32 @llvm.ct.select.i32(i1 %cond, i32 42, i32 17)
- %key = call i64 @llvm.ct.select.i64(i1 %cond, i64 %k_a, i64 %k_b)
-
- ; Constant-time 128-bit integer vector selection (scalar condition broadcast to all lanes)
- %v4 = call <4 x i32> @llvm.ct.select.v4i32(i1 %cond,
- <4 x i32> <i32 1, i32 2, i32 3, i32 4>,
- <4 x i32> <i32 5, i32 6, i32 7, i32 8>)
-
- ; Constant-time 256-bit integer vector selection
- %v8 = call <8 x i32> @llvm.ct.select.v8i32(i1 %cond,
- <8 x i32> %vec_a, <8 x i32> %vec_b)
-
- ; Constant-time 256-bit float vector selection
- %v8f = call <8 x float> @llvm.ct.select.v8f32(i1 %cond,
- <8 x float> %fvec_a, <8 x float> %fvec_b)
-
- ; Constant-time float vector selection
- %f = call float @llvm.ct.select.f32(i1 %cond, float 1.0, float 0.0)
-
- ; Constant-time pointer selection
- %ptr = call ptr @llvm.ct.select.p0(i1 %cond, ptr %ptr_a, ptr %ptr_b)
-
Standard C/C++ Library Intrinsics
---------------------------------
diff --git a/llvm/test/CodeGen/X86/ctselect.ll b/llvm/test/CodeGen/X86/ctselect.ll
index a970fd8933b9b..2b6091c880637 100644
--- a/llvm/test/CodeGen/X86/ctselect.ll
+++ b/llvm/test/CodeGen/X86/ctselect.ll
@@ -1210,193 +1210,6 @@ define <8 x i32> @test_ctselect_v8i32_avx(i1 %cond, <8 x i32> %a, <8 x i32> %b)
ret <8 x i32> %result
}
-define <8 x float> @test_ctselect_v8f32(i1 %cond, <8 x float> %a, <8 x float> %b) {
-; X64-LABEL: test_ctselect_v8f32:
-; X64: # %bb.0:
-; X64-NEXT: movd %edi, %xmm4
-; X64-NEXT: pshufd {{.*#+}} xmm4 = xmm4[0,0,0,0]
-; X64-NEXT: pslld $31, %xmm4
-; X64-NEXT: psrad $31, %xmm4
-; X64-NEXT: movdqa %xmm4, %xmm5
-; X64-NEXT: pandn %xmm2, %xmm5
-; X64-NEXT: pand %xmm4, %xmm0
-; X64-NEXT: por %xmm5, %xmm0
-; X64-NEXT: pand %xmm4, %xmm1
-; X64-NEXT: pandn %xmm3, %xmm4
-; X64-NEXT: por %xmm4, %xmm1
-; X64-NEXT: retq
-;
-; X32-LABEL: test_ctselect_v8f32:
-; X32: # %bb.0:
-; X32-NEXT: pushl %ebp
-; X32-NEXT: .cfi_def_cfa_offset 8
-; X32-NEXT: pushl %ebx
-; X32-NEXT: .cfi_def_cfa_offset 12
-; X32-NEXT: pushl %edi
-; X32-NEXT: .cfi_def_cfa_offset 16
-; X32-NEXT: pushl %esi
-; X32-NEXT: .cfi_def_cfa_offset 20
-; X32-NEXT: subl $8, %esp
-; X32-NEXT: .cfi_def_cfa_offset 28
-; X32-NEXT: .cfi_offset %esi, -20
-; X32-NEXT: .cfi_offset %edi, -16
-; X32-NEXT: .cfi_offset %ebx, -12
-; X32-NEXT: .cfi_offset %ebp, -8
-; X32-NEXT: movl {{[0-9]+}}(%esp), %edi
-; X32-NEXT: movl {{[0-9]+}}(%esp), %ebp
-; X32-NEXT: movl {{[0-9]+}}(%esp), %ebx
-; X32-NEXT: movl {{[0-9]+}}(%esp), %esi
-; X32-NEXT: movl {{[0-9]+}}(%esp), %eax
-; X32-NEXT: movl {{[0-9]+}}(%esp), %ecx
-; X32-NEXT: xorl %eax, %ecx
-; X32-NEXT: movzbl {{[0-9]+}}(%esp), %edx
-; X32-NEXT: andl $1, %edx
-; X32-NEXT: negl %edx
-; X32-NEXT: andl %edx, %ecx
-; X32-NEXT: xorl %eax, %ecx
-; X32-NEXT: movl %ecx, {{[-0-9]+}}(%e{{[sb]}}p) # 4-byte Spill
-; X32-NEXT: movl {{[0-9]+}}(%esp), %eax
-; X32-NEXT: xorl %esi, %eax
-; X32-NEXT: andl %edx, %eax
-; X32-NEXT: xorl %esi, %eax
-; X32-NEXT: movl %eax, (%esp) # 4-byte Spill
-; X32-NEXT: movl {{[0-9]+}}(%esp), %esi
-; X32-NEXT: xorl %ebx, %esi
-; X32-NEXT: andl %edx, %esi
-; X32-NEXT: xorl %ebx, %esi
-; X32-NEXT: movl {{[0-9]+}}(%esp), %ebx
-; X32-NEXT: xorl %ebp, %ebx
-; X32-NEXT: andl %edx, %ebx
-; X32-NEXT: xorl %ebp, %ebx
-; X32-NEXT: movl {{[0-9]+}}(%esp), %ebp
-; X32-NEXT: xorl %edi, %ebp
-; X32-NEXT: andl %edx, %ebp
-; X32-NEXT: xorl %edi, %ebp
-; X32-NEXT: movl {{[0-9]+}}(%esp), %eax
-; X32-NEXT: movl {{[0-9]+}}(%esp), %edi
-; X32-NEXT: xorl %eax, %edi
-; X32-NEXT: andl %edx, %edi
-; X32-NEXT: xorl %eax, %edi
-; X32-NEXT: movl {{[0-9]+}}(%esp), %eax
-; X32-NEXT: movl {{[0-9]+}}(%esp), %ecx
-; X32-NEXT: xorl %eax, %ecx
-; X32-NEXT: andl %edx, %ecx
-; X32-NEXT: xorl %eax, %ecx
-; X32-NEXT: movl {{[0-9]+}}(%esp), %eax
-; X32-NEXT: xorl {{[0-9]+}}(%esp), %eax
-; X32-NEXT: andl %edx, %eax
-; X32-NEXT: xorl {{[0-9]+}}(%esp), %eax
-; X32-NEXT: movl {{[0-9]+}}(%esp), %edx
-; X32-NEXT: movl %eax, 28(%edx)
-; X32-NEXT: movl %ecx, 24(%edx)
-; X32-NEXT: movl %edi, 20(%edx)
-; X32-NEXT: movl %ebp, 16(%edx)
-; X32-NEXT: movl %ebx, 12(%edx)
-; X32-NEXT: movl %esi, 8(%edx)
-; X32-NEXT: movl (%esp), %eax # 4-byte Reload
-; X32-NEXT: movl %eax, 4(%edx)
-; X32-NEXT: movl {{[-0-9]+}}(%e{{[sb]}}p), %eax # 4-byte Reload
-; X32-NEXT: movl %eax, (%edx)
-; X32-NEXT: movl %edx, %eax
-; X32-NEXT: addl $8, %esp
-; X32-NEXT: .cfi_def_cfa_offset 20
-; X32-NEXT: popl %esi
-; X32-NEXT: .cfi_def_cfa_offset 16
-; X32-NEXT: popl %edi
-; X32-NEXT: .cfi_def_cfa_offset 12
-; X32-NEXT: popl %ebx
-; X32-NEXT: .cfi_def_cfa_offset 8
-; X32-NEXT: popl %ebp
-; X32-NEXT: .cfi_def_cfa_offset 4
-; X32-NEXT: retl $4
-;
-; X32-NOCMOV-LABEL: test_ctselect_v8f32:
-; X32-NOCMOV: # %bb.0:
-; X32-NOCMOV-NEXT: pushl %ebp
-; X32-NOCMOV-NEXT: .cfi_def_cfa_offset 8
-; X32-NOCMOV-NEXT: pushl %ebx
-; X32-NOCMOV-NEXT: .cfi_def_cfa_offset 12
-; X32-NOCMOV-NEXT: pushl %edi
-; X32-NOCMOV-NEXT: .cfi_def_cfa_offset 16
-; X32-NOCMOV-NEXT: pushl %esi
-; X32-NOCMOV-NEXT: .cfi_def_cfa_offset 20
-; X32-NOCMOV-NEXT: subl $8, %esp
-; X32-NOCMOV-NEXT: .cfi_def_cfa_offset 28
-; X32-NOCMOV-NEXT: .cfi_offset %esi, -20
-; X32-NOCMOV-NEXT: .cfi_offset %edi, -16
-; X32-NOCMOV-NEXT: .cfi_offset %ebx, -12
-; X32-NOCMOV-NEXT: .cfi_offset %ebp, -8
-; X32-NOCMOV-NEXT: movl {{[0-9]+}}(%esp), %edi
-; X32-NOCMOV-NEXT: movl {{[0-9]+}}(%esp), %ebp
-; X32-NOCMOV-NEXT: movl {{[0-9]+}}(%esp), %ebx
-; X32-NOCMOV-NEXT: movl {{[0-9]+}}(%esp), %esi
-; X32-NOCMOV-NEXT: movl {{[0-9]+}}(%esp), %eax
-; X32-NOCMOV-NEXT: movl {{[0-9]+}}(%esp), %ecx
-; X32-NOCMOV-NEXT: xorl %eax, %ecx
-; X32-NOCMOV-NEXT: movzbl {{[0-9]+}}(%esp), %edx
-; X32-NOCMOV-NEXT: andl $1, %edx
-; X32-NOCMOV-NEXT: negl %edx
-; X32-NOCMOV-NEXT: andl %edx, %ecx
-; X32-NOCMOV-NEXT: xorl %eax, %ecx
-; X32-NOCMOV-NEXT: movl %ecx, {{[-0-9]+}}(%e{{[sb]}}p) # 4-byte Spill
-; X32-NOCMOV-NEXT: movl {{[0-9]+}}(%esp), %eax
-; X32-NOCMOV-NEXT: xorl %esi, %eax
-; X32-NOCMOV-NEXT: andl %edx, %eax
-; X32-NOCMOV-NEXT: xorl %esi, %eax
-; X32-NOCMOV-NEXT: movl %eax, (%esp) # 4-byte Spill
-; X32-NOCMOV-NEXT: movl {{[0-9]+}}(%esp), %esi
-; X32-NOCMOV-NEXT: xorl %ebx, %esi
-; X32-NOCMOV-NEXT: andl %edx, %esi
-; X32-NOCMOV-NEXT: xorl %ebx, %esi
-; X32-NOCMOV-NEXT: movl {{[0-9]+}}(%esp), %ebx
-; X32-NOCMOV-NEXT: xorl %ebp, %ebx
-; X32-NOCMOV-NEXT: andl %edx, %ebx
-; X32-NOCMOV-NEXT: xorl %ebp, %ebx
-; X32-NOCMOV-NEXT: movl {{[0-9]+}}(%esp), %ebp
-; X32-NOCMOV-NEXT: xorl %edi, %ebp
-; X32-NOCMOV-NEXT: andl %edx, %ebp
-; X32-NOCMOV-NEXT: xorl %edi, %ebp
-; X32-NOCMOV-NEXT: movl {{[0-9]+}}(%esp), %eax
-; X32-NOCMOV-NEXT: movl {{[0-9]+}}(%esp), %edi
-; X32-NOCMOV-NEXT: xorl %eax, %edi
-; X32-NOCMOV-NEXT: andl %edx, %edi
-; X32-NOCMOV-NEXT: xorl %eax, %edi
-; X32-NOCMOV-NEXT: movl {{[0-9]+}}(%esp), %eax
-; X32-NOCMOV-NEXT: movl {{[0-9]+}}(%esp), %ecx
-; X32-NOCMOV-NEXT: xorl %eax, %ecx
-; X32-NOCMOV-NEXT: andl %edx, %ecx
-; X32-NOCMOV-NEXT: xorl %eax, %ecx
-; X32-NOCMOV-NEXT: movl {{[0-9]+}}(%esp), %eax
-; X32-NOCMOV-NEXT: xorl {{[0-9]+}}(%esp), %eax
-; X32-NOCMOV-NEXT: andl %edx, %eax
-; X32-NOCMOV-NEXT: xorl {{[0-9]+}}(%esp), %eax
-; X32-NOCMOV-NEXT: movl {{[0-9]+}}(%esp), %edx
-; X32-NOCMOV-NEXT: movl %eax, 28(%edx)
-; X32-NOCMOV-NEXT: movl %ecx, 24(%edx)
-; X32-NOCMOV-NEXT: movl %edi, 20(%edx)
-; X32-NOCMOV-NEXT: movl %ebp, 16(%edx)
-; X32-NOCMOV-NEXT: movl %ebx, 12(%edx)
-; X32-NOCMOV-NEXT: movl %esi, 8(%edx)
-; X32-NOCMOV-NEXT: movl (%esp), %eax # 4-byte Reload
-; X32-NOCMOV-NEXT: movl %eax, 4(%edx)
-; X32-NOCMOV-NEXT: movl {{[-0-9]+}}(%e{{[sb]}}p), %eax # 4-byte Reload
-; X32-NOCMOV-NEXT: movl %eax, (%edx)
-; X32-NOCMOV-NEXT: movl %edx, %eax
-; X32-NOCMOV-NEXT: addl $8, %esp
-; X32-NOCMOV-NEXT: .cfi_def_cfa_offset 20
-; X32-NOCMOV-NEXT: popl %esi
-; X32-NOCMOV-NEXT: .cfi_def_cfa_offset 16
-; X32-NOCMOV-NEXT: popl %edi
-; X32-NOCMOV-NEXT: .cfi_def_cfa_offset 12
-; X32-NOCMOV-NEXT: popl %ebx
-; X32-NOCMOV-NEXT: .cfi_def_cfa_offset 8
-; X32-NOCMOV-NEXT: popl %ebp
-; X32-NOCMOV-NEXT: .cfi_def_cfa_offset 4
-; X32-NOCMOV-NEXT: retl $4
- %result = call <8 x float> @llvm.ct.select.v8f32(i1 %cond, <8 x float> %a, <8 x float> %b)
- ret <8 x float> %result
-}
-
define float @test_ctselect_f32_nan_inf(i1 %cond) {
; X64-LABEL: test_ctselect_f32_nan_inf:
; X64: # %bb.0:
@@ -1506,4 +1319,3 @@ declare <16 x i8> @llvm.ct.select.v16i8(i1, <16 x i8>, <16 x i8>)
declare <4 x float> @llvm.ct.select.v4f32(i1, <4 x float>, <4 x float>)
declare <2 x double> @llvm.ct.select.v2f64(i1, <2 x double>, <2 x double>)
declare <8 x i32> @llvm.ct.select.v8i32(i1, <8 x i32>, <8 x i32>)
-declare <8 x float> @llvm.ct.select.v8f32(i1, <8 x float>, <8 x float>)
More information about the llvm-branch-commits
mailing list