[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