diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp index fb34e181efee15..51d122639d3e1b 100644 --- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp @@ -9139,6 +9139,59 @@ static SDValue performSRACombine(SDNode *N, SelectionDAG &DAG, DAG.getConstant(32 - ShAmt, DL, MVT::i64)); } +// Invert (and/or (set cc X, Y), (xor Z, 1)) to (or/and (set !cc X, Y)), Z) if +// the result is used as the conditon of a br_cc or select_cc we can invert, +// inverting the setcc is free, and Z is 0/1. Caller will invert the +// br_cc/select_cc. +static SDValue tryDemorganOfBooleanCondition(SDValue Cond, SelectionDAG &DAG) { + bool IsAnd = Cond.getOpcode() == ISD::AND; + if (!IsAnd && Cond.getOpcode() != ISD::OR) + return SDValue(); + + if (!Cond.hasOneUse()) + return SDValue(); + + SDValue Setcc = Cond.getOperand(0); + SDValue Xor = Cond.getOperand(1); + // Canonicalize setcc to LHS. + if (Setcc.getOpcode() != ISD::SETCC) + std::swap(Setcc, Xor); + // LHS should be a setcc and RHS should be an xor. + if (Setcc.getOpcode() != ISD::SETCC || !Setcc.hasOneUse() || + Xor.getOpcode() != ISD::XOR || !Xor.hasOneUse()) + return SDValue(); + + // If the condition is an And, SimplifyDemandedBits may have changed + // (xor Z, 1) to (not Z). + SDValue Xor1 = Xor.getOperand(1); + if (!isOneConstant(Xor1) && !(IsAnd && isAllOnesConstant(Xor1))) + return SDValue(); + + EVT VT = Cond.getValueType(); + SDValue Xor0 = Xor.getOperand(0); + + // The LHS of the xor needs to be 0/1. + APInt Mask = APInt::getBitsSetFrom(VT.getSizeInBits(), 1); + if (!DAG.MaskedValueIsZero(Xor0, Mask)) + return SDValue(); + + // We can only invert integer setccs. + EVT SetCCOpVT = Setcc.getOperand(0).getValueType(); + if (!SetCCOpVT.isScalarInteger()) + return SDValue(); + + ISD::CondCode CCVal = cast(Setcc.getOperand(2))->get(); + if (ISD::isIntEqualitySetCC(CCVal)) { + CCVal = ISD::getSetCCInverse(CCVal, SetCCOpVT); + Setcc = DAG.getSetCC(SDLoc(Setcc), VT, Setcc.getOperand(0), + Setcc.getOperand(1), CCVal); + } else + return SDValue(); + + unsigned Opc = IsAnd ? ISD::OR : ISD::AND; + return DAG.getNode(Opc, SDLoc(Cond), VT, Setcc, Xor.getOperand(0)); +} + // Perform common combines for BR_CC and SELECT_CC condtions. static bool combine_CC(SDValue &LHS, SDValue &RHS, SDValue &CC, const SDLoc &DL, SelectionDAG &DAG, const RISCVSubtarget &Subtarget) { @@ -9205,6 +9258,15 @@ static bool combine_CC(SDValue &LHS, SDValue &RHS, SDValue &CC, const SDLoc &DL, return true; } + if (isNullConstant(RHS)) { + if (SDValue NewCond = tryDemorganOfBooleanCondition(LHS, DAG)) { + CCVal = ISD::getSetCCInverse(CCVal, LHS.getValueType()); + CC = DAG.getCondCode(CCVal); + LHS = NewCond; + return true; + } + } + return false; } diff --git a/llvm/test/CodeGen/RISCV/setcc-logic.ll b/llvm/test/CodeGen/RISCV/setcc-logic.ll index 48cc03f337c7a5..8c0652dfa2ce49 100644 --- a/llvm/test/CodeGen/RISCV/setcc-logic.ll +++ b/llvm/test/CodeGen/RISCV/setcc-logic.ll @@ -301,11 +301,10 @@ define void @and_sge_eq(i32 signext %0, i32 signext %1, i32 signext %2, i32 sign ; RV32I-LABEL: and_sge_eq: ; RV32I: # %bb.0: ; RV32I-NEXT: slt a0, a0, a1 -; RV32I-NEXT: not a0, a0 ; RV32I-NEXT: xor a1, a2, a3 -; RV32I-NEXT: seqz a1, a1 -; RV32I-NEXT: and a0, a0, a1 -; RV32I-NEXT: beqz a0, .LBB13_2 +; RV32I-NEXT: snez a1, a1 +; RV32I-NEXT: or a0, a1, a0 +; RV32I-NEXT: bnez a0, .LBB13_2 ; RV32I-NEXT: # %bb.1: ; RV32I-NEXT: ret ; RV32I-NEXT: .LBB13_2: @@ -314,11 +313,10 @@ define void @and_sge_eq(i32 signext %0, i32 signext %1, i32 signext %2, i32 sign ; RV64I-LABEL: and_sge_eq: ; RV64I: # %bb.0: ; RV64I-NEXT: slt a0, a0, a1 -; RV64I-NEXT: not a0, a0 ; RV64I-NEXT: xor a1, a2, a3 -; RV64I-NEXT: seqz a1, a1 -; RV64I-NEXT: and a0, a0, a1 -; RV64I-NEXT: beqz a0, .LBB13_2 +; RV64I-NEXT: snez a1, a1 +; RV64I-NEXT: or a0, a1, a0 +; RV64I-NEXT: bnez a0, .LBB13_2 ; RV64I-NEXT: # %bb.1: ; RV64I-NEXT: ret ; RV64I-NEXT: .LBB13_2: @@ -340,11 +338,10 @@ define void @and_sle_eq(i32 signext %0, i32 signext %1, i32 signext %2, i32 sign ; RV32I-LABEL: and_sle_eq: ; RV32I: # %bb.0: ; RV32I-NEXT: slt a0, a1, a0 -; RV32I-NEXT: not a0, a0 ; RV32I-NEXT: xor a1, a2, a3 -; RV32I-NEXT: seqz a1, a1 -; RV32I-NEXT: and a0, a0, a1 -; RV32I-NEXT: beqz a0, .LBB14_2 +; RV32I-NEXT: snez a1, a1 +; RV32I-NEXT: or a0, a1, a0 +; RV32I-NEXT: bnez a0, .LBB14_2 ; RV32I-NEXT: # %bb.1: ; RV32I-NEXT: ret ; RV32I-NEXT: .LBB14_2: @@ -353,11 +350,10 @@ define void @and_sle_eq(i32 signext %0, i32 signext %1, i32 signext %2, i32 sign ; RV64I-LABEL: and_sle_eq: ; RV64I: # %bb.0: ; RV64I-NEXT: slt a0, a1, a0 -; RV64I-NEXT: not a0, a0 ; RV64I-NEXT: xor a1, a2, a3 -; RV64I-NEXT: seqz a1, a1 -; RV64I-NEXT: and a0, a0, a1 -; RV64I-NEXT: beqz a0, .LBB14_2 +; RV64I-NEXT: snez a1, a1 +; RV64I-NEXT: or a0, a1, a0 +; RV64I-NEXT: bnez a0, .LBB14_2 ; RV64I-NEXT: # %bb.1: ; RV64I-NEXT: ret ; RV64I-NEXT: .LBB14_2: @@ -379,11 +375,10 @@ define void @and_uge_eq(i32 signext %0, i32 signext %1, i32 signext %2, i32 sign ; RV32I-LABEL: and_uge_eq: ; RV32I: # %bb.0: ; RV32I-NEXT: sltu a0, a0, a1 -; RV32I-NEXT: not a0, a0 ; RV32I-NEXT: xor a1, a2, a3 -; RV32I-NEXT: seqz a1, a1 -; RV32I-NEXT: and a0, a0, a1 -; RV32I-NEXT: beqz a0, .LBB15_2 +; RV32I-NEXT: snez a1, a1 +; RV32I-NEXT: or a0, a1, a0 +; RV32I-NEXT: bnez a0, .LBB15_2 ; RV32I-NEXT: # %bb.1: ; RV32I-NEXT: ret ; RV32I-NEXT: .LBB15_2: @@ -392,11 +387,10 @@ define void @and_uge_eq(i32 signext %0, i32 signext %1, i32 signext %2, i32 sign ; RV64I-LABEL: and_uge_eq: ; RV64I: # %bb.0: ; RV64I-NEXT: sltu a0, a0, a1 -; RV64I-NEXT: not a0, a0 ; RV64I-NEXT: xor a1, a2, a3 -; RV64I-NEXT: seqz a1, a1 -; RV64I-NEXT: and a0, a0, a1 -; RV64I-NEXT: beqz a0, .LBB15_2 +; RV64I-NEXT: snez a1, a1 +; RV64I-NEXT: or a0, a1, a0 +; RV64I-NEXT: bnez a0, .LBB15_2 ; RV64I-NEXT: # %bb.1: ; RV64I-NEXT: ret ; RV64I-NEXT: .LBB15_2: @@ -418,11 +412,10 @@ define void @and_ule_eq(i32 signext %0, i32 signext %1, i32 signext %2, i32 sign ; RV32I-LABEL: and_ule_eq: ; RV32I: # %bb.0: ; RV32I-NEXT: sltu a0, a1, a0 -; RV32I-NEXT: not a0, a0 ; RV32I-NEXT: xor a1, a2, a3 -; RV32I-NEXT: seqz a1, a1 -; RV32I-NEXT: and a0, a0, a1 -; RV32I-NEXT: beqz a0, .LBB16_2 +; RV32I-NEXT: snez a1, a1 +; RV32I-NEXT: or a0, a1, a0 +; RV32I-NEXT: bnez a0, .LBB16_2 ; RV32I-NEXT: # %bb.1: ; RV32I-NEXT: ret ; RV32I-NEXT: .LBB16_2: @@ -431,11 +424,10 @@ define void @and_ule_eq(i32 signext %0, i32 signext %1, i32 signext %2, i32 sign ; RV64I-LABEL: and_ule_eq: ; RV64I: # %bb.0: ; RV64I-NEXT: sltu a0, a1, a0 -; RV64I-NEXT: not a0, a0 ; RV64I-NEXT: xor a1, a2, a3 -; RV64I-NEXT: seqz a1, a1 -; RV64I-NEXT: and a0, a0, a1 -; RV64I-NEXT: beqz a0, .LBB16_2 +; RV64I-NEXT: snez a1, a1 +; RV64I-NEXT: or a0, a1, a0 +; RV64I-NEXT: bnez a0, .LBB16_2 ; RV64I-NEXT: # %bb.1: ; RV64I-NEXT: ret ; RV64I-NEXT: .LBB16_2: @@ -457,11 +449,10 @@ define void @and_sge_ne(i32 signext %0, i32 signext %1, i32 signext %2, i32 sign ; RV32I-LABEL: and_sge_ne: ; RV32I: # %bb.0: ; RV32I-NEXT: slt a0, a0, a1 -; RV32I-NEXT: not a0, a0 ; RV32I-NEXT: xor a1, a2, a3 -; RV32I-NEXT: snez a1, a1 -; RV32I-NEXT: and a0, a0, a1 -; RV32I-NEXT: beqz a0, .LBB17_2 +; RV32I-NEXT: seqz a1, a1 +; RV32I-NEXT: or a0, a1, a0 +; RV32I-NEXT: bnez a0, .LBB17_2 ; RV32I-NEXT: # %bb.1: ; RV32I-NEXT: ret ; RV32I-NEXT: .LBB17_2: @@ -470,11 +461,10 @@ define void @and_sge_ne(i32 signext %0, i32 signext %1, i32 signext %2, i32 sign ; RV64I-LABEL: and_sge_ne: ; RV64I: # %bb.0: ; RV64I-NEXT: slt a0, a0, a1 -; RV64I-NEXT: not a0, a0 ; RV64I-NEXT: xor a1, a2, a3 -; RV64I-NEXT: snez a1, a1 -; RV64I-NEXT: and a0, a0, a1 -; RV64I-NEXT: beqz a0, .LBB17_2 +; RV64I-NEXT: seqz a1, a1 +; RV64I-NEXT: or a0, a1, a0 +; RV64I-NEXT: bnez a0, .LBB17_2 ; RV64I-NEXT: # %bb.1: ; RV64I-NEXT: ret ; RV64I-NEXT: .LBB17_2: @@ -496,11 +486,10 @@ define void @and_sle_ne(i32 signext %0, i32 signext %1, i32 signext %2, i32 sign ; RV32I-LABEL: and_sle_ne: ; RV32I: # %bb.0: ; RV32I-NEXT: slt a0, a1, a0 -; RV32I-NEXT: not a0, a0 ; RV32I-NEXT: xor a1, a2, a3 -; RV32I-NEXT: snez a1, a1 -; RV32I-NEXT: and a0, a0, a1 -; RV32I-NEXT: beqz a0, .LBB18_2 +; RV32I-NEXT: seqz a1, a1 +; RV32I-NEXT: or a0, a1, a0 +; RV32I-NEXT: bnez a0, .LBB18_2 ; RV32I-NEXT: # %bb.1: ; RV32I-NEXT: ret ; RV32I-NEXT: .LBB18_2: @@ -509,11 +498,10 @@ define void @and_sle_ne(i32 signext %0, i32 signext %1, i32 signext %2, i32 sign ; RV64I-LABEL: and_sle_ne: ; RV64I: # %bb.0: ; RV64I-NEXT: slt a0, a1, a0 -; RV64I-NEXT: not a0, a0 ; RV64I-NEXT: xor a1, a2, a3 -; RV64I-NEXT: snez a1, a1 -; RV64I-NEXT: and a0, a0, a1 -; RV64I-NEXT: beqz a0, .LBB18_2 +; RV64I-NEXT: seqz a1, a1 +; RV64I-NEXT: or a0, a1, a0 +; RV64I-NEXT: bnez a0, .LBB18_2 ; RV64I-NEXT: # %bb.1: ; RV64I-NEXT: ret ; RV64I-NEXT: .LBB18_2: @@ -535,11 +523,10 @@ define void @and_uge_ne(i32 signext %0, i32 signext %1, i32 signext %2, i32 sign ; RV32I-LABEL: and_uge_ne: ; RV32I: # %bb.0: ; RV32I-NEXT: sltu a0, a0, a1 -; RV32I-NEXT: not a0, a0 ; RV32I-NEXT: xor a1, a2, a3 -; RV32I-NEXT: snez a1, a1 -; RV32I-NEXT: and a0, a0, a1 -; RV32I-NEXT: beqz a0, .LBB19_2 +; RV32I-NEXT: seqz a1, a1 +; RV32I-NEXT: or a0, a1, a0 +; RV32I-NEXT: bnez a0, .LBB19_2 ; RV32I-NEXT: # %bb.1: ; RV32I-NEXT: ret ; RV32I-NEXT: .LBB19_2: @@ -548,11 +535,10 @@ define void @and_uge_ne(i32 signext %0, i32 signext %1, i32 signext %2, i32 sign ; RV64I-LABEL: and_uge_ne: ; RV64I: # %bb.0: ; RV64I-NEXT: sltu a0, a0, a1 -; RV64I-NEXT: not a0, a0 ; RV64I-NEXT: xor a1, a2, a3 -; RV64I-NEXT: snez a1, a1 -; RV64I-NEXT: and a0, a0, a1 -; RV64I-NEXT: beqz a0, .LBB19_2 +; RV64I-NEXT: seqz a1, a1 +; RV64I-NEXT: or a0, a1, a0 +; RV64I-NEXT: bnez a0, .LBB19_2 ; RV64I-NEXT: # %bb.1: ; RV64I-NEXT: ret ; RV64I-NEXT: .LBB19_2: @@ -574,11 +560,10 @@ define void @and_ule_ne(i32 signext %0, i32 signext %1, i32 signext %2, i32 sign ; RV32I-LABEL: and_ule_ne: ; RV32I: # %bb.0: ; RV32I-NEXT: sltu a0, a1, a0 -; RV32I-NEXT: not a0, a0 ; RV32I-NEXT: xor a1, a2, a3 -; RV32I-NEXT: snez a1, a1 -; RV32I-NEXT: and a0, a0, a1 -; RV32I-NEXT: beqz a0, .LBB20_2 +; RV32I-NEXT: seqz a1, a1 +; RV32I-NEXT: or a0, a1, a0 +; RV32I-NEXT: bnez a0, .LBB20_2 ; RV32I-NEXT: # %bb.1: ; RV32I-NEXT: ret ; RV32I-NEXT: .LBB20_2: @@ -587,11 +572,10 @@ define void @and_ule_ne(i32 signext %0, i32 signext %1, i32 signext %2, i32 sign ; RV64I-LABEL: and_ule_ne: ; RV64I: # %bb.0: ; RV64I-NEXT: sltu a0, a1, a0 -; RV64I-NEXT: not a0, a0 ; RV64I-NEXT: xor a1, a2, a3 -; RV64I-NEXT: snez a1, a1 -; RV64I-NEXT: and a0, a0, a1 -; RV64I-NEXT: beqz a0, .LBB20_2 +; RV64I-NEXT: seqz a1, a1 +; RV64I-NEXT: or a0, a1, a0 +; RV64I-NEXT: bnez a0, .LBB20_2 ; RV64I-NEXT: # %bb.1: ; RV64I-NEXT: ret ; RV64I-NEXT: .LBB20_2: @@ -613,11 +597,10 @@ define void @or_sge_eq(i32 signext %0, i32 signext %1, i32 signext %2, i32 signe ; RV32I-LABEL: or_sge_eq: ; RV32I: # %bb.0: ; RV32I-NEXT: slt a0, a0, a1 -; RV32I-NEXT: xori a0, a0, 1 ; RV32I-NEXT: xor a1, a2, a3 -; RV32I-NEXT: seqz a1, a1 -; RV32I-NEXT: or a0, a0, a1 -; RV32I-NEXT: beqz a0, .LBB21_2 +; RV32I-NEXT: snez a1, a1 +; RV32I-NEXT: and a0, a1, a0 +; RV32I-NEXT: bnez a0, .LBB21_2 ; RV32I-NEXT: # %bb.1: ; RV32I-NEXT: ret ; RV32I-NEXT: .LBB21_2: @@ -626,11 +609,10 @@ define void @or_sge_eq(i32 signext %0, i32 signext %1, i32 signext %2, i32 signe ; RV64I-LABEL: or_sge_eq: ; RV64I: # %bb.0: ; RV64I-NEXT: slt a0, a0, a1 -; RV64I-NEXT: xori a0, a0, 1 ; RV64I-NEXT: xor a1, a2, a3 -; RV64I-NEXT: seqz a1, a1 -; RV64I-NEXT: or a0, a0, a1 -; RV64I-NEXT: beqz a0, .LBB21_2 +; RV64I-NEXT: snez a1, a1 +; RV64I-NEXT: and a0, a1, a0 +; RV64I-NEXT: bnez a0, .LBB21_2 ; RV64I-NEXT: # %bb.1: ; RV64I-NEXT: ret ; RV64I-NEXT: .LBB21_2: @@ -652,11 +634,10 @@ define void @or_sle_eq(i32 signext %0, i32 signext %1, i32 signext %2, i32 signe ; RV32I-LABEL: or_sle_eq: ; RV32I: # %bb.0: ; RV32I-NEXT: slt a0, a1, a0 -; RV32I-NEXT: xori a0, a0, 1 ; RV32I-NEXT: xor a1, a2, a3 -; RV32I-NEXT: seqz a1, a1 -; RV32I-NEXT: or a0, a0, a1 -; RV32I-NEXT: beqz a0, .LBB22_2 +; RV32I-NEXT: snez a1, a1 +; RV32I-NEXT: and a0, a1, a0 +; RV32I-NEXT: bnez a0, .LBB22_2 ; RV32I-NEXT: # %bb.1: ; RV32I-NEXT: ret ; RV32I-NEXT: .LBB22_2: @@ -665,11 +646,10 @@ define void @or_sle_eq(i32 signext %0, i32 signext %1, i32 signext %2, i32 signe ; RV64I-LABEL: or_sle_eq: ; RV64I: # %bb.0: ; RV64I-NEXT: slt a0, a1, a0 -; RV64I-NEXT: xori a0, a0, 1 ; RV64I-NEXT: xor a1, a2, a3 -; RV64I-NEXT: seqz a1, a1 -; RV64I-NEXT: or a0, a0, a1 -; RV64I-NEXT: beqz a0, .LBB22_2 +; RV64I-NEXT: snez a1, a1 +; RV64I-NEXT: and a0, a1, a0 +; RV64I-NEXT: bnez a0, .LBB22_2 ; RV64I-NEXT: # %bb.1: ; RV64I-NEXT: ret ; RV64I-NEXT: .LBB22_2: @@ -691,11 +671,10 @@ define void @or_uge_eq(i32 signext %0, i32 signext %1, i32 signext %2, i32 signe ; RV32I-LABEL: or_uge_eq: ; RV32I: # %bb.0: ; RV32I-NEXT: sltu a0, a0, a1 -; RV32I-NEXT: xori a0, a0, 1 ; RV32I-NEXT: xor a1, a2, a3 -; RV32I-NEXT: seqz a1, a1 -; RV32I-NEXT: or a0, a0, a1 -; RV32I-NEXT: beqz a0, .LBB23_2 +; RV32I-NEXT: snez a1, a1 +; RV32I-NEXT: and a0, a1, a0 +; RV32I-NEXT: bnez a0, .LBB23_2 ; RV32I-NEXT: # %bb.1: ; RV32I-NEXT: ret ; RV32I-NEXT: .LBB23_2: @@ -704,11 +683,10 @@ define void @or_uge_eq(i32 signext %0, i32 signext %1, i32 signext %2, i32 signe ; RV64I-LABEL: or_uge_eq: ; RV64I: # %bb.0: ; RV64I-NEXT: sltu a0, a0, a1 -; RV64I-NEXT: xori a0, a0, 1 ; RV64I-NEXT: xor a1, a2, a3 -; RV64I-NEXT: seqz a1, a1 -; RV64I-NEXT: or a0, a0, a1 -; RV64I-NEXT: beqz a0, .LBB23_2 +; RV64I-NEXT: snez a1, a1 +; RV64I-NEXT: and a0, a1, a0 +; RV64I-NEXT: bnez a0, .LBB23_2 ; RV64I-NEXT: # %bb.1: ; RV64I-NEXT: ret ; RV64I-NEXT: .LBB23_2: @@ -730,11 +708,10 @@ define void @or_ule_eq(i32 signext %0, i32 signext %1, i32 signext %2, i32 signe ; RV32I-LABEL: or_ule_eq: ; RV32I: # %bb.0: ; RV32I-NEXT: sltu a0, a1, a0 -; RV32I-NEXT: xori a0, a0, 1 ; RV32I-NEXT: xor a1, a2, a3 -; RV32I-NEXT: seqz a1, a1 -; RV32I-NEXT: or a0, a0, a1 -; RV32I-NEXT: beqz a0, .LBB24_2 +; RV32I-NEXT: snez a1, a1 +; RV32I-NEXT: and a0, a1, a0 +; RV32I-NEXT: bnez a0, .LBB24_2 ; RV32I-NEXT: # %bb.1: ; RV32I-NEXT: ret ; RV32I-NEXT: .LBB24_2: @@ -743,11 +720,10 @@ define void @or_ule_eq(i32 signext %0, i32 signext %1, i32 signext %2, i32 signe ; RV64I-LABEL: or_ule_eq: ; RV64I: # %bb.0: ; RV64I-NEXT: sltu a0, a1, a0 -; RV64I-NEXT: xori a0, a0, 1 ; RV64I-NEXT: xor a1, a2, a3 -; RV64I-NEXT: seqz a1, a1 -; RV64I-NEXT: or a0, a0, a1 -; RV64I-NEXT: beqz a0, .LBB24_2 +; RV64I-NEXT: snez a1, a1 +; RV64I-NEXT: and a0, a1, a0 +; RV64I-NEXT: bnez a0, .LBB24_2 ; RV64I-NEXT: # %bb.1: ; RV64I-NEXT: ret ; RV64I-NEXT: .LBB24_2: @@ -769,11 +745,10 @@ define void @or_sge_ne(i32 signext %0, i32 signext %1, i32 signext %2, i32 signe ; RV32I-LABEL: or_sge_ne: ; RV32I: # %bb.0: ; RV32I-NEXT: slt a0, a0, a1 -; RV32I-NEXT: xori a0, a0, 1 ; RV32I-NEXT: xor a1, a2, a3 -; RV32I-NEXT: snez a1, a1 -; RV32I-NEXT: or a0, a0, a1 -; RV32I-NEXT: beqz a0, .LBB25_2 +; RV32I-NEXT: seqz a1, a1 +; RV32I-NEXT: and a0, a1, a0 +; RV32I-NEXT: bnez a0, .LBB25_2 ; RV32I-NEXT: # %bb.1: ; RV32I-NEXT: ret ; RV32I-NEXT: .LBB25_2: @@ -782,11 +757,10 @@ define void @or_sge_ne(i32 signext %0, i32 signext %1, i32 signext %2, i32 signe ; RV64I-LABEL: or_sge_ne: ; RV64I: # %bb.0: ; RV64I-NEXT: slt a0, a0, a1 -; RV64I-NEXT: xori a0, a0, 1 ; RV64I-NEXT: xor a1, a2, a3 -; RV64I-NEXT: snez a1, a1 -; RV64I-NEXT: or a0, a0, a1 -; RV64I-NEXT: beqz a0, .LBB25_2 +; RV64I-NEXT: seqz a1, a1 +; RV64I-NEXT: and a0, a1, a0 +; RV64I-NEXT: bnez a0, .LBB25_2 ; RV64I-NEXT: # %bb.1: ; RV64I-NEXT: ret ; RV64I-NEXT: .LBB25_2: @@ -808,11 +782,10 @@ define void @or_sle_ne(i32 signext %0, i32 signext %1, i32 signext %2, i32 signe ; RV32I-LABEL: or_sle_ne: ; RV32I: # %bb.0: ; RV32I-NEXT: slt a0, a1, a0 -; RV32I-NEXT: xori a0, a0, 1 ; RV32I-NEXT: xor a1, a2, a3 -; RV32I-NEXT: snez a1, a1 -; RV32I-NEXT: or a0, a0, a1 -; RV32I-NEXT: beqz a0, .LBB26_2 +; RV32I-NEXT: seqz a1, a1 +; RV32I-NEXT: and a0, a1, a0 +; RV32I-NEXT: bnez a0, .LBB26_2 ; RV32I-NEXT: # %bb.1: ; RV32I-NEXT: ret ; RV32I-NEXT: .LBB26_2: @@ -821,11 +794,10 @@ define void @or_sle_ne(i32 signext %0, i32 signext %1, i32 signext %2, i32 signe ; RV64I-LABEL: or_sle_ne: ; RV64I: # %bb.0: ; RV64I-NEXT: slt a0, a1, a0 -; RV64I-NEXT: xori a0, a0, 1 ; RV64I-NEXT: xor a1, a2, a3 -; RV64I-NEXT: snez a1, a1 -; RV64I-NEXT: or a0, a0, a1 -; RV64I-NEXT: beqz a0, .LBB26_2 +; RV64I-NEXT: seqz a1, a1 +; RV64I-NEXT: and a0, a1, a0 +; RV64I-NEXT: bnez a0, .LBB26_2 ; RV64I-NEXT: # %bb.1: ; RV64I-NEXT: ret ; RV64I-NEXT: .LBB26_2: @@ -847,11 +819,10 @@ define void @or_uge_ne(i32 signext %0, i32 signext %1, i32 signext %2, i32 signe ; RV32I-LABEL: or_uge_ne: ; RV32I: # %bb.0: ; RV32I-NEXT: sltu a0, a0, a1 -; RV32I-NEXT: xori a0, a0, 1 ; RV32I-NEXT: xor a1, a2, a3 -; RV32I-NEXT: snez a1, a1 -; RV32I-NEXT: or a0, a0, a1 -; RV32I-NEXT: beqz a0, .LBB27_2 +; RV32I-NEXT: seqz a1, a1 +; RV32I-NEXT: and a0, a1, a0 +; RV32I-NEXT: bnez a0, .LBB27_2 ; RV32I-NEXT: # %bb.1: ; RV32I-NEXT: ret ; RV32I-NEXT: .LBB27_2: @@ -860,11 +831,10 @@ define void @or_uge_ne(i32 signext %0, i32 signext %1, i32 signext %2, i32 signe ; RV64I-LABEL: or_uge_ne: ; RV64I: # %bb.0: ; RV64I-NEXT: sltu a0, a0, a1 -; RV64I-NEXT: xori a0, a0, 1 ; RV64I-NEXT: xor a1, a2, a3 -; RV64I-NEXT: snez a1, a1 -; RV64I-NEXT: or a0, a0, a1 -; RV64I-NEXT: beqz a0, .LBB27_2 +; RV64I-NEXT: seqz a1, a1 +; RV64I-NEXT: and a0, a1, a0 +; RV64I-NEXT: bnez a0, .LBB27_2 ; RV64I-NEXT: # %bb.1: ; RV64I-NEXT: ret ; RV64I-NEXT: .LBB27_2: @@ -886,11 +856,10 @@ define void @or_ule_ne(i32 signext %0, i32 signext %1, i32 signext %2, i32 signe ; RV32I-LABEL: or_ule_ne: ; RV32I: # %bb.0: ; RV32I-NEXT: sltu a0, a1, a0 -; RV32I-NEXT: xori a0, a0, 1 ; RV32I-NEXT: xor a1, a2, a3 -; RV32I-NEXT: snez a1, a1 -; RV32I-NEXT: or a0, a0, a1 -; RV32I-NEXT: beqz a0, .LBB28_2 +; RV32I-NEXT: seqz a1, a1 +; RV32I-NEXT: and a0, a1, a0 +; RV32I-NEXT: bnez a0, .LBB28_2 ; RV32I-NEXT: # %bb.1: ; RV32I-NEXT: ret ; RV32I-NEXT: .LBB28_2: @@ -899,11 +868,10 @@ define void @or_ule_ne(i32 signext %0, i32 signext %1, i32 signext %2, i32 signe ; RV64I-LABEL: or_ule_ne: ; RV64I: # %bb.0: ; RV64I-NEXT: sltu a0, a1, a0 -; RV64I-NEXT: xori a0, a0, 1 ; RV64I-NEXT: xor a1, a2, a3 -; RV64I-NEXT: snez a1, a1 -; RV64I-NEXT: or a0, a0, a1 -; RV64I-NEXT: beqz a0, .LBB28_2 +; RV64I-NEXT: seqz a1, a1 +; RV64I-NEXT: and a0, a1, a0 +; RV64I-NEXT: bnez a0, .LBB28_2 ; RV64I-NEXT: # %bb.1: ; RV64I-NEXT: ret ; RV64I-NEXT: .LBB28_2: @@ -925,11 +893,10 @@ define void @and_eq_sge(i32 signext %0, i32 signext %1, i32 signext %2, i32 sign ; RV32I-LABEL: and_eq_sge: ; RV32I: # %bb.0: ; RV32I-NEXT: xor a0, a0, a1 -; RV32I-NEXT: seqz a0, a0 +; RV32I-NEXT: snez a0, a0 ; RV32I-NEXT: slt a1, a2, a3 -; RV32I-NEXT: xori a1, a1, 1 -; RV32I-NEXT: and a0, a0, a1 -; RV32I-NEXT: beqz a0, .LBB29_2 +; RV32I-NEXT: or a0, a0, a1 +; RV32I-NEXT: bnez a0, .LBB29_2 ; RV32I-NEXT: # %bb.1: ; RV32I-NEXT: ret ; RV32I-NEXT: .LBB29_2: @@ -938,11 +905,10 @@ define void @and_eq_sge(i32 signext %0, i32 signext %1, i32 signext %2, i32 sign ; RV64I-LABEL: and_eq_sge: ; RV64I: # %bb.0: ; RV64I-NEXT: xor a0, a0, a1 -; RV64I-NEXT: seqz a0, a0 +; RV64I-NEXT: snez a0, a0 ; RV64I-NEXT: slt a1, a2, a3 -; RV64I-NEXT: xori a1, a1, 1 -; RV64I-NEXT: and a0, a0, a1 -; RV64I-NEXT: beqz a0, .LBB29_2 +; RV64I-NEXT: or a0, a0, a1 +; RV64I-NEXT: bnez a0, .LBB29_2 ; RV64I-NEXT: # %bb.1: ; RV64I-NEXT: ret ; RV64I-NEXT: .LBB29_2: @@ -964,11 +930,10 @@ define void @and_eq_sle(i32 signext %0, i32 signext %1, i32 signext %2, i32 sign ; RV32I-LABEL: and_eq_sle: ; RV32I: # %bb.0: ; RV32I-NEXT: xor a0, a0, a1 -; RV32I-NEXT: seqz a0, a0 +; RV32I-NEXT: snez a0, a0 ; RV32I-NEXT: slt a1, a3, a2 -; RV32I-NEXT: xori a1, a1, 1 -; RV32I-NEXT: and a0, a0, a1 -; RV32I-NEXT: beqz a0, .LBB30_2 +; RV32I-NEXT: or a0, a0, a1 +; RV32I-NEXT: bnez a0, .LBB30_2 ; RV32I-NEXT: # %bb.1: ; RV32I-NEXT: ret ; RV32I-NEXT: .LBB30_2: @@ -977,11 +942,10 @@ define void @and_eq_sle(i32 signext %0, i32 signext %1, i32 signext %2, i32 sign ; RV64I-LABEL: and_eq_sle: ; RV64I: # %bb.0: ; RV64I-NEXT: xor a0, a0, a1 -; RV64I-NEXT: seqz a0, a0 +; RV64I-NEXT: snez a0, a0 ; RV64I-NEXT: slt a1, a3, a2 -; RV64I-NEXT: xori a1, a1, 1 -; RV64I-NEXT: and a0, a0, a1 -; RV64I-NEXT: beqz a0, .LBB30_2 +; RV64I-NEXT: or a0, a0, a1 +; RV64I-NEXT: bnez a0, .LBB30_2 ; RV64I-NEXT: # %bb.1: ; RV64I-NEXT: ret ; RV64I-NEXT: .LBB30_2: @@ -1003,11 +967,10 @@ define void @and_eq_uge(i32 signext %0, i32 signext %1, i32 signext %2, i32 sign ; RV32I-LABEL: and_eq_uge: ; RV32I: # %bb.0: ; RV32I-NEXT: xor a0, a0, a1 -; RV32I-NEXT: seqz a0, a0 +; RV32I-NEXT: snez a0, a0 ; RV32I-NEXT: sltu a1, a2, a3 -; RV32I-NEXT: xori a1, a1, 1 -; RV32I-NEXT: and a0, a0, a1 -; RV32I-NEXT: beqz a0, .LBB31_2 +; RV32I-NEXT: or a0, a0, a1 +; RV32I-NEXT: bnez a0, .LBB31_2 ; RV32I-NEXT: # %bb.1: ; RV32I-NEXT: ret ; RV32I-NEXT: .LBB31_2: @@ -1016,11 +979,10 @@ define void @and_eq_uge(i32 signext %0, i32 signext %1, i32 signext %2, i32 sign ; RV64I-LABEL: and_eq_uge: ; RV64I: # %bb.0: ; RV64I-NEXT: xor a0, a0, a1 -; RV64I-NEXT: seqz a0, a0 +; RV64I-NEXT: snez a0, a0 ; RV64I-NEXT: sltu a1, a2, a3 -; RV64I-NEXT: xori a1, a1, 1 -; RV64I-NEXT: and a0, a0, a1 -; RV64I-NEXT: beqz a0, .LBB31_2 +; RV64I-NEXT: or a0, a0, a1 +; RV64I-NEXT: bnez a0, .LBB31_2 ; RV64I-NEXT: # %bb.1: ; RV64I-NEXT: ret ; RV64I-NEXT: .LBB31_2: @@ -1042,11 +1004,10 @@ define void @and_eq_ule(i32 signext %0, i32 signext %1, i32 signext %2, i32 sign ; RV32I-LABEL: and_eq_ule: ; RV32I: # %bb.0: ; RV32I-NEXT: xor a0, a0, a1 -; RV32I-NEXT: seqz a0, a0 +; RV32I-NEXT: snez a0, a0 ; RV32I-NEXT: sltu a1, a3, a2 -; RV32I-NEXT: xori a1, a1, 1 -; RV32I-NEXT: and a0, a0, a1 -; RV32I-NEXT: beqz a0, .LBB32_2 +; RV32I-NEXT: or a0, a0, a1 +; RV32I-NEXT: bnez a0, .LBB32_2 ; RV32I-NEXT: # %bb.1: ; RV32I-NEXT: ret ; RV32I-NEXT: .LBB32_2: @@ -1055,11 +1016,10 @@ define void @and_eq_ule(i32 signext %0, i32 signext %1, i32 signext %2, i32 sign ; RV64I-LABEL: and_eq_ule: ; RV64I: # %bb.0: ; RV64I-NEXT: xor a0, a0, a1 -; RV64I-NEXT: seqz a0, a0 +; RV64I-NEXT: snez a0, a0 ; RV64I-NEXT: sltu a1, a3, a2 -; RV64I-NEXT: xori a1, a1, 1 -; RV64I-NEXT: and a0, a0, a1 -; RV64I-NEXT: beqz a0, .LBB32_2 +; RV64I-NEXT: or a0, a0, a1 +; RV64I-NEXT: bnez a0, .LBB32_2 ; RV64I-NEXT: # %bb.1: ; RV64I-NEXT: ret ; RV64I-NEXT: .LBB32_2: @@ -1081,11 +1041,10 @@ define void @and_ne_sge(i32 signext %0, i32 signext %1, i32 signext %2, i32 sign ; RV32I-LABEL: and_ne_sge: ; RV32I: # %bb.0: ; RV32I-NEXT: xor a0, a0, a1 -; RV32I-NEXT: snez a0, a0 +; RV32I-NEXT: seqz a0, a0 ; RV32I-NEXT: slt a1, a2, a3 -; RV32I-NEXT: xori a1, a1, 1 -; RV32I-NEXT: and a0, a0, a1 -; RV32I-NEXT: beqz a0, .LBB33_2 +; RV32I-NEXT: or a0, a0, a1 +; RV32I-NEXT: bnez a0, .LBB33_2 ; RV32I-NEXT: # %bb.1: ; RV32I-NEXT: ret ; RV32I-NEXT: .LBB33_2: @@ -1094,11 +1053,10 @@ define void @and_ne_sge(i32 signext %0, i32 signext %1, i32 signext %2, i32 sign ; RV64I-LABEL: and_ne_sge: ; RV64I: # %bb.0: ; RV64I-NEXT: xor a0, a0, a1 -; RV64I-NEXT: snez a0, a0 +; RV64I-NEXT: seqz a0, a0 ; RV64I-NEXT: slt a1, a2, a3 -; RV64I-NEXT: xori a1, a1, 1 -; RV64I-NEXT: and a0, a0, a1 -; RV64I-NEXT: beqz a0, .LBB33_2 +; RV64I-NEXT: or a0, a0, a1 +; RV64I-NEXT: bnez a0, .LBB33_2 ; RV64I-NEXT: # %bb.1: ; RV64I-NEXT: ret ; RV64I-NEXT: .LBB33_2: @@ -1120,11 +1078,10 @@ define void @and_ne_sle(i32 signext %0, i32 signext %1, i32 signext %2, i32 sign ; RV32I-LABEL: and_ne_sle: ; RV32I: # %bb.0: ; RV32I-NEXT: xor a0, a0, a1 -; RV32I-NEXT: snez a0, a0 +; RV32I-NEXT: seqz a0, a0 ; RV32I-NEXT: slt a1, a3, a2 -; RV32I-NEXT: xori a1, a1, 1 -; RV32I-NEXT: and a0, a0, a1 -; RV32I-NEXT: beqz a0, .LBB34_2 +; RV32I-NEXT: or a0, a0, a1 +; RV32I-NEXT: bnez a0, .LBB34_2 ; RV32I-NEXT: # %bb.1: ; RV32I-NEXT: ret ; RV32I-NEXT: .LBB34_2: @@ -1133,11 +1090,10 @@ define void @and_ne_sle(i32 signext %0, i32 signext %1, i32 signext %2, i32 sign ; RV64I-LABEL: and_ne_sle: ; RV64I: # %bb.0: ; RV64I-NEXT: xor a0, a0, a1 -; RV64I-NEXT: snez a0, a0 +; RV64I-NEXT: seqz a0, a0 ; RV64I-NEXT: slt a1, a3, a2 -; RV64I-NEXT: xori a1, a1, 1 -; RV64I-NEXT: and a0, a0, a1 -; RV64I-NEXT: beqz a0, .LBB34_2 +; RV64I-NEXT: or a0, a0, a1 +; RV64I-NEXT: bnez a0, .LBB34_2 ; RV64I-NEXT: # %bb.1: ; RV64I-NEXT: ret ; RV64I-NEXT: .LBB34_2: @@ -1159,11 +1115,10 @@ define void @and_ne_uge(i32 signext %0, i32 signext %1, i32 signext %2, i32 sign ; RV32I-LABEL: and_ne_uge: ; RV32I: # %bb.0: ; RV32I-NEXT: xor a0, a0, a1 -; RV32I-NEXT: snez a0, a0 +; RV32I-NEXT: seqz a0, a0 ; RV32I-NEXT: sltu a1, a2, a3 -; RV32I-NEXT: xori a1, a1, 1 -; RV32I-NEXT: and a0, a0, a1 -; RV32I-NEXT: beqz a0, .LBB35_2 +; RV32I-NEXT: or a0, a0, a1 +; RV32I-NEXT: bnez a0, .LBB35_2 ; RV32I-NEXT: # %bb.1: ; RV32I-NEXT: ret ; RV32I-NEXT: .LBB35_2: @@ -1172,11 +1127,10 @@ define void @and_ne_uge(i32 signext %0, i32 signext %1, i32 signext %2, i32 sign ; RV64I-LABEL: and_ne_uge: ; RV64I: # %bb.0: ; RV64I-NEXT: xor a0, a0, a1 -; RV64I-NEXT: snez a0, a0 +; RV64I-NEXT: seqz a0, a0 ; RV64I-NEXT: sltu a1, a2, a3 -; RV64I-NEXT: xori a1, a1, 1 -; RV64I-NEXT: and a0, a0, a1 -; RV64I-NEXT: beqz a0, .LBB35_2 +; RV64I-NEXT: or a0, a0, a1 +; RV64I-NEXT: bnez a0, .LBB35_2 ; RV64I-NEXT: # %bb.1: ; RV64I-NEXT: ret ; RV64I-NEXT: .LBB35_2: @@ -1198,11 +1152,10 @@ define void @and_ne_ule(i32 signext %0, i32 signext %1, i32 signext %2, i32 sign ; RV32I-LABEL: and_ne_ule: ; RV32I: # %bb.0: ; RV32I-NEXT: xor a0, a0, a1 -; RV32I-NEXT: snez a0, a0 +; RV32I-NEXT: seqz a0, a0 ; RV32I-NEXT: sltu a1, a3, a2 -; RV32I-NEXT: xori a1, a1, 1 -; RV32I-NEXT: and a0, a0, a1 -; RV32I-NEXT: beqz a0, .LBB36_2 +; RV32I-NEXT: or a0, a0, a1 +; RV32I-NEXT: bnez a0, .LBB36_2 ; RV32I-NEXT: # %bb.1: ; RV32I-NEXT: ret ; RV32I-NEXT: .LBB36_2: @@ -1211,11 +1164,10 @@ define void @and_ne_ule(i32 signext %0, i32 signext %1, i32 signext %2, i32 sign ; RV64I-LABEL: and_ne_ule: ; RV64I: # %bb.0: ; RV64I-NEXT: xor a0, a0, a1 -; RV64I-NEXT: snez a0, a0 +; RV64I-NEXT: seqz a0, a0 ; RV64I-NEXT: sltu a1, a3, a2 -; RV64I-NEXT: xori a1, a1, 1 -; RV64I-NEXT: and a0, a0, a1 -; RV64I-NEXT: beqz a0, .LBB36_2 +; RV64I-NEXT: or a0, a0, a1 +; RV64I-NEXT: bnez a0, .LBB36_2 ; RV64I-NEXT: # %bb.1: ; RV64I-NEXT: ret ; RV64I-NEXT: .LBB36_2: