diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp index c5a706ae2b765..fbf02cad514b2 100644 --- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp @@ -16660,6 +16660,13 @@ performSIGN_EXTEND_INREGCombine(SDNode *N, SelectionDAG &DAG, return DAG.getNode(RISCVISD::SLLW, SDLoc(N), VT, Src.getOperand(0), Src.getOperand(1)); + // Fold (sext_inreg (xor (setcc), -1), i1) -> (add (setcc), -1) + if (Opc == ISD::XOR && SrcVT == MVT::i1 && + isAllOnesConstant(Src.getOperand(1)) && + Src.getOperand(0).getOpcode() == ISD::SETCC) + return DAG.getNode(ISD::ADD, SDLoc(N), VT, Src.getOperand(0), + DAG.getAllOnesConstant(SDLoc(N), VT)); + return SDValue(); } diff --git a/llvm/test/CodeGen/RISCV/rv32xandesperf.ll b/llvm/test/CodeGen/RISCV/rv32xandesperf.ll index 5cabb8c53e261..6f1d168358e2e 100644 --- a/llvm/test/CodeGen/RISCV/rv32xandesperf.ll +++ b/llvm/test/CodeGen/RISCV/rv32xandesperf.ll @@ -364,6 +364,19 @@ define i32 @sexti1_i32_2(i1 %a) { ret i32 %1 } +; Make sure we don't use not+nds.bfos +define zeroext i8 @sexti1_i32_setcc(i32 signext %a) { +; CHECK-LABEL: sexti1_i32_setcc: +; CHECK: # %bb.0: +; CHECK-NEXT: srli a0, a0, 31 +; CHECK-NEXT: addi a0, a0, -1 +; CHECK-NEXT: zext.b a0, a0 +; CHECK-NEXT: ret + %icmp = icmp sgt i32 %a, -1 + %sext = sext i1 %icmp to i8 + ret i8 %sext +} + define i32 @sexti8_i32(i32 %a) { ; CHECK-LABEL: sexti8_i32: ; CHECK: # %bb.0: diff --git a/llvm/test/CodeGen/RISCV/rv32xtheadbb.ll b/llvm/test/CodeGen/RISCV/rv32xtheadbb.ll index 723437a610ff8..784f08ca616cc 100644 --- a/llvm/test/CodeGen/RISCV/rv32xtheadbb.ll +++ b/llvm/test/CodeGen/RISCV/rv32xtheadbb.ll @@ -314,6 +314,26 @@ define i32 @sexti1_i32_2(i1 %a) nounwind { ret i32 %sext } +; Make sure we don't use not+th.ext +define zeroext i8 @sexti1_i32_setcc(i32 signext %a) { +; RV32I-LABEL: sexti1_i32_setcc: +; RV32I: # %bb.0: +; RV32I-NEXT: srli a0, a0, 31 +; RV32I-NEXT: addi a0, a0, -1 +; RV32I-NEXT: zext.b a0, a0 +; RV32I-NEXT: ret +; +; RV32XTHEADBB-LABEL: sexti1_i32_setcc: +; RV32XTHEADBB: # %bb.0: +; RV32XTHEADBB-NEXT: srli a0, a0, 31 +; RV32XTHEADBB-NEXT: addi a0, a0, -1 +; RV32XTHEADBB-NEXT: zext.b a0, a0 +; RV32XTHEADBB-NEXT: ret + %icmp = icmp sgt i32 %a, -1 + %sext = sext i1 %icmp to i8 + ret i8 %sext +} + define i32 @sextb_i32(i32 %a) nounwind { ; RV32I-LABEL: sextb_i32: ; RV32I: # %bb.0: diff --git a/llvm/test/CodeGen/RISCV/rv64xandesperf.ll b/llvm/test/CodeGen/RISCV/rv64xandesperf.ll index 98cda42665169..406e5247ae0dd 100644 --- a/llvm/test/CodeGen/RISCV/rv64xandesperf.ll +++ b/llvm/test/CodeGen/RISCV/rv64xandesperf.ll @@ -277,6 +277,19 @@ define signext i32 @sexti1_i32_2(i1 %a) { ret i32 %1 } +; Make sure we don't use not+nds.bfos +define zeroext i8 @sexti1_i32_setcc(i32 signext %a) { +; CHECK-LABEL: sexti1_i32_setcc: +; CHECK: # %bb.0: +; CHECK-NEXT: srli a0, a0, 63 +; CHECK-NEXT: addi a0, a0, -1 +; CHECK-NEXT: zext.b a0, a0 +; CHECK-NEXT: ret + %icmp = icmp sgt i32 %a, -1 + %sext = sext i1 %icmp to i8 + ret i8 %sext +} + define signext i32 @sexti8_i32(i32 signext %a) { ; CHECK-LABEL: sexti8_i32: ; CHECK: # %bb.0: @@ -334,6 +347,19 @@ define i64 @sexti1_i64_2(i1 %a) { ret i64 %1 } +; Make sure we don't use not+nds.bfos +define zeroext i8 @sexti1_i64_setcc(i64 %a) { +; CHECK-LABEL: sexti1_i64_setcc: +; CHECK: # %bb.0: +; CHECK-NEXT: srli a0, a0, 63 +; CHECK-NEXT: addi a0, a0, -1 +; CHECK-NEXT: zext.b a0, a0 +; CHECK-NEXT: ret + %icmp = icmp sgt i64 %a, -1 + %sext = sext i1 %icmp to i8 + ret i8 %sext +} + define i64 @sexti8_i64(i64 %a) { ; CHECK-LABEL: sexti8_i64: ; CHECK: # %bb.0: diff --git a/llvm/test/CodeGen/RISCV/rv64xtheadbb.ll b/llvm/test/CodeGen/RISCV/rv64xtheadbb.ll index 81acb4f724136..c7902342f7f03 100644 --- a/llvm/test/CodeGen/RISCV/rv64xtheadbb.ll +++ b/llvm/test/CodeGen/RISCV/rv64xtheadbb.ll @@ -635,6 +635,26 @@ define signext i32 @sexti1_i32_2(i1 %a) nounwind { ret i32 %sext } +; Make sure we don't use not+th.ext +define zeroext i8 @sexti1_i32_setcc(i32 signext %a) { +; RV64I-LABEL: sexti1_i32_setcc: +; RV64I: # %bb.0: +; RV64I-NEXT: srli a0, a0, 63 +; RV64I-NEXT: addi a0, a0, -1 +; RV64I-NEXT: zext.b a0, a0 +; RV64I-NEXT: ret +; +; RV64XTHEADBB-LABEL: sexti1_i32_setcc: +; RV64XTHEADBB: # %bb.0: +; RV64XTHEADBB-NEXT: srli a0, a0, 63 +; RV64XTHEADBB-NEXT: addi a0, a0, -1 +; RV64XTHEADBB-NEXT: zext.b a0, a0 +; RV64XTHEADBB-NEXT: ret + %icmp = icmp sgt i32 %a, -1 + %sext = sext i1 %icmp to i8 + ret i8 %sext +} + define i64 @sexti1_i64(i64 %a) nounwind { ; RV64I-LABEL: sexti1_i64: ; RV64I: # %bb.0: @@ -666,6 +686,26 @@ define i64 @sexti1_i64_2(i1 %a) nounwind { ret i64 %sext } +; Make sure we don't use not+th.ext +define zeroext i8 @sexti1_i64_setcc(i64 %a) { +; RV64I-LABEL: sexti1_i64_setcc: +; RV64I: # %bb.0: +; RV64I-NEXT: srli a0, a0, 63 +; RV64I-NEXT: addi a0, a0, -1 +; RV64I-NEXT: zext.b a0, a0 +; RV64I-NEXT: ret +; +; RV64XTHEADBB-LABEL: sexti1_i64_setcc: +; RV64XTHEADBB: # %bb.0: +; RV64XTHEADBB-NEXT: srli a0, a0, 63 +; RV64XTHEADBB-NEXT: addi a0, a0, -1 +; RV64XTHEADBB-NEXT: zext.b a0, a0 +; RV64XTHEADBB-NEXT: ret + %icmp = icmp sgt i64 %a, -1 + %sext = sext i1 %icmp to i8 + ret i8 %sext +} + define signext i32 @sextb_i32(i32 signext %a) nounwind { ; RV64I-LABEL: sextb_i32: ; RV64I: # %bb.0: diff --git a/llvm/test/CodeGen/RISCV/xqcibm-extract.ll b/llvm/test/CodeGen/RISCV/xqcibm-extract.ll index 481bfdd666430..fc3d8fe54602a 100644 --- a/llvm/test/CodeGen/RISCV/xqcibm-extract.ll +++ b/llvm/test/CodeGen/RISCV/xqcibm-extract.ll @@ -47,6 +47,33 @@ define i32 @sexti1_i32_2(i32 %a) { ret i32 %shr } +; Make sure we don't use not+qc.ext +define zeroext i8 @sexti1_i32_setcc(i32 signext %a) { +; RV32I-LABEL: sexti1_i32_setcc: +; RV32I: # %bb.0: +; RV32I-NEXT: srli a0, a0, 31 +; RV32I-NEXT: addi a0, a0, -1 +; RV32I-NEXT: zext.b a0, a0 +; RV32I-NEXT: ret +; +; RV32XQCIBM-LABEL: sexti1_i32_setcc: +; RV32XQCIBM: # %bb.0: +; RV32XQCIBM-NEXT: srli a0, a0, 31 +; RV32XQCIBM-NEXT: addi a0, a0, -1 +; RV32XQCIBM-NEXT: qc.extu a0, a0, 8, 0 +; RV32XQCIBM-NEXT: ret +; +; RV32XQCIBMZBB-LABEL: sexti1_i32_setcc: +; RV32XQCIBMZBB: # %bb.0: +; RV32XQCIBMZBB-NEXT: srli a0, a0, 31 +; RV32XQCIBMZBB-NEXT: addi a0, a0, -1 +; RV32XQCIBMZBB-NEXT: qc.extu a0, a0, 8, 0 +; RV32XQCIBMZBB-NEXT: ret + %icmp = icmp sgt i32 %a, -1 + %sext = sext i1 %icmp to i8 + ret i8 %sext +} + define i32 @sexti8_i32(i8 %a) nounwind { ; RV32I-LABEL: sexti8_i32: