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>) _______________________________________________ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
