[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
Wed Aug 26 12:51:29 PDT 2026
================
@@ -13625,6 +13627,57 @@ SDValue DAGCombiner::visitSELECT(SDNode *N) {
return SDValue();
}
+// Keep CT_SELECT combines deliberately conservative to preserve constant-time
+// intent across generic DAG combines. We only accept:
+// - canonicalization of negated conditions (flip true/false operands), and
+// - i1 CT_SELECT nesting merges via AND/OR that keep the result as CT_SELECT.
+// Broader rewrites should be done in target-specific lowering when stronger
+// guarantees about legality and constant-time preservation are available.
+SDValue DAGCombiner::visitCT_SELECT(SDNode *N) {
+ SDValue N0 = N->getOperand(0);
+ SDValue N1 = N->getOperand(1);
+ SDValue N2 = N->getOperand(2);
+ EVT VT = N->getValueType(0);
+ EVT VT0 = N0.getValueType();
+ SDLoc DL(N);
+
+ // ct_select (not Cond), N1, N2 -> ct_select Cond, N2, N1
+ // This is a CT-safe canonicalization: flip negated condition by swapping
+ // arms. extractBooleanFlip only matches boolean xor-with-1, so this preserves
+ // dataflow semantics and does not introduce data-dependent control flow.
+ if (SDValue F = extractBooleanFlip(N0, DAG, TLI, false))
+ return DAG.getCTSelect(DL, VT, F, N2, N1);
+
+ if (VT0 == MVT::i1) {
+ // Merge nested i1 ct_selects. The AND/OR of the two conditions is itself
+ // constant-time and the result remains a CT_SELECT.
+
+ // ct_select C0, (ct_select C1, X, Y), Y -> ct_select (C0 & C1), X, Y
+ if (N1.getOpcode() == ISD::CT_SELECT && N1.hasOneUse()) {
----------------
kumarak wrote:
Same idea as InstSimplify, but these preserve `CT_SELECT` because they canonicalize a negated condition by swapping the arms, and merge nested `CT_SELECTs` with a shared arm using branchless AND/OR. Both remain constant-time, and the merge can reduce two blends to one.
Happy to drop these if we’d prefer to keep visitCT_SELECT minimal.
https://github.com/llvm/llvm-project/pull/166702
More information about the llvm-commits
mailing list