[LoongArch] Add intrinsics for ibar, break and syscall
Diagnostics for intrinsic input parameters have also been added. Differential Revision: https://reviews.llvm.org/D138094
This commit is contained in:
parent
fd6d660917
commit
c2ec455f18
|
@ -18,6 +18,9 @@
|
||||||
// TODO: Support more builtins.
|
// TODO: Support more builtins.
|
||||||
// TODO: Added feature constraints.
|
// TODO: Added feature constraints.
|
||||||
TARGET_BUILTIN(__builtin_loongarch_dbar, "vIUi", "nc", "")
|
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_crc_w_d_w, "iLii", "nc", "64bit")
|
TARGET_BUILTIN(__builtin_loongarch_crc_w_d_w, "iLii", "nc", "64bit")
|
||||||
|
|
||||||
|
|
|
@ -19663,6 +19663,15 @@ Value *CodeGenFunction::EmitLoongArchBuiltinExpr(unsigned BuiltinID,
|
||||||
case LoongArch::BI__builtin_loongarch_crc_w_d_w:
|
case LoongArch::BI__builtin_loongarch_crc_w_d_w:
|
||||||
ID = Intrinsic::loongarch_crc_w_d_w;
|
ID = Intrinsic::loongarch_crc_w_d_w;
|
||||||
break;
|
break;
|
||||||
|
case LoongArch::BI__builtin_loongarch_break:
|
||||||
|
ID = Intrinsic::loongarch_break;
|
||||||
|
break;
|
||||||
|
case LoongArch::BI__builtin_loongarch_ibar:
|
||||||
|
ID = Intrinsic::loongarch_ibar;
|
||||||
|
break;
|
||||||
|
case LoongArch::BI__builtin_loongarch_syscall:
|
||||||
|
ID = Intrinsic::loongarch_syscall;
|
||||||
|
break;
|
||||||
// TODO: Support more Intrinsics.
|
// TODO: Support more Intrinsics.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,8 +22,14 @@ extern __inline int
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define __break(/*ui15*/ _1) __builtin_loongarch_break((_1))
|
||||||
|
|
||||||
#define __dbar(/*ui15*/ _1) __builtin_loongarch_dbar((_1))
|
#define __dbar(/*ui15*/ _1) __builtin_loongarch_dbar((_1))
|
||||||
|
|
||||||
|
#define __ibar(/*ui15*/ _1) __builtin_loongarch_ibar((_1))
|
||||||
|
|
||||||
|
#define __syscall(/*ui15*/ _1) __builtin_loongarch_syscall((_1))
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -3710,7 +3710,10 @@ bool Sema::CheckLoongArchBuiltinFunctionCall(const TargetInfo &TI,
|
||||||
diag::err_loongarch_builtin_requires_la64)
|
diag::err_loongarch_builtin_requires_la64)
|
||||||
<< TheCall->getSourceRange();
|
<< TheCall->getSourceRange();
|
||||||
break;
|
break;
|
||||||
|
case LoongArch::BI__builtin_loongarch_break:
|
||||||
case LoongArch::BI__builtin_loongarch_dbar:
|
case LoongArch::BI__builtin_loongarch_dbar:
|
||||||
|
case LoongArch::BI__builtin_loongarch_ibar:
|
||||||
|
case LoongArch::BI__builtin_loongarch_syscall:
|
||||||
// Check if immediate is in [0, 32767].
|
// Check if immediate is in [0, 32767].
|
||||||
return SemaBuiltinConstantArgRange(TheCall, 0, 0, 32767);
|
return SemaBuiltinConstantArgRange(TheCall, 0, 0, 32767);
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,10 +7,26 @@ 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}}
|
return __builtin_loongarch_crc_w_d_w(a, b); // expected-error {{this builtin requires target: loongarch64}}
|
||||||
}
|
}
|
||||||
|
|
||||||
void dbar_out_of_hi_range() {
|
void dbar(int a) {
|
||||||
return __builtin_loongarch_dbar(32768); // expected-error {{argument value 32768 is outside the valid range [0, 32767]}}
|
__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]}}
|
||||||
|
__builtin_loongarch_dbar(a); // expected-error {{argument to '__builtin_loongarch_dbar' must be a constant integer}}
|
||||||
}
|
}
|
||||||
|
|
||||||
void dbar_out_of_lo_range() {
|
void ibar(int a) {
|
||||||
return __builtin_loongarch_dbar(-1); // expected-error {{argument value 4294967295 is outside the valid range [0, 32767]}}
|
__builtin_loongarch_ibar(32769); // expected-error {{argument value 32769 is outside the valid range [0, 32767]}}
|
||||||
|
__builtin_loongarch_ibar(-1); // expected-error {{argument value 4294967295 is outside the valid range [0, 32767]}}
|
||||||
|
__builtin_loongarch_ibar(a); // expected-error {{argument to '__builtin_loongarch_ibar' must be a constant integer}}
|
||||||
|
}
|
||||||
|
|
||||||
|
void loongarch_break(int a) {
|
||||||
|
__builtin_loongarch_break(32769); // expected-error {{argument value 32769 is outside the valid range [0, 32767]}}
|
||||||
|
__builtin_loongarch_break(-1); // expected-error {{argument value 4294967295 is outside the valid range [0, 32767]}}
|
||||||
|
__builtin_loongarch_break(a); // expected-error {{argument to '__builtin_loongarch_break' must be a constant integer}}
|
||||||
|
}
|
||||||
|
|
||||||
|
void syscall(int a) {
|
||||||
|
__builtin_loongarch_syscall(32769); // expected-error {{argument value 32769 is outside the valid range [0, 32767]}}
|
||||||
|
__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}}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,3 +20,44 @@ void dbar() {
|
||||||
return __builtin_loongarch_dbar(0);
|
return __builtin_loongarch_dbar(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// LA32-LABEL: @ibar(
|
||||||
|
// LA32-NEXT: entry:
|
||||||
|
// LA32-NEXT: call void @llvm.loongarch.ibar(i32 0)
|
||||||
|
// LA32-NEXT: ret void
|
||||||
|
//
|
||||||
|
// LA64-LABEL: @ibar(
|
||||||
|
// LA64-NEXT: entry:
|
||||||
|
// LA64-NEXT: call void @llvm.loongarch.ibar(i32 0)
|
||||||
|
// LA64-NEXT: ret void
|
||||||
|
//
|
||||||
|
void ibar() {
|
||||||
|
return __builtin_loongarch_ibar(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// LA32-LABEL: @loongarch_break(
|
||||||
|
// LA32-NEXT: entry:
|
||||||
|
// LA32-NEXT: call void @llvm.loongarch.break(i32 1)
|
||||||
|
// LA32-NEXT: ret void
|
||||||
|
//
|
||||||
|
// LA64-LABEL: @loongarch_break(
|
||||||
|
// LA64-NEXT: entry:
|
||||||
|
// LA64-NEXT: call void @llvm.loongarch.break(i32 1)
|
||||||
|
// LA64-NEXT: ret void
|
||||||
|
//
|
||||||
|
void loongarch_break() {
|
||||||
|
__builtin_loongarch_break(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// LA32-LABEL: @syscall(
|
||||||
|
// LA32-NEXT: entry:
|
||||||
|
// LA32-NEXT: call void @llvm.loongarch.syscall(i32 1)
|
||||||
|
// LA32-NEXT: ret void
|
||||||
|
//
|
||||||
|
// LA64-LABEL: @syscall(
|
||||||
|
// LA64-NEXT: entry:
|
||||||
|
// LA64-NEXT: call void @llvm.loongarch.syscall(i32 1)
|
||||||
|
// LA64-NEXT: ret void
|
||||||
|
//
|
||||||
|
void syscall() {
|
||||||
|
__builtin_loongarch_syscall(1);
|
||||||
|
}
|
||||||
|
|
|
@ -49,7 +49,11 @@ defm int_loongarch_masked_cmpxchg : MaskedAtomicRMWFiveOpIntrinsics;
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// LoongArch BASE
|
// LoongArch BASE
|
||||||
|
|
||||||
def int_loongarch_dbar : Intrinsic<[], [llvm_i32_ty]>;
|
def int_loongarch_break : Intrinsic<[], [llvm_i32_ty], [ImmArg<ArgIndex<0>>]>;
|
||||||
|
def int_loongarch_dbar : Intrinsic<[], [llvm_i32_ty], [ImmArg<ArgIndex<0>>]>;
|
||||||
|
def int_loongarch_ibar : Intrinsic<[], [llvm_i32_ty], [ImmArg<ArgIndex<0>>]>;
|
||||||
|
def int_loongarch_syscall : Intrinsic<[], [llvm_i32_ty], [ImmArg<ArgIndex<0>>]>;
|
||||||
|
|
||||||
def int_loongarch_crc_w_d_w : Intrinsic<[llvm_i32_ty],
|
def int_loongarch_crc_w_d_w : Intrinsic<[llvm_i32_ty],
|
||||||
[llvm_i64_ty, llvm_i32_ty]>;
|
[llvm_i64_ty, llvm_i32_ty]>;
|
||||||
} // TargetPrefix = "loongarch"
|
} // TargetPrefix = "loongarch"
|
||||||
|
|
|
@ -578,35 +578,64 @@ LoongArchTargetLowering::lowerINTRINSIC_W_CHAIN(SDValue Op,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Helper function that emits error message for intrinsics with void return
|
||||||
|
// value.
|
||||||
|
static SDValue emitIntrinsicErrorMessage(SDValue Op, StringRef Name,
|
||||||
|
StringRef ErrorMsg,
|
||||||
|
SelectionDAG &DAG) {
|
||||||
|
|
||||||
|
DAG.getContext()->emitError("argument to '" + Name + "' " + ErrorMsg);
|
||||||
|
return Op.getOperand(0);
|
||||||
|
}
|
||||||
|
|
||||||
SDValue LoongArchTargetLowering::lowerINTRINSIC_VOID(SDValue Op,
|
SDValue LoongArchTargetLowering::lowerINTRINSIC_VOID(SDValue Op,
|
||||||
SelectionDAG &DAG) const {
|
SelectionDAG &DAG) const {
|
||||||
SDLoc DL(Op);
|
SDLoc DL(Op);
|
||||||
MVT GRLenVT = Subtarget.getGRLenVT();
|
MVT GRLenVT = Subtarget.getGRLenVT();
|
||||||
|
SDValue Op0 = Op.getOperand(0);
|
||||||
|
SDValue Op2 = Op.getOperand(2);
|
||||||
|
const StringRef ErrorMsgOOR = "out of range";
|
||||||
|
|
||||||
switch (Op.getConstantOperandVal(1)) {
|
switch (Op.getConstantOperandVal(1)) {
|
||||||
default:
|
default:
|
||||||
// TODO: Add more Intrinsics.
|
// TODO: Add more Intrinsics.
|
||||||
return SDValue();
|
return SDValue();
|
||||||
case Intrinsic::loongarch_dbar: {
|
case Intrinsic::loongarch_dbar: {
|
||||||
SDValue Op0 = Op.getOperand(0);
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
unsigned Imm = cast<ConstantSDNode>(Op2)->getZExtValue();
|
unsigned Imm = cast<ConstantSDNode>(Op2)->getZExtValue();
|
||||||
if (!isUInt<15>(Imm)) {
|
if (!isUInt<15>(Imm))
|
||||||
DAG.getContext()->emitError(
|
return emitIntrinsicErrorMessage(Op, "__builtin_loongarch_dbar",
|
||||||
"argument to '__builtin_loongarch_dbar' out of range");
|
ErrorMsgOOR, DAG);
|
||||||
return Op0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (GRLenVT == MVT::i32)
|
|
||||||
return Op;
|
|
||||||
return DAG.getNode(LoongArchISD::DBAR, DL, MVT::Other, Op0,
|
return DAG.getNode(LoongArchISD::DBAR, DL, MVT::Other, Op0,
|
||||||
DAG.getConstant(Imm, DL, GRLenVT));
|
DAG.getConstant(Imm, DL, GRLenVT));
|
||||||
}
|
}
|
||||||
|
case Intrinsic::loongarch_ibar: {
|
||||||
|
unsigned Imm = cast<ConstantSDNode>(Op2)->getZExtValue();
|
||||||
|
if (!isUInt<15>(Imm))
|
||||||
|
return emitIntrinsicErrorMessage(Op, "__builtin_loongarch_ibar",
|
||||||
|
ErrorMsgOOR, DAG);
|
||||||
|
|
||||||
|
return DAG.getNode(LoongArchISD::IBAR, DL, MVT::Other, Op0,
|
||||||
|
DAG.getConstant(Imm, DL, GRLenVT));
|
||||||
|
}
|
||||||
|
case Intrinsic::loongarch_break: {
|
||||||
|
unsigned Imm = cast<ConstantSDNode>(Op2)->getZExtValue();
|
||||||
|
if (!isUInt<15>(Imm))
|
||||||
|
return emitIntrinsicErrorMessage(Op, "__builtin_loongarch_break",
|
||||||
|
ErrorMsgOOR, DAG);
|
||||||
|
|
||||||
|
return DAG.getNode(LoongArchISD::BREAK, DL, MVT::Other, Op0,
|
||||||
|
DAG.getConstant(Imm, DL, GRLenVT));
|
||||||
|
}
|
||||||
|
case Intrinsic::loongarch_syscall: {
|
||||||
|
unsigned Imm = cast<ConstantSDNode>(Op2)->getZExtValue();
|
||||||
|
if (!isUInt<15>(Imm))
|
||||||
|
return emitIntrinsicErrorMessage(Op, "__builtin_loongarch_syscall",
|
||||||
|
ErrorMsgOOR, DAG);
|
||||||
|
|
||||||
|
return DAG.getNode(LoongArchISD::SYSCALL, DL, MVT::Other, Op0,
|
||||||
|
DAG.getConstant(Imm, DL, GRLenVT));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1354,6 +1383,9 @@ const char *LoongArchTargetLowering::getTargetNodeName(unsigned Opcode) const {
|
||||||
NODE_NAME_CASE(CLZ_W)
|
NODE_NAME_CASE(CLZ_W)
|
||||||
NODE_NAME_CASE(CTZ_W)
|
NODE_NAME_CASE(CTZ_W)
|
||||||
NODE_NAME_CASE(DBAR)
|
NODE_NAME_CASE(DBAR)
|
||||||
|
NODE_NAME_CASE(IBAR)
|
||||||
|
NODE_NAME_CASE(BREAK)
|
||||||
|
NODE_NAME_CASE(SYSCALL)
|
||||||
NODE_NAME_CASE(CRC_W_D_W)
|
NODE_NAME_CASE(CRC_W_D_W)
|
||||||
}
|
}
|
||||||
#undef NODE_NAME_CASE
|
#undef NODE_NAME_CASE
|
||||||
|
|
|
@ -60,7 +60,10 @@ enum NodeType : unsigned {
|
||||||
BITREV_W,
|
BITREV_W,
|
||||||
|
|
||||||
// Intrinsic operations
|
// Intrinsic operations
|
||||||
|
BREAK,
|
||||||
DBAR,
|
DBAR,
|
||||||
|
IBAR,
|
||||||
|
SYSCALL,
|
||||||
|
|
||||||
// CRC check operations
|
// CRC check operations
|
||||||
CRC_W_D_W
|
CRC_W_D_W
|
||||||
|
|
|
@ -35,7 +35,8 @@ def SDT_LoongArchBStrPick: SDTypeProfile<1, 3, [
|
||||||
SDTCisInt<0>, SDTCisSameAs<0, 1>, SDTCisInt<2>, SDTCisSameAs<2, 3>
|
SDTCisInt<0>, SDTCisSameAs<0, 1>, SDTCisInt<2>, SDTCisSameAs<2, 3>
|
||||||
]>;
|
]>;
|
||||||
|
|
||||||
def SDT_LoongArchDBAR : SDTypeProfile<0, 1, [SDTCisVT<0, GRLenVT>]>;
|
// "VI" means no output and an integer input.
|
||||||
|
def SDT_LoongArchVI : SDTypeProfile<0, 1, [SDTCisVT<0, GRLenVT>]>;
|
||||||
|
|
||||||
// TODO: Add LoongArch specific DAG Nodes
|
// TODO: Add LoongArch specific DAG Nodes
|
||||||
// Target-independent nodes, but with target-specific formats.
|
// Target-independent nodes, but with target-specific formats.
|
||||||
|
@ -70,7 +71,13 @@ def loongarch_bitrev_4b : SDNode<"LoongArchISD::BITREV_4B", SDTUnaryOp>;
|
||||||
def loongarch_bitrev_w : SDNode<"LoongArchISD::BITREV_W", SDTUnaryOp>;
|
def loongarch_bitrev_w : SDNode<"LoongArchISD::BITREV_W", SDTUnaryOp>;
|
||||||
def loongarch_clzw : SDNode<"LoongArchISD::CLZ_W", SDTIntBitCountUnaryOp>;
|
def loongarch_clzw : SDNode<"LoongArchISD::CLZ_W", SDTIntBitCountUnaryOp>;
|
||||||
def loongarch_ctzw : SDNode<"LoongArchISD::CTZ_W", SDTIntBitCountUnaryOp>;
|
def loongarch_ctzw : SDNode<"LoongArchISD::CTZ_W", SDTIntBitCountUnaryOp>;
|
||||||
def loongarch_dbar : SDNode<"LoongArchISD::DBAR", SDT_LoongArchDBAR,
|
def loongarch_dbar : SDNode<"LoongArchISD::DBAR", SDT_LoongArchVI,
|
||||||
|
[SDNPHasChain, SDNPSideEffect]>;
|
||||||
|
def loongarch_ibar : SDNode<"LoongArchISD::IBAR", SDT_LoongArchVI,
|
||||||
|
[SDNPHasChain, SDNPSideEffect]>;
|
||||||
|
def loongarch_break : SDNode<"LoongArchISD::BREAK", SDT_LoongArchVI,
|
||||||
|
[SDNPHasChain, SDNPSideEffect]>;
|
||||||
|
def loongarch_syscall : SDNode<"LoongArchISD::SYSCALL", SDT_LoongArchVI,
|
||||||
[SDNPHasChain, SDNPSideEffect]>;
|
[SDNPHasChain, SDNPSideEffect]>;
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
@ -1341,13 +1348,12 @@ def : Pat<(atomic_load_xor_32 GPR:$addr, GPR:$incr),
|
||||||
|
|
||||||
/// Intrinsics
|
/// Intrinsics
|
||||||
|
|
||||||
let Predicates = [IsLA32] in {
|
def : Pat<(loongarch_dbar uimm15:$imm15), (DBAR uimm15:$imm15)>;
|
||||||
def : Pat<(int_loongarch_dbar uimm15:$imm15), (DBAR uimm15:$imm15)>;
|
def : Pat<(loongarch_ibar uimm15:$imm15), (IBAR uimm15:$imm15)>;
|
||||||
} // Predicates = [IsLA32]
|
def : Pat<(loongarch_break uimm15:$imm15), (BREAK uimm15:$imm15)>;
|
||||||
|
def : Pat<(loongarch_syscall uimm15:$imm15), (SYSCALL uimm15:$imm15)>;
|
||||||
|
|
||||||
let Predicates = [IsLA64] in {
|
let Predicates = [IsLA64] in {
|
||||||
def : Pat<(loongarch_dbar uimm15:$imm15), (DBAR uimm15:$imm15)>;
|
|
||||||
|
|
||||||
// CRC Check Instructions
|
// CRC Check Instructions
|
||||||
def : PatGprGpr<loongarch_crc_w_d_w, CRC_W_D_W>;
|
def : PatGprGpr<loongarch_crc_w_d_w, CRC_W_D_W>;
|
||||||
} // Predicates = [IsLA64]
|
} // Predicates = [IsLA64]
|
||||||
|
|
|
@ -1,12 +1,10 @@
|
||||||
; RUN: not llc --mtriple=loongarch32 --disable-verify < %s 2>&1 | FileCheck %s
|
; RUN: not llc --mtriple=loongarch32 < %s 2>&1 | FileCheck %s
|
||||||
; RUN: not llc --mtriple=loongarch64 --disable-verify < %s 2>&1 | FileCheck %s
|
; RUN: not llc --mtriple=loongarch64 < %s 2>&1 | FileCheck %s
|
||||||
|
|
||||||
define void @dbar_not_constant(i32 %x) nounwind {
|
declare void @llvm.loongarch.dbar(i32)
|
||||||
; CHECK: argument to '__builtin_loongarch_dbar' must be a constant integer
|
declare void @llvm.loongarch.ibar(i32)
|
||||||
entry:
|
declare void @llvm.loongarch.break(i32)
|
||||||
call void @llvm.loongarch.dbar(i32 %x)
|
declare void @llvm.loongarch.syscall(i32)
|
||||||
ret void
|
|
||||||
}
|
|
||||||
|
|
||||||
define void @dbar_imm_out_of_hi_range() nounwind {
|
define void @dbar_imm_out_of_hi_range() nounwind {
|
||||||
; CHECK: argument to '__builtin_loongarch_dbar' out of range
|
; CHECK: argument to '__builtin_loongarch_dbar' out of range
|
||||||
|
@ -22,4 +20,44 @@ entry:
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
declare void @llvm.loongarch.dbar(i32)
|
define void @ibar_imm_out_of_hi_range() nounwind {
|
||||||
|
; CHECK: argument to '__builtin_loongarch_ibar' out of range
|
||||||
|
entry:
|
||||||
|
call void @llvm.loongarch.ibar(i32 32769)
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
|
||||||
|
define void @ibar_imm_out_of_lo_range() nounwind {
|
||||||
|
; CHECK: argument to '__builtin_loongarch_ibar' out of range
|
||||||
|
entry:
|
||||||
|
call void @llvm.loongarch.ibar(i32 -1)
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
|
||||||
|
define void @break_imm_out_of_hi_range() nounwind {
|
||||||
|
; CHECK: argument to '__builtin_loongarch_break' out of range
|
||||||
|
entry:
|
||||||
|
call void @llvm.loongarch.break(i32 32769)
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
|
||||||
|
define void @break_imm_out_of_lo_range() nounwind {
|
||||||
|
; CHECK: argument to '__builtin_loongarch_break' out of range
|
||||||
|
entry:
|
||||||
|
call void @llvm.loongarch.break(i32 -1)
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
|
||||||
|
define void @syscall_imm_out_of_hi_range() nounwind {
|
||||||
|
; CHECK: argument to '__builtin_loongarch_syscall' out of range
|
||||||
|
entry:
|
||||||
|
call void @llvm.loongarch.syscall(i32 32769)
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
|
||||||
|
define void @syscall_imm_out_of_lo_range() nounwind {
|
||||||
|
; CHECK: argument to '__builtin_loongarch_syscall' out of range
|
||||||
|
entry:
|
||||||
|
call void @llvm.loongarch.syscall(i32 -1)
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
; RUN: not llc --mtriple=loongarch32 < %s 2>&1 | FileCheck %s
|
||||||
|
; RUN: not llc --mtriple=loongarch64 < %s 2>&1 | FileCheck %s
|
||||||
|
|
||||||
|
declare void @llvm.loongarch.dbar(i32)
|
||||||
|
declare void @llvm.loongarch.ibar(i32)
|
||||||
|
declare void @llvm.loongarch.break(i32)
|
||||||
|
declare void @llvm.loongarch.syscall(i32)
|
||||||
|
|
||||||
|
define void @dbar_not_constant(i32 %x) nounwind {
|
||||||
|
; CHECK: immarg operand has non-immediate parameter
|
||||||
|
entry:
|
||||||
|
call void @llvm.loongarch.dbar(i32 %x)
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
|
||||||
|
define void @ibar(i32 %x) nounwind {
|
||||||
|
; CHECK: immarg operand has non-immediate parameter
|
||||||
|
entry:
|
||||||
|
call void @llvm.loongarch.ibar(i32 %x)
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
|
||||||
|
define void @break(i32 %x) nounwind {
|
||||||
|
; CHECK: immarg operand has non-immediate parameter
|
||||||
|
entry:
|
||||||
|
call void @llvm.loongarch.break(i32 %x)
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
|
||||||
|
define void @syscall(i32 %x) nounwind {
|
||||||
|
; CHECK: immarg operand has non-immediate parameter
|
||||||
|
entry:
|
||||||
|
call void @llvm.loongarch.syscall(i32 %x)
|
||||||
|
ret void
|
||||||
|
}
|
|
@ -3,6 +3,9 @@
|
||||||
; RUN: llc --mtriple=loongarch64 < %s | FileCheck %s
|
; RUN: llc --mtriple=loongarch64 < %s | FileCheck %s
|
||||||
|
|
||||||
declare void @llvm.loongarch.dbar(i32)
|
declare void @llvm.loongarch.dbar(i32)
|
||||||
|
declare void @llvm.loongarch.ibar(i32)
|
||||||
|
declare void @llvm.loongarch.break(i32)
|
||||||
|
declare void @llvm.loongarch.syscall(i32)
|
||||||
|
|
||||||
define void @foo() nounwind {
|
define void @foo() nounwind {
|
||||||
; CHECK-LABEL: foo:
|
; CHECK-LABEL: foo:
|
||||||
|
@ -13,3 +16,33 @@ entry:
|
||||||
call void @llvm.loongarch.dbar(i32 0)
|
call void @llvm.loongarch.dbar(i32 0)
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
|
define void @ibar() nounwind {
|
||||||
|
; CHECK-LABEL: ibar:
|
||||||
|
; CHECK: # %bb.0: # %entry
|
||||||
|
; CHECK-NEXT: ibar 0
|
||||||
|
; CHECK-NEXT: ret
|
||||||
|
entry:
|
||||||
|
call void @llvm.loongarch.ibar(i32 0)
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
|
||||||
|
define void @break() nounwind {
|
||||||
|
; CHECK-LABEL: break:
|
||||||
|
; CHECK: # %bb.0: # %entry
|
||||||
|
; CHECK-NEXT: break 1
|
||||||
|
; CHECK-NEXT: ret
|
||||||
|
entry:
|
||||||
|
call void @llvm.loongarch.break(i32 1)
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
|
||||||
|
define void @syscall() nounwind {
|
||||||
|
; CHECK-LABEL: syscall:
|
||||||
|
; CHECK: # %bb.0: # %entry
|
||||||
|
; CHECK-NEXT: syscall 1
|
||||||
|
; CHECK-NEXT: ret
|
||||||
|
entry:
|
||||||
|
call void @llvm.loongarch.syscall(i32 1)
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue