diff --git a/clang/include/clang/Basic/BuiltinsLoongArch.def b/clang/include/clang/Basic/BuiltinsLoongArch.def --- a/clang/include/clang/Basic/BuiltinsLoongArch.def +++ b/clang/include/clang/Basic/BuiltinsLoongArch.def @@ -21,6 +21,9 @@ 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_cpucfg, "UiUi", "nc", "") +TARGET_BUILTIN(__builtin_loongarch_asrtle_d, "vLiLi", "nc", "64bit") +TARGET_BUILTIN(__builtin_loongarch_asrtgt_d, "vLiLi", "nc", "64bit") TARGET_BUILTIN(__builtin_loongarch_crc_w_b_w, "iii", "nc", "64bit") TARGET_BUILTIN(__builtin_loongarch_crc_w_h_w, "iii", "nc", "64bit") @@ -47,5 +50,8 @@ TARGET_BUILTIN(__builtin_loongarch_iocsrwr_w, "vUiUi", "nc", "") TARGET_BUILTIN(__builtin_loongarch_iocsrwr_d, "vULiUi", "nc", "64bit") +TARGET_BUILTIN(__builtin_loongarch_lddir_d, "LiLiIULi", "nc", "64bit") +TARGET_BUILTIN(__builtin_loongarch_ldpte_d, "vLiIULi", "nc", "64bit") + #undef BUILTIN #undef TARGET_BUILTIN diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -19724,6 +19724,21 @@ case LoongArch::BI__builtin_loongarch_iocsrwr_d: ID = Intrinsic::loongarch_iocsrwr_d; break; + case LoongArch::BI__builtin_loongarch_cpucfg: + ID = Intrinsic::loongarch_cpucfg; + break; + case LoongArch::BI__builtin_loongarch_asrtle_d: + ID = Intrinsic::loongarch_asrtle_d; + break; + case LoongArch::BI__builtin_loongarch_asrtgt_d: + ID = Intrinsic::loongarch_asrtgt_d; + break; + case LoongArch::BI__builtin_loongarch_lddir_d: + ID = Intrinsic::loongarch_lddir_d; + break; + case LoongArch::BI__builtin_loongarch_ldpte_d: + ID = Intrinsic::loongarch_ldpte_d; + break; // TODO: Support more Intrinsics. } diff --git a/clang/lib/Headers/larchintrin.h b/clang/lib/Headers/larchintrin.h --- a/clang/lib/Headers/larchintrin.h +++ b/clang/lib/Headers/larchintrin.h @@ -139,12 +139,38 @@ __builtin_loongarch_iocsrwr_w((unsigned int)_1, (unsigned int)_2); } +extern __inline unsigned int + __attribute__((__gnu_inline__, __always_inline__, __artificial__)) + __cpucfg(unsigned int _1) { + return (unsigned int)__builtin_loongarch_cpucfg((unsigned int)_1); +} + #if __loongarch_grlen == 64 extern __inline void __attribute__((__gnu_inline__, __always_inline__, __artificial__)) __iocsrwr_d(unsigned long int _1, unsigned int _2) { __builtin_loongarch_iocsrwr_d((unsigned long int)_1, (unsigned int)_2); } + +extern __inline void + __attribute__((__gnu_inline__, __always_inline__, __artificial__)) + __asrtgt_d(long int _1, long int _2) { + __builtin_loongarch_asrtgt_d((long int)_1, (long int)_2); +} + +extern __inline void + __attribute__((__gnu_inline__, __always_inline__, __artificial__)) + __asrtle_d(long int _1, long int _2) { + __builtin_loongarch_asrtle_d((long int)_1, (long int)_2); +} +#endif + +#if __loongarch_grlen == 64 +#define __lddir_d(/*long int*/ _1, /*ui5*/ _2) \ + ((long int)__builtin_loongarch_lddir_d((long int)(_1), (_2))) + +#define __ldpte_d(/*long int*/ _1, /*ui5*/ _2) \ + ((void)__builtin_loongarch_ldpte_d((long int)(_1), (_2))) #endif #ifdef __cplusplus diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -3715,6 +3715,8 @@ case LoongArch::BI__builtin_loongarch_crcc_w_d_w: case LoongArch::BI__builtin_loongarch_iocsrrd_d: case LoongArch::BI__builtin_loongarch_iocsrwr_d: + case LoongArch::BI__builtin_loongarch_asrtle_d: + case LoongArch::BI__builtin_loongarch_asrtgt_d: if (!TI.hasFeature("64bit")) return Diag(TheCall->getBeginLoc(), diag::err_loongarch_builtin_requires_la64) @@ -3750,6 +3752,13 @@ diag::err_loongarch_builtin_requires_la64) << TheCall->getSourceRange(); return SemaBuiltinConstantArgRange(TheCall, 2, 0, 16383); + case LoongArch::BI__builtin_loongarch_lddir_d: + case LoongArch::BI__builtin_loongarch_ldpte_d: + if (!TI.hasFeature("64bit")) + return Diag(TheCall->getBeginLoc(), + diag::err_loongarch_builtin_requires_la64) + << TheCall->getSourceRange(); + return SemaBuiltinConstantArgRange(TheCall, 1, 0, 31); } return false; diff --git a/clang/test/CodeGen/LoongArch/intrinsic-la32-error.c b/clang/test/CodeGen/LoongArch/intrinsic-la32-error.c --- a/clang/test/CodeGen/LoongArch/intrinsic-la32-error.c +++ b/clang/test/CodeGen/LoongArch/intrinsic-la32-error.c @@ -95,3 +95,19 @@ void iocsrwr_d(unsigned long int a, unsigned int b) { __builtin_loongarch_iocsrwr_d(a, b); // expected-error {{this builtin requires target: loongarch64}} } + +void asrtle_d(long int a, long int b) { + __builtin_loongarch_asrtle_d(a, b); // expected-error {{this builtin requires target: loongarch64}} +} + +void asrtgt_d(long int a, long int b) { + __builtin_loongarch_asrtgt_d(a, b); // expected-error {{this builtin requires target: loongarch64}} +} + +void lddir_d(long int a, int b) { + __builtin_loongarch_lddir_d(a, 1); // expected-error {{this builtin requires target: loongarch64}} +} + +void ldpte_d(long int a, int b) { + __builtin_loongarch_ldpte_d(a, 1); // expected-error {{this builtin requires target: loongarch64}} +} diff --git a/clang/test/CodeGen/LoongArch/intrinsic-la32.c b/clang/test/CodeGen/LoongArch/intrinsic-la32.c --- a/clang/test/CodeGen/LoongArch/intrinsic-la32.c +++ b/clang/test/CodeGen/LoongArch/intrinsic-la32.c @@ -154,3 +154,15 @@ __iocsrwr_w(a, b); __builtin_loongarch_iocsrwr_w(a, b); } + +// LA32-LABEL: @cpucfg( +// LA32-NEXT: entry: +// LA32-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.loongarch.cpucfg(i32 [[A:%.*]]) +// LA32-NEXT: [[TMP1:%.*]] = tail call i32 @llvm.loongarch.cpucfg(i32 [[A]]) +// LA32-NEXT: ret i32 0 +// +unsigned int cpucfg(unsigned int a) { + unsigned int b = __cpucfg(a); + unsigned int c = __builtin_loongarch_cpucfg(a); + return 0; +} diff --git a/clang/test/CodeGen/LoongArch/intrinsic-la64-error.c b/clang/test/CodeGen/LoongArch/intrinsic-la64-error.c --- a/clang/test/CodeGen/LoongArch/intrinsic-la64-error.c +++ b/clang/test/CodeGen/LoongArch/intrinsic-la64-error.c @@ -20,3 +20,15 @@ __builtin_loongarch_csrxchg_d(a, b, -1); // expected-error {{argument value 4294967295 is outside the valid range [0, 16383]}} __builtin_loongarch_csrxchg_d(a, b, b); // expected-error {{argument to '__builtin_loongarch_csrxchg_d' must be a constant integer}} } + +void lddir_d(long int a, int b) { + __builtin_loongarch_lddir_d(a, 32); // expected-error {{argument value 32 is outside the valid range [0, 31]}} + __builtin_loongarch_lddir_d(a, -1); // expected-error {{argument value 18446744073709551615 is outside the valid range [0, 31]}} + __builtin_loongarch_lddir_d(a, b); // expected-error {{argument to '__builtin_loongarch_lddir_d' must be a constant integer}} +} + +void ldpte_d(long int a, int b) { + __builtin_loongarch_ldpte_d(a, 32); // expected-error {{argument value 32 is outside the valid range [0, 31]}} + __builtin_loongarch_ldpte_d(a, -1); // expected-error {{argument value 18446744073709551615 is outside the valid range [0, 31]}} + __builtin_loongarch_ldpte_d(a, b); // expected-error {{argument to '__builtin_loongarch_ldpte_d' must be a constant integer}} +} diff --git a/clang/test/CodeGen/LoongArch/intrinsic-la64.c b/clang/test/CodeGen/LoongArch/intrinsic-la64.c --- a/clang/test/CodeGen/LoongArch/intrinsic-la64.c +++ b/clang/test/CodeGen/LoongArch/intrinsic-la64.c @@ -316,3 +316,60 @@ __iocsrwr_d(a, b); __builtin_loongarch_iocsrwr_d(a, b); } + +// CHECK-LABEL: @asrtle_d( +// CHECK-NEXT: entry: +// CHECK-NEXT: tail call void @llvm.loongarch.asrtle.d(i64 [[A:%.*]], i64 [[B:%.*]]) +// CHECK-NEXT: tail call void @llvm.loongarch.asrtle.d(i64 [[A]], i64 [[B]]) +// CHECK-NEXT: ret void +// +void asrtle_d(long int a, long int b) { + __asrtle_d(a, b); + __builtin_loongarch_asrtle_d(a, b); +} + +// CHECK-LABEL: @asrtgt_d( +// CHECK-NEXT: entry: +// CHECK-NEXT: tail call void @llvm.loongarch.asrtgt.d(i64 [[A:%.*]], i64 [[B:%.*]]) +// CHECK-NEXT: tail call void @llvm.loongarch.asrtgt.d(i64 [[A]], i64 [[B]]) +// CHECK-NEXT: ret void +// +void asrtgt_d(long int a, long int b) { + __asrtgt_d(a, b); + __builtin_loongarch_asrtgt_d(a, b); +} + +// CHECK-LABEL: @lddir_d( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call i64 @llvm.loongarch.lddir.d(i64 [[A:%.*]], i64 1) +// CHECK-NEXT: [[TMP1:%.*]] = tail call i64 @llvm.loongarch.lddir.d(i64 [[A]], i64 1) +// CHECK-NEXT: ret i64 0 +// +long int lddir_d(long int a) { + long int b = __lddir_d(a, 1); + long int c = __builtin_loongarch_lddir_d(a, 1); + return 0; +} + +// CHECK-LABEL: @ldpte_d( +// CHECK-NEXT: entry: +// CHECK-NEXT: tail call void @llvm.loongarch.ldpte.d(i64 [[A:%.*]], i64 1) +// CHECK-NEXT: tail call void @llvm.loongarch.ldpte.d(i64 [[A]], i64 1) +// CHECK-NEXT: ret void +// +void ldpte_d(long int a) { + __ldpte_d(a, 1); + __builtin_loongarch_ldpte_d(a, 1); +} + +// CHECK-LABEL: @cpucfg( +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.loongarch.cpucfg(i32 [[A:%.*]]) +// CHECK-NEXT: [[TMP1:%.*]] = tail call i32 @llvm.loongarch.cpucfg(i32 [[A]]) +// CHECK-NEXT: ret i32 0 +// +unsigned int cpucfg(unsigned int a) { + unsigned int b = __cpucfg(a); + unsigned int c = __builtin_loongarch_cpucfg(a); + return 0; +} diff --git a/llvm/include/llvm/IR/IntrinsicsLoongArch.td b/llvm/include/llvm/IR/IntrinsicsLoongArch.td --- a/llvm/include/llvm/IR/IntrinsicsLoongArch.td +++ b/llvm/include/llvm/IR/IntrinsicsLoongArch.td @@ -102,4 +102,15 @@ def int_loongarch_iocsrwr_h : Intrinsic<[], [llvm_i32_ty, llvm_i32_ty]>; def int_loongarch_iocsrwr_w : Intrinsic<[], [llvm_i32_ty, llvm_i32_ty]>; def int_loongarch_iocsrwr_d : Intrinsic<[], [llvm_i64_ty, llvm_i32_ty]>; + +def int_loongarch_cpucfg : Intrinsic<[llvm_i32_ty], [llvm_i32_ty]>; + +def int_loongarch_asrtle_d : Intrinsic<[], [llvm_i64_ty, llvm_i64_ty]>; +def int_loongarch_asrtgt_d : Intrinsic<[], [llvm_i64_ty, llvm_i64_ty]>; + +def int_loongarch_lddir_d : Intrinsic<[llvm_i64_ty], + [llvm_i64_ty, llvm_i64_ty], + [ImmArg>]>; +def int_loongarch_ldpte_d : Intrinsic<[], [llvm_i64_ty, llvm_i64_ty], + [ImmArg>]>; } // TargetPrefix = "loongarch" diff --git a/llvm/lib/Target/LoongArch/LoongArchISelLowering.h b/llvm/lib/Target/LoongArch/LoongArchISelLowering.h --- a/llvm/lib/Target/LoongArch/LoongArchISelLowering.h +++ b/llvm/lib/Target/LoongArch/LoongArchISelLowering.h @@ -88,6 +88,9 @@ IOCSRWR_H, IOCSRWR_W, IOCSRWR_D, + + // Read CPU configuration information operation + CPUCFG, }; } // end namespace LoongArchISD diff --git a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp --- a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp +++ b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp @@ -95,6 +95,7 @@ setOperationAction(ISD::CTLZ, MVT::i32, Custom); setOperationAction(ISD::INTRINSIC_VOID, MVT::i32, Custom); setOperationAction(ISD::INTRINSIC_W_CHAIN, MVT::i32, Custom); + setOperationAction(ISD::INTRINSIC_W_CHAIN, MVT::Other, Custom); setOperationAction(ISD::READ_REGISTER, MVT::i32, Custom); setOperationAction(ISD::WRITE_REGISTER, MVT::i32, Custom); if (Subtarget.hasBasicF() && !Subtarget.hasBasicD()) @@ -687,6 +688,22 @@ IOCSRRD_CASE(iocsrrd_h, IOCSRRD_H); IOCSRRD_CASE(iocsrrd_w, IOCSRRD_W); #undef IOCSRRD_CASE + case Intrinsic::loongarch_cpucfg: { + return DAG.getMergeValues( + {DAG.getNode(LoongArchISD::CPUCFG, DL, GRLenVT, Op0, Op.getOperand(2)), + Op0}, + DL); + } + case Intrinsic::loongarch_lddir_d: { + unsigned Imm = cast(Op.getOperand(3))->getZExtValue(); + if (!isUInt<8>(Imm)) { + DAG.getContext()->emitError("argument to '" + Op->getOperationName(0) + + "' out of range"); + return DAG.getMergeValues({DAG.getUNDEF(Op.getValueType()), Op0}, DL); + } + + return Op; + } } } @@ -769,6 +786,29 @@ return Op.getOperand(0); } } +#define ASRT_LE_GT_CASE(NAME) \ + case Intrinsic::loongarch_##NAME: { \ + if (!Subtarget.is64Bit()) { \ + DAG.getContext()->emitError(Op->getOperationName(0) + \ + " requires target: loongarch64"); \ + return Op.getOperand(0); \ + } \ + return Op; \ + } + ASRT_LE_GT_CASE(asrtle_d) + ASRT_LE_GT_CASE(asrtgt_d) +#undef ASRT_LE_GT_CASE + case Intrinsic::loongarch_ldpte_d: { + unsigned Imm = cast(Op.getOperand(3))->getZExtValue(); + if (!isUInt<8>(Imm)) + return emitIntrinsicErrorMessage(Op, ErrorMsgOOR, DAG); + if (!Subtarget.is64Bit()) { + DAG.getContext()->emitError(Op->getOperationName(0) + + " requires target: loongarch64"); + return Op.getOperand(0); + } + return Op; + } } } @@ -1159,6 +1199,24 @@ IOCSRRD_CASE(iocsrrd_h, IOCSRRD_H); IOCSRRD_CASE(iocsrrd_w, IOCSRRD_W); #undef IOCSRRD_CASE + case Intrinsic::loongarch_cpucfg: { + Results.push_back(DAG.getNode( + ISD::TRUNCATE, DL, VT, + DAG.getNode(LoongArchISD::CPUCFG, DL, GRLenVT, Op0, + DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i64, Op2)))); + Results.push_back(Op0); + break; + } + case Intrinsic::loongarch_lddir_d: { + if (!Subtarget.is64Bit()) { + DAG.getContext()->emitError(N->getOperationName(0) + + " requires target: loongarch64"); + Results.push_back(DAG.getUNDEF(VT)); + Results.push_back(Op0); + break; + } + break; + } } break; } @@ -1651,6 +1709,7 @@ NODE_NAME_CASE(IOCSRWR_H) NODE_NAME_CASE(IOCSRWR_W) NODE_NAME_CASE(IOCSRWR_D) + NODE_NAME_CASE(CPUCFG) } #undef NODE_NAME_CASE return nullptr; diff --git a/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td b/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td --- a/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td +++ b/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td @@ -131,6 +131,8 @@ def loongarch_iocsrwr_d : SDNode<"LoongArchISD::IOCSRWR_D", SDT_LoongArchIocsrwr, [SDNPHasChain, SDNPSideEffect]>; +def loongarch_cpucfg : SDNode<"LoongArchISD::CPUCFG", SDTUnaryOp, + [SDNPHasChain, SDNPSideEffect]>; //===----------------------------------------------------------------------===// // Operand and SDNode transformation definitions. @@ -194,7 +196,7 @@ let ParserMatchClass = UImmAsmOperand<6>; } -def uimm8 : Operand { +def uimm8 : Operand, ImmLeaf(Imm);}]> { let ParserMatchClass = UImmAsmOperand<8>; } @@ -1700,7 +1702,17 @@ def : Pat<(loongarch_iocsrwr_h GPR:$rd, GPR:$rj), (IOCSRWR_H GPR:$rd, GPR:$rj)>; def : Pat<(loongarch_iocsrwr_w GPR:$rd, GPR:$rj), (IOCSRWR_W GPR:$rd, GPR:$rj)>; +def : Pat<(loongarch_cpucfg GPR:$rj), (CPUCFG GPR:$rj)>; + let Predicates = [IsLA64] in { def : Pat<(loongarch_iocsrrd_d GPR:$rj), (IOCSRRD_D GPR:$rj)>; def : Pat<(loongarch_iocsrwr_d GPR:$rd, GPR:$rj), (IOCSRWR_D GPR:$rd, GPR:$rj)>; +def : Pat<(int_loongarch_asrtle_d GPR:$rj, GPR:$rk), + (ASRTLE_D GPR:$rj, GPR:$rk)>; +def : Pat<(int_loongarch_asrtgt_d GPR:$rj, GPR:$rk), + (ASRTGT_D GPR:$rj, GPR:$rk)>; +def : Pat<(int_loongarch_lddir_d GPR:$rj, timm:$imm8), + (LDDIR GPR:$rj, uimm8:$imm8)>; +def : Pat<(int_loongarch_ldpte_d GPR:$rj, timm:$imm8), + (LDPTE GPR:$rj, uimm8:$imm8)>; } // Predicates = [IsLA64] diff --git a/llvm/test/CodeGen/LoongArch/intrinsic-la32-error.ll b/llvm/test/CodeGen/LoongArch/intrinsic-la32-error.ll --- a/llvm/test/CodeGen/LoongArch/intrinsic-la32-error.ll +++ b/llvm/test/CodeGen/LoongArch/intrinsic-la32-error.ll @@ -13,6 +13,10 @@ declare i64 @llvm.loongarch.csrxchg.d(i64, i64, i32 immarg) declare i64 @llvm.loongarch.iocsrrd.d(i32) declare void @llvm.loongarch.iocsrwr.d(i64, i32) +declare void @llvm.loongarch.asrtle.d(i64, i64) +declare void @llvm.loongarch.asrtgt.d(i64, i64) +declare i64 @llvm.loongarch.lddir.d(i64, i32) +declare void @llvm.loongarch.ldpte.d(i64, i32) define i32 @crc_w_b_w(i32 %a, i32 %b) nounwind { ; CHECK: llvm.loongarch.crc.w.b.w requires target: loongarch64 @@ -104,3 +108,31 @@ tail call void @llvm.loongarch.iocsrwr.d(i64 %a, i32 %b) ret void } + +define void @asrtle_d(i64 %a, i64 %b) { +; CHECK: llvm.loongarch.asrtle.d requires target: loongarch64 +entry: + tail call void @llvm.loongarch.asrtle.d(i64 %a, i64 %b) + ret void +} + +define void @asrtgt_d(i64 %a, i64 %b) { +; CHECK: llvm.loongarch.asrtgt.d requires target: loongarch64 +entry: + tail call void @llvm.loongarch.asrtgt.d(i64 %a, i64 %b) + ret void +} + +define i64 @lddir_d(i64 %a) { +; CHECK: llvm.loongarch.lddir.d requires target: loongarch64 +entry: + %0 = tail call i64 @llvm.loongarch.lddir.d(i64 %a, i32 1) + ret i64 %0 +} + +define void @ldpte_d(i64 %a) { +; CHECK: llvm.loongarch.ldpte.d requires target: loongarch64 +entry: + tail call void @llvm.loongarch.ldpte.d(i64 %a, i32 1) + ret void +} diff --git a/llvm/test/CodeGen/LoongArch/intrinsic-la64.ll b/llvm/test/CodeGen/LoongArch/intrinsic-la64.ll --- a/llvm/test/CodeGen/LoongArch/intrinsic-la64.ll +++ b/llvm/test/CodeGen/LoongArch/intrinsic-la64.ll @@ -14,6 +14,10 @@ declare i64 @llvm.loongarch.csrxchg.d(i64, i64, i32 immarg) declare i64 @llvm.loongarch.iocsrrd.d(i32) declare void @llvm.loongarch.iocsrwr.d(i64, i32) +declare void @llvm.loongarch.asrtle.d(i64, i64) +declare void @llvm.loongarch.asrtgt.d(i64, i64) +declare i64 @llvm.loongarch.lddir.d(i64, i64) +declare void @llvm.loongarch.ldpte.d(i64, i64) define i32 @crc_w_b_w(i32 %a, i32 %b) nounwind { ; CHECK-LABEL: crc_w_b_w: @@ -136,3 +140,43 @@ tail call void @llvm.loongarch.iocsrwr.d(i64 %a, i32 %b) ret void } + +define void @asrtle_d(i64 %a, i64 %b) { +; CHECK-LABEL: asrtle_d: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: asrtle.d $a0, $a1 +; CHECK-NEXT: ret +entry: + tail call void @llvm.loongarch.asrtle.d(i64 %a, i64 %b) + ret void +} + +define void @asrtgt_d(i64 %a, i64 %b) { +; CHECK-LABEL: asrtgt_d: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: asrtgt.d $a0, $a1 +; CHECK-NEXT: ret +entry: + tail call void @llvm.loongarch.asrtgt.d(i64 %a, i64 %b) + ret void +} + +define i64 @lddir_d(i64 %a) { +; CHECK-LABEL: lddir_d: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: lddir $a0, $a0, 1 +; CHECK-NEXT: ret +entry: + %0 = tail call i64 @llvm.loongarch.lddir.d(i64 %a, i64 1) + ret i64 %0 +} + +define void @ldpte_d(i64 %a) { +; CHECK-LABEL: ldpte_d: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: ldpte $a0, 1 +; CHECK-NEXT: ret +entry: + tail call void @llvm.loongarch.ldpte.d(i64 %a, i64 1) + ret void +} diff --git a/llvm/test/CodeGen/LoongArch/intrinsic.ll b/llvm/test/CodeGen/LoongArch/intrinsic.ll --- a/llvm/test/CodeGen/LoongArch/intrinsic.ll +++ b/llvm/test/CodeGen/LoongArch/intrinsic.ll @@ -15,6 +15,7 @@ declare void @llvm.loongarch.iocsrwr.b(i32, i32) declare void @llvm.loongarch.iocsrwr.h(i32, i32) declare void @llvm.loongarch.iocsrwr.w(i32, i32) +declare i32 @llvm.loongarch.cpucfg(i32) define void @foo() nounwind { ; CHECK-LABEL: foo: @@ -145,3 +146,13 @@ tail call void @llvm.loongarch.iocsrwr.w(i32 %a, i32 %b) ret void } + +define i32 @cpucfg(i32 %a) { +; CHECK-LABEL: cpucfg: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: cpucfg $a0, $a0 +; CHECK-NEXT: ret +entry: + %0 = tail call i32 @llvm.loongarch.cpucfg(i32 %a) + ret i32 %0 +}