[llvm] [RISCV]DAG combine special vp.select to logic (PR #79101)

Luke Lau via llvm-commits llvm-commits at lists.llvm.org
Tue Jan 23 23:05:03 PST 2024


================
@@ -15556,6 +15556,35 @@ SDValue RISCVTargetLowering::PerformDAGCombine(SDNode *N,
     }
     break;
   }
+  case ISD::VP_SELECT: {
+    EVT VT = N->getOperand(1).getValueType();
+    if (VT.isSimple() && VT.isScalableVector() &&
+        VT.getVectorElementType() == MVT::i1) {
+      SDValue N0 = N->getOperand(0);
+      SDValue N1 = N->getOperand(1);
+      SDValue N2 = N->getOperand(2);
+      SDValue VL = N->getOperand(3);
+      SDLoc DL(N);
+      // vp.select Cond, 0, F, EVL --> and (not Cond), F, EVL
+      // vp.select Cond, T, 0, EVL --> and Cond, T, EVL
+      // vp.select Cond, 1, F, EVL --> or Cond, F, EVL
+      // vp.select Cond, T, 1, EVL --> or (not Cond), T, EVL
+      if (isNullOrNullSplat(N1)) {
+        SDValue Not = DAG.getNode(RISCVISD::VMXOR_VL, DL, VT, N0,
+                                  DAG.getAllOnesConstant(DL, VT), VL);
+        return DAG.getNode(RISCVISD::VMAND_VL, DL, VT, Not, N2, VL);
+      } else if (isNullOrNullSplat(N2)) {
+        return DAG.getNode(RISCVISD::VMAND_VL, DL, VT, N0, N1, VL);
+      } else if (isOneOrOneSplat(N1)) {
+        return DAG.getNode(RISCVISD::VMOR_VL, DL, VT, N0, N1, VL);
+      } else if (isOneOrOneSplat(N2)) {
+        SDValue Not = DAG.getNode(RISCVISD::VMXOR_VL, DL, VT, N0,
+                                  DAG.getAllOnesConstant(DL, VT), VL);
+        return DAG.getNode(RISCVISD::VMOR_VL, DL, VT, Not, N1, VL);
+      }
+    }
+    return SDValue();
+  }
----------------
lukel97 wrote:

Is it possible to make this target agnostic and do this in DAGCombiner.cpp?

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


More information about the llvm-commits mailing list