From 624401612c3ae1b3e96a691ac37631fb10197313 Mon Sep 17 00:00:00 2001 From: gonglingqin Date: Thu, 1 Dec 2022 09:18:00 +0800 Subject: [PATCH] [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 --- clang/include/clang/Basic/BuiltinsLoongArch.def | 7 +++ clang/lib/CodeGen/CGBuiltin.cpp | 27 ++++++++- clang/lib/Headers/larchintrin.h | 42 +++++++++++++ clang/lib/Sema/SemaChecking.cpp | 7 +++ clang/test/CodeGen/LoongArch/intrinsic-error.c | 35 +++++++++-- clang/test/CodeGen/LoongArch/intrinsic-la64.c | 63 +++++++++++++++++++ llvm/include/llvm/IR/IntrinsicsLoongArch.td | 15 +++++ .../lib/Target/LoongArch/LoongArchISelLowering.cpp | 61 +++++++++++++++---- llvm/lib/Target/LoongArch/LoongArchISelLowering.h | 9 ++- llvm/lib/Target/LoongArch/LoongArchInstrInfo.td | 21 +++++++ .../test/CodeGen/LoongArch/intrinsic-la32-error.ll | 56 +++++++++++++++++ llvm/test/CodeGen/LoongArch/intrinsic-la64.ll | 70 ++++++++++++++++++++++ 12 files changed, 393 insertions(+), 20 deletions(-) diff --git a/clang/include/clang/Basic/BuiltinsLoongArch.def b/clang/include/clang/Basic/BuiltinsLoongArch.def index fe29004..85635b0 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 801872d..403dfe4 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 ad284f6..b16161b 100644 --- a/clang/lib/Headers/larchintrin.h +++ b/clang/lib/Headers/larchintrin.h @@ -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)) diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index e7d968a..9e38bee 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 8deed36..8c2bddc 100644 --- a/clang/test/CodeGen/LoongArch/intrinsic-error.c +++ b/clang/test/CodeGen/LoongArch/intrinsic-error.c @@ -3,10 +3,6 @@ #include -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 9fc3746..702686f 100644 --- a/clang/test/CodeGen/LoongArch/intrinsic-la64.c +++ b/clang/test/CodeGen/LoongArch/intrinsic-la64.c @@ -3,6 +3,33 @@ #include +// 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 c11334d..8da6599 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>]>; def int_loongarch_ibar : Intrinsic<[], [llvm_i32_ty], [ImmArg>]>; def int_loongarch_syscall : Intrinsic<[], [llvm_i32_ty], [ImmArg>]>; +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 c1b2b06..0d1645d 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 4f650fe..6f34284 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 0da02c7..1a2fd2e 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; +def : PatGprGpr; +def : PatGprGpr; def : PatGprGpr; +def : PatGprGpr; +def : PatGprGpr; +def : PatGprGpr; +def : PatGprGpr; } // 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 15ddc51..9aeff0f 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 a2eaa52..fd06313 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 +} -- 2.7.4