[llvm] [RISCV] Implement Intrinsics and CodeGen Support for XCValu Extension… (PR #78138)

Craig Topper via llvm-commits llvm-commits at lists.llvm.org
Thu Jan 25 11:57:02 PST 2024


================
@@ -704,3 +749,112 @@ let Predicates = [HasVendorXCVbitmanip, IsRV32] in {
             (CV_BITREV GPR:$rs1, cv_tuimm2:$radix, cv_tuimm5:$pts)>;
   def : Pat<(bitreverse (XLenVT GPR:$rs)), (CV_BITREV GPR:$rs, 0, 0)>;
 }
+
+class PatCoreVAluGpr <string intr, string asm> :
+  PatGpr<!cast<Intrinsic>("int_riscv_cv_alu_" # intr),
+            !cast<RVInst>("CV_" # asm)>;
+class PatCoreVAluGprGpr <string intr, string asm> :
+  PatGprGpr<!cast<Intrinsic>("int_riscv_cv_alu_" # intr),
+               !cast<RVInst>("CV_" # asm)>;
+
+multiclass PatCoreVAluGprImm <Intrinsic intr> {
+  def "CV_" # NAME # "_PSEUDO" :
+    Pseudo<(outs GPR:$rd), (ins GPR:$rs, cv_uimm32:$imm), []>;
+  def : PatGprGpr<intr, !cast<RVInst>("CV_" # NAME # "R")>;
+  def : PatGprImm<intr, !cast<RVInst>("CV_" # NAME # "_PSEUDO"), cv_uimm32>;
+}
+
+multiclass PatCoreVAluGprGprImm <Intrinsic intr> {
+  def "CV_" # NAME # "_PSEUDO" :
+    Pseudo<(outs GPR:$rd), (ins GPR:$rs1, GPR:$rs2, uimm5:$imm), []>;
+  def : Pat<(intr GPR:$rs1, GPR:$rs2, GPR:$rs3),
+            (!cast<RVInst>("CV_" # NAME # "R") GPR:$rs1, GPR:$rs2, GPR:$rs3)>;
+  def : Pat<(intr GPR:$rs1, GPR:$rs2, uimm5:$imm),
+            (!cast<RVInst>("CV_" # NAME # "_PSEUDO") GPR:$rs1, GPR:$rs2,
+            uimm5:$imm)>;
+}
+
+let Predicates = [HasVendorXCValu, IsRV32], AddedComplexity = 1 in {
+  def : PatGpr<abs, CV_ABS>;
+  def : PatGprGpr<setle, CV_SLET>;
+  def : PatGprGpr<setule, CV_SLETU>;
+  def : PatGprGpr<smin, CV_MIN>;
+  def : PatGprGpr<umin, CV_MINU>;
+  def : PatGprGpr<smax, CV_MAX>;
+  def : PatGprGpr<umax, CV_MAXU>;
+
+  def : Pat<(sext_inreg (XLenVT GPR:$rs1), i16), (CV_EXTHS GPR:$rs1)>;
+  def : Pat<(sext_inreg (XLenVT GPR:$rs1), i8), (CV_EXTBS GPR:$rs1)>;
+
+  def : Pat<(and (XLenVT GPR:$rs1), 0xffff), (CV_EXTHZ GPR:$rs1)>;
+  def : Pat<(and (XLenVT GPR:$rs1), 0xff),   (CV_EXTBZ GPR:$rs1)>;
+
+  def : Pat<(clip powerOf2Minus1:$upperBound, (XLenVT GPR:$rs1)),
+            (CV_CLIP GPR:$rs1, (trailing1sPlus1 imm:$upperBound))>;
+  def : Pat<(between (not GPR:$rs2), GPR:$rs2, (XLenVT GPR:$rs1)),
+            (CV_CLIPR GPR:$rs1, GPR:$rs2)>;
+  def : Pat<(betweenu powerOf2Minus1:$upperBound, (XLenVT GPR:$rs1)),
+            (CV_CLIPU GPR:$rs1, (trailing1sPlus1 imm:$upperBound))>;
+  def : Pat<(betweenu GPR:$rs2, (XLenVT GPR:$rs1)),
+            (CV_CLIPUR GPR:$rs1, GPR:$rs2)>;
+
+  def : Pat<(sra (add (XLenVT GPR:$rs1), (XLenVT GPR:$rs2)), uimm5:$imm5),
+            (CV_ADDN GPR:$rs1, GPR:$rs2, uimm5:$imm5)>;
+  def : Pat<(srl (add (XLenVT GPR:$rs1), (XLenVT GPR:$rs2)), uimm5:$imm5),
----------------
topperc wrote:

Ok. I just expected it would work like the vaaddu instruction with RDN. The instruction seemed more useful with that behavior since it is hard to get the extract precision otherwise. But if that's not what the hardware does, then this pattern is correct.

https://github.com/llvm/llvm-project/pull/78138


More information about the llvm-commits mailing list