[LoongArch] Add remaining intrinsics for CRC check instructions
authorgonglingqin <gonglingqin@loongson.cn>
Thu, 1 Dec 2022 01:18:00 +0000 (09:18 +0800)
committergonglingqin <gonglingqin@loongson.cn>
Thu, 1 Dec 2022 01:40:50 +0000 (09:40 +0800)
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

12 files changed:
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

index fe29004..85635b0 100644 (file)
@@ -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
index 801872d..403dfe4 100644 (file)
@@ -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.
   }
 
index ad284f6..b16161b 100644 (file)
@@ -17,9 +17,51 @@ extern "C" {
 #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))
index e7d968a..9e38bee 100644 (file)
@@ -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)
index 8deed36..8c2bddc 100644 (file)
@@ -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}}
+}
index 9fc3746..702686f 100644 (file)
@@ -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:%.*]])
 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);
+}
index c11334d..8da6599 100644 (file)
@@ -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"
index c1b2b06..0d1645d 100644 (file)
@@ -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;
index 4f650fe..6f34284 100644 (file)
@@ -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
 
index 0da02c7..1a2fd2e 100644 (file)
@@ -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
index 15ddc51..9aeff0f 100644 (file)
@@ -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
+}
index a2eaa52..fd06313 100644 (file)
@@ -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
+}