gonglingqin updated this revision to Diff 473561.
gonglingqin added a comment.
Address @SixWeining's comments.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D136906/new/
https://reviews.llvm.org/D136906
Files:
clang/include/clang/Basic/BuiltinsLoongArch.def
clang/include/clang/Basic/TargetBuiltins.h
clang/include/clang/module.modulemap
clang/lib/Basic/Targets/LoongArch.cpp
clang/lib/Basic/Targets/LoongArch.h
clang/lib/CodeGen/CGBuiltin.cpp
clang/lib/CodeGen/CodeGenFunction.h
clang/lib/Headers/CMakeLists.txt
clang/lib/Headers/larchintrin.h
clang/test/CodeGen/LoongArch/intrinsic.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-error.ll
llvm/test/CodeGen/LoongArch/intrinsic.ll
Index: llvm/test/CodeGen/LoongArch/intrinsic.ll
===================================================================
--- /dev/null
+++ llvm/test/CodeGen/LoongArch/intrinsic.ll
@@ -0,0 +1,15 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc --mtriple=loongarch32 < %s | FileCheck %s
+; RUN: llc --mtriple=loongarch64 < %s | FileCheck %s
+
+declare void @llvm.loongarch.dbar(i32)
+
+define void @foo() nounwind {
+; CHECK-LABEL: foo:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: dbar 0
+; CHECK-NEXT: ret
+entry:
+ call void @llvm.loongarch.dbar(i32 0)
+ ret void
+}
Index: llvm/test/CodeGen/LoongArch/intrinsic-error.ll
===================================================================
--- /dev/null
+++ llvm/test/CodeGen/LoongArch/intrinsic-error.ll
@@ -0,0 +1,10 @@
+; RUN: not llc --mtriple=loongarch64 --disable-verify < %s 2>&1 | FileCheck %s
+
+define void @foo(i32 %x) nounwind {
+; CHECK: argument to '__builtin_loongarch_dbar' must be a constant integer
+entry:
+ call void @llvm.loongarch.dbar(i32 %x)
+ ret void
+}
+
+declare void @llvm.loongarch.dbar(i32)
Index: llvm/lib/Target/LoongArch/LoongArchInstrInfo.td
===================================================================
--- llvm/lib/Target/LoongArch/LoongArchInstrInfo.td
+++ llvm/lib/Target/LoongArch/LoongArchInstrInfo.td
@@ -35,6 +35,8 @@
SDTCisInt<0>, SDTCisSameAs<0, 1>, SDTCisInt<2>, SDTCisSameAs<2, 3>
]>;
+def SDT_LoongArchDBAR : SDTypeProfile<0, 1, [SDTCisVT<0, GRLenVT>]>;
+
// TODO: Add LoongArch specific DAG Nodes
// Target-independent nodes, but with target-specific formats.
def callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_CallSeqStart,
@@ -63,6 +65,8 @@
def loongarch_bitrev_w : SDNode<"LoongArchISD::BITREV_W", SDTUnaryOp>;
def loongarch_clzw : SDNode<"LoongArchISD::CLZ_W", SDTIntBitCountUnaryOp>;
def loongarch_ctzw : SDNode<"LoongArchISD::CTZ_W", SDTIntBitCountUnaryOp>;
+def loongarch_dbar : SDNode<"LoongArchISD::DBAR", SDT_LoongArchDBAR,
+ [SDNPHasChain, SDNPSideEffect]>;
//===----------------------------------------------------------------------===//
// Operand and SDNode transformation definitions.
@@ -130,7 +134,8 @@
let ParserMatchClass = UImmAsmOperand<14>;
}
-def uimm15 : Operand<GRLenVT> {
+def uimm15 : Operand<GRLenVT>,
+ ImmLeaf <GRLenVT, [{return isUInt<15>(Imm);}]> {
let ParserMatchClass = UImmAsmOperand<15>;
}
@@ -1261,6 +1266,16 @@
(PseudoAtomicLoadXor32 GPR:$incr, GPR:$addr)>;
} // Predicates = [IsLA32]
+/// Intrinsics
+
+let Predicates = [IsLA32] in {
+def : Pat<(int_loongarch_dbar uimm15:$imm15), (DBAR uimm15:$imm15)>;
+} // Predicates = [IsLA32]
+
+let Predicates = [IsLA64] in {
+def : Pat<(loongarch_dbar uimm15:$imm15), (DBAR uimm15:$imm15)>;
+} // Predicates = [IsLA64]
+
/// Other pseudo-instructions
// Pessimistically assume the stack pointer will be clobbered
Index: llvm/lib/Target/LoongArch/LoongArchISelLowering.h
===================================================================
--- llvm/lib/Target/LoongArch/LoongArchISelLowering.h
+++ llvm/lib/Target/LoongArch/LoongArchISelLowering.h
@@ -56,6 +56,9 @@
REVB_2W,
BITREV_4B,
BITREV_W,
+
+ // Intrinsic operations
+ DBAR,
};
} // end namespace LoongArchISD
@@ -162,6 +165,7 @@
SDValue lowerUINT_TO_FP(SDValue Op, SelectionDAG &DAG) const;
SDValue lowerVASTART(SDValue Op, SelectionDAG &DAG) const;
SDValue lowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG) const;
+ SDValue lowerINTRINSIC_VOID(SDValue Op, SelectionDAG &DAG) const;
SDValue lowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const;
SDValue lowerRETURNADDR(SDValue Op, SelectionDAG &DAG) const;
Index: llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
===================================================================
--- llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
+++ llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
@@ -87,6 +87,7 @@
setOperationAction(ISD::ROTL, MVT::i32, Custom);
setOperationAction(ISD::CTTZ, MVT::i32, Custom);
setOperationAction(ISD::CTLZ, MVT::i32, Custom);
+ setOperationAction(ISD::INTRINSIC_VOID, MVT::i32, Custom);
if (Subtarget.hasBasicF() && !Subtarget.hasBasicD())
setOperationAction(ISD::FP_TO_UINT, MVT::i32, Custom);
if (Subtarget.hasBasicF())
@@ -202,6 +203,8 @@
return lowerGlobalTLSAddress(Op, DAG);
case ISD::INTRINSIC_WO_CHAIN:
return lowerINTRINSIC_WO_CHAIN(Op, DAG);
+ case ISD::INTRINSIC_VOID:
+ return lowerINTRINSIC_VOID(Op, DAG);
case ISD::BlockAddress:
return lowerBlockAddress(Op, DAG);
case ISD::JumpTable:
@@ -503,6 +506,30 @@
}
}
+SDValue LoongArchTargetLowering::lowerINTRINSIC_VOID(SDValue Op,
+ SelectionDAG &DAG) const {
+ SDLoc DL(Op);
+
+ switch (Op.getConstantOperandVal(1)) {
+ default:
+ // TODO: Add more Intrinsics.
+ return SDValue();
+ case Intrinsic::loongarch_dbar: {
+ SDValue Op2 = Op.getOperand(2);
+ if (!isa<ConstantSDNode>(Op2)) {
+ DAG.getContext()->emitError("argument to '__builtin_loongarch_dbar' must "
+ "be a constant integer");
+ return Op.getOperand(0);
+ }
+
+ return DAG.getNode(
+ LoongArchISD::DBAR, DL, MVT::Other, Op.getOperand(0),
+ DAG.getConstant(dyn_cast<ConstantSDNode>(Op2)->getZExtValue(), DL,
+ Subtarget.getGRLenVT()));
+ }
+ }
+}
+
SDValue LoongArchTargetLowering::lowerShiftLeftParts(SDValue Op,
SelectionDAG &DAG) const {
SDLoc DL(Op);
@@ -1226,6 +1253,7 @@
NODE_NAME_CASE(ROTL_W)
NODE_NAME_CASE(CLZ_W)
NODE_NAME_CASE(CTZ_W)
+ NODE_NAME_CASE(DBAR)
}
#undef NODE_NAME_CASE
return nullptr;
Index: llvm/include/llvm/IR/IntrinsicsLoongArch.td
===================================================================
--- llvm/include/llvm/IR/IntrinsicsLoongArch.td
+++ llvm/include/llvm/IR/IntrinsicsLoongArch.td
@@ -35,4 +35,6 @@
defm int_loongarch_masked_atomicrmw_nand : MaskedAtomicRMWIntrinsics;
defm int_loongarch_masked_atomicrmw_umax : MaskedAtomicRMWIntrinsics;
defm int_loongarch_masked_atomicrmw_umin : MaskedAtomicRMWIntrinsics;
+
+def int_loongarch_dbar : Intrinsic<[], [llvm_i32_ty]>;
} // TargetPrefix = "loongarch"
Index: clang/test/CodeGen/LoongArch/intrinsic.c
===================================================================
--- /dev/null
+++ clang/test/CodeGen/LoongArch/intrinsic.c
@@ -0,0 +1,22 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
+// RUN: %clang_cc1 -triple loongarch32 -emit-llvm %s -o - \
+// RUN: | FileCheck %s -check-prefix=LA32
+// RUN: %clang_cc1 -triple loongarch64 -emit-llvm %s -o - \
+// RUN: | FileCheck %s -check-prefix=LA64
+
+#include <larchintrin.h>
+
+// LA32-LABEL: @dbar(
+// LA32-NEXT: entry:
+// LA32-NEXT: call void @llvm.loongarch.dbar(i32 0)
+// LA32-NEXT: ret void
+//
+// LA64-LABEL: @dbar(
+// LA64-NEXT: entry:
+// LA64-NEXT: call void @llvm.loongarch.dbar(i32 0)
+// LA64-NEXT: ret void
+//
+void dbar() {
+ return __builtin_loongarch_dbar(0);
+}
+
Index: clang/lib/Headers/larchintrin.h
===================================================================
--- /dev/null
+++ clang/lib/Headers/larchintrin.h
@@ -0,0 +1,22 @@
+/*===------------ larchintrin.h - LoongArch intrinsics ---------------------===
+ *
+ * Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+ * See https://llvm.org/LICENSE.txt for license information.
+ * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+ *
+ *===-----------------------------------------------------------------------===
+ */
+
+#ifndef _LOONGARCH_BASE_INTRIN_H
+#define _LOONGARCH_BASE_INTRIN_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define __dbar(/*ui15*/ _1) __builtin_loongarch_dbar((_1))
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* _LOONGARCH_BASE_INTRIN_H */
Index: clang/lib/Headers/CMakeLists.txt
===================================================================
--- clang/lib/Headers/CMakeLists.txt
+++ clang/lib/Headers/CMakeLists.txt
@@ -74,6 +74,10 @@
${hlsl_subdir_files}
)
+set(loongarch_files
+ larchintrin.h
+ )
+
set(mips_msa_files
msa.h
)
@@ -229,6 +233,7 @@
${cuda_files}
${hexagon_files}
${hip_files}
+ ${loongarch_files}
${mips_msa_files}
${opencl_files}
${ppc_files}
@@ -413,6 +418,7 @@
add_header_target("cuda-resource-headers" "${cuda_files};${cuda_wrapper_files}")
add_header_target("hexagon-resource-headers" "${hexagon_files}")
add_header_target("hip-resource-headers" "${hip_files}")
+add_header_target("loongarch-resource-headers" "${loongarch_files}")
add_header_target("mips-resource-headers" "${mips_msa_files}")
add_header_target("ppc-resource-headers" "${ppc_files};${ppc_wrapper_files}")
add_header_target("ppc-htm-resource-headers" "${ppc_htm_files}")
@@ -503,6 +509,12 @@
EXCLUDE_FROM_ALL
COMPONENT hip-resource-headers)
+install(
+ FILES ${loongarch_files}
+ DESTINATION ${header_install_dir}
+ EXCLUDE_FROM_ALL
+ COMPONENT loongarch-resource-headers)
+
install(
FILES ${mips_msa_files}
DESTINATION ${header_install_dir}
Index: clang/lib/CodeGen/CodeGenFunction.h
===================================================================
--- clang/lib/CodeGen/CodeGenFunction.h
+++ clang/lib/CodeGen/CodeGenFunction.h
@@ -4259,6 +4259,7 @@
llvm::Value *EmitHexagonBuiltinExpr(unsigned BuiltinID, const CallExpr *E);
llvm::Value *EmitRISCVBuiltinExpr(unsigned BuiltinID, const CallExpr *E,
ReturnValueSlot ReturnValue);
+ llvm::Value *EmitLoongArchBuiltinExpr(unsigned BuiltinID, const CallExpr *E);
void ProcessOrderScopeAMDGCN(llvm::Value *Order, llvm::Value *Scope,
llvm::AtomicOrdering &AO,
llvm::SyncScope::ID &SSID);
Index: clang/lib/CodeGen/CGBuiltin.cpp
===================================================================
--- clang/lib/CodeGen/CGBuiltin.cpp
+++ clang/lib/CodeGen/CGBuiltin.cpp
@@ -41,6 +41,7 @@
#include "llvm/IR/IntrinsicsARM.h"
#include "llvm/IR/IntrinsicsBPF.h"
#include "llvm/IR/IntrinsicsHexagon.h"
+#include "llvm/IR/IntrinsicsLoongArch.h"
#include "llvm/IR/IntrinsicsNVPTX.h"
#include "llvm/IR/IntrinsicsPowerPC.h"
#include "llvm/IR/IntrinsicsR600.h"
@@ -5447,6 +5448,9 @@
case llvm::Triple::riscv32:
case llvm::Triple::riscv64:
return CGF->EmitRISCVBuiltinExpr(BuiltinID, E, ReturnValue);
+ case llvm::Triple::loongarch32:
+ case llvm::Triple::loongarch64:
+ return CGF->EmitLoongArchBuiltinExpr(BuiltinID, E);
default:
return nullptr;
}
@@ -19597,3 +19601,27 @@
llvm::Function *F = CGM.getIntrinsic(ID, IntrinsicTypes);
return Builder.CreateCall(F, Ops, "");
}
+
+Value *CodeGenFunction::EmitLoongArchBuiltinExpr(unsigned BuiltinID,
+ const CallExpr *E) {
+ SmallVector<Value *, 4> Ops;
+
+ for (unsigned i = 0, e = E->getNumArgs(); i != e; i++)
+ Ops.push_back(EmitScalarExpr(E->getArg(i)));
+
+ Intrinsic::ID ID = Intrinsic::not_intrinsic;
+
+ switch (BuiltinID) {
+ default:
+ llvm_unreachable("unexpected builtin ID.");
+ case LoongArch::BI__builtin_loongarch_dbar:
+ ID = Intrinsic::loongarch_dbar;
+ break;
+ // TODO: Support more Intrinsics.
+ }
+
+ assert(ID != Intrinsic::not_intrinsic);
+
+ llvm::Function *F = CGM.getIntrinsic(ID);
+ return Builder.CreateCall(F, Ops);
+}
Index: clang/lib/Basic/Targets/LoongArch.h
===================================================================
--- clang/lib/Basic/Targets/LoongArch.h
+++ clang/lib/Basic/Targets/LoongArch.h
@@ -26,6 +26,7 @@
std::string ABI;
bool HasFeatureD;
bool HasFeatureF;
+ static const Builtin::Info BuiltinInfo[];
public:
LoongArchTargetInfo(const llvm::Triple &Triple, const TargetOptions &)
Index: clang/lib/Basic/Targets/LoongArch.cpp
===================================================================
--- clang/lib/Basic/Targets/LoongArch.cpp
+++ clang/lib/Basic/Targets/LoongArch.cpp
@@ -156,9 +156,17 @@
}
}
+const Builtin::Info LoongArchTargetInfo::BuiltinInfo[] = {
+#define BUILTIN(ID, TYPE, ATTRS) \
+ {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr},
+#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \
+ {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, FEATURE},
+#include "clang/Basic/BuiltinsLoongArch.def"
+};
+
ArrayRef<Builtin::Info> LoongArchTargetInfo::getTargetBuiltins() const {
- // TODO: To be implemented in future.
- return {};
+ return llvm::makeArrayRef(BuiltinInfo, clang::LoongArch::LastTSBuiltin -
+ Builtin::FirstTSBuiltin);
}
bool LoongArchTargetInfo::handleTargetFeatures(
Index: clang/include/clang/module.modulemap
===================================================================
--- clang/include/clang/module.modulemap
+++ clang/include/clang/module.modulemap
@@ -42,6 +42,7 @@
textual header "Basic/BuiltinsHexagon.def"
textual header "Basic/BuiltinsHexagonDep.def"
textual header "Basic/BuiltinsHexagonMapCustomDep.def"
+ textual header "Basic/BuiltinsLoongArch.def"
textual header "Basic/BuiltinsMips.def"
textual header "Basic/BuiltinsNEON.def"
textual header "Basic/BuiltinsNVPTX.def"
Index: clang/include/clang/Basic/TargetBuiltins.h
===================================================================
--- clang/include/clang/Basic/TargetBuiltins.h
+++ clang/include/clang/Basic/TargetBuiltins.h
@@ -151,6 +151,16 @@
};
} // namespace RISCV
+ /// LoongArch builtins
+ namespace LoongArch {
+ enum {
+ LastTIBuiltin = clang::Builtin::FirstTSBuiltin - 1,
+#define BUILTIN(ID, TYPE, ATTRS) BI##ID,
+#include "clang/Basic/BuiltinsLoongArch.def"
+ LastTSBuiltin
+ };
+ } // namespace LoongArch
+
/// Flags to identify the types for overloaded Neon builtins.
///
/// These must be kept in sync with the flags in utils/TableGen/NeonEmitter.h.
Index: clang/include/clang/Basic/BuiltinsLoongArch.def
===================================================================
--- /dev/null
+++ clang/include/clang/Basic/BuiltinsLoongArch.def
@@ -0,0 +1,23 @@
+//==- BuiltinsLoongArch.def - LoongArch Builtin function database -- C++ -*-==//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the LoongArch-specific builtin function database. Users of
+// this file must define the BUILTIN macro to make use of this information.
+//
+//===----------------------------------------------------------------------===//
+
+#if defined(BUILTIN) && !defined(TARGET_BUILTIN)
+# define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) BUILTIN(ID, TYPE, ATTRS)
+#endif
+
+// TODO: Support more builtins.
+// TODO: Added feature constraints.
+TARGET_BUILTIN(__builtin_loongarch_dbar, "vIUi", "nc", "")
+
+#undef BUILTIN
+#undef TARGET_BUILTIN
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits