diff --git a/clang/include/clang/Basic/BuiltinsLoongArch.def b/clang/include/clang/Basic/BuiltinsLoongArch.def index fe2900497a500b..85635b0b12424e 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 801872dd700af7..403dfe4ff6e87c 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 ad284f62d815d0..b16161b7cabc6d 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 e7d968a93007c0..9e38bee2ef03a7 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 8deed3693b2549..8c2bddc362bfef 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 9fc37460a5efc7..702686f5e6d3e5 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 c11334da929c9a..8da6599bf9eb54 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 c1b2b06a46222d..0d1645d5f0ea1f 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 4f650feee47a0d..6f34284ccec539 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 0da02c70102c60..1a2fd2ebdc7e67 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 15ddc51087657d..9aeff0f57ffd60 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 a2eaa529828013..fd06313a37c4ae 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 +}