[clang] 6244016 - [LoongArch] Add remaining intrinsics for CRC check instructions

via cfe-commits cfe-commits at lists.llvm.org
Wed Nov 30 17:47:47 PST 2022


Author: gonglingqin
Date: 2022-12-01T09:40:50+08:00
New Revision: 624401612c3ae1b3e96a691ac37631fb10197313

URL: https://github.com/llvm/llvm-project/commit/624401612c3ae1b3e96a691ac37631fb10197313
DIFF: https://github.com/llvm/llvm-project/commit/624401612c3ae1b3e96a691ac37631fb10197313.diff

LOG: [LoongArch] Add remaining intrinsics for CRC check instructions

After D137316 implements the intrinsics of the first crc check instruction
and related diagnosis, this patch implements the intrinsics of all remaining
crc check instructions.

Differential Revision: https://reviews.llvm.org/D138418

Added: 
    

Modified: 
    clang/include/clang/Basic/BuiltinsLoongArch.def
    clang/lib/CodeGen/CGBuiltin.cpp
    clang/lib/Headers/larchintrin.h
    clang/lib/Sema/SemaChecking.cpp
    clang/test/CodeGen/LoongArch/intrinsic-error.c
    clang/test/CodeGen/LoongArch/intrinsic-la64.c
    llvm/include/llvm/IR/IntrinsicsLoongArch.td
    llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
    llvm/lib/Target/LoongArch/LoongArchISelLowering.h
    llvm/lib/Target/LoongArch/LoongArchInstrInfo.td
    llvm/test/CodeGen/LoongArch/intrinsic-la32-error.ll
    llvm/test/CodeGen/LoongArch/intrinsic-la64.ll

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/Basic/BuiltinsLoongArch.def b/clang/include/clang/Basic/BuiltinsLoongArch.def
index fe2900497a500..85635b0b12424 100644
--- a/clang/include/clang/Basic/BuiltinsLoongArch.def
+++ b/clang/include/clang/Basic/BuiltinsLoongArch.def
@@ -22,7 +22,14 @@ TARGET_BUILTIN(__builtin_loongarch_ibar, "vIUi", "nc", "")
 TARGET_BUILTIN(__builtin_loongarch_break, "vIUi", "nc", "")
 TARGET_BUILTIN(__builtin_loongarch_syscall, "vIUi", "nc", "")
 
+TARGET_BUILTIN(__builtin_loongarch_crc_w_b_w, "iii", "nc", "64bit")
+TARGET_BUILTIN(__builtin_loongarch_crc_w_h_w, "iii", "nc", "64bit")
+TARGET_BUILTIN(__builtin_loongarch_crc_w_w_w, "iii", "nc", "64bit")
 TARGET_BUILTIN(__builtin_loongarch_crc_w_d_w, "iLii", "nc", "64bit")
+TARGET_BUILTIN(__builtin_loongarch_crcc_w_b_w, "iii", "nc", "64bit")
+TARGET_BUILTIN(__builtin_loongarch_crcc_w_h_w, "iii", "nc", "64bit")
+TARGET_BUILTIN(__builtin_loongarch_crcc_w_w_w, "iii", "nc", "64bit")
+TARGET_BUILTIN(__builtin_loongarch_crcc_w_d_w, "iLii", "nc", "64bit")
 
 #undef BUILTIN
 #undef TARGET_BUILTIN

