================
@@ -12592,93 +12596,57 @@ SDValue DAGCombiner::visitConstantTimeSelect(SDNode 
*N) {
   SDLoc DL(N);
   SDNodeFlags Flags = N->getFlags();
 
-  if (SDValue V = foldBoolSelectToLogic<EmptyMatchContext>(N, DL, DAG))
-    return V;
-
   // ctselect (not Cond), N1, N2 -> ctselect 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)) {
     SDValue SelectOp = DAG.getNode(ISD::CTSELECT, DL, VT, F, N2, N1);
     SelectOp->setFlags(Flags);
     return SelectOp;
   }
 
   if (VT0 == MVT::i1) {
-    // The code in this block deals with the following 2 equivalences:
-    //    select(C0|C1, x, y) <=> select(C0, x, select(C1, x, y))
-    //    select(C0&C1, x, y) <=> select(C0, select(C1, x, y), y)
-    // The target can specify its preferred form with the
-    // shouldNormalizeToSelectSequence() callback. However we always transform
-    // to the right anyway if we find the inner select exists in the DAG anyway
-    // and we always transform to the left side if we know that we can further
-    // optimize the combination of the conditions.
-    bool normalizeToSequence =
-        TLI.shouldNormalizeToSelectSequence(*DAG.getContext(), VT);
-    // ctselect (and Cond0, Cond1), X, Y
-    //   -> ctselect Cond0, (ctselect Cond1, X, Y), Y
-    if (N0->getOpcode() == ISD::AND && N0->hasOneUse()) {
-      SDValue Cond0 = N0->getOperand(0);
-      SDValue Cond1 = N0->getOperand(1);
-      SDValue InnerSelect = DAG.getNode(ISD::CTSELECT, DL, N1.getValueType(),
-                                        Cond1, N1, N2, Flags);
-      if (normalizeToSequence || !InnerSelect.use_empty())
-        return DAG.getNode(ISD::CTSELECT, DL, N1.getValueType(), Cond0,
-                           InnerSelect, N2, Flags);
-      // Cleanup on failure.
-      if (InnerSelect.use_empty())
-        recursivelyDeleteUnusedNodes(InnerSelect.getNode());
-    }
-    // ctselect (or Cond0, Cond1), X, Y -> ctselect Cond0, X, (ctselect Cond1,
-    // X, Y)
-    if (N0->getOpcode() == ISD::OR && N0->hasOneUse()) {
-      SDValue Cond0 = N0->getOperand(0);
-      SDValue Cond1 = N0->getOperand(1);
-      SDValue InnerSelect = DAG.getNode(ISD::CTSELECT, DL, N1.getValueType(),
-                                        Cond1, N1, N2, Flags);
-      if (normalizeToSequence || !InnerSelect.use_empty())
-        return DAG.getNode(ISD::CTSELECT, DL, N1.getValueType(), Cond0, N1,
-                           InnerSelect, Flags);
-      // Cleanup on failure.
-      if (InnerSelect.use_empty())
-        recursivelyDeleteUnusedNodes(InnerSelect.getNode());
-    }
-
-    // ctselect Cond0, (ctselect Cond1, X, Y), Y -> ctselect (and Cond0, 
Cond1),
-    // X, Y
+    // Nested CTSELECT merging optimizations for i1 conditions.
+    // These are CT-safe because:
+    //   1. AND/OR are bitwise operations that execute in constant time
+    //   2. The optimization combines two sequential CTSELECTs into one,
+    //   reducing
+    //      the total number of constant-time operations without changing
+    //      semantics
----------------
wizardengineer wrote:

nit: The formatting for this seems a bit off. Would it be okay if we can fix 
this?

https://github.com/llvm/llvm-project/pull/180883
_______________________________________________
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits

Reply via email to