[llvm] [DAGCombiner] Combine (fshl A, B, S) | (fshr C, D, BW-S) --> (fshl (A|C), (B|D), S) (PR #180889)

Craig Topper via llvm-commits llvm-commits at lists.llvm.org
Wed Feb 11 08:40:59 PST 2026


================
@@ -8527,6 +8527,22 @@ static SDValue visitORCommutative(SelectionDAG &DAG, SDValue N0, SDValue N1,
     }
   }
 
+  // (fshl A, B, S) | (fshr C, D, BW-S) --> fshl (A|C), (B|D), S
+  if (N0.getOpcode() == ISD::FSHL && N1.getOpcode() == ISD::FSHR &&
+      N0.hasOneUse() && N1.hasOneUse()) {
+    auto *S0 = dyn_cast<ConstantSDNode>(N0.getOperand(2));
+    auto *S1 = dyn_cast<ConstantSDNode>(N1.getOperand(2));
+    if (S0 && S1 && (S0->getZExtValue() + S1->getZExtValue()) == BW) {
+      SDValue A = N0.getOperand(0);
+      SDValue B = N0.getOperand(1);
+      SDValue C = N1.getOperand(0);
+      SDValue D = N1.getOperand(1);
+      SDValue NewLHS = DAG.getNode(ISD::OR, DL, VT, A, C);
+      SDValue NewRHS = DAG.getNode(ISD::OR, DL, VT, B, D);
+      return DAG.getNode(ISD::FSHL, DL, VT, NewLHS, NewRHS, N0.getOperand(2));
----------------
topperc wrote:

Why is it unsafe? The shift amount is interpreted modulo the bit width so one of them being BW is equivalent to it being 0.

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


More information about the llvm-commits mailing list