[llvm] 95388f7 - [RISCV] Improve selection of PACK/PACKW for AssertZExt input.

Craig Topper via llvm-commits llvm-commits at lists.llvm.org
Sun Nov 13 16:02:54 PST 2022


Author: Craig Topper
Date: 2022-11-13T16:00:45-08:00
New Revision: 95388f732962f2bfa2d27895ab9e7e4fd3ae3efd

URL: https://github.com/llvm/llvm-project/commit/95388f732962f2bfa2d27895ab9e7e4fd3ae3efd
DIFF: https://github.com/llvm/llvm-project/commit/95388f732962f2bfa2d27895ab9e7e4fd3ae3efd.diff

LOG: [RISCV] Improve selection of PACK/PACKW for AssertZExt input.

Added: 
    

Modified: 
    llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
    llvm/lib/Target/RISCV/RISCVISelDAGToDAG.h
    llvm/lib/Target/RISCV/RISCVInstrInfo.td
    llvm/lib/Target/RISCV/RISCVInstrInfoZb.td
    llvm/test/CodeGen/RISCV/rv32zbkb.ll
    llvm/test/CodeGen/RISCV/rv64zbkb.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
index 7cd52b5edd208..87f5f7c62df0b 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<ConstantSDNode>(N.getOperand(1));
-    if (C && C->getZExtValue() == UINT64_C(0xFFFFFFFF)) {
+    if (C && C->getZExtValue() == maskTrailingOnes<uint64_t>(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 d0c05ecdd9030..9dae3b4c08290 100644
--- a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.h
+++ b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.h
@@ -60,7 +60,10 @@ class RISCVDAGToDAGISel : public SelectionDAGISel {
   }
 
   bool selectSExti32(SDValue N, SDValue &Val);
-  bool selectZExti32(SDValue N, SDValue &Val);
+  bool selectZExtBits(SDValue N, unsigned Bits, SDValue &Val);
+  template <unsigned Bits> bool selectZExtBits(SDValue N, SDValue &Val) {
+    return selectZExtBits(N, Bits, Val);
+  }
 
   bool selectSHXADDOp(SDValue N, unsigned ShAmt, SDValue &Val);
   template <unsigned ShAmt> bool selectSHXADDOp(SDValue N, SDValue &Val) {

diff  --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.td b/llvm/lib/Target/RISCV/RISCVInstrInfo.td
index ebf3113497b96..38ff9290f4081 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.td
@@ -1172,7 +1172,8 @@ def sexti32 : ComplexPattern<i64, 1, "selectSExti32">;
 def assertzexti32 : PatFrag<(ops node:$src), (assertzext node:$src), [{
   return cast<VTSDNode>(N->getOperand(1))->getVT().bitsLE(MVT::i32);
 }]>;
-def zexti32 : ComplexPattern<i64, 1, "selectZExti32">;
+def zexti32 : ComplexPattern<i64, 1, "selectZExtBits<32>">;
+def zexti16 : ComplexPattern<XLenVT, 1, "selectZExtBits<16>">;
 
 class binop_oneuse<SDPatternOperator operator>
     : PatFrag<(ops node:$A, node:$B),

diff  --git a/llvm/lib/Target/RISCV/RISCVInstrInfoZb.td b/llvm/lib/Target/RISCV/RISCVInstrInfoZb.td
index 602e895e9a8c7..25d5a3a3067e4 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 09ffcc9c83f78..56eac8873afb7 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 ac28336dd0b6a..c86f720818b04 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:


        


More information about the llvm-commits mailing list