diff  --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 801872dd700af..403dfe4ff6e87 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -19661,9 +19661,6 @@ Value *CodeGenFunction::EmitLoongArchBuiltinExpr(unsigned BuiltinID,
   case LoongArch::BI__builtin_loongarch_dbar:
     ID = Intrinsic::loongarch_dbar;
     break;
-  case LoongArch::BI__builtin_loongarch_crc_w_d_w:
-    ID = Intrinsic::loongarch_crc_w_d_w;
-    break;
   case LoongArch::BI__builtin_loongarch_break:
     ID = Intrinsic::loongarch_break;
     break;
@@ -19673,6 +19670,30 @@ Value *CodeGenFunction::EmitLoongArchBuiltinExpr(unsigned BuiltinID,
   case LoongArch::BI__builtin_loongarch_syscall:
     ID = Intrinsic::loongarch_syscall;
     break;
+  case LoongArch::BI__builtin_loongarch_crc_w_b_w:
+    ID = Intrinsic::loongarch_crc_w_b_w;
+    break;
+  case LoongArch::BI__builtin_loongarch_crc_w_h_w:
+    ID = Intrinsic::loongarch_crc_w_h_w;
+    break;
+  case LoongArch::BI__builtin_loongarch_crc_w_w_w:
+    ID = Intrinsic::loongarch_crc_w_w_w;
+    break;
+  case LoongArch::BI__builtin_loongarch_crc_w_d_w:
+    ID = Intrinsic::loongarch_crc_w_d_w;
+    break;
+  case LoongArch::BI__builtin_loongarch_crcc_w_b_w:
+    ID = Intrinsic::loongarch_crcc_w_b_w;
+    break;
+  case LoongArch::BI__builtin_loongarch_crcc_w_h_w:
+    ID = Intrinsic::loongarch_crcc_w_h_w;
+    break;
+  case LoongArch::BI__builtin_loongarch_crcc_w_w_w:
+    ID = Intrinsic::loongarch_crcc_w_w_w;
+    break;
+  case LoongArch::BI__builtin_loongarch_crcc_w_d_w:
+    ID = Intrinsic::loongarch_crcc_w_d_w;
+    break;
     // TODO: Support more Intrinsics.
   }
 

diff  --git a/clang/lib/Headers/larchintrin.h b/clang/lib/Headers/larchintrin.h
index ad284f62d815d..b16161b7cabc6 100644
--- a/clang/lib/Headers/larchintrin.h
+++ b/clang/lib/Headers/larchintrin.h
@@ -15,11 +15,53 @@ extern "C" {
 #endif
 
 #if __loongarch_grlen == 64
+extern __inline int
+    __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+    __crc_w_b_w(char _1, int _2) {
+  return (int)__builtin_loongarch_crc_w_b_w((char)_1, (int)_2);
+}
+
+extern __inline int
+    __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+    __crc_w_h_w(short _1, int _2) {
+  return (int)__builtin_loongarch_crc_w_h_w((short)_1, (int)_2);
+}
+
+extern __inline int
+    __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+    __crc_w_w_w(int _1, int _2) {
+  return (int)__builtin_loongarch_crc_w_w_w((int)_1, (int)_2);
+}
+
 extern __inline int
     __attribute__((__gnu_inline__, __always_inline__, __artificial__))
     __crc_w_d_w(long int _1, int _2) {
   return (int)__builtin_loongarch_crc_w_d_w((long int)_1, (int)_2);
 }
+
+extern __inline int
+    __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+    __crcc_w_b_w(char _1, int _2) {
+  return (int)__builtin_loongarch_crcc_w_b_w((char)_1, (int)_2);
+}
+
+extern __inline int
+    __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+    __crcc_w_h_w(short _1, int _2) {
+  return (int)__builtin_loongarch_crcc_w_h_w((short)_1, (int)_2);
+}
+
+extern __inline int
+    __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+    __crcc_w_w_w(int _1, int _2) {
+  return (int)__builtin_loongarch_crcc_w_w_w((int)_1, (int)_2);
+}
+
+extern __inline int
+    __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+    __crcc_w_d_w(long int _1, int _2) {
+  return (int)__builtin_loongarch_crcc_w_d_w((long int)_1, (int)_2);
+}
 #endif
 
 #define __break(/*ui15*/ _1) __builtin_loongarch_break((_1))

diff  --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index e7d968a93007c..9e38bee2ef03a 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -3704,7 +3704,14 @@ bool Sema::CheckLoongArchBuiltinFunctionCall(const TargetInfo &TI,
   switch (BuiltinID) {
   default:
     break;
+  case LoongArch::BI__builtin_loongarch_crc_w_b_w:
+  case LoongArch::BI__builtin_loongarch_crc_w_h_w:
+  case LoongArch::BI__builtin_loongarch_crc_w_w_w:
   case LoongArch::BI__builtin_loongarch_crc_w_d_w:
+  case LoongArch::BI__builtin_loongarch_crcc_w_b_w:
+  case LoongArch::BI__builtin_loongarch_crcc_w_h_w:
+  case LoongArch::BI__builtin_loongarch_crcc_w_w_w:
+  case LoongArch::BI__builtin_loongarch_crcc_w_d_w:
     if (!TI.hasFeature("64bit"))
       return Diag(TheCall->getBeginLoc(),
                   diag::err_loongarch_builtin_requires_la64)

diff  --git a/clang/test/CodeGen/LoongArch/intrinsic-error.c b/clang/test/CodeGen/LoongArch/intrinsic-error.c
index 8deed3693b254..8c2bddc362bfe 100644
--- a/clang/test/CodeGen/LoongArch/intrinsic-error.c
+++ b/clang/test/CodeGen/LoongArch/intrinsic-error.c
@@ -3,10 +3,6 @@
 
 #include <larchintrin.h>
 
-int crc_w_d_w(long int a, int b) {
-  return __builtin_loongarch_crc_w_d_w(a, b); // expected-error {{this builtin requires target: loongarch64}}
-}
-
 void dbar(int a) {
   __builtin_loongarch_dbar(32768); // expected-error {{argument value 32768 is outside the valid range [0, 32767]}}
   __builtin_loongarch_dbar(-1); // expected-error {{argument value 4294967295 is outside the valid range [0, 32767]}}
@@ -30,3 +26,34 @@ void syscall(int a) {
   __builtin_loongarch_syscall(-1); // expected-error {{argument value 4294967295 is outside the valid range [0, 32767]}}
   __builtin_loongarch_syscall(a); // expected-error {{argument to '__builtin_loongarch_syscall' must be a constant integer}}
 }
+
+int crc_w_b_w(char a, int b) {
+  return __builtin_loongarch_crc_w_b_w(a, b); // expected-error {{this builtin requires target: loongarch64}}
+}
+
+int crc_w_h_w(short a, int b) {
+  return __builtin_loongarch_crc_w_h_w(a, b); // expected-error {{this builtin requires target: loongarch64}}
+}
+
+int crc_w_w_w(int a, int b) {
+  return __builtin_loongarch_crc_w_w_w(a, b); // expected-error {{this builtin requires target: loongarch64}}
+}
+
+int crc_w_d_w(long int a, int b) {
+  return __builtin_loongarch_crc_w_d_w(a, b); // expected-error {{this builtin requires target: loongarch64}}
+}
+int crcc_w_b_w(char a, int b) {
+  return __builtin_loongarch_crcc_w_b_w(a, b); // expected-error {{this builtin requires target: loongarch64}}
+}
+
+int crcc_w_h_w(short a, int b) {
+  return __builtin_loongarch_crcc_w_h_w(a, b); // expected-error {{this builtin requires target: loongarch64}}
+}
+
+int crcc_w_w_w(int a, int b) {
+  return __builtin_loongarch_crcc_w_w_w(a, b); // expected-error {{this builtin requires target: loongarch64}}
+}
+
+int crcc_w_d_w(long int a, int b) {
+  return __builtin_loongarch_crcc_w_d_w(a, b); // expected-error {{this builtin requires target: loongarch64}}
+}

diff  --git a/clang/test/CodeGen/LoongArch/intrinsic-la64.c b/clang/test/CodeGen/LoongArch/intrinsic-la64.c
index 9fc37460a5efc..702686f5e6d3e 100644
--- a/clang/test/CodeGen/LoongArch/intrinsic-la64.c
+++ b/clang/test/CodeGen/LoongArch/intrinsic-la64.c
@@ -3,6 +3,33 @@
 
 #include <larchintrin.h>
 
+// CHECK-LABEL: @crc_w_b_w(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = tail call i32 @llvm.loongarch.crc.w.b.w(i32 [[A:%.*]], i32 [[B:%.*]])
+// CHECK-NEXT:    ret i32 [[TMP0]]
+//
+int crc_w_b_w(int a, int b) {
+  return __builtin_loongarch_crc_w_b_w(a, b);
+}
+
+// CHECK-LABEL: @crc_w_h_w(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = tail call i32 @llvm.loongarch.crc.w.h.w(i32 [[A:%.*]], i32 [[B:%.*]])
+// CHECK-NEXT:    ret i32 [[TMP0]]
+//
+int crc_w_h_w(int a, int b) {
+  return __builtin_loongarch_crc_w_h_w(a, b);
+}
+
+// CHECK-LABEL: @crc_w_w_w(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = tail call i32 @llvm.loongarch.crc.w.w.w(i32 [[A:%.*]], i32 [[B:%.*]])
+// CHECK-NEXT:    ret i32 [[TMP0]]
+//
+int crc_w_w_w(int a, int b) {
+  return __builtin_loongarch_crc_w_w_w(a, b);
+}
+
 // CHECK-LABEL: @crc_w_d_w(
 // CHECK-NEXT:  entry:
 // CHECK-NEXT:    [[TMP0:%.*]] = tail call i32 @llvm.loongarch.crc.w.d.w(i64 [[A:%.*]], i32 [[B:%.*]])
@@ -11,3 +38,39 @@
 int crc_w_d_w(long int a, int b) {
   return __builtin_loongarch_crc_w_d_w(a, b);
 }
+
+// CHECK-LABEL: @crcc_w_b_w(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = tail call i32 @llvm.loongarch.crcc.w.b.w(i32 [[A:%.*]], i32 [[B:%.*]])
+// CHECK-NEXT:    ret i32 [[TMP0]]
+//
+int crcc_w_b_w(int a, int b) {
+  return __builtin_loongarch_crcc_w_b_w(a, b);
+}
+
+// CHECK-LABEL: @crcc_w_h_w(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = tail call i32 @llvm.loongarch.crcc.w.h.w(i32 [[A:%.*]], i32 [[B:%.*]])
+// CHECK-NEXT:    ret i32 [[TMP0]]
+//
+int crcc_w_h_w(int a, int b) {
+  return __builtin_loongarch_crcc_w_h_w(a, b);
+}
+
+// CHECK-LABEL: @crcc_w_w_w(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = tail call i32 @llvm.loongarch.crcc.w.w.w(i32 [[A:%.*]], i32 [[B:%.*]])
+// CHECK-NEXT:    ret i32 [[TMP0]]
+//
+int crcc_w_w_w(int a, int b) {
+  return __builtin_loongarch_crcc_w_w_w(a, b);
+}
+
+// CHECK-LABEL: @crcc_w_d_w(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = tail call i32 @llvm.loongarch.crcc.w.d.w(i64 [[A:%.*]], i32 [[B:%.*]])
+// CHECK-NEXT:    ret i32 [[TMP0]]
+//
+int crcc_w_d_w(long int a, int b) {
+  return __builtin_loongarch_crcc_w_d_w(a, b);
+}

diff  --git a/llvm/include/llvm/IR/IntrinsicsLoongArch.td b/llvm/include/llvm/IR/IntrinsicsLoongArch.td
index c11334da929c9..8da6599bf9eb5 100644
--- a/llvm/include/llvm/IR/IntrinsicsLoongArch.td
+++ b/llvm/include/llvm/IR/IntrinsicsLoongArch.td
@@ -56,6 +56,21 @@ def int_loongarch_dbar : Intrinsic<[], [llvm_i32_ty], [ImmArg<ArgIndex<0>>]>;
 def int_loongarch_ibar : Intrinsic<[], [llvm_i32_ty], [ImmArg<ArgIndex<0>>]>;
 def int_loongarch_syscall : Intrinsic<[], [llvm_i32_ty], [ImmArg<ArgIndex<0>>]>;
 
+def int_loongarch_crc_w_b_w : Intrinsic<[llvm_i32_ty],
+                                        [llvm_i32_ty, llvm_i32_ty]>;
+def int_loongarch_crc_w_h_w : Intrinsic<[llvm_i32_ty],
+                                        [llvm_i32_ty, llvm_i32_ty]>;
+def int_loongarch_crc_w_w_w : Intrinsic<[llvm_i32_ty],
+                                        [llvm_i32_ty, llvm_i32_ty]>;
 def int_loongarch_crc_w_d_w : Intrinsic<[llvm_i32_ty],
                                         [llvm_i64_ty, llvm_i32_ty]>;
+
+def int_loongarch_crcc_w_b_w : Intrinsic<[llvm_i32_ty],
+                                         [llvm_i32_ty, llvm_i32_ty]>;
+def int_loongarch_crcc_w_h_w : Intrinsic<[llvm_i32_ty],
+                                         [llvm_i32_ty, llvm_i32_ty]>;
+def int_loongarch_crcc_w_w_w : Intrinsic<[llvm_i32_ty],
+                                         [llvm_i32_ty, llvm_i32_ty]>;
+def int_loongarch_crcc_w_d_w : Intrinsic<[llvm_i32_ty],
+                                         [llvm_i64_ty, llvm_i32_ty]>;
 } // TargetPrefix = "loongarch"

diff  --git a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
index c1b2b06a46222..0d1645d5f0ea1 100644
--- a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
+++ b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
@@ -122,6 +122,7 @@ LoongArchTargetLowering::LoongArchTargetLowering(const TargetMachine &TM,
     setOperationAction(ISD::INTRINSIC_W_CHAIN, MVT::i64, Custom);
     setOperationAction(ISD::READ_REGISTER, MVT::i64, Custom);
     setOperationAction(ISD::WRITE_REGISTER, MVT::i64, Custom);
+    setOperationAction(ISD::INTRINSIC_W_CHAIN, MVT::Other, Custom);
   }
 
   static const ISD::CondCode FPCCToExpand[] = {
@@ -597,9 +598,16 @@ LoongArchTargetLowering::lowerINTRINSIC_W_CHAIN(SDValue Op,
   switch (Op.getConstantOperandVal(1)) {
   default:
     return Op;
-  case Intrinsic::loongarch_crc_w_d_w: {
-    DAG.getContext()->emitError(
-        "llvm.loongarch.crc.w.d.w requires target: loongarch64");
+  case Intrinsic::loongarch_crc_w_b_w:
+  case Intrinsic::loongarch_crc_w_h_w:
+  case Intrinsic::loongarch_crc_w_w_w:
+  case Intrinsic::loongarch_crc_w_d_w:
+  case Intrinsic::loongarch_crcc_w_b_w:
+  case Intrinsic::loongarch_crcc_w_h_w:
+  case Intrinsic::loongarch_crcc_w_w_w:
+  case Intrinsic::loongarch_crcc_w_d_w: {
+    std::string Name = Op->getOperationName(0);
+    DAG.getContext()->emitError(Name + " requires target: loongarch64");
     return DAG.getMergeValues(
         {DAG.getUNDEF(Op.getValueType()), Op.getOperand(0)}, SDLoc(Op));
   }
@@ -935,19 +943,41 @@ void LoongArchTargetLowering::ReplaceNodeResults(
   case ISD::INTRINSIC_W_CHAIN: {
     assert(N->getValueType(0) == MVT::i32 && Subtarget.is64Bit() &&
            "Unexpected custom legalisation");
+    EVT VT = N->getValueType(0);
+    SDValue Op2 = N->getOperand(2);
+    SDValue Op3 = N->getOperand(3);
 
     switch (N->getConstantOperandVal(1)) {
     default:
       llvm_unreachable("Unexpected Intrinsic.");
-    case Intrinsic::loongarch_crc_w_d_w: {
-      Results.push_back(DAG.getNode(
-          ISD::TRUNCATE, DL, N->getValueType(0),
-          DAG.getNode(
-              LoongArchISD::CRC_W_D_W, DL, MVT::i64, N->getOperand(2),
-              DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i64, N->getOperand(3)))));
-      Results.push_back(N->getOperand(0));
-      break;
-    }
+#define CRC_CASE_EXT_BINARYOP(NAME, NODE)                                      \
+  case Intrinsic::loongarch_##NAME: {                                          \
+    Results.push_back(DAG.getNode(                                             \
+        ISD::TRUNCATE, DL, VT,                                                 \
+        DAG.getNode(LoongArchISD::NODE, DL, MVT::i64,                          \
+                    DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i64, Op2),           \
+                    DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i64, Op3))));        \
+    Results.push_back(N->getOperand(0));                                       \
+    break;                                                                     \
+  }
+      CRC_CASE_EXT_BINARYOP(crc_w_b_w, CRC_W_B_W)
+      CRC_CASE_EXT_BINARYOP(crc_w_h_w, CRC_W_H_W)
+      CRC_CASE_EXT_BINARYOP(crc_w_w_w, CRC_W_W_W)
+      CRC_CASE_EXT_BINARYOP(crcc_w_b_w, CRCC_W_B_W)
+      CRC_CASE_EXT_BINARYOP(crcc_w_h_w, CRCC_W_H_W)
+      CRC_CASE_EXT_BINARYOP(crcc_w_w_w, CRCC_W_W_W)
+
+#define CRC_CASE_EXT_UNARYOP(NAME, NODE)                                       \
+  case Intrinsic::loongarch_##NAME: {                                          \
+    Results.push_back(DAG.getNode(                                             \
+        ISD::TRUNCATE, DL, VT,                                                 \
+        DAG.getNode(LoongArchISD::NODE, DL, MVT::i64, Op2,                     \
+                    DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i64, Op3))));        \
+    Results.push_back(N->getOperand(0));                                       \
+    break;                                                                     \
+  }
+      CRC_CASE_EXT_UNARYOP(crc_w_d_w, CRC_W_D_W)
+      CRC_CASE_EXT_UNARYOP(crcc_w_d_w, CRCC_W_D_W)
     }
     break;
   }
@@ -1421,7 +1451,14 @@ const char *LoongArchTargetLowering::getTargetNodeName(unsigned Opcode) const {
     NODE_NAME_CASE(IBAR)
     NODE_NAME_CASE(BREAK)
     NODE_NAME_CASE(SYSCALL)
+    NODE_NAME_CASE(CRC_W_B_W)
+    NODE_NAME_CASE(CRC_W_H_W)
+    NODE_NAME_CASE(CRC_W_W_W)
     NODE_NAME_CASE(CRC_W_D_W)
+    NODE_NAME_CASE(CRCC_W_B_W)
+    NODE_NAME_CASE(CRCC_W_H_W)
+    NODE_NAME_CASE(CRCC_W_W_W)
+    NODE_NAME_CASE(CRCC_W_D_W)
   }
 #undef NODE_NAME_CASE
   return nullptr;

diff  --git a/llvm/lib/Target/LoongArch/LoongArchISelLowering.h b/llvm/lib/Target/LoongArch/LoongArchISelLowering.h
index 4f650feee47a0..6f34284ccec53 100644
--- a/llvm/lib/Target/LoongArch/LoongArchISelLowering.h
+++ b/llvm/lib/Target/LoongArch/LoongArchISelLowering.h
@@ -66,7 +66,14 @@ enum NodeType : unsigned {
   SYSCALL,
 
   // CRC check operations
-  CRC_W_D_W
+  CRC_W_B_W,
+  CRC_W_H_W,
+  CRC_W_W_W,
+  CRC_W_D_W,
+  CRCC_W_B_W,
+  CRCC_W_H_W,
+  CRCC_W_W_W,
+  CRCC_W_D_W
 };
 } // end namespace LoongArchISD
 

diff  --git a/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td b/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td
index 0da02c70102c6..1a2fd2ebdc7e6 100644
--- a/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td
+++ b/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td
@@ -59,8 +59,22 @@ def loongarch_sra_w : SDNode<"LoongArchISD::SRA_W", SDT_LoongArchIntBinOpW>;
 def loongarch_srl_w : SDNode<"LoongArchISD::SRL_W", SDT_LoongArchIntBinOpW>;
 def loongarch_rotr_w : SDNode<"LoongArchISD::ROTR_W", SDT_LoongArchIntBinOpW>;
 def loongarch_rotl_w : SDNode<"LoongArchISD::ROTL_W", SDT_LoongArchIntBinOpW>;
+def loongarch_crc_w_b_w
+    : SDNode<"LoongArchISD::CRC_W_B_W", SDT_LoongArchIntBinOpW>;
+def loongarch_crc_w_h_w
+    : SDNode<"LoongArchISD::CRC_W_H_W", SDT_LoongArchIntBinOpW>;
+def loongarch_crc_w_w_w
+    : SDNode<"LoongArchISD::CRC_W_W_W", SDT_LoongArchIntBinOpW>;
 def loongarch_crc_w_d_w
     : SDNode<"LoongArchISD::CRC_W_D_W", SDT_LoongArchIntBinOpW>;
+def loongarch_crcc_w_b_w
+    : SDNode<"LoongArchISD::CRCC_W_B_W", SDT_LoongArchIntBinOpW>;
+def loongarch_crcc_w_h_w
+    : SDNode<"LoongArchISD::CRCC_W_H_W", SDT_LoongArchIntBinOpW>;
+def loongarch_crcc_w_w_w
+    : SDNode<"LoongArchISD::CRCC_W_W_W", SDT_LoongArchIntBinOpW>;
+def loongarch_crcc_w_d_w
+    : SDNode<"LoongArchISD::CRCC_W_D_W", SDT_LoongArchIntBinOpW>;
 def loongarch_bstrins
     : SDNode<"LoongArchISD::BSTRINS", SDT_LoongArchBStrIns>;
 def loongarch_bstrpick
@@ -1487,7 +1501,14 @@ def : Pat<(loongarch_syscall uimm15:$imm15), (SYSCALL uimm15:$imm15)>;
 
 let Predicates = [IsLA64] in {
 // CRC Check Instructions
+def : PatGprGpr<loongarch_crc_w_b_w, CRC_W_B_W>;
+def : PatGprGpr<loongarch_crc_w_h_w, CRC_W_H_W>;
+def : PatGprGpr<loongarch_crc_w_w_w, CRC_W_W_W>;
 def : PatGprGpr<loongarch_crc_w_d_w, CRC_W_D_W>;
+def : PatGprGpr<loongarch_crcc_w_b_w, CRCC_W_B_W>;
+def : PatGprGpr<loongarch_crcc_w_h_w, CRCC_W_H_W>;
+def : PatGprGpr<loongarch_crcc_w_w_w, CRCC_W_W_W>;
+def : PatGprGpr<loongarch_crcc_w_d_w, CRCC_W_D_W>;
 } // Predicates = [IsLA64]
 
 /// Other pseudo-instructions

diff  --git a/llvm/test/CodeGen/LoongArch/intrinsic-la32-error.ll b/llvm/test/CodeGen/LoongArch/intrinsic-la32-error.ll
index 15ddc51087657..9aeff0f57ffd6 100644
--- a/llvm/test/CodeGen/LoongArch/intrinsic-la32-error.ll
+++ b/llvm/test/CodeGen/LoongArch/intrinsic-la32-error.ll
@@ -1,6 +1,34 @@
 ; RUN: not llc --mtriple=loongarch32 --disable-verify < %s 2>&1 | FileCheck %s
 
+declare i32 @llvm.loongarch.crc.w.b.w(i32, i32)
+declare i32 @llvm.loongarch.crc.w.h.w(i32, i32)
+declare i32 @llvm.loongarch.crc.w.w.w(i32, i32)
 declare i32 @llvm.loongarch.crc.w.d.w(i64, i32)
+declare i32 @llvm.loongarch.crcc.w.b.w(i32, i32)
+declare i32 @llvm.loongarch.crcc.w.h.w(i32, i32)
+declare i32 @llvm.loongarch.crcc.w.w.w(i32, i32)
+declare i32 @llvm.loongarch.crcc.w.d.w(i64, i32)
+
+define i32 @crc_w_b_w(i32 %a, i32 %b) nounwind {
+; CHECK: llvm.loongarch.crc.w.b.w requires target: loongarch64
+entry:
+  %res = call i32 @llvm.loongarch.crc.w.b.w(i32 %a, i32 %b)
+  ret i32 %res
+}
+
+define i32 @crc_w_h_w(i32 %a, i32 %b) nounwind {
+; CHECK: llvm.loongarch.crc.w.h.w requires target: loongarch64
+entry:
+  %res = call i32 @llvm.loongarch.crc.w.h.w(i32 %a, i32 %b)
+  ret i32 %res
+}
+
+define i32 @crc_w_w_w(i32 %a, i32 %b) nounwind {
+; CHECK: llvm.loongarch.crc.w.w.w requires target: loongarch64
+entry:
+  %res = call i32 @llvm.loongarch.crc.w.w.w(i32 %a, i32 %b)
+  ret i32 %res
+}
 
 define i32 @crc_w_d_w(i64 %a, i32 %b) nounwind {
 ; CHECK: llvm.loongarch.crc.w.d.w requires target: loongarch64
@@ -8,3 +36,31 @@ entry:
   %res = call i32 @llvm.loongarch.crc.w.d.w(i64 %a, i32 %b)
   ret i32 %res
 }
+
+define i32 @crcc_w_b_w(i32 %a, i32 %b) nounwind {
+; CHECK: llvm.loongarch.crcc.w.b.w requires target: loongarch64
+entry:
+  %res = call i32 @llvm.loongarch.crcc.w.b.w(i32 %a, i32 %b)
+  ret i32 %res
+}
+
+define i32 @crcc_w_h_w(i32 %a, i32 %b) nounwind {
+; CHECK: llvm.loongarch.crcc.w.h.w requires target: loongarch64
+entry:
+  %res = call i32 @llvm.loongarch.crcc.w.h.w(i32 %a, i32 %b)
+  ret i32 %res
+}
+
+define i32 @crcc_w_w_w(i32 %a, i32 %b) nounwind {
+; CHECK: llvm.loongarch.crcc.w.w.w requires target: loongarch64
+entry:
+  %res = call i32 @llvm.loongarch.crcc.w.w.w(i32 %a, i32 %b)
+  ret i32 %res
+}
+
+define i32 @crcc_w_d_w(i64 %a, i32 %b) nounwind {
+; CHECK: llvm.loongarch.crcc.w.d.w requires target: loongarch64
+entry:
+  %res = call i32 @llvm.loongarch.crcc.w.d.w(i64 %a, i32 %b)
+  ret i32 %res
+}

diff  --git a/llvm/test/CodeGen/LoongArch/intrinsic-la64.ll b/llvm/test/CodeGen/LoongArch/intrinsic-la64.ll
index a2eaa52982801..fd06313a37c4a 100644
--- a/llvm/test/CodeGen/LoongArch/intrinsic-la64.ll
+++ b/llvm/test/CodeGen/LoongArch/intrinsic-la64.ll
@@ -1,7 +1,41 @@
 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
 ; RUN: llc --mtriple=loongarch64 < %s | FileCheck %s
 
+declare i32 @llvm.loongarch.crc.w.b.w(i32, i32)
+declare i32 @llvm.loongarch.crc.w.h.w(i32, i32)
+declare i32 @llvm.loongarch.crc.w.w.w(i32, i32)
 declare i32 @llvm.loongarch.crc.w.d.w(i64, i32)
+declare i32 @llvm.loongarch.crcc.w.b.w(i32, i32)
+declare i32 @llvm.loongarch.crcc.w.h.w(i32, i32)
+declare i32 @llvm.loongarch.crcc.w.w.w(i32, i32)
+declare i32 @llvm.loongarch.crcc.w.d.w(i64, i32)
+
+define i32 @crc_w_b_w(i32 %a, i32 %b) nounwind {
+; CHECK-LABEL: crc_w_b_w:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    crc.w.b.w $a0, $a0, $a1
+; CHECK-NEXT:    ret
+  %res = call i32 @llvm.loongarch.crc.w.b.w(i32 %a, i32 %b)
+  ret i32 %res
+}
+
+define i32 @crc_w_h_w(i32 %a, i32 %b) nounwind {
+; CHECK-LABEL: crc_w_h_w:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    crc.w.h.w $a0, $a0, $a1
+; CHECK-NEXT:    ret
+  %res = call i32 @llvm.loongarch.crc.w.h.w(i32 %a, i32 %b)
+  ret i32 %res
+}
+
+define i32 @crc_w_w_w(i32 %a, i32 %b) nounwind {
+; CHECK-LABEL: crc_w_w_w:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    crc.w.w.w $a0, $a0, $a1
+; CHECK-NEXT:    ret
+  %res = call i32 @llvm.loongarch.crc.w.w.w(i32 %a, i32 %b)
+  ret i32 %res
+}
 
 define i32 @crc_w_d_w(i64 %a, i32 %b) nounwind {
 ; CHECK-LABEL: crc_w_d_w:
@@ -11,3 +45,39 @@ define i32 @crc_w_d_w(i64 %a, i32 %b) nounwind {
   %res = call i32 @llvm.loongarch.crc.w.d.w(i64 %a, i32 %b)
   ret i32 %res
 }
+
+define i32 @crcc_w_b_w(i32 %a, i32 %b) nounwind {
+; CHECK-LABEL: crcc_w_b_w:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    crcc.w.b.w $a0, $a0, $a1
+; CHECK-NEXT:    ret
+  %res = call i32 @llvm.loongarch.crcc.w.b.w(i32 %a, i32 %b)
+  ret i32 %res
+}
+
+define i32 @crcc_w_h_w(i32 %a, i32 %b) nounwind {
+; CHECK-LABEL: crcc_w_h_w:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    crcc.w.h.w $a0, $a0, $a1
+; CHECK-NEXT:    ret
+  %res = call i32 @llvm.loongarch.crcc.w.h.w(i32 %a, i32 %b)
+  ret i32 %res
+}
+
+define i32 @crcc_w_w_w(i32 %a, i32 %b) nounwind {
+; CHECK-LABEL: crcc_w_w_w:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    crcc.w.w.w $a0, $a0, $a1
+; CHECK-NEXT:    ret
+  %res = call i32 @llvm.loongarch.crcc.w.w.w(i32 %a, i32 %b)
+  ret i32 %res
+}
+
+define i32 @crcc_w_d_w(i64 %a, i32 %b) nounwind {
+; CHECK-LABEL: crcc_w_d_w:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    crcc.w.d.w $a0, $a0, $a1
+; CHECK-NEXT:    ret
+  %res = call i32 @llvm.loongarch.crcc.w.d.w(i64 %a, i32 %b)
+  ret i32 %res
+}


        


More information about the cfe-commits mailing list