From 95388f732962f2bfa2d27895ab9e7e4fd3ae3efd Mon Sep 17 00:00:00 2001 From: Craig Topper Date: Sun, 13 Nov 2022 13:35:04 -0800 Subject: [PATCH] [RISCV] Improve selection of PACK/PACKW for AssertZExt input. --- llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp | 6 ++--- llvm/lib/Target/RISCV/RISCVISelDAGToDAG.h | 5 +++- llvm/lib/Target/RISCV/RISCVInstrInfo.td | 3 ++- llvm/lib/Target/RISCV/RISCVInstrInfoZb.td | 6 ++--- llvm/test/CodeGen/RISCV/rv32zbkb.ll | 29 ++++++++++++++++++++++ llvm/test/CodeGen/RISCV/rv64zbkb.ll | 38 +++++++++++++++++++++++++++++ 6 files changed, 79 insertions(+), 8 deletions(-) diff --git a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp index 7cd52b5..87f5f7c 100644 --- a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp @@ -2117,16 +2117,16 @@ bool RISCVDAGToDAGISel::selectSExti32(SDValue N, SDValue &Val) { return false; } -bool RISCVDAGToDAGISel::selectZExti32(SDValue N, SDValue &Val) { +bool RISCVDAGToDAGISel::selectZExtBits(SDValue N, unsigned Bits, SDValue &Val) { if (N.getOpcode() == ISD::AND) { auto *C = dyn_cast(N.getOperand(1)); - if (C && C->getZExtValue() == UINT64_C(0xFFFFFFFF)) { + if (C && C->getZExtValue() == maskTrailingOnes(Bits)) { Val = N.getOperand(0); return true; } } MVT VT = N.getSimpleValueType(); - APInt Mask = APInt::getHighBitsSet(VT.getSizeInBits(), 32); + APInt Mask = APInt::getBitsSetFrom(VT.getSizeInBits(), Bits); if (CurDAG->MaskedValueIsZero(N, Mask)) { Val = N; return true; diff --git a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.h b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.h index d0c05ec..9dae3b4 100644 --- a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.h +++ b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.h @@ -60,7 +60,10 @@ public: } bool selectSExti32(SDValue N, SDValue &Val); - bool selectZExti32(SDValue N, SDValue &Val); + bool selectZExtBits(SDValue N, unsigned Bits, SDValue &Val); + template bool selectZExtBits(SDValue N, SDValue &Val) { + return selectZExtBits(N, Bits, Val); + } bool selectSHXADDOp(SDValue N, unsigned ShAmt, SDValue &Val); template bool selectSHXADDOp(SDValue N, SDValue &Val) { diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.td b/llvm/lib/Target/RISCV/RISCVInstrInfo.td index ebf3113..38ff929 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfo.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.td @@ -1172,7 +1172,8 @@ def sexti32 : ComplexPattern; def assertzexti32 : PatFrag<(ops node:$src), (assertzext node:$src), [{ return cast(N->getOperand(1))->getVT().bitsLE(MVT::i32); }]>; -def zexti32 : ComplexPattern; +def zexti32 : ComplexPattern">; +def zexti16 : ComplexPattern">; class binop_oneuse : PatFrag<(ops node:$A, node:$B), diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoZb.td b/llvm/lib/Target/RISCV/RISCVInstrInfoZb.td index 602e895..25d5a3a 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfoZb.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoZb.td @@ -641,7 +641,7 @@ def : Pat<(or (shl (and GPR:$rs2, 0x00FF), (XLenVT 8)), } // Predicates = [HasStdExtZbkb] let Predicates = [HasStdExtZbkb, IsRV32] in -def : Pat<(i32 (or (and GPR:$rs1, 0x0000FFFF), (shl GPR:$rs2, (i32 16)))), +def : Pat<(i32 (or (zexti16 GPR:$rs1), (shl GPR:$rs2, (i32 16)))), (PACK GPR:$rs1, GPR:$rs2)>; let Predicates = [HasStdExtZbkb, IsRV64] in { @@ -649,11 +649,11 @@ def : Pat<(i64 (or (and GPR:$rs1, 0x00000000FFFFFFFF), (shl GPR:$rs2, (i64 32))) (PACK GPR:$rs1, GPR:$rs2)>; def : Pat<(i64 (sext_inreg (or (shl GPR:$rs2, (i64 16)), - (and GPR:$rs1, 0x000000000000FFFF)), + (zexti16 GPR:$rs1)), i32)), (PACKW GPR:$rs1, GPR:$rs2)>; def : Pat<(i64 (or (sext_inreg (shl GPR:$rs2, (i64 16)), i32), - (and GPR:$rs1, 0x000000000000FFFF))), + (zexti16 GPR:$rs1))), (PACKW GPR:$rs1, GPR:$rs2)>; } // Predicates = [HasStdExtZbkb, IsRV64] diff --git a/llvm/test/CodeGen/RISCV/rv32zbkb.ll b/llvm/test/CodeGen/RISCV/rv32zbkb.ll index 09ffcc9c..56eac88 100644 --- a/llvm/test/CodeGen/RISCV/rv32zbkb.ll +++ b/llvm/test/CodeGen/RISCV/rv32zbkb.ll @@ -23,6 +23,24 @@ define i32 @pack_i32(i32 %a, i32 %b) nounwind { ret i32 %or } +define i32 @pack_i32_2(i16 zeroext %a, i16 zeroext %b) nounwind { +; RV32I-LABEL: pack_i32_2: +; RV32I: # %bb.0: +; RV32I-NEXT: slli a1, a1, 16 +; RV32I-NEXT: or a0, a1, a0 +; RV32I-NEXT: ret +; +; RV32ZBKB-LABEL: pack_i32_2: +; RV32ZBKB: # %bb.0: +; RV32ZBKB-NEXT: pack a0, a0, a1 +; RV32ZBKB-NEXT: ret + %zexta = zext i16 %a to i32 + %zextb = zext i16 %b to i32 + %shl1 = shl i32 %zextb, 16 + %or = or i32 %shl1, %zexta + ret i32 %or +} + ; As we are not matching directly i64 code patterns on RV32 some i64 patterns ; don't have yet any matching bit manipulation instructions on RV32. ; This test is presented here in case future expansions of the Bitmanip @@ -39,6 +57,17 @@ define i64 @pack_i64(i64 %a, i64 %b) nounwind { ret i64 %or } +define i64 @pack_i64_2(i32 %a, i32 %b) nounwind { +; CHECK-LABEL: pack_i64_2: +; CHECK: # %bb.0: +; CHECK-NEXT: ret + %zexta = zext i32 %a to i64 + %zextb = zext i32 %b to i64 + %shl1 = shl i64 %zextb, 32 + %or = or i64 %shl1, %zexta + ret i64 %or +} + ; As we are not matching directly i64 code patterns on RV32 some i64 patterns ; don't have yet any matching bit manipulation instructions on RV32. ; This test is presented here in case future expansions of the Bitmanip diff --git a/llvm/test/CodeGen/RISCV/rv64zbkb.ll b/llvm/test/CodeGen/RISCV/rv64zbkb.ll index ac28336..c86f720 100644 --- a/llvm/test/CodeGen/RISCV/rv64zbkb.ll +++ b/llvm/test/CodeGen/RISCV/rv64zbkb.ll @@ -23,6 +23,24 @@ define signext i32 @pack_i32(i32 signext %a, i32 signext %b) nounwind { ret i32 %or } +define signext i32 @pack_i32_2(i16 zeroext %a, i16 zeroext %b) nounwind { +; RV64I-LABEL: pack_i32_2: +; RV64I: # %bb.0: +; RV64I-NEXT: slliw a1, a1, 16 +; RV64I-NEXT: or a0, a1, a0 +; RV64I-NEXT: ret +; +; RV64ZBKB-LABEL: pack_i32_2: +; RV64ZBKB: # %bb.0: +; RV64ZBKB-NEXT: packw a0, a0, a1 +; RV64ZBKB-NEXT: ret + %zexta = zext i16 %a to i32 + %zextb = zext i16 %b to i32 + %shl1 = shl i32 %zextb, 16 + %or = or i32 %shl1, %zexta + ret i32 %or +} + define i64 @pack_i64(i64 %a, i64 %b) nounwind { ; RV64I-LABEL: pack_i64: ; RV64I: # %bb.0: @@ -42,6 +60,26 @@ define i64 @pack_i64(i64 %a, i64 %b) nounwind { ret i64 %or } +define i64 @pack_i64_2(i32 signext %a, i32 signext %b) nounwind { +; RV64I-LABEL: pack_i64_2: +; RV64I: # %bb.0: +; RV64I-NEXT: slli a0, a0, 32 +; RV64I-NEXT: srli a0, a0, 32 +; RV64I-NEXT: slli a1, a1, 32 +; RV64I-NEXT: or a0, a1, a0 +; RV64I-NEXT: ret +; +; RV64ZBKB-LABEL: pack_i64_2: +; RV64ZBKB: # %bb.0: +; RV64ZBKB-NEXT: pack a0, a0, a1 +; RV64ZBKB-NEXT: ret + %zexta = zext i32 %a to i64 + %zextb = zext i32 %b to i64 + %shl1 = shl i64 %zextb, 32 + %or = or i64 %shl1, %zexta + ret i64 %or +} + define signext i32 @packh_i32(i32 signext %a, i32 signext %b) nounwind { ; RV64I-LABEL: packh_i32: ; RV64I: # %bb.0: -- 2.7.4