[llvm] 914682e - [RISCV] Move combineANDOfSETCCToCZERO to isel patterns. (#219318)

via llvm-commits llvm-commits at lists.llvm.org
Fri Aug 28 12:18:16 PDT 2026


Author: Craig Topper
Date: 2026-08-28T12:18:11-07:00
New Revision: 914682e1590eaa13b6ad156cece36984445f19c5

URL: https://github.com/llvm/llvm-project/commit/914682e1590eaa13b6ad156cece36984445f19c5
DIFF: https://github.com/llvm/llvm-project/commit/914682e1590eaa13b6ad156cece36984445f19c5.diff

LOG: [RISCV] Move combineANDOfSETCCToCZERO to isel patterns. (#219318)

This allows us to reuse RISCVDAGToDAGISel::selectSETCC to pick
the best instruction when comparing against a constant.

Added: 
    llvm/test/CodeGen/RISCV/rvv/zicond-crash.ll

Modified: 
    llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
    llvm/lib/Target/RISCV/RISCVISelDAGToDAG.h
    llvm/lib/Target/RISCV/RISCVISelLowering.cpp
    llvm/lib/Target/RISCV/RISCVInstrInfo.td
    llvm/lib/Target/RISCV/RISCVInstrInfoXVentana.td
    llvm/lib/Target/RISCV/RISCVInstrInfoZicond.td
    llvm/test/CodeGen/RISCV/zicond-opts.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
index 29d133b5adba9..2b376bd8005bf 100644
--- a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
@@ -4022,7 +4022,7 @@ bool RISCVDAGToDAGISel::selectShiftMask(SDValue N, unsigned ShiftWidth,
 /// \p ExpectedCCVal indicates the condition code to attempt to match (e.g.
 /// ISD::SETNE).
 bool RISCVDAGToDAGISel::selectSETCC(SDValue N, ISD::CondCode ExpectedCCVal,
-                                    SDValue &Val) {
+                                    SDValue &Val, bool OneUse) {
   assert(ISD::isIntEqualitySetCC(ExpectedCCVal) &&
          "Unexpected condition code!");
 
@@ -4030,6 +4030,9 @@ bool RISCVDAGToDAGISel::selectSETCC(SDValue N, ISD::CondCode ExpectedCCVal,
   if (N->getOpcode() != ISD::SETCC)
     return false;
 
+  if (OneUse && !N->hasOneUse())
+    return false;
+
   // Must be an equality comparison.
   ISD::CondCode CCVal = cast<CondCodeSDNode>(N->getOperand(2))->get();
   if (CCVal != ExpectedCCVal)

diff  --git a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.h b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.h
index 6c4adaf515224..da08a6032d94f 100644
--- a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.h
+++ b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.h
@@ -117,12 +117,13 @@ class RISCVDAGToDAGISel : public SelectionDAGISel {
     return selectShiftMask(N, Size, ShAmt);
   }
 
-  bool selectSETCC(SDValue N, ISD::CondCode ExpectedCCVal, SDValue &Val);
-  bool selectSETNE(SDValue N, SDValue &Val) {
-    return selectSETCC(N, ISD::SETNE, Val);
+  bool selectSETCC(SDValue N, ISD::CondCode ExpectedCCVal, SDValue &Val,
+                   bool OneUse);
+  template <bool OneUse = false> bool selectSETNE(SDValue N, SDValue &Val) {
+    return selectSETCC(N, ISD::SETNE, Val, OneUse);
   }
-  bool selectSETEQ(SDValue N, SDValue &Val) {
-    return selectSETCC(N, ISD::SETEQ, Val);
+  template <bool OneUse = false> bool selectSETEQ(SDValue N, SDValue &Val) {
+    return selectSETCC(N, ISD::SETEQ, Val, OneUse);
   }
 
   bool selectSExtBits(SDValue N, unsigned Bits, SDValue &Val);

diff  --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 96ece8ff6b4ce..1acff2381d5d4 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -18634,62 +18634,6 @@ static SDValue reverseZExtICmpCombine(SDNode *N, SelectionDAG &DAG,
   return DAG.getNode(ISD::ZERO_EXTEND, DL, VT, Res);
 }
 
-// (and (i1) f, (setcc a, b, eq)) -> (czero.nez f, (xor a, b))
-// (and (i1) f, (setcc a, b, ne)) -> (czero.eqz f, (xor a, b))
-// (and (setcc a, b, eq), (i1) g) -> (czero.nez g, (xor a, b))
-// (and (setcc a, b, ne), (i1) g) -> (czero.eqz g, (xor a, b))
-//
-// (and (i1) f, (setcc c, 0, ne)) -> (czero.nez f, c)
-// (and (i1) f, (setcc c, 0, eq)) -> (czero.eqz f, c)
-// (and (setcc c, 0, ne), (i1) g) -> (czero.nez g, c)
-// (and (setcc c, 0, eq), (i1) g) -> (czero.eqz g, c)
-static SDValue combineANDOfSETCCToCZERO(SDNode *N, SelectionDAG &DAG,
-                                        const RISCVSubtarget &Subtarget) {
-  if (!Subtarget.hasCZEROLike())
-    return SDValue();
-
-  SDValue N0 = N->getOperand(0);
-  SDValue N1 = N->getOperand(1);
-
-  auto IsSetCCEquality = [](SDValue &V) -> bool {
-    if (V.getOpcode() == ISD::SETCC) {
-      ISD::CondCode CC = cast<CondCodeSDNode>(V.getOperand(2))->get();
-      if (ISD::isIntEqualitySetCC(CC))
-        return true;
-    }
-    return false;
-  };
-
-  if (!IsSetCCEquality(N0) || !N0.hasOneUse())
-    std::swap(N0, N1);
-  if (!IsSetCCEquality(N0) || !N0.hasOneUse())
-    return SDValue();
-
-  KnownBits Known = DAG.computeKnownBits(N1);
-  if (Known.getMaxValue().ugt(1))
-    return SDValue();
-
-  SDLoc DL(N);
-  EVT VT = N->getValueType(0);
-  unsigned CzeroOpcode =
-      (cast<CondCodeSDNode>(N0.getOperand(2))->get() == ISD::SETNE)
-          ? RISCVISD::CZERO_EQZ
-          : RISCVISD::CZERO_NEZ;
-
-  // From here we have two cases:
-  // Either setcc is a comparision with zero, and we can lower directly to a
-  // czero instruction; Or it's not a constant zero, in which case we can still
-  // use a czero, but we first need to get a zero or one value comparing the two
-  // sides of setcc.
-  SDValue Rhs = N0.getOperand(0);
-  if (!isNullConstant(N0->getOperand(1))) {
-    Rhs = DAG.getNode(ISD::XOR, DL, N0.getValueType(), N0.getOperand(0),
-                      N0.getOperand(1));
-  }
-
-  return DAG.getNode(CzeroOpcode, DL, VT, N1, Rhs);
-}
-
 static SDValue reduceANDOfAtomicLoad(SDNode *N,
                                      TargetLowering::DAGCombinerInfo &DCI) {
   SelectionDAG &DAG = DCI.DAG;
@@ -18797,9 +18741,6 @@ static SDValue performANDCombine(SDNode *N,
     return V;
   if (SDValue V = reverseZExtICmpCombine(N, DAG, Subtarget))
     return V;
-  if (DCI.isAfterLegalizeDAG())
-    if (SDValue V = combineANDOfSETCCToCZERO(N, DAG, Subtarget))
-      return V;
   if (SDValue V = combineBinOpToReduce(N, DAG, Subtarget))
     return V;
   if (SDValue V = combineBinOpOfExtractToReduceTree(N, DAG, Subtarget))

diff  --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.td b/llvm/lib/Target/RISCV/RISCVInstrInfo.td
index 72f4046e84e3e..1a0f85271a9b1 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.td
@@ -1669,6 +1669,13 @@ def : PatGprSimm12<setult, SLTIU>;
 // These ComplexPatterns must be used in pairs.
 def riscv_setne : ComplexPattern<XLenVT, 1, "selectSETNE", [setcc]>;
 def riscv_seteq : ComplexPattern<XLenVT, 1, "selectSETEQ", [setcc]>;
+def riscv_setne_oneuse : ComplexPattern<XLenVT, 1, "selectSETNE<true>">;
+def riscv_seteq_oneuse : ComplexPattern<XLenVT, 1, "selectSETEQ<true>">;
+
+// Check that the value is known to be 0 or 1, i.e. a boolean value.
+def zero_or_one : PatLeaf<(XLenVT GPR:$src), [{
+  return CurDAG->computeKnownBits(SDValue(N, 0)).getMaxValue().ule(1);
+}]>;
 
 // Define pattern expansions for setcc operations that aren't directly
 // handled by a RISC-V instruction.

diff  --git a/llvm/lib/Target/RISCV/RISCVInstrInfoXVentana.td b/llvm/lib/Target/RISCV/RISCVInstrInfoXVentana.td
index b1a7a18a3bf85..d309689378901 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoXVentana.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXVentana.td
@@ -42,4 +42,12 @@ def : Pat<(XLenVT (riscv_czero_nez GPR:$rs1, (riscv_setne (XLenVT GPR:$rc)))),
           (VT_MASKCN GPR:$rs1, GPR:$rc)>;
 def : Pat<(XLenVT (riscv_czero_nez GPR:$rs1, (riscv_seteq (XLenVT GPR:$rc)))),
           (VT_MASKC GPR:$rs1, GPR:$rc)>;
+
+// (and (setcc a, b, ne), c) -> (vt.maskc c, (xor a, b))
+// (and (setcc a, b, eq), c) -> (vt.maskcn c, (xor a, b))
+// where c is known to be 0 or 1.
+def : Pat<(XLenVT (and (riscv_setne_oneuse (XLenVT GPR:$rs1)), zero_or_one:$rc)),
+          (VT_MASKC GPR:$rc, GPR:$rs1)>;
+def : Pat<(XLenVT (and (riscv_seteq_oneuse (XLenVT GPR:$rs1)), zero_or_one:$rc)),
+          (VT_MASKCN GPR:$rc, GPR:$rs1)>;
 } // Predicates = [HasVendorXVentanaCondOps]

diff  --git a/llvm/lib/Target/RISCV/RISCVInstrInfoZicond.td b/llvm/lib/Target/RISCV/RISCVInstrInfoZicond.td
index fcd3987bc10ab..4861dc47ff133 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoZicond.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoZicond.td
@@ -49,4 +49,12 @@ def : Pat<(XLenVT (riscv_czero_nez GPR:$rs1, (riscv_setne (XLenVT GPR:$rc)))),
           (CZERO_NEZ GPR:$rs1, GPR:$rc)>;
 def : Pat<(XLenVT (riscv_czero_nez GPR:$rs1, (riscv_seteq (XLenVT GPR:$rc)))),
           (CZERO_EQZ GPR:$rs1, GPR:$rc)>;
+
+// (and (setcc a, b, ne), c) -> (czero.eqz c, (xor a, b))
+// (and (setcc a, b, eq), c) -> (czero.nez c, (xor a, b))
+// where c is known to be 0 or 1.
+def : Pat<(XLenVT (and (riscv_setne_oneuse (XLenVT GPR:$rs1)), zero_or_one:$rc)),
+          (CZERO_EQZ GPR:$rc, GPR:$rs1)>;
+def : Pat<(XLenVT (and (riscv_seteq_oneuse (XLenVT GPR:$rs1)), zero_or_one:$rc)),
+          (CZERO_NEZ GPR:$rc, GPR:$rs1)>;
 } // Predicates = [HasStdExtZicond]

diff  --git a/llvm/test/CodeGen/RISCV/rvv/zicond-crash.ll b/llvm/test/CodeGen/RISCV/rvv/zicond-crash.ll
new file mode 100644
index 0000000000000..3a092f2c08be6
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/rvv/zicond-crash.ll
@@ -0,0 +1,15 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
+; RUN: llc < %s -mtriple=riscv64 -mattr=+zicond,+v | FileCheck %s
+
+; This test previously crashed when V and Zicond were both enabled.
+
+define <vscale x 2 x i1> @vector(<vscale x 2 x i1> %a, <vscale x 2 x i32> %b, <vscale x 2 x i32> %c) {
+; CHECK-LABEL: vector:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    vsetvli a0, zero, e32, m1, ta, mu
+; CHECK-NEXT:    vmseq.vv v0, v8, v9, v0.t
+; CHECK-NEXT:    ret
+  %cmp = icmp eq <vscale x 2 x i32> %b, %c
+  %and = and <vscale x 2 x i1> %a, %cmp
+  ret <vscale x 2 x i1> %and
+}

diff  --git a/llvm/test/CodeGen/RISCV/zicond-opts.ll b/llvm/test/CodeGen/RISCV/zicond-opts.ll
index 34e4da410ed79..800c4b55563ae 100644
--- a/llvm/test/CodeGen/RISCV/zicond-opts.ll
+++ b/llvm/test/CodeGen/RISCV/zicond-opts.ll
@@ -1,8 +1,10 @@
 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
 ; RUN: llc -mtriple=riscv32 -O2 -verify-machineinstrs -mattr=+b,+zicond < %s | FileCheck %s -check-prefix=RV32ZICOND
 ; RUN: llc -mtriple=riscv64 -O2 -verify-machineinstrs -mattr=+b,+zicond < %s | FileCheck %s -check-prefix=RV64ZICOND
+; RUN: llc -mtriple=riscv32 -O2 -verify-machineinstrs -mattr=+b,+xventanacondops < %s | FileCheck %s -check-prefix=RV32XVENTANACONDOPS
+; RUN: llc -mtriple=riscv64 -O2 -verify-machineinstrs -mattr=+b,+xventanacondops < %s | FileCheck %s -check-prefix=RV64XVENTANACONDOPS
 
-; (and (icmp x. 0, ne), (icmp y, 0, ne)) -> (czero.eqz (icmp x, 0, ne), y)
+; (and (icmp x, 0, ne), (icmp y, 0, ne)) -> (czero.eqz (icmp x, 0, ne), y)
 define i32 @icmp_and(i64 %x, i64 %y) {
 ; RV32ZICOND-LABEL: icmp_and:
 ; RV32ZICOND:       # %bb.0:
@@ -17,6 +19,20 @@ define i32 @icmp_and(i64 %x, i64 %y) {
 ; RV64ZICOND-NEXT:    snez a1, a1
 ; RV64ZICOND-NEXT:    czero.eqz a0, a1, a0
 ; RV64ZICOND-NEXT:    ret
+;
+; RV32XVENTANACONDOPS-LABEL: icmp_and:
+; RV32XVENTANACONDOPS:       # %bb.0:
+; RV32XVENTANACONDOPS-NEXT:    or a2, a2, a3
+; RV32XVENTANACONDOPS-NEXT:    snez a2, a2
+; RV32XVENTANACONDOPS-NEXT:    or a0, a0, a1
+; RV32XVENTANACONDOPS-NEXT:    vt.maskc a0, a2, a0
+; RV32XVENTANACONDOPS-NEXT:    ret
+;
+; RV64XVENTANACONDOPS-LABEL: icmp_and:
+; RV64XVENTANACONDOPS:       # %bb.0:
+; RV64XVENTANACONDOPS-NEXT:    snez a1, a1
+; RV64XVENTANACONDOPS-NEXT:    vt.maskc a0, a1, a0
+; RV64XVENTANACONDOPS-NEXT:    ret
   %3 = icmp ne i64 %y, 0
   %4 = icmp ne i64 %x, 0
   %5 = and i1 %4, %3
@@ -41,6 +57,22 @@ define i32 @icmp_and_x_multiple_uses(i64 %x, i64 %y) {
 ; RV64ZICOND-NEXT:    czero.eqz a1, a0, a1
 ; RV64ZICOND-NEXT:    add a0, a1, a0
 ; RV64ZICOND-NEXT:    ret
+;
+; RV32XVENTANACONDOPS-LABEL: icmp_and_x_multiple_uses:
+; RV32XVENTANACONDOPS:       # %bb.0:
+; RV32XVENTANACONDOPS-NEXT:    or a0, a0, a1
+; RV32XVENTANACONDOPS-NEXT:    or a2, a2, a3
+; RV32XVENTANACONDOPS-NEXT:    snez a0, a0
+; RV32XVENTANACONDOPS-NEXT:    vt.maskc a1, a0, a2
+; RV32XVENTANACONDOPS-NEXT:    add a0, a1, a0
+; RV32XVENTANACONDOPS-NEXT:    ret
+;
+; RV64XVENTANACONDOPS-LABEL: icmp_and_x_multiple_uses:
+; RV64XVENTANACONDOPS:       # %bb.0:
+; RV64XVENTANACONDOPS-NEXT:    snez a0, a0
+; RV64XVENTANACONDOPS-NEXT:    vt.maskc a1, a0, a1
+; RV64XVENTANACONDOPS-NEXT:    add a0, a1, a0
+; RV64XVENTANACONDOPS-NEXT:    ret
   %3 = icmp ne i64 %y, 0
   %4 = icmp ne i64 %x, 0
   %5 = and i1 %4, %3
@@ -67,6 +99,22 @@ define i32 @icmp_and_y_multiple_uses(i64 %x, i64 %y) {
 ; RV64ZICOND-NEXT:    czero.eqz a0, a1, a0
 ; RV64ZICOND-NEXT:    add a0, a0, a1
 ; RV64ZICOND-NEXT:    ret
+;
+; RV32XVENTANACONDOPS-LABEL: icmp_and_y_multiple_uses:
+; RV32XVENTANACONDOPS:       # %bb.0:
+; RV32XVENTANACONDOPS-NEXT:    or a2, a2, a3
+; RV32XVENTANACONDOPS-NEXT:    snez a2, a2
+; RV32XVENTANACONDOPS-NEXT:    or a0, a0, a1
+; RV32XVENTANACONDOPS-NEXT:    vt.maskc a0, a2, a0
+; RV32XVENTANACONDOPS-NEXT:    add a0, a0, a2
+; RV32XVENTANACONDOPS-NEXT:    ret
+;
+; RV64XVENTANACONDOPS-LABEL: icmp_and_y_multiple_uses:
+; RV64XVENTANACONDOPS:       # %bb.0:
+; RV64XVENTANACONDOPS-NEXT:    snez a1, a1
+; RV64XVENTANACONDOPS-NEXT:    vt.maskc a0, a1, a0
+; RV64XVENTANACONDOPS-NEXT:    add a0, a0, a1
+; RV64XVENTANACONDOPS-NEXT:    ret
   %3 = icmp ne i64 %y, 0
   %4 = icmp ne i64 %x, 0
   %5 = and i1 %4, %3
@@ -97,6 +145,26 @@ define i32 @icmp_and_xy_multiple_uses(i64 %x, i64 %y) {
 ; RV64ZICOND-NEXT:    add a0, a1, a0
 ; RV64ZICOND-NEXT:    add a0, a2, a0
 ; RV64ZICOND-NEXT:    ret
+;
+; RV32XVENTANACONDOPS-LABEL: icmp_and_xy_multiple_uses:
+; RV32XVENTANACONDOPS:       # %bb.0:
+; RV32XVENTANACONDOPS-NEXT:    or a2, a2, a3
+; RV32XVENTANACONDOPS-NEXT:    or a0, a0, a1
+; RV32XVENTANACONDOPS-NEXT:    snez a1, a2
+; RV32XVENTANACONDOPS-NEXT:    snez a0, a0
+; RV32XVENTANACONDOPS-NEXT:    and a2, a0, a1
+; RV32XVENTANACONDOPS-NEXT:    add a0, a1, a0
+; RV32XVENTANACONDOPS-NEXT:    add a0, a2, a0
+; RV32XVENTANACONDOPS-NEXT:    ret
+;
+; RV64XVENTANACONDOPS-LABEL: icmp_and_xy_multiple_uses:
+; RV64XVENTANACONDOPS:       # %bb.0:
+; RV64XVENTANACONDOPS-NEXT:    snez a1, a1
+; RV64XVENTANACONDOPS-NEXT:    snez a0, a0
+; RV64XVENTANACONDOPS-NEXT:    and a2, a0, a1
+; RV64XVENTANACONDOPS-NEXT:    add a0, a1, a0
+; RV64XVENTANACONDOPS-NEXT:    add a0, a2, a0
+; RV64XVENTANACONDOPS-NEXT:    ret
   %3 = icmp ne i64 %y, 0
   %4 = icmp ne i64 %x, 0
   %5 = and i1 %4, %3
@@ -109,7 +177,7 @@ define i32 @icmp_and_xy_multiple_uses(i64 %x, i64 %y) {
 }
 
 
-; (and (icmp x. 0, ne), (icmp y, 0, ne)) -> (czero.eqz (icmp x, 0, ne), y)
+; (and (icmp x, 0, ne), (icmp y, 0, ne)) -> (czero.eqz (icmp x, 0, ne), y)
 define i32 @icmp_and_select(i64 %x, i64 %y, i32 %z) {
 ; RV32ZICOND-LABEL: icmp_and_select:
 ; RV32ZICOND:       # %bb.0:
@@ -129,6 +197,25 @@ define i32 @icmp_and_select(i64 %x, i64 %y, i32 %z) {
 ; RV64ZICOND-NEXT:    czero.eqz a0, a1, a0
 ; RV64ZICOND-NEXT:    czero.eqz a0, a2, a0
 ; RV64ZICOND-NEXT:    ret
+;
+; RV32XVENTANACONDOPS-LABEL: icmp_and_select:
+; RV32XVENTANACONDOPS:       # %bb.0:
+; RV32XVENTANACONDOPS-NEXT:    sgtz a5, a3
+; RV32XVENTANACONDOPS-NEXT:    snez a2, a2
+; RV32XVENTANACONDOPS-NEXT:    vt.maskc a5, a5, a3
+; RV32XVENTANACONDOPS-NEXT:    vt.maskcn a2, a2, a3
+; RV32XVENTANACONDOPS-NEXT:    or a2, a2, a5
+; RV32XVENTANACONDOPS-NEXT:    or a0, a0, a1
+; RV32XVENTANACONDOPS-NEXT:    vt.maskc a0, a2, a0
+; RV32XVENTANACONDOPS-NEXT:    vt.maskc a0, a4, a0
+; RV32XVENTANACONDOPS-NEXT:    ret
+;
+; RV64XVENTANACONDOPS-LABEL: icmp_and_select:
+; RV64XVENTANACONDOPS:       # %bb.0:
+; RV64XVENTANACONDOPS-NEXT:    sgtz a1, a1
+; RV64XVENTANACONDOPS-NEXT:    vt.maskc a0, a1, a0
+; RV64XVENTANACONDOPS-NEXT:    vt.maskc a0, a2, a0
+; RV64XVENTANACONDOPS-NEXT:    ret
   %3 = icmp sgt i64 %y, 0
   %4 = icmp ne i64 %x, 0
   %5 = and i1 %4, %3
@@ -154,6 +241,23 @@ define i32 @icmp_and_and(i64 %x, i64 %y, i64 %z) {
 ; RV64ZICOND-NEXT:    czero.eqz a0, a0, a1
 ; RV64ZICOND-NEXT:    czero.eqz a0, a0, a2
 ; RV64ZICOND-NEXT:    ret
+;
+; RV32XVENTANACONDOPS-LABEL: icmp_and_and:
+; RV32XVENTANACONDOPS:       # %bb.0:
+; RV32XVENTANACONDOPS-NEXT:    or a0, a0, a1
+; RV32XVENTANACONDOPS-NEXT:    or a2, a2, a3
+; RV32XVENTANACONDOPS-NEXT:    snez a0, a0
+; RV32XVENTANACONDOPS-NEXT:    vt.maskc a0, a0, a2
+; RV32XVENTANACONDOPS-NEXT:    or a4, a4, a5
+; RV32XVENTANACONDOPS-NEXT:    vt.maskc a0, a0, a4
+; RV32XVENTANACONDOPS-NEXT:    ret
+;
+; RV64XVENTANACONDOPS-LABEL: icmp_and_and:
+; RV64XVENTANACONDOPS:       # %bb.0:
+; RV64XVENTANACONDOPS-NEXT:    snez a0, a0
+; RV64XVENTANACONDOPS-NEXT:    vt.maskc a0, a0, a1
+; RV64XVENTANACONDOPS-NEXT:    vt.maskc a0, a0, a2
+; RV64XVENTANACONDOPS-NEXT:    ret
   %4 = icmp ne i64 %y, 0
   %5 = icmp ne i64 %x, 0
   %6 = and i1 %4, %5
@@ -191,6 +295,33 @@ define i1 @and_icmp_eq_non_constant(i64 %x0, i64 %x1, i64 %y0, i64 %y1) {
 ; RV64ZICOND-NEXT:    sltu a1, a1, a3
 ; RV64ZICOND-NEXT:    or a0, a1, a0
 ; RV64ZICOND-NEXT:    ret
+;
+; RV32XVENTANACONDOPS-LABEL: and_icmp_eq_non_constant:
+; RV32XVENTANACONDOPS:       # %bb.0:
+; RV32XVENTANACONDOPS-NEXT:    xor t0, a1, a5
+; RV32XVENTANACONDOPS-NEXT:    sltu a0, a0, a4
+; RV32XVENTANACONDOPS-NEXT:    vt.maskcn a0, a0, t0
+; RV32XVENTANACONDOPS-NEXT:    sltu a1, a1, a5
+; RV32XVENTANACONDOPS-NEXT:    or a0, a0, a1
+; RV32XVENTANACONDOPS-NEXT:    xor a1, a3, a7
+; RV32XVENTANACONDOPS-NEXT:    xor a4, a2, a6
+; RV32XVENTANACONDOPS-NEXT:    or a4, a4, a1
+; RV32XVENTANACONDOPS-NEXT:    sltu a2, a2, a6
+; RV32XVENTANACONDOPS-NEXT:    vt.maskcn a1, a2, a1
+; RV32XVENTANACONDOPS-NEXT:    sltu a2, a3, a7
+; RV32XVENTANACONDOPS-NEXT:    vt.maskcn a0, a0, a4
+; RV32XVENTANACONDOPS-NEXT:    or a1, a1, a2
+; RV32XVENTANACONDOPS-NEXT:    or a0, a1, a0
+; RV32XVENTANACONDOPS-NEXT:    ret
+;
+; RV64XVENTANACONDOPS-LABEL: and_icmp_eq_non_constant:
+; RV64XVENTANACONDOPS:       # %bb.0:
+; RV64XVENTANACONDOPS-NEXT:    sltu a0, a0, a2
+; RV64XVENTANACONDOPS-NEXT:    xor a2, a1, a3
+; RV64XVENTANACONDOPS-NEXT:    vt.maskcn a0, a0, a2
+; RV64XVENTANACONDOPS-NEXT:    sltu a1, a1, a3
+; RV64XVENTANACONDOPS-NEXT:    or a0, a1, a0
+; RV64XVENTANACONDOPS-NEXT:    ret
 
   %5 = icmp ult i64 %x0, %y0
   %6 = icmp eq i64 %x1, %y1
@@ -228,6 +359,33 @@ define i1 @and_icmp_ne_non_constant(i64 %x0, i64 %x1, i64 %y0, i64 %y1) {
 ; RV64ZICOND-NEXT:    sltu a1, a1, a3
 ; RV64ZICOND-NEXT:    or a0, a1, a0
 ; RV64ZICOND-NEXT:    ret
+;
+; RV32XVENTANACONDOPS-LABEL: and_icmp_ne_non_constant:
+; RV32XVENTANACONDOPS:       # %bb.0:
+; RV32XVENTANACONDOPS-NEXT:    xor t0, a1, a5
+; RV32XVENTANACONDOPS-NEXT:    sltu a0, a0, a4
+; RV32XVENTANACONDOPS-NEXT:    vt.maskcn a0, a0, t0
+; RV32XVENTANACONDOPS-NEXT:    sltu a1, a1, a5
+; RV32XVENTANACONDOPS-NEXT:    or a0, a0, a1
+; RV32XVENTANACONDOPS-NEXT:    xor a1, a3, a7
+; RV32XVENTANACONDOPS-NEXT:    xor a4, a2, a6
+; RV32XVENTANACONDOPS-NEXT:    or a4, a4, a1
+; RV32XVENTANACONDOPS-NEXT:    sltu a2, a2, a6
+; RV32XVENTANACONDOPS-NEXT:    vt.maskcn a1, a2, a1
+; RV32XVENTANACONDOPS-NEXT:    sltu a2, a3, a7
+; RV32XVENTANACONDOPS-NEXT:    vt.maskc a0, a0, a4
+; RV32XVENTANACONDOPS-NEXT:    or a1, a1, a2
+; RV32XVENTANACONDOPS-NEXT:    or a0, a1, a0
+; RV32XVENTANACONDOPS-NEXT:    ret
+;
+; RV64XVENTANACONDOPS-LABEL: and_icmp_ne_non_constant:
+; RV64XVENTANACONDOPS:       # %bb.0:
+; RV64XVENTANACONDOPS-NEXT:    sltu a0, a0, a2
+; RV64XVENTANACONDOPS-NEXT:    xor a2, a1, a3
+; RV64XVENTANACONDOPS-NEXT:    vt.maskc a0, a0, a2
+; RV64XVENTANACONDOPS-NEXT:    sltu a1, a1, a3
+; RV64XVENTANACONDOPS-NEXT:    or a0, a1, a0
+; RV64XVENTANACONDOPS-NEXT:    ret
 
   %5 = icmp ult i64 %x0, %y0
   %6 = icmp ne i64 %x1, %y1
@@ -263,6 +421,30 @@ define i32 @and_icmp_eq_non_constant_multiple_uses(i64 %x0, i64 %x1, i64 %y0, i6
 ; RV64ZICOND-NEXT:    and a0, a0, a1
 ; RV64ZICOND-NEXT:    add a0, a0, a1
 ; RV64ZICOND-NEXT:    ret
+;
+; RV32XVENTANACONDOPS-LABEL: and_icmp_eq_non_constant_multiple_uses:
+; RV32XVENTANACONDOPS:       # %bb.0:
+; RV32XVENTANACONDOPS-NEXT:    xor t0, a1, a5
+; RV32XVENTANACONDOPS-NEXT:    sltu a0, a0, a4
+; RV32XVENTANACONDOPS-NEXT:    vt.maskcn a0, a0, t0
+; RV32XVENTANACONDOPS-NEXT:    xor a3, a3, a7
+; RV32XVENTANACONDOPS-NEXT:    xor a2, a2, a6
+; RV32XVENTANACONDOPS-NEXT:    sltu a1, a1, a5
+; RV32XVENTANACONDOPS-NEXT:    or a2, a2, a3
+; RV32XVENTANACONDOPS-NEXT:    or a0, a0, a1
+; RV32XVENTANACONDOPS-NEXT:    seqz a1, a2
+; RV32XVENTANACONDOPS-NEXT:    and a0, a0, a1
+; RV32XVENTANACONDOPS-NEXT:    add a0, a0, a1
+; RV32XVENTANACONDOPS-NEXT:    ret
+;
+; RV64XVENTANACONDOPS-LABEL: and_icmp_eq_non_constant_multiple_uses:
+; RV64XVENTANACONDOPS:       # %bb.0:
+; RV64XVENTANACONDOPS-NEXT:    xor a1, a1, a3
+; RV64XVENTANACONDOPS-NEXT:    sltu a0, a0, a2
+; RV64XVENTANACONDOPS-NEXT:    seqz a1, a1
+; RV64XVENTANACONDOPS-NEXT:    and a0, a0, a1
+; RV64XVENTANACONDOPS-NEXT:    add a0, a0, a1
+; RV64XVENTANACONDOPS-NEXT:    ret
 
   %lt = icmp ult i64 %x0, %y0
   %eq = icmp eq i64 %x1, %y1
@@ -309,6 +491,35 @@ define i64 @rotate_l_nez(i64 %x, i64 %rot.amt, i1 %cond) {
 ; RV64ZICOND-NEXT:    czero.nez a1, a1, a2
 ; RV64ZICOND-NEXT:    rol a0, a0, a1
 ; RV64ZICOND-NEXT:    ret
+;
+; RV32XVENTANACONDOPS-LABEL: rotate_l_nez:
+; RV32XVENTANACONDOPS:       # %bb.0:
+; RV32XVENTANACONDOPS-NEXT:    andi a4, a4, 1
+; RV32XVENTANACONDOPS-NEXT:    vt.maskcn a2, a2, a4
+; RV32XVENTANACONDOPS-NEXT:    bexti a3, a2, 5
+; RV32XVENTANACONDOPS-NEXT:    vt.maskcn a4, a0, a3
+; RV32XVENTANACONDOPS-NEXT:    vt.maskc a5, a1, a3
+; RV32XVENTANACONDOPS-NEXT:    vt.maskcn a1, a1, a3
+; RV32XVENTANACONDOPS-NEXT:    vt.maskc a0, a0, a3
+; RV32XVENTANACONDOPS-NEXT:    or a4, a5, a4
+; RV32XVENTANACONDOPS-NEXT:    or a0, a0, a1
+; RV32XVENTANACONDOPS-NEXT:    sll a1, a4, a2
+; RV32XVENTANACONDOPS-NEXT:    srli a3, a0, 1
+; RV32XVENTANACONDOPS-NEXT:    not a5, a2
+; RV32XVENTANACONDOPS-NEXT:    srl a3, a3, a5
+; RV32XVENTANACONDOPS-NEXT:    srli a4, a4, 1
+; RV32XVENTANACONDOPS-NEXT:    sll a2, a0, a2
+; RV32XVENTANACONDOPS-NEXT:    srl a4, a4, a5
+; RV32XVENTANACONDOPS-NEXT:    or a0, a1, a3
+; RV32XVENTANACONDOPS-NEXT:    or a1, a2, a4
+; RV32XVENTANACONDOPS-NEXT:    ret
+;
+; RV64XVENTANACONDOPS-LABEL: rotate_l_nez:
+; RV64XVENTANACONDOPS:       # %bb.0:
+; RV64XVENTANACONDOPS-NEXT:    andi a2, a2, 1
+; RV64XVENTANACONDOPS-NEXT:    vt.maskcn a1, a1, a2
+; RV64XVENTANACONDOPS-NEXT:    rol a0, a0, a1
+; RV64XVENTANACONDOPS-NEXT:    ret
   %6 = call i64 @llvm.fshl.i64(i64 %x, i64 %x, i64 %rot.amt)
   %7 = select i1 %cond, i64 %x, i64 %6
   ret i64 %7
@@ -344,6 +555,35 @@ define i64 @rotate_l_eqz(i64 %x, i64 %rot.amt, i1 %cond) {
 ; RV64ZICOND-NEXT:    czero.eqz a1, a1, a2
 ; RV64ZICOND-NEXT:    rol a0, a0, a1
 ; RV64ZICOND-NEXT:    ret
+;
+; RV32XVENTANACONDOPS-LABEL: rotate_l_eqz:
+; RV32XVENTANACONDOPS:       # %bb.0:
+; RV32XVENTANACONDOPS-NEXT:    andi a4, a4, 1
+; RV32XVENTANACONDOPS-NEXT:    vt.maskc a2, a2, a4
+; RV32XVENTANACONDOPS-NEXT:    bexti a3, a2, 5
+; RV32XVENTANACONDOPS-NEXT:    vt.maskcn a4, a0, a3
+; RV32XVENTANACONDOPS-NEXT:    vt.maskc a5, a1, a3
+; RV32XVENTANACONDOPS-NEXT:    vt.maskcn a1, a1, a3
+; RV32XVENTANACONDOPS-NEXT:    vt.maskc a0, a0, a3
+; RV32XVENTANACONDOPS-NEXT:    or a4, a5, a4
+; RV32XVENTANACONDOPS-NEXT:    or a0, a0, a1
+; RV32XVENTANACONDOPS-NEXT:    sll a1, a4, a2
+; RV32XVENTANACONDOPS-NEXT:    srli a3, a0, 1
+; RV32XVENTANACONDOPS-NEXT:    not a5, a2
+; RV32XVENTANACONDOPS-NEXT:    srl a3, a3, a5
+; RV32XVENTANACONDOPS-NEXT:    srli a4, a4, 1
+; RV32XVENTANACONDOPS-NEXT:    sll a2, a0, a2
+; RV32XVENTANACONDOPS-NEXT:    srl a4, a4, a5
+; RV32XVENTANACONDOPS-NEXT:    or a0, a1, a3
+; RV32XVENTANACONDOPS-NEXT:    or a1, a2, a4
+; RV32XVENTANACONDOPS-NEXT:    ret
+;
+; RV64XVENTANACONDOPS-LABEL: rotate_l_eqz:
+; RV64XVENTANACONDOPS:       # %bb.0:
+; RV64XVENTANACONDOPS-NEXT:    andi a2, a2, 1
+; RV64XVENTANACONDOPS-NEXT:    vt.maskc a1, a1, a2
+; RV64XVENTANACONDOPS-NEXT:    rol a0, a0, a1
+; RV64XVENTANACONDOPS-NEXT:    ret
   %6 = call i64 @llvm.fshl.i64(i64 %x, i64 %x, i64 %rot.amt)
   %7 = select i1 %cond, i64 %6, i64 %x
   ret i64 %7
@@ -367,6 +607,23 @@ define i64 @select_imm_reg(i64 %t, i1 %cond) {
 ; RV64ZICOND-NEXT:    czero.nez a0, a0, a1
 ; RV64ZICOND-NEXT:    addi a0, a0, 3
 ; RV64ZICOND-NEXT:    ret
+;
+; RV32XVENTANACONDOPS-LABEL: select_imm_reg:
+; RV32XVENTANACONDOPS:       # %bb.0:
+; RV32XVENTANACONDOPS-NEXT:    andi a2, a2, 1
+; RV32XVENTANACONDOPS-NEXT:    addi a0, a0, -3
+; RV32XVENTANACONDOPS-NEXT:    vt.maskcn a0, a0, a2
+; RV32XVENTANACONDOPS-NEXT:    vt.maskcn a1, a1, a2
+; RV32XVENTANACONDOPS-NEXT:    addi a0, a0, 3
+; RV32XVENTANACONDOPS-NEXT:    ret
+;
+; RV64XVENTANACONDOPS-LABEL: select_imm_reg:
+; RV64XVENTANACONDOPS:       # %bb.0:
+; RV64XVENTANACONDOPS-NEXT:    andi a1, a1, 1
+; RV64XVENTANACONDOPS-NEXT:    addi a0, a0, -3
+; RV64XVENTANACONDOPS-NEXT:    vt.maskcn a0, a0, a1
+; RV64XVENTANACONDOPS-NEXT:    addi a0, a0, 3
+; RV64XVENTANACONDOPS-NEXT:    ret
   %4 = select i1 %cond, i64 3, i64 %t
   ret i64 %4
 }
@@ -389,6 +646,23 @@ define i64 @select_reg_imm(i64 %t, i1 %cond) {
 ; RV64ZICOND-NEXT:    czero.eqz a0, a0, a1
 ; RV64ZICOND-NEXT:    addi a0, a0, 3
 ; RV64ZICOND-NEXT:    ret
+;
+; RV32XVENTANACONDOPS-LABEL: select_reg_imm:
+; RV32XVENTANACONDOPS:       # %bb.0:
+; RV32XVENTANACONDOPS-NEXT:    andi a2, a2, 1
+; RV32XVENTANACONDOPS-NEXT:    addi a0, a0, -3
+; RV32XVENTANACONDOPS-NEXT:    vt.maskc a0, a0, a2
+; RV32XVENTANACONDOPS-NEXT:    vt.maskc a1, a1, a2
+; RV32XVENTANACONDOPS-NEXT:    addi a0, a0, 3
+; RV32XVENTANACONDOPS-NEXT:    ret
+;
+; RV64XVENTANACONDOPS-LABEL: select_reg_imm:
+; RV64XVENTANACONDOPS:       # %bb.0:
+; RV64XVENTANACONDOPS-NEXT:    andi a1, a1, 1
+; RV64XVENTANACONDOPS-NEXT:    addi a0, a0, -3
+; RV64XVENTANACONDOPS-NEXT:    vt.maskc a0, a0, a1
+; RV64XVENTANACONDOPS-NEXT:    addi a0, a0, 3
+; RV64XVENTANACONDOPS-NEXT:    ret
   %4 = select i1 %cond, i64 %t, i64 3
   ret i64 %4
 }
@@ -412,6 +686,24 @@ define i64 @select_imm_reg_neg_2048(i64 %t, i1 %cond) {
 ; RV64ZICOND-NEXT:    czero.nez a0, a0, a1
 ; RV64ZICOND-NEXT:    xori a0, a0, -2048
 ; RV64ZICOND-NEXT:    ret
+;
+; RV32XVENTANACONDOPS-LABEL: select_imm_reg_neg_2048:
+; RV32XVENTANACONDOPS:       # %bb.0:
+; RV32XVENTANACONDOPS-NEXT:    andi a2, a2, 1
+; RV32XVENTANACONDOPS-NEXT:    xori a0, a0, -2048
+; RV32XVENTANACONDOPS-NEXT:    neg a3, a2
+; RV32XVENTANACONDOPS-NEXT:    vt.maskcn a0, a0, a2
+; RV32XVENTANACONDOPS-NEXT:    or a1, a3, a1
+; RV32XVENTANACONDOPS-NEXT:    xori a0, a0, -2048
+; RV32XVENTANACONDOPS-NEXT:    ret
+;
+; RV64XVENTANACONDOPS-LABEL: select_imm_reg_neg_2048:
+; RV64XVENTANACONDOPS:       # %bb.0:
+; RV64XVENTANACONDOPS-NEXT:    andi a1, a1, 1
+; RV64XVENTANACONDOPS-NEXT:    xori a0, a0, -2048
+; RV64XVENTANACONDOPS-NEXT:    vt.maskcn a0, a0, a1
+; RV64XVENTANACONDOPS-NEXT:    xori a0, a0, -2048
+; RV64XVENTANACONDOPS-NEXT:    ret
   %4 = select i1 %cond, i64 -2048, i64 %t
   ret i64 %4
 }
@@ -436,6 +728,25 @@ define i64 @select_imm_reg_2048(i64 %t, i1 %cond) {
 ; RV64ZICOND-NEXT:    czero.eqz a1, a2, a1
 ; RV64ZICOND-NEXT:    or a0, a1, a0
 ; RV64ZICOND-NEXT:    ret
+;
+; RV32XVENTANACONDOPS-LABEL: select_imm_reg_2048:
+; RV32XVENTANACONDOPS:       # %bb.0:
+; RV32XVENTANACONDOPS-NEXT:    andi a2, a2, 1
+; RV32XVENTANACONDOPS-NEXT:    bseti a3, zero, 11
+; RV32XVENTANACONDOPS-NEXT:    vt.maskcn a0, a0, a2
+; RV32XVENTANACONDOPS-NEXT:    vt.maskc a3, a3, a2
+; RV32XVENTANACONDOPS-NEXT:    or a0, a3, a0
+; RV32XVENTANACONDOPS-NEXT:    vt.maskcn a1, a1, a2
+; RV32XVENTANACONDOPS-NEXT:    ret
+;
+; RV64XVENTANACONDOPS-LABEL: select_imm_reg_2048:
+; RV64XVENTANACONDOPS:       # %bb.0:
+; RV64XVENTANACONDOPS-NEXT:    andi a1, a1, 1
+; RV64XVENTANACONDOPS-NEXT:    bseti a2, zero, 11
+; RV64XVENTANACONDOPS-NEXT:    vt.maskcn a0, a0, a1
+; RV64XVENTANACONDOPS-NEXT:    vt.maskc a1, a2, a1
+; RV64XVENTANACONDOPS-NEXT:    or a0, a1, a0
+; RV64XVENTANACONDOPS-NEXT:    ret
   %4 = select i1 %cond, i64 2048, i64 %t
   ret i64 %4
 }
@@ -457,6 +768,22 @@ define i64 @test_inv_and_nez(i64 %f, i64 %x, i1 %cond) {
 ; RV64ZICOND-NEXT:    czero.eqz a1, a1, a2
 ; RV64ZICOND-NEXT:    andn a0, a0, a1
 ; RV64ZICOND-NEXT:    ret
+;
+; RV32XVENTANACONDOPS-LABEL: test_inv_and_nez:
+; RV32XVENTANACONDOPS:       # %bb.0:
+; RV32XVENTANACONDOPS-NEXT:    andi a4, a4, 1
+; RV32XVENTANACONDOPS-NEXT:    vt.maskc a3, a3, a4
+; RV32XVENTANACONDOPS-NEXT:    vt.maskc a2, a2, a4
+; RV32XVENTANACONDOPS-NEXT:    andn a0, a0, a2
+; RV32XVENTANACONDOPS-NEXT:    andn a1, a1, a3
+; RV32XVENTANACONDOPS-NEXT:    ret
+;
+; RV64XVENTANACONDOPS-LABEL: test_inv_and_nez:
+; RV64XVENTANACONDOPS:       # %bb.0:
+; RV64XVENTANACONDOPS-NEXT:    andi a2, a2, 1
+; RV64XVENTANACONDOPS-NEXT:    vt.maskc a1, a1, a2
+; RV64XVENTANACONDOPS-NEXT:    andn a0, a0, a1
+; RV64XVENTANACONDOPS-NEXT:    ret
   %5 = xor i64 %x, -1
   %6 = select i1 %cond, i64 %5, i64 -1
   %7 = and i64 %6, %f
@@ -480,6 +807,22 @@ define i64 @test_inv_and_eqz(i64 %f, i64 %x, i1 %cond) {
 ; RV64ZICOND-NEXT:    czero.nez a1, a1, a2
 ; RV64ZICOND-NEXT:    andn a0, a0, a1
 ; RV64ZICOND-NEXT:    ret
+;
+; RV32XVENTANACONDOPS-LABEL: test_inv_and_eqz:
+; RV32XVENTANACONDOPS:       # %bb.0:
+; RV32XVENTANACONDOPS-NEXT:    andi a4, a4, 1
+; RV32XVENTANACONDOPS-NEXT:    vt.maskcn a3, a3, a4
+; RV32XVENTANACONDOPS-NEXT:    vt.maskcn a2, a2, a4
+; RV32XVENTANACONDOPS-NEXT:    andn a0, a0, a2
+; RV32XVENTANACONDOPS-NEXT:    andn a1, a1, a3
+; RV32XVENTANACONDOPS-NEXT:    ret
+;
+; RV64XVENTANACONDOPS-LABEL: test_inv_and_eqz:
+; RV64XVENTANACONDOPS:       # %bb.0:
+; RV64XVENTANACONDOPS-NEXT:    andi a2, a2, 1
+; RV64XVENTANACONDOPS-NEXT:    vt.maskcn a1, a1, a2
+; RV64XVENTANACONDOPS-NEXT:    andn a0, a0, a1
+; RV64XVENTANACONDOPS-NEXT:    ret
   %5 = xor i64 %x, -1
   %6 = select i1 %cond, i64 -1, i64 %5
   %7 = and i64 %6, %f
@@ -508,6 +851,28 @@ define i32 @pr166596(i32 %conv.i, i1 %iszero) #0 {
 ; RV64ZICOND-NEXT:    czero.nez a0, a0, a1
 ; RV64ZICOND-NEXT:    addi a0, a0, -9
 ; RV64ZICOND-NEXT:    ret
+;
+; RV32XVENTANACONDOPS-LABEL: pr166596:
+; RV32XVENTANACONDOPS:       # %bb.0: # %entry
+; RV32XVENTANACONDOPS-NEXT:    xori a0, a0, 1
+; RV32XVENTANACONDOPS-NEXT:    zext.h a0, a0
+; RV32XVENTANACONDOPS-NEXT:    clz a0, a0
+; RV32XVENTANACONDOPS-NEXT:    andi a1, a1, 1
+; RV32XVENTANACONDOPS-NEXT:    addi a0, a0, 41
+; RV32XVENTANACONDOPS-NEXT:    vt.maskcn a0, a0, a1
+; RV32XVENTANACONDOPS-NEXT:    addi a0, a0, -9
+; RV32XVENTANACONDOPS-NEXT:    ret
+;
+; RV64XVENTANACONDOPS-LABEL: pr166596:
+; RV64XVENTANACONDOPS:       # %bb.0: # %entry
+; RV64XVENTANACONDOPS-NEXT:    xori a0, a0, 1
+; RV64XVENTANACONDOPS-NEXT:    zext.h a0, a0
+; RV64XVENTANACONDOPS-NEXT:    clz a0, a0
+; RV64XVENTANACONDOPS-NEXT:    andi a1, a1, 1
+; RV64XVENTANACONDOPS-NEXT:    addi a0, a0, 9
+; RV64XVENTANACONDOPS-NEXT:    vt.maskcn a0, a0, a1
+; RV64XVENTANACONDOPS-NEXT:    addi a0, a0, -9
+; RV64XVENTANACONDOPS-NEXT:    ret
 entry:
   %not.i = xor i32 %conv.i, 1
   %conv2.i = trunc i32 %not.i to i16
@@ -535,6 +900,23 @@ define i64 @select_wo_optsize_minsize(i64 %true, i64 %false, i1 zeroext %c) {
 ; RV64ZICOND-NEXT:    czero.eqz a0, a0, a2
 ; RV64ZICOND-NEXT:    or a0, a0, a1
 ; RV64ZICOND-NEXT:    ret
+;
+; RV32XVENTANACONDOPS-LABEL: select_wo_optsize_minsize:
+; RV32XVENTANACONDOPS:       # %bb.0:
+; RV32XVENTANACONDOPS-NEXT:    vt.maskcn a2, a2, a4
+; RV32XVENTANACONDOPS-NEXT:    vt.maskc a0, a0, a4
+; RV32XVENTANACONDOPS-NEXT:    vt.maskcn a3, a3, a4
+; RV32XVENTANACONDOPS-NEXT:    vt.maskc a1, a1, a4
+; RV32XVENTANACONDOPS-NEXT:    or a0, a0, a2
+; RV32XVENTANACONDOPS-NEXT:    or a1, a1, a3
+; RV32XVENTANACONDOPS-NEXT:    ret
+;
+; RV64XVENTANACONDOPS-LABEL: select_wo_optsize_minsize:
+; RV64XVENTANACONDOPS:       # %bb.0:
+; RV64XVENTANACONDOPS-NEXT:    vt.maskcn a1, a1, a2
+; RV64XVENTANACONDOPS-NEXT:    vt.maskc a0, a0, a2
+; RV64XVENTANACONDOPS-NEXT:    or a0, a0, a1
+; RV64XVENTANACONDOPS-NEXT:    ret
   %r = select i1 %c, i64 %true, i64 %false
   ret i64 %r
 }
@@ -556,6 +938,23 @@ define i64 @select_w_optsize(i64 %true, i64 %false, i1 zeroext %c) optsize {
 ; RV64ZICOND-NEXT:    mv a0, a1
 ; RV64ZICOND-NEXT:  .LBB19_2:
 ; RV64ZICOND-NEXT:    ret
+;
+; RV32XVENTANACONDOPS-LABEL: select_w_optsize:
+; RV32XVENTANACONDOPS:       # %bb.0:
+; RV32XVENTANACONDOPS-NEXT:    bnez a4, .LBB19_2
+; RV32XVENTANACONDOPS-NEXT:  # %bb.1:
+; RV32XVENTANACONDOPS-NEXT:    mv a0, a2
+; RV32XVENTANACONDOPS-NEXT:    mv a1, a3
+; RV32XVENTANACONDOPS-NEXT:  .LBB19_2:
+; RV32XVENTANACONDOPS-NEXT:    ret
+;
+; RV64XVENTANACONDOPS-LABEL: select_w_optsize:
+; RV64XVENTANACONDOPS:       # %bb.0:
+; RV64XVENTANACONDOPS-NEXT:    bnez a2, .LBB19_2
+; RV64XVENTANACONDOPS-NEXT:  # %bb.1:
+; RV64XVENTANACONDOPS-NEXT:    mv a0, a1
+; RV64XVENTANACONDOPS-NEXT:  .LBB19_2:
+; RV64XVENTANACONDOPS-NEXT:    ret
   %r = select i1 %c, i64 %true, i64 %false
   ret i64 %r
 }
@@ -577,6 +976,107 @@ define i64 @select_w_minsize(i64 %true, i64 %false, i1 zeroext %c) minsize {
 ; RV64ZICOND-NEXT:    mv a0, a1
 ; RV64ZICOND-NEXT:  .LBB20_2:
 ; RV64ZICOND-NEXT:    ret
+;
+; RV32XVENTANACONDOPS-LABEL: select_w_minsize:
+; RV32XVENTANACONDOPS:       # %bb.0:
+; RV32XVENTANACONDOPS-NEXT:    bnez a4, .LBB20_2
+; RV32XVENTANACONDOPS-NEXT:  # %bb.1:
+; RV32XVENTANACONDOPS-NEXT:    mv a0, a2
+; RV32XVENTANACONDOPS-NEXT:    mv a1, a3
+; RV32XVENTANACONDOPS-NEXT:  .LBB20_2:
+; RV32XVENTANACONDOPS-NEXT:    ret
+;
+; RV64XVENTANACONDOPS-LABEL: select_w_minsize:
+; RV64XVENTANACONDOPS:       # %bb.0:
+; RV64XVENTANACONDOPS-NEXT:    bnez a2, .LBB20_2
+; RV64XVENTANACONDOPS-NEXT:  # %bb.1:
+; RV64XVENTANACONDOPS-NEXT:    mv a0, a1
+; RV64XVENTANACONDOPS-NEXT:  .LBB20_2:
+; RV64XVENTANACONDOPS-NEXT:    ret
   %r = select i1 %c, i64 %true, i64 %false
   ret i64 %r
 }
+
+; (and (icmp x, C, eq), (icmp y, C, eq)) -> (czero.eqz (icmp x, 0, eq), (addi x, -C))
+define i32 @and_icmp_eq_non_zero(i64 %x, i64 %y) {
+; RV32ZICOND-LABEL: and_icmp_eq_non_zero:
+; RV32ZICOND:       # %bb.0:
+; RV32ZICOND-NEXT:    srli a3, a3, 31
+; RV32ZICOND-NEXT:    xori a0, a0, 1234
+; RV32ZICOND-NEXT:    or a0, a0, a1
+; RV32ZICOND-NEXT:    czero.nez a0, a3, a0
+; RV32ZICOND-NEXT:    ret
+;
+; RV64ZICOND-LABEL: and_icmp_eq_non_zero:
+; RV64ZICOND:       # %bb.0:
+; RV64ZICOND-NEXT:    srli a1, a1, 63
+; RV64ZICOND-NEXT:    addi a0, a0, -1234
+; RV64ZICOND-NEXT:    czero.nez a0, a1, a0
+; RV64ZICOND-NEXT:    ret
+;
+; RV32XVENTANACONDOPS-LABEL: and_icmp_eq_non_zero:
+; RV32XVENTANACONDOPS:       # %bb.0:
+; RV32XVENTANACONDOPS-NEXT:    srli a3, a3, 31
+; RV32XVENTANACONDOPS-NEXT:    xori a0, a0, 1234
+; RV32XVENTANACONDOPS-NEXT:    or a0, a0, a1
+; RV32XVENTANACONDOPS-NEXT:    vt.maskcn a0, a3, a0
+; RV32XVENTANACONDOPS-NEXT:    ret
+;
+; RV64XVENTANACONDOPS-LABEL: and_icmp_eq_non_zero:
+; RV64XVENTANACONDOPS:       # %bb.0:
+; RV64XVENTANACONDOPS-NEXT:    srli a1, a1, 63
+; RV64XVENTANACONDOPS-NEXT:    addi a0, a0, -1234
+; RV64XVENTANACONDOPS-NEXT:    vt.maskcn a0, a1, a0
+; RV64XVENTANACONDOPS-NEXT:    ret
+
+  %3 = icmp slt i64 %y, 0
+  %4 = icmp eq i64 %x, 1234
+  %5 = and i1 %4, %3
+  %6 = zext i1 %5 to i32
+  ret i32 %6
+}
+
+; (and (icmp x, C, ne), (icmp y, C, ne)) -> (czero.eqz (icmp x, 0, ne), (addi x, -C))
+define i32 @and_icmp_ne_non_zero(i64 %x, i64 %y) {
+; RV32ZICOND-LABEL: and_icmp_ne_non_zero:
+; RV32ZICOND:       # %bb.0:
+; RV32ZICOND-NEXT:    xori a2, a2, 1234
+; RV32ZICOND-NEXT:    or a2, a2, a3
+; RV32ZICOND-NEXT:    xori a0, a0, 1234
+; RV32ZICOND-NEXT:    snez a2, a2
+; RV32ZICOND-NEXT:    or a0, a0, a1
+; RV32ZICOND-NEXT:    czero.eqz a0, a2, a0
+; RV32ZICOND-NEXT:    ret
+;
+; RV64ZICOND-LABEL: and_icmp_ne_non_zero:
+; RV64ZICOND:       # %bb.0:
+; RV64ZICOND-NEXT:    addi a1, a1, -1234
+; RV64ZICOND-NEXT:    snez a1, a1
+; RV64ZICOND-NEXT:    addi a0, a0, -1234
+; RV64ZICOND-NEXT:    czero.eqz a0, a1, a0
+; RV64ZICOND-NEXT:    ret
+;
+; RV32XVENTANACONDOPS-LABEL: and_icmp_ne_non_zero:
+; RV32XVENTANACONDOPS:       # %bb.0:
+; RV32XVENTANACONDOPS-NEXT:    xori a2, a2, 1234
+; RV32XVENTANACONDOPS-NEXT:    or a2, a2, a3
+; RV32XVENTANACONDOPS-NEXT:    xori a0, a0, 1234
+; RV32XVENTANACONDOPS-NEXT:    snez a2, a2
+; RV32XVENTANACONDOPS-NEXT:    or a0, a0, a1
+; RV32XVENTANACONDOPS-NEXT:    vt.maskc a0, a2, a0
+; RV32XVENTANACONDOPS-NEXT:    ret
+;
+; RV64XVENTANACONDOPS-LABEL: and_icmp_ne_non_zero:
+; RV64XVENTANACONDOPS:       # %bb.0:
+; RV64XVENTANACONDOPS-NEXT:    addi a1, a1, -1234
+; RV64XVENTANACONDOPS-NEXT:    snez a1, a1
+; RV64XVENTANACONDOPS-NEXT:    addi a0, a0, -1234
+; RV64XVENTANACONDOPS-NEXT:    vt.maskc a0, a1, a0
+; RV64XVENTANACONDOPS-NEXT:    ret
+
+  %3 = icmp ne i64 %y, 1234
+  %4 = icmp ne i64 %x, 1234
+  %5 = and i1 %4, %3
+  %6 = zext i1 %5 to i32
+  ret i32 %6
+}


        


More information about the llvm-commits mailing list