[clang] aeb8f91 - [Clang][LoongArch] Add intrinsic for asrtle, asrtgt, lddir, ldpte and cpucfg

via cfe-commits cfe-commits at lists.llvm.org
Thu Dec 22 03:17:40 PST 2022


Author: gonglingqin
Date: 2022-12-22T18:56:34+08:00
New Revision: aeb8f911b1695778aa518db4bed471e8447dc57f

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

LOG: [Clang][LoongArch] Add intrinsic for asrtle, asrtgt, lddir, ldpte and cpucfg

`__cpucfg` is required by Linux [1].

[1]: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/loongarch/include/asm/loongarch.h#n59

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

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-la32-error.c
    clang/test/CodeGen/LoongArch/intrinsic-la32.c
    clang/test/CodeGen/LoongArch/intrinsic-la64-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
    llvm/test/CodeGen/LoongArch/intrinsic.ll

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/Basic/BuiltinsLoongArch.def b/clang/include/clang/Basic/BuiltinsLoongArch.def
index 5b0dd799a4bc..98b1738b7223 100644
--- a/clang/include/clang/Basic/BuiltinsLoongArch.def
+++ b/clang/include/clang/Basic/BuiltinsLoongArch.def
@@ -21,6 +21,9 @@ TARGET_BUILTIN(__builtin_loongarch_dbar, "vIUi", "nc", "")
 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_h, "vUiUi", "nc", "")
 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
index fc7b73d9ee6e..a194fc7b105c 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -19724,6 +19724,21 @@ Value *CodeGenFunction::EmitLoongArchBuiltinExpr(unsigned BuiltinID,
   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
index 787b7b8deda2..22e6d4025c98 100644
--- a/clang/lib/Headers/larchintrin.h
+++ b/clang/lib/Headers/larchintrin.h
@@ -139,12 +139,38 @@ extern __inline void
   __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
index d009d55c1c2c..67c4ea581229 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -3715,6 +3715,8 @@ bool Sema::CheckLoongArchBuiltinFunctionCall(const TargetInfo &TI,
   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 @@ bool Sema::CheckLoongArchBuiltinFunctionCall(const TargetInfo &TI,
                   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
index be4f319e884d..56ac396624f2 100644
--- a/clang/test/CodeGen/LoongArch/intrinsic-la32-error.c
+++ b/clang/test/CodeGen/LoongArch/intrinsic-la32-error.c
@@ -95,3 +95,19 @@ unsigned long int iocsrrd_d(unsigned int a) {
 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
index 490082dc1d5a..529732ebf648 100644
--- a/clang/test/CodeGen/LoongArch/intrinsic-la32.c
+++ b/clang/test/CodeGen/LoongArch/intrinsic-la32.c
@@ -154,3 +154,15 @@ void iocsrwr_w(unsigned int a, unsigned int b) {
   __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
index b6e40446b14b..93294af03af2 100644
--- a/clang/test/CodeGen/LoongArch/intrinsic-la64-error.c
+++ b/clang/test/CodeGen/LoongArch/intrinsic-la64-error.c
@@ -20,3 +20,15 @@ void csrxchg_d(unsigned long int a, unsigned long int b) {
   __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
index 4497fae66a75..11f54087fab1 100644
--- a/clang/test/CodeGen/LoongArch/intrinsic-la64.c
+++ b/clang/test/CodeGen/LoongArch/intrinsic-la64.c
@@ -316,3 +316,60 @@ void iocsrwr_d(unsigned long int a, unsigned int b) {
   __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
index 8fc20d98d484..ec3c2402849d 100644
--- a/llvm/include/llvm/IR/IntrinsicsLoongArch.td
+++ b/llvm/include/llvm/IR/IntrinsicsLoongArch.td
@@ -102,4 +102,15 @@ def int_loongarch_iocsrwr_b : Intrinsic<[], [llvm_i32_ty, llvm_i32_ty]>;
 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<ArgIndex<1>>]>;
+def int_loongarch_ldpte_d : Intrinsic<[], [llvm_i64_ty, llvm_i64_ty],
+                                          [ImmArg<ArgIndex<1>>]>;
 } // TargetPrefix = "loongarch"

diff  --git a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
index 08d2730698ca..2268e5e3f443 100644
--- a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
+++ b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
@@ -95,6 +95,7 @@ LoongArchTargetLowering::LoongArchTargetLowering(const TargetMachine &TM,
     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 @@ LoongArchTargetLowering::lowerINTRINSIC_W_CHAIN(SDValue Op,
     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<ConstantSDNode>(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 @@ SDValue LoongArchTargetLowering::lowerINTRINSIC_VOID(SDValue Op,
       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<ConstantSDNode>(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 @@ void LoongArchTargetLowering::ReplaceNodeResults(
       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 @@ const char *LoongArchTargetLowering::getTargetNodeName(unsigned Opcode) const {
     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/LoongArchISelLowering.h b/llvm/lib/Target/LoongArch/LoongArchISelLowering.h
index e9177e5c1fd2..858cd05ba931 100644
--- a/llvm/lib/Target/LoongArch/LoongArchISelLowering.h
+++ b/llvm/lib/Target/LoongArch/LoongArchISelLowering.h
@@ -88,6 +88,9 @@ enum NodeType : unsigned {
   IOCSRWR_H,
   IOCSRWR_W,
   IOCSRWR_D,
+
+  // Read CPU configuration information operation
+  CPUCFG,
 };
 } // end namespace LoongArchISD
 

diff  --git a/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td b/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td
index e139ceeaba11..e15579276378 100644
--- a/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td
+++ b/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td
@@ -131,6 +131,8 @@ def loongarch_iocsrwr_w : SDNode<"LoongArchISD::IOCSRWR_W",
 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 @@ def uimm6 : Operand<GRLenVT>, ImmLeaf<GRLenVT, [{return isUInt<6>(Imm);}]> {
   let ParserMatchClass = UImmAsmOperand<6>;
 }
 
-def uimm8 : Operand<GRLenVT> {
+def uimm8 : Operand<GRLenVT>, ImmLeaf<GRLenVT, [{return isUInt<8>(Imm);}]> {
   let ParserMatchClass = UImmAsmOperand<8>;
 }
 
@@ -1700,7 +1702,17 @@ def : Pat<(loongarch_iocsrwr_b GPR:$rd, GPR:$rj), (IOCSRWR_B GPR:$rd, GPR:$rj)>;
 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
index 3bbeb13df034..c4910ccad4d5 100644
--- 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.csrwr.d(i64, i32 immarg)
 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 @@ entry:
   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
index b2ad3776fdc4..1ec55f341629 100644
--- a/llvm/test/CodeGen/LoongArch/intrinsic-la64.ll
+++ b/llvm/test/CodeGen/LoongArch/intrinsic-la64.ll
@@ -14,6 +14,10 @@ declare i64 @llvm.loongarch.csrwr.d(i64, i32 immarg)
 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 @@ entry:
   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
index b3bf8159ce0a..4f5887a9936d 100644
--- a/llvm/test/CodeGen/LoongArch/intrinsic.ll
+++ b/llvm/test/CodeGen/LoongArch/intrinsic.ll
@@ -15,6 +15,7 @@ declare i32 @llvm.loongarch.iocsrrd.w(i32)
 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 @@ entry:
   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
+}


        


More information about the cfe-commits mailing list