[LoongArch] Add missing chains and remove unnecessary SDNPSideEffect property for some intrinsic nodes

This commit is contained in:
Weining Lu
2023-06-20 17:21:31 +08:00
parent 1d27ad2077
commit 2efdacf74c
4 changed files with 209 additions and 70 deletions

View File

@@ -633,11 +633,8 @@ LoongArchTargetLowering::lowerINTRINSIC_W_CHAIN(SDValue Op,
unsigned Imm = cast<ConstantSDNode>(Op.getOperand(2))->getZExtValue();
return !isUInt<14>(Imm)
? emitIntrinsicWithChainErrorMessage(Op, ErrorMsgOOR, DAG)
: DAG.getMergeValues(
{DAG.getNode(LoongArchISD::CSRRD, DL, GRLenVT, Chain,
DAG.getConstant(Imm, DL, GRLenVT)),
Chain},
DL);
: DAG.getNode(LoongArchISD::CSRRD, DL, {GRLenVT, MVT::Other},
{Chain, DAG.getConstant(Imm, DL, GRLenVT)});
}
case Intrinsic::loongarch_csrwr_w:
case Intrinsic::loongarch_csrwr_d: {
@@ -658,29 +655,22 @@ LoongArchTargetLowering::lowerINTRINSIC_W_CHAIN(SDValue Op,
DAG.getConstant(Imm, DL, GRLenVT)});
}
case Intrinsic::loongarch_iocsrrd_d: {
return DAG.getMergeValues(
{DAG.getNode(
LoongArchISD::IOCSRRD_D, DL, GRLenVT, Chain,
DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i64, Op.getOperand(2))),
Chain},
DL);
return DAG.getNode(
LoongArchISD::IOCSRRD_D, DL, {GRLenVT, MVT::Other},
{Chain, DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i64, Op.getOperand(2))});
}
#define IOCSRRD_CASE(NAME, NODE) \
case Intrinsic::loongarch_##NAME: { \
return DAG.getMergeValues({DAG.getNode(LoongArchISD::NODE, DL, GRLenVT, \
Chain, Op.getOperand(2)), \
Chain}, \
DL); \
return DAG.getNode(LoongArchISD::NODE, DL, {GRLenVT, MVT::Other}, \
{Chain, Op.getOperand(2)}); \
}
IOCSRRD_CASE(iocsrrd_b, IOCSRRD_B);
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,
Chain, Op.getOperand(2)),
Chain},
DL);
return DAG.getNode(LoongArchISD::CPUCFG, DL, {GRLenVT, MVT::Other},
{Chain, Op.getOperand(2)});
}
case Intrinsic::loongarch_lddir_d: {
unsigned Imm = cast<ConstantSDNode>(Op.getOperand(3))->getZExtValue();
@@ -694,11 +684,8 @@ LoongArchTargetLowering::lowerINTRINSIC_W_CHAIN(SDValue Op,
unsigned Imm = cast<ConstantSDNode>(Op.getOperand(2))->getZExtValue();
return !isUInt<2>(Imm)
? emitIntrinsicWithChainErrorMessage(Op, ErrorMsgOOR, DAG)
: DAG.getMergeValues(
{DAG.getNode(LoongArchISD::MOVFCSR2GR, DL, VT,
DAG.getConstant(Imm, DL, GRLenVT)),
Chain},
DL);
: DAG.getNode(LoongArchISD::MOVFCSR2GR, DL, {VT, MVT::Other},
{Chain, DAG.getConstant(Imm, DL, GRLenVT)});
}
}
}
@@ -1121,22 +1108,22 @@ void LoongArchTargetLowering::ReplaceNodeResults(
ErrorMsgOOR);
return;
}
SDValue MOVFCSR2GRResults = DAG.getNode(
LoongArchISD::MOVFCSR2GR, SDLoc(N), {MVT::i64, MVT::Other},
{Chain, DAG.getConstant(Imm, DL, GRLenVT)});
Results.push_back(
DAG.getNode(ISD::TRUNCATE, DL, VT,
DAG.getNode(LoongArchISD::MOVFCSR2GR, SDLoc(N), MVT::i64,
DAG.getConstant(Imm, DL, GRLenVT))));
Results.push_back(Chain);
DAG.getNode(ISD::TRUNCATE, DL, VT, MOVFCSR2GRResults.getValue(0)));
Results.push_back(MOVFCSR2GRResults.getValue(1));
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, N->getOperand(3))))); \
Results.push_back(Chain); \
SDValue NODE = DAG.getNode( \
LoongArchISD::NODE, DL, {MVT::i64, MVT::Other}, \
{Chain, DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i64, Op2), \
DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i64, N->getOperand(3))}); \
Results.push_back(DAG.getNode(ISD::TRUNCATE, DL, VT, NODE.getValue(0))); \
Results.push_back(NODE.getValue(1)); \
break; \
}
CRC_CASE_EXT_BINARYOP(crc_w_b_w, CRC_W_B_W)
@@ -1149,12 +1136,12 @@ void LoongArchTargetLowering::ReplaceNodeResults(
#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, \
N->getOperand(3))))); \
Results.push_back(Chain); \
SDValue NODE = DAG.getNode( \
LoongArchISD::NODE, DL, {MVT::i64, MVT::Other}, \
{Chain, Op2, \
DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i64, N->getOperand(3))}); \
Results.push_back(DAG.getNode(ISD::TRUNCATE, DL, VT, NODE.getValue(0))); \
Results.push_back(NODE.getValue(1)); \
break; \
}
CRC_CASE_EXT_UNARYOP(crc_w_d_w, CRC_W_D_W)
@@ -1179,11 +1166,12 @@ void LoongArchTargetLowering::ReplaceNodeResults(
ErrorMsgOOR);
return;
}
SDValue CSRRDResults =
DAG.getNode(LoongArchISD::CSRRD, DL, {GRLenVT, MVT::Other},
{Chain, DAG.getConstant(Imm, DL, GRLenVT)});
Results.push_back(
DAG.getNode(ISD::TRUNCATE, DL, VT,
DAG.getNode(LoongArchISD::CSRRD, DL, GRLenVT, Chain,
DAG.getConstant(Imm, DL, GRLenVT))));
Results.push_back(Chain);
DAG.getNode(ISD::TRUNCATE, DL, VT, CSRRDResults.getValue(0)));
Results.push_back(CSRRDResults.getValue(1));
break;
}
case Intrinsic::loongarch_csrwr_w: {
@@ -1221,11 +1209,12 @@ void LoongArchTargetLowering::ReplaceNodeResults(
}
#define IOCSRRD_CASE(NAME, NODE) \
case Intrinsic::loongarch_##NAME: { \
Results.push_back(DAG.getNode( \
ISD::TRUNCATE, DL, VT, \
DAG.getNode(LoongArchISD::NODE, DL, MVT::i64, Chain, \
DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i64, Op2)))); \
Results.push_back(Chain); \
SDValue IOCSRRDResults = \
DAG.getNode(LoongArchISD::NODE, DL, {MVT::i64, MVT::Other}, \
{Chain, DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i64, Op2)}); \
Results.push_back( \
DAG.getNode(ISD::TRUNCATE, DL, VT, IOCSRRDResults.getValue(0))); \
Results.push_back(IOCSRRDResults.getValue(1)); \
break; \
}
IOCSRRD_CASE(iocsrrd_b, IOCSRRD_B);
@@ -1233,11 +1222,12 @@ void LoongArchTargetLowering::ReplaceNodeResults(
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, Chain,
DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i64, Op2))));
Results.push_back(Chain);
SDValue CPUCFGResults =
DAG.getNode(LoongArchISD::CPUCFG, DL, {GRLenVT, MVT::Other},
{Chain, DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i64, Op2)});
Results.push_back(
DAG.getNode(ISD::TRUNCATE, DL, VT, CPUCFGResults.getValue(0)));
Results.push_back(CPUCFGResults.getValue(1));
break;
}
case Intrinsic::loongarch_lddir_d: {

View File

@@ -75,21 +75,21 @@ 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>;
: SDNode<"LoongArchISD::CRC_W_B_W", SDT_LoongArchIntBinOpW, [SDNPHasChain]>;
def loongarch_crc_w_h_w
: SDNode<"LoongArchISD::CRC_W_H_W", SDT_LoongArchIntBinOpW>;
: SDNode<"LoongArchISD::CRC_W_H_W", SDT_LoongArchIntBinOpW, [SDNPHasChain]>;
def loongarch_crc_w_w_w
: SDNode<"LoongArchISD::CRC_W_W_W", SDT_LoongArchIntBinOpW>;
: SDNode<"LoongArchISD::CRC_W_W_W", SDT_LoongArchIntBinOpW, [SDNPHasChain]>;
def loongarch_crc_w_d_w
: SDNode<"LoongArchISD::CRC_W_D_W", SDT_LoongArchIntBinOpW>;
: SDNode<"LoongArchISD::CRC_W_D_W", SDT_LoongArchIntBinOpW, [SDNPHasChain]>;
def loongarch_crcc_w_b_w
: SDNode<"LoongArchISD::CRCC_W_B_W", SDT_LoongArchIntBinOpW>;
: SDNode<"LoongArchISD::CRCC_W_B_W", SDT_LoongArchIntBinOpW, [SDNPHasChain]>;
def loongarch_crcc_w_h_w
: SDNode<"LoongArchISD::CRCC_W_H_W", SDT_LoongArchIntBinOpW>;
: SDNode<"LoongArchISD::CRCC_W_H_W", SDT_LoongArchIntBinOpW, [SDNPHasChain]>;
def loongarch_crcc_w_w_w
: SDNode<"LoongArchISD::CRCC_W_W_W", SDT_LoongArchIntBinOpW>;
: SDNode<"LoongArchISD::CRCC_W_W_W", SDT_LoongArchIntBinOpW, [SDNPHasChain]>;
def loongarch_crcc_w_d_w
: SDNode<"LoongArchISD::CRCC_W_D_W", SDT_LoongArchIntBinOpW>;
: SDNode<"LoongArchISD::CRCC_W_D_W", SDT_LoongArchIntBinOpW, [SDNPHasChain]>;
def loongarch_bstrins
: SDNode<"LoongArchISD::BSTRINS", SDT_LoongArchBStrIns>;
def loongarch_bstrpick
@@ -106,26 +106,27 @@ def loongarch_ibar : SDNode<"LoongArchISD::IBAR", SDT_LoongArchVI,
[SDNPHasChain, SDNPSideEffect]>;
def loongarch_break : SDNode<"LoongArchISD::BREAK", SDT_LoongArchVI,
[SDNPHasChain, SDNPSideEffect]>;
def loongarch_movfcsr2gr : SDNode<"LoongArchISD::MOVFCSR2GR", SDT_LoongArchMovfcsr2gr>;
def loongarch_movfcsr2gr : SDNode<"LoongArchISD::MOVFCSR2GR", SDT_LoongArchMovfcsr2gr,
[SDNPHasChain]>;
def loongarch_movgr2fcsr : SDNode<"LoongArchISD::MOVGR2FCSR", SDT_LoongArchMovgr2fcsr,
[SDNPHasChain, SDNPSideEffect]>;
def loongarch_syscall : SDNode<"LoongArchISD::SYSCALL", SDT_LoongArchVI,
[SDNPHasChain, SDNPSideEffect]>;
def loongarch_csrrd : SDNode<"LoongArchISD::CSRRD", SDT_LoongArchCsrrd,
[SDNPHasChain, SDNPSideEffect]>;
[SDNPHasChain]>;
def loongarch_csrwr : SDNode<"LoongArchISD::CSRWR", SDT_LoongArchCsrwr,
[SDNPHasChain, SDNPSideEffect]>;
def loongarch_csrxchg : SDNode<"LoongArchISD::CSRXCHG",
SDT_LoongArchCsrxchg,
[SDNPHasChain, SDNPSideEffect]>;
def loongarch_iocsrrd_b : SDNode<"LoongArchISD::IOCSRRD_B", SDTUnaryOp,
[SDNPHasChain, SDNPSideEffect]>;
[SDNPHasChain]>;
def loongarch_iocsrrd_h : SDNode<"LoongArchISD::IOCSRRD_H", SDTUnaryOp,
[SDNPHasChain, SDNPSideEffect]>;
[SDNPHasChain]>;
def loongarch_iocsrrd_w : SDNode<"LoongArchISD::IOCSRRD_W", SDTUnaryOp,
[SDNPHasChain, SDNPSideEffect]>;
[SDNPHasChain]>;
def loongarch_iocsrrd_d : SDNode<"LoongArchISD::IOCSRRD_D", SDTUnaryOp,
[SDNPHasChain, SDNPSideEffect]>;
[SDNPHasChain]>;
def loongarch_iocsrwr_b : SDNode<"LoongArchISD::IOCSRWR_B",
SDT_LoongArchIocsrwr,
[SDNPHasChain, SDNPSideEffect]>;
@@ -139,7 +140,7 @@ def loongarch_iocsrwr_d : SDNode<"LoongArchISD::IOCSRWR_D",
SDT_LoongArchIocsrwr,
[SDNPHasChain, SDNPSideEffect]>;
def loongarch_cpucfg : SDNode<"LoongArchISD::CPUCFG", SDTUnaryOp,
[SDNPHasChain, SDNPSideEffect]>;
[SDNPHasChain]>;
//===----------------------------------------------------------------------===//
// Operand and SDNode transformation definitions.

View File

@@ -29,6 +29,14 @@ define i32 @crc_w_b_w(i32 %a, i32 %b) nounwind {
ret i32 %res
}
define void @crc_w_b_w_noret(i32 %a, i32 %b) nounwind {
; CHECK-LABEL: crc_w_b_w_noret:
; CHECK: # %bb.0:
; CHECK-NEXT: ret
%res = call i32 @llvm.loongarch.crc.w.b.w(i32 %a, i32 %b)
ret void
}
define i32 @crc_w_h_w(i32 %a, i32 %b) nounwind {
; CHECK-LABEL: crc_w_h_w:
; CHECK: # %bb.0:
@@ -38,6 +46,14 @@ define i32 @crc_w_h_w(i32 %a, i32 %b) nounwind {
ret i32 %res
}
define void @crc_w_h_w_noret(i32 %a, i32 %b) nounwind {
; CHECK-LABEL: crc_w_h_w_noret:
; CHECK: # %bb.0:
; CHECK-NEXT: ret
%res = call i32 @llvm.loongarch.crc.w.h.w(i32 %a, i32 %b)
ret void
}
define i32 @crc_w_w_w(i32 %a, i32 %b) nounwind {
; CHECK-LABEL: crc_w_w_w:
; CHECK: # %bb.0:
@@ -47,6 +63,14 @@ define i32 @crc_w_w_w(i32 %a, i32 %b) nounwind {
ret i32 %res
}
define void @crc_w_w_w_noret(i32 %a, i32 %b) nounwind {
; CHECK-LABEL: crc_w_w_w_noret:
; CHECK: # %bb.0:
; CHECK-NEXT: ret
%res = call i32 @llvm.loongarch.crc.w.w.w(i32 %a, i32 %b)
ret void
}
define void @cacop_d(i64 %a) nounwind {
; CHECK-LABEL: cacop_d:
; CHECK: # %bb.0:
@@ -65,6 +89,14 @@ define i32 @crc_w_d_w(i64 %a, i32 %b) nounwind {
ret i32 %res
}
define void @crc_w_d_w_noret(i64 %a, i32 %b) nounwind {
; CHECK-LABEL: crc_w_d_w_noret:
; CHECK: # %bb.0:
; CHECK-NEXT: ret
%res = call i32 @llvm.loongarch.crc.w.d.w(i64 %a, i32 %b)
ret void
}
define i32 @crcc_w_b_w(i32 %a, i32 %b) nounwind {
; CHECK-LABEL: crcc_w_b_w:
; CHECK: # %bb.0:
@@ -74,6 +106,14 @@ define i32 @crcc_w_b_w(i32 %a, i32 %b) nounwind {
ret i32 %res
}
define void @crcc_w_b_w_noret(i32 %a, i32 %b) nounwind {
; CHECK-LABEL: crcc_w_b_w_noret:
; CHECK: # %bb.0:
; CHECK-NEXT: ret
%res = call i32 @llvm.loongarch.crcc.w.b.w(i32 %a, i32 %b)
ret void
}
define i32 @crcc_w_h_w(i32 %a, i32 %b) nounwind {
; CHECK-LABEL: crcc_w_h_w:
; CHECK: # %bb.0:
@@ -83,6 +123,14 @@ define i32 @crcc_w_h_w(i32 %a, i32 %b) nounwind {
ret i32 %res
}
define void @crcc_w_h_w_noret(i32 %a, i32 %b) nounwind {
; CHECK-LABEL: crcc_w_h_w_noret:
; CHECK: # %bb.0:
; CHECK-NEXT: ret
%res = call i32 @llvm.loongarch.crcc.w.h.w(i32 %a, i32 %b)
ret void
}
define i32 @crcc_w_w_w(i32 %a, i32 %b) nounwind {
; CHECK-LABEL: crcc_w_w_w:
; CHECK: # %bb.0:
@@ -92,6 +140,14 @@ define i32 @crcc_w_w_w(i32 %a, i32 %b) nounwind {
ret i32 %res
}
define void @crcc_w_w_w_noret(i32 %a, i32 %b) nounwind {
; CHECK-LABEL: crcc_w_w_w_noret:
; CHECK: # %bb.0:
; CHECK-NEXT: ret
%res = call i32 @llvm.loongarch.crcc.w.w.w(i32 %a, i32 %b)
ret void
}
define i32 @crcc_w_d_w(i64 %a, i32 %b) nounwind {
; CHECK-LABEL: crcc_w_d_w:
; CHECK: # %bb.0:
@@ -101,6 +157,14 @@ define i32 @crcc_w_d_w(i64 %a, i32 %b) nounwind {
ret i32 %res
}
define void @crcc_w_d_w_noret(i64 %a, i32 %b) nounwind {
; CHECK-LABEL: crcc_w_d_w_noret:
; CHECK: # %bb.0:
; CHECK-NEXT: ret
%res = call i32 @llvm.loongarch.crcc.w.d.w(i64 %a, i32 %b)
ret void
}
define i64 @csrrd_d() {
; CHECK-LABEL: csrrd_d:
; CHECK: # %bb.0: # %entry
@@ -111,6 +175,15 @@ entry:
ret i64 %0
}
define void @csrrd_d_noret() {
; CHECK-LABEL: csrrd_d_noret:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: ret
entry:
%0 = tail call i64 @llvm.loongarch.csrrd.d(i32 1)
ret void
}
define i64 @csrwr_d(i64 %a) {
; CHECK-LABEL: csrwr_d:
; CHECK: # %bb.0: # %entry
@@ -163,6 +236,15 @@ entry:
ret i64 %0
}
define void @iocsrrd_d_noret(i32 %a) {
; CHECK-LABEL: iocsrrd_d_noret:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: ret
entry:
%0 = tail call i64 @llvm.loongarch.iocsrrd.d(i32 %a)
ret void
}
define void @iocsrwr_d(i64 %a, i32 signext %b) {
; CHECK-LABEL: iocsrwr_d:
; CHECK: # %bb.0: # %entry
@@ -203,6 +285,16 @@ entry:
ret i64 %0
}
define void @lddir_d_noret(i64 %a) {
; CHECK-LABEL: lddir_d_noret:
; 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 void
}
define void @ldpte_d(i64 %a) {
; CHECK-LABEL: ldpte_d:
; CHECK: # %bb.0: # %entry

View File

@@ -69,6 +69,17 @@ entry:
ret i32 %res
}
;; TODO: Optimize out `movfcsr2gr` without data-dependency.
define void @movfcsr2gr_noret() nounwind {
; CHECK-LABEL: movfcsr2gr_noret:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: movfcsr2gr $a0, $fcsr1
; CHECK-NEXT: ret
entry:
%res = call i32 @llvm.loongarch.movfcsr2gr(i32 1)
ret void
}
define void @syscall() nounwind {
; CHECK-LABEL: syscall:
; CHECK: # %bb.0: # %entry
@@ -89,6 +100,15 @@ entry:
ret i32 %0
}
define void @csrrd_w_noret() {
; CHECK-LABEL: csrrd_w_noret:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: ret
entry:
%0 = tail call i32 @llvm.loongarch.csrrd.w(i32 1)
ret void
}
define i32 @csrwr_w(i32 signext %a) {
; CHECK-LABEL: csrwr_w:
; CHECK: # %bb.0: # %entry
@@ -161,6 +181,33 @@ entry:
ret i32 %0
}
define void @iocsrrd_b_noret(i32 %a) {
; CHECK-LABEL: iocsrrd_b_noret:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: ret
entry:
%0 = tail call i32 @llvm.loongarch.iocsrrd.b(i32 %a)
ret void
}
define void @iocsrrd_h_noret(i32 %a) {
; CHECK-LABEL: iocsrrd_h_noret:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: ret
entry:
%0 = tail call i32 @llvm.loongarch.iocsrrd.h(i32 %a)
ret void
}
define void @iocsrrd_w_noret(i32 %a) {
; CHECK-LABEL: iocsrrd_w_noret:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: ret
entry:
%0 = tail call i32 @llvm.loongarch.iocsrrd.w(i32 %a)
ret void
}
define void @iocsrwr_b(i32 %a, i32 %b) {
; CHECK-LABEL: iocsrwr_b:
; CHECK: # %bb.0: # %entry
@@ -200,3 +247,12 @@ entry:
%0 = tail call i32 @llvm.loongarch.cpucfg(i32 %a)
ret i32 %0
}
define void @cpucfg_noret(i32 %a) {
; CHECK-LABEL: cpucfg_noret:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: ret
entry:
%0 = tail call i32 @llvm.loongarch.cpucfg(i32 %a)
ret void
}