[llvm] [RISCV] Optimize (and (icmp x, 0, eq), (icmp y, 0, eq)) utilizing zicond extension (PR #166469)

Craig Topper via llvm-commits llvm-commits at lists.llvm.org
Tue Nov 4 16:01:43 PST 2025


================
@@ -2763,6 +2763,51 @@ bool RISCVTargetLowering::mergeStoresAfterLegalization(EVT VT) const {
          (VT.isFixedLengthVector() && VT.getVectorElementType() == MVT::i1);
 }
 
+// Can the given operation be interchanged with a Zicond::CZERO operation
+// Must be:
+// - a SETCC instruction
+// - Must compare a value for [in]equality against 0
+static bool isCzeroCompatible(const SDValue Op) {
+  if (Op.getValueType() == MVT::i1 && Op.getOpcode() == ISD::SETCC &&
+      isNullConstant(Op.getOperand(1))) {
+    ISD::CondCode CondCode = cast<CondCodeSDNode>(Op.getOperand(2))->get();
+    return CondCode == ISD::SETNE || CondCode == ISD::SETEQ;
+  }
+  return false;
+}
+
+// Disable normalizing for most cases
+// select(N0&N1, X, Y) => select(N0, select(N1, X, Y), Y) and
+// select(N0|N1, X, Y) => select(N0, Y, select(N1, X, Y))
+// For select(N0, select(N1, X, Y), Y), if Y=0 and N0=setcc(eqz || nez):
+// %N1 = setcc [any_cond] %A, %B
+// %CZ = czero.eqz %N1, X
+// %Res = czero.eqz %N0, %CZ
+// ...
+// But for select(N0&N1, X, Y):
+// %N0 = setcc [eq/ne] %C, 0
+// %N1 = setcc [any_cond] %A, %B
+// %And = and %N0, %N1
+// %Res = czero.eqz %And, %X
+bool RISCVTargetLowering::shouldNormalizeToSelectSequence(LLVMContext &, EVT VT,
+                                                          SDNode *N) const {
+  if (Subtarget.hasStdExtZicond() || Subtarget.hasVendorXVentanaCondOps()) {
----------------
topperc wrote:

```suggestion
  if (Subtarget.hasCZEROLike()) {
```

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


More information about the llvm-commits mailing list