forked from OSchip/llvm-project
[RISCV][CodeGen] Implement IR Intrinsic support for K extension
This revision implements IR Intrinsic support for RISCV Scalar Crypto extension according to the specification of version [[ https://github.com/riscv/riscv-crypto/releases/tag/v1.0.0-scalar | 1.0]] Co-author:@ksyx & @VincentWu & @lihongliang & @achieveartificialintelligence Reviewed By: craig.topper Differential Revision: https://reviews.llvm.org/D102310
This commit is contained in:
parent
3bc152769d
commit
615d71d9a3
|
@ -88,9 +88,11 @@ let TargetPrefix = "riscv" in {
|
|||
// Zbb
|
||||
def int_riscv_orc_b : BitManipGPRIntrinsics;
|
||||
|
||||
// Zbc
|
||||
// Zbc or Zbkc
|
||||
def int_riscv_clmul : BitManipGPRGPRIntrinsics;
|
||||
def int_riscv_clmulh : BitManipGPRGPRIntrinsics;
|
||||
|
||||
// Zbc
|
||||
def int_riscv_clmulr : BitManipGPRGPRIntrinsics;
|
||||
|
||||
// Zbe
|
||||
|
@ -123,6 +125,15 @@ let TargetPrefix = "riscv" in {
|
|||
// Zbt
|
||||
def int_riscv_fsl : BitManipGPRGPRGRIntrinsics;
|
||||
def int_riscv_fsr : BitManipGPRGPRGRIntrinsics;
|
||||
|
||||
// Zbkb
|
||||
def int_riscv_brev8 : BitManipGPRIntrinsics;
|
||||
def int_riscv_zip : BitManipGPRIntrinsics;
|
||||
def int_riscv_unzip : BitManipGPRIntrinsics;
|
||||
|
||||
// Zbkx
|
||||
def int_riscv_xperm4 : BitManipGPRGPRIntrinsics;
|
||||
def int_riscv_xperm8 : BitManipGPRGPRIntrinsics;
|
||||
} // TargetPrefix = "riscv"
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -1453,3 +1464,92 @@ let TargetPrefix = "riscv" in {
|
|||
llvm_anyint_ty, LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>],
|
||||
[NoCapture<ArgIndex<1>>, IntrWriteMem]>;
|
||||
} // TargetPrefix = "riscv"
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Scalar Cryptography
|
||||
//
|
||||
// These intrinsics will lower directly into the corresponding instructions
|
||||
// added by the scalar cyptography extension, if the extension is present.
|
||||
|
||||
let TargetPrefix = "riscv" in {
|
||||
|
||||
class ScalarCryptoGprIntrinsicAny
|
||||
: Intrinsic<[llvm_anyint_ty],
|
||||
[LLVMMatchType<0>],
|
||||
[IntrNoMem, IntrSpeculatable]>;
|
||||
|
||||
class ScalarCryptoByteSelect32
|
||||
: Intrinsic<[llvm_i32_ty],
|
||||
[llvm_i32_ty, llvm_i32_ty, llvm_i8_ty],
|
||||
[IntrNoMem, IntrWillReturn, IntrSpeculatable,
|
||||
ImmArg<ArgIndex<2>>]>;
|
||||
|
||||
class ScalarCryptoGprGprIntrinsic32
|
||||
: Intrinsic<[llvm_i32_ty],
|
||||
[llvm_i32_ty, llvm_i32_ty],
|
||||
[IntrNoMem, IntrWillReturn, IntrSpeculatable]>;
|
||||
|
||||
class ScalarCryptoGprGprIntrinsic64
|
||||
: Intrinsic<[llvm_i64_ty],
|
||||
[llvm_i64_ty, llvm_i64_ty],
|
||||
[IntrNoMem, IntrWillReturn, IntrSpeculatable]>;
|
||||
|
||||
class ScalarCryptoGprIntrinsic64
|
||||
: Intrinsic<[llvm_i64_ty],
|
||||
[llvm_i64_ty],
|
||||
[IntrNoMem, IntrWillReturn, IntrSpeculatable]>;
|
||||
|
||||
class ScalarCryptoByteSelectAny
|
||||
: Intrinsic<[llvm_anyint_ty],
|
||||
[LLVMMatchType<0>, LLVMMatchType<0>, llvm_i8_ty],
|
||||
[IntrNoMem, IntrSpeculatable, IntrWillReturn,
|
||||
ImmArg<ArgIndex<2>>, Returned<ArgIndex<0>>]>;
|
||||
|
||||
// Zknd
|
||||
def int_riscv_aes32dsi : ScalarCryptoByteSelect32;
|
||||
def int_riscv_aes32dsmi : ScalarCryptoByteSelect32;
|
||||
|
||||
def int_riscv_aes64ds : ScalarCryptoGprGprIntrinsic64;
|
||||
def int_riscv_aes64dsm : ScalarCryptoGprGprIntrinsic64;
|
||||
|
||||
def int_riscv_aes64im : ScalarCryptoGprIntrinsic64;
|
||||
|
||||
// Zkne
|
||||
def int_riscv_aes32esi : ScalarCryptoByteSelect32;
|
||||
def int_riscv_aes32esmi : ScalarCryptoByteSelect32;
|
||||
|
||||
def int_riscv_aes64es : ScalarCryptoGprGprIntrinsic64;
|
||||
def int_riscv_aes64esm : ScalarCryptoGprGprIntrinsic64;
|
||||
|
||||
// Zknd & Zkne
|
||||
def int_riscv_aes64ks2 : ScalarCryptoGprGprIntrinsic64;
|
||||
def int_riscv_aes64ks1i : Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_i32_ty],
|
||||
[IntrNoMem, IntrSpeculatable,
|
||||
IntrWillReturn, ImmArg<ArgIndex<1>>]>;
|
||||
|
||||
// Zknh
|
||||
def int_riscv_sha256sig0 : ScalarCryptoGprIntrinsicAny;
|
||||
def int_riscv_sha256sig1 : ScalarCryptoGprIntrinsicAny;
|
||||
def int_riscv_sha256sum0 : ScalarCryptoGprIntrinsicAny;
|
||||
def int_riscv_sha256sum1 : ScalarCryptoGprIntrinsicAny;
|
||||
|
||||
def int_riscv_sha512sig0l : ScalarCryptoGprGprIntrinsic32;
|
||||
def int_riscv_sha512sig0h : ScalarCryptoGprGprIntrinsic32;
|
||||
def int_riscv_sha512sig1l : ScalarCryptoGprGprIntrinsic32;
|
||||
def int_riscv_sha512sig1h : ScalarCryptoGprGprIntrinsic32;
|
||||
def int_riscv_sha512sum0r : ScalarCryptoGprGprIntrinsic32;
|
||||
def int_riscv_sha512sum1r : ScalarCryptoGprGprIntrinsic32;
|
||||
|
||||
def int_riscv_sha512sig0 : ScalarCryptoGprIntrinsic64;
|
||||
def int_riscv_sha512sig1 : ScalarCryptoGprIntrinsic64;
|
||||
def int_riscv_sha512sum0 : ScalarCryptoGprIntrinsic64;
|
||||
def int_riscv_sha512sum1 : ScalarCryptoGprIntrinsic64;
|
||||
|
||||
// Zksed
|
||||
def int_riscv_sm4ks : ScalarCryptoByteSelectAny;
|
||||
def int_riscv_sm4ed : ScalarCryptoByteSelectAny;
|
||||
|
||||
// Zksh
|
||||
def int_riscv_sm3p0 : ScalarCryptoGprIntrinsicAny;
|
||||
def int_riscv_sm3p1 : ScalarCryptoGprIntrinsicAny;
|
||||
} // TargetPrefix = "riscv"
|
||||
|
|
|
@ -169,6 +169,12 @@ def HasStdExtZbpOrZbkb
|
|||
"'Zbp' (Permutation 'Zb' Instructions) or "
|
||||
"'Zbkb' (Bitmanip instructions for Cryptography)">;
|
||||
|
||||
def HasStdExtZbbOrZbkb
|
||||
: Predicate<"Subtarget->hasStdExtZbb() || Subtarget->hasStdExtZbkb()">,
|
||||
AssemblerPredicate<(any_of FeatureStdExtZbb, FeatureStdExtZbkb),
|
||||
"'Zbb' (Basic Bit-Manipulation) or "
|
||||
"'Zbkb' (Bitmanip instructions for Cryptography)">;
|
||||
|
||||
def HasStdExtZbbOrZbpOrZbkb
|
||||
: Predicate<"Subtarget->hasStdExtZbb() || Subtarget->hasStdExtZbp() || Subtarget->hasStdExtZbkb()">,
|
||||
AssemblerPredicate<(any_of FeatureStdExtZbb, FeatureStdExtZbp, FeatureStdExtZbkb),
|
||||
|
|
|
@ -250,7 +250,8 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
|
|||
setOperationAction(ISD::SRL_PARTS, XLenVT, Custom);
|
||||
setOperationAction(ISD::SRA_PARTS, XLenVT, Custom);
|
||||
|
||||
if (Subtarget.hasStdExtZbb() || Subtarget.hasStdExtZbp()) {
|
||||
if (Subtarget.hasStdExtZbb() || Subtarget.hasStdExtZbp() ||
|
||||
Subtarget.hasStdExtZbkb()) {
|
||||
if (Subtarget.is64Bit()) {
|
||||
setOperationAction(ISD::ROTL, MVT::i32, Custom);
|
||||
setOperationAction(ISD::ROTR, MVT::i32, Custom);
|
||||
|
@ -278,7 +279,9 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
|
|||
// With Zbb we have an XLen rev8 instruction, but not GREVI. So we'll
|
||||
// pattern match it directly in isel.
|
||||
setOperationAction(ISD::BSWAP, XLenVT,
|
||||
Subtarget.hasStdExtZbb() ? Legal : Expand);
|
||||
(Subtarget.hasStdExtZbb() || Subtarget.hasStdExtZbkb())
|
||||
? Legal
|
||||
: Expand);
|
||||
}
|
||||
|
||||
if (Subtarget.hasStdExtZbb()) {
|
||||
|
@ -1232,7 +1235,8 @@ bool RISCVTargetLowering::hasAndNotCompare(SDValue Y) const {
|
|||
if (VT.isVector())
|
||||
return false;
|
||||
|
||||
return (Subtarget.hasStdExtZbb() || Subtarget.hasStdExtZbp()) &&
|
||||
return (Subtarget.hasStdExtZbb() || Subtarget.hasStdExtZbp() ||
|
||||
Subtarget.hasStdExtZbkb()) &&
|
||||
!isa<ConstantSDNode>(Y);
|
||||
}
|
||||
|
||||
|
|
|
@ -794,16 +794,16 @@ def : InstAlias<"bext $rd, $rs1, $shamt",
|
|||
// Codegen patterns
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
let Predicates = [HasStdExtZbbOrZbp] in {
|
||||
let Predicates = [HasStdExtZbbOrZbpOrZbkb] in {
|
||||
def : Pat<(and GPR:$rs1, (not GPR:$rs2)), (ANDN GPR:$rs1, GPR:$rs2)>;
|
||||
def : Pat<(or GPR:$rs1, (not GPR:$rs2)), (ORN GPR:$rs1, GPR:$rs2)>;
|
||||
def : Pat<(xor GPR:$rs1, (not GPR:$rs2)), (XNOR GPR:$rs1, GPR:$rs2)>;
|
||||
} // Predicates = [HasStdExtZbbOrZbp]
|
||||
} // Predicates = [HasStdExtZbbOrZbpOrZbkb]
|
||||
|
||||
let Predicates = [HasStdExtZbbOrZbp] in {
|
||||
let Predicates = [HasStdExtZbbOrZbpOrZbkb] in {
|
||||
def : PatGprGpr<rotl, ROL>;
|
||||
def : PatGprGpr<rotr, ROR>;
|
||||
} // Predicates = [HasStdExtZbbOrZbp]
|
||||
} // Predicates = [HasStdExtZbbOrZbpOrZbkb]
|
||||
|
||||
let Predicates = [HasStdExtZbs] in {
|
||||
def : Pat<(and (not (shiftop<shl> 1, GPR:$rs2)), GPR:$rs1),
|
||||
|
@ -854,7 +854,7 @@ def : Pat<(and GPR:$r, BCLRIANDIMask:$i),
|
|||
|
||||
// There's no encoding for roli in the the 'B' extension as it can be
|
||||
// implemented with rori by negating the immediate.
|
||||
let Predicates = [HasStdExtZbbOrZbp] in {
|
||||
let Predicates = [HasStdExtZbbOrZbpOrZbkb] in {
|
||||
def : PatGprImm<rotr, RORI, uimmlog2xlen>;
|
||||
def : Pat<(rotl GPR:$rs1, uimmlog2xlen:$shamt),
|
||||
(RORI GPR:$rs1, (ImmSubFromXLen uimmlog2xlen:$shamt))>;
|
||||
|
@ -960,35 +960,38 @@ def : PatGprGpr<umin, MINU>;
|
|||
def : PatGprGpr<umax, MAXU>;
|
||||
} // Predicates = [HasStdExtZbb]
|
||||
|
||||
let Predicates = [HasStdExtZbb, IsRV32] in {
|
||||
let Predicates = [HasStdExtZbbOrZbkb, IsRV32] in {
|
||||
def : Pat<(i32 (bswap GPR:$rs1)), (REV8_RV32 GPR:$rs1)>;
|
||||
} // Predicates = [HasStdExtZbb, IsRV32]
|
||||
} // Predicates = [HasStdExtZbbOrZbkb, IsRV32]
|
||||
|
||||
let Predicates = [HasStdExtZbb, IsRV64] in {
|
||||
let Predicates = [HasStdExtZbbOrZbkb, IsRV64] in {
|
||||
def : Pat<(i64 (bswap GPR:$rs1)), (REV8_RV64 GPR:$rs1)>;
|
||||
} // Predicates = [HasStdExtZbb, IsRV64]
|
||||
} // Predicates = [HasStdExtZbbOrZbkb, IsRV64]
|
||||
|
||||
let Predicates = [HasStdExtZbp, IsRV32] in {
|
||||
let Predicates = [HasStdExtZbpOrZbkb, IsRV32] in
|
||||
def : Pat<(i32 (or (and GPR:$rs1, 0x0000FFFF), (shl GPR:$rs2, (i32 16)))),
|
||||
(PACK GPR:$rs1, GPR:$rs2)>;
|
||||
|
||||
let Predicates = [HasStdExtZbp, IsRV32] in
|
||||
def : Pat<(i32 (or (and GPR:$rs2, 0xFFFF0000), (srl GPR:$rs1, (i32 16)))),
|
||||
(PACKU GPR:$rs1, GPR:$rs2)>;
|
||||
|
||||
}
|
||||
let Predicates = [HasStdExtZbp, IsRV64] in {
|
||||
let Predicates = [HasStdExtZbpOrZbkb, IsRV64] in
|
||||
def : Pat<(i64 (or (and GPR:$rs1, 0x00000000FFFFFFFF), (shl GPR:$rs2, (i64 32)))),
|
||||
(PACK GPR:$rs1, GPR:$rs2)>;
|
||||
|
||||
let Predicates = [HasStdExtZbp, IsRV64] in
|
||||
def : Pat<(i64 (or (and GPR:$rs2, 0xFFFFFFFF00000000), (srl GPR:$rs1, (i64 32)))),
|
||||
(PACKU GPR:$rs1, GPR:$rs2)>;
|
||||
}
|
||||
let Predicates = [HasStdExtZbp] in {
|
||||
|
||||
let Predicates = [HasStdExtZbpOrZbkb] in {
|
||||
def : Pat<(or (and (shl GPR:$rs2, (XLenVT 8)), 0xFFFF),
|
||||
(and GPR:$rs1, 0x00FF)),
|
||||
(PACKH GPR:$rs1, GPR:$rs2)>;
|
||||
def : Pat<(or (shl (and GPR:$rs2, 0x00FF), (XLenVT 8)),
|
||||
(and GPR:$rs1, 0x00FF)),
|
||||
(PACKH GPR:$rs1, GPR:$rs2)>;
|
||||
}
|
||||
} // Predicates = [HasStdExtZbpOrZbkb]
|
||||
|
||||
let Predicates = [HasStdExtZbbOrZbp, IsRV32] in
|
||||
def : Pat<(i32 (and GPR:$rs, 0xFFFF)), (ZEXTH_RV32 GPR:$rs)>;
|
||||
|
@ -1091,13 +1094,13 @@ def : Pat<(i64 (add (and (shl GPR:$rs1, (i64 3)), 0x7FFFFFFFF), non_imm12:$rs2))
|
|||
(SH3ADDUW GPR:$rs1, GPR:$rs2)>;
|
||||
} // Predicates = [HasStdExtZba, IsRV64]
|
||||
|
||||
let Predicates = [HasStdExtZbbOrZbp, IsRV64] in {
|
||||
let Predicates = [HasStdExtZbbOrZbpOrZbkb, IsRV64] in {
|
||||
def : PatGprGpr<riscv_rolw, ROLW>;
|
||||
def : PatGprGpr<riscv_rorw, RORW>;
|
||||
def : PatGprImm<riscv_rorw, RORIW, uimm5>;
|
||||
def : Pat<(riscv_rolw GPR:$rs1, uimm5:$rs2),
|
||||
(RORIW GPR:$rs1, (ImmSubFrom32 uimm5:$rs2))>;
|
||||
} // Predicates = [HasStdExtZbbOrZbp, IsRV64]
|
||||
} // Predicates = [HasStdExtZbbOrZbpOrZbkb, IsRV64]
|
||||
|
||||
let Predicates = [HasStdExtZbp, IsRV64] in {
|
||||
def : Pat<(riscv_rorw (riscv_grevw GPR:$rs1, 24), 16), (GREVIW GPR:$rs1, 8)>;
|
||||
|
@ -1129,7 +1132,7 @@ def : PatGpr<riscv_ctzw, CTZW>;
|
|||
def : Pat<(i64 (ctpop (i64 (zexti32 (i64 GPR:$rs1))))), (CPOPW GPR:$rs1)>;
|
||||
} // Predicates = [HasStdExtZbb, IsRV64]
|
||||
|
||||
let Predicates = [HasStdExtZbp, IsRV64] in {
|
||||
let Predicates = [HasStdExtZbpOrZbkb, IsRV64] in {
|
||||
def : Pat<(i64 (sext_inreg (or (shl GPR:$rs2, (i64 16)),
|
||||
(and GPR:$rs1, 0x000000000000FFFF)),
|
||||
i32)),
|
||||
|
@ -1137,16 +1140,21 @@ def : Pat<(i64 (sext_inreg (or (shl GPR:$rs2, (i64 16)),
|
|||
def : Pat<(i64 (or (sext_inreg (shl GPR:$rs2, (i64 16)), i32),
|
||||
(and GPR:$rs1, 0x000000000000FFFF))),
|
||||
(PACKW GPR:$rs1, GPR:$rs2)>;
|
||||
}
|
||||
|
||||
let Predicates = [HasStdExtZbp, IsRV64] in
|
||||
def : Pat<(i64 (or (and (assertsexti32 GPR:$rs2), 0xFFFFFFFFFFFF0000),
|
||||
(srl (and GPR:$rs1, 0xFFFFFFFF), (i64 16)))),
|
||||
(PACKUW GPR:$rs1, GPR:$rs2)>;
|
||||
} // Predicates = [HasStdExtZbp, IsRV64]
|
||||
|
||||
let Predicates = [HasStdExtZbc] in {
|
||||
|
||||
let Predicates = [HasStdExtZbcOrZbkc] in {
|
||||
def : PatGprGpr<int_riscv_clmul, CLMUL>;
|
||||
def : PatGprGpr<int_riscv_clmulh, CLMULH>;
|
||||
} // Predicates = [HasStdExtZbcOrZbkc]
|
||||
|
||||
let Predicates = [HasStdExtZbc] in
|
||||
def : PatGprGpr<int_riscv_clmulr, CLMULR>;
|
||||
} // Predicates = [HasStdExtZbc]
|
||||
|
||||
let Predicates = [HasStdExtZbe] in {
|
||||
def : PatGprGpr<riscv_bcompress, BCOMPRESS>;
|
||||
|
@ -1177,3 +1185,17 @@ def : PatGprGpr<riscv_bfp, BFP>;
|
|||
|
||||
let Predicates = [HasStdExtZbf, IsRV64] in
|
||||
def : PatGprGpr<riscv_bfpw, BFPW>;
|
||||
|
||||
let Predicates = [HasStdExtZbkb] in {
|
||||
def : PatGpr<int_riscv_brev8, BREV8>;
|
||||
} // Predicates = [HasStdExtZbkb]
|
||||
|
||||
let Predicates = [HasStdExtZbkb, IsRV32] in {
|
||||
def : PatGpr<int_riscv_zip, ZIP_RV32>;
|
||||
def : PatGpr<int_riscv_unzip, UNZIP_RV32>;
|
||||
} // Predicates = [HasStdExtZbkb, IsRV32]
|
||||
|
||||
let Predicates = [HasStdExtZbkx] in {
|
||||
def : PatGprGpr<int_riscv_xperm4, XPERMN>;
|
||||
def : PatGprGpr<int_riscv_xperm8, XPERMB>;
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ def RnumArg : AsmOperandClass {
|
|||
let DiagnosticType = "InvalidRnumArg";
|
||||
}
|
||||
|
||||
def rnum : Operand<XLenVT>, ImmLeaf<XLenVT, [{return (Imm >= 0 && Imm <= 10);}]> {
|
||||
def rnum : Operand<i32>, TImmLeaf<i32, [{return (Imm >= 0 && Imm <= 10);}]> {
|
||||
let ParserMatchClass = RnumArg;
|
||||
let EncoderMethod = "getImmOpValue";
|
||||
let DecoderMethod = "decodeUImmOperand<4>";
|
||||
|
@ -29,6 +29,13 @@ def rnum : Operand<XLenVT>, ImmLeaf<XLenVT, [{return (Imm >= 0 && Imm <= 10);}]>
|
|||
let OperandNamespace = "RISCVOp";
|
||||
}
|
||||
|
||||
def byteselect : Operand<i8>, TImmLeaf<i8, [{return isUInt<2>(Imm);}]> {
|
||||
let ParserMatchClass = UImmAsmOperand<2>;
|
||||
let DecoderMethod = "decodeUImmOperand<2>";
|
||||
let OperandType = "OPERAND_UIMM2";
|
||||
let OperandNamespace = "RISCVOp";
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Instruction class templates
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -42,7 +49,7 @@ class RVKUnary<bits<12> imm12_in, bits<3> funct3, string opcodestr>
|
|||
let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
|
||||
class RVKByteSelect<bits<5> funct5, string opcodestr>
|
||||
: RVInstR<{0b00, funct5}, 0b000, OPC_OP, (outs GPR:$rd),
|
||||
(ins GPR:$rs1, GPR:$rs2, uimm2:$bs),
|
||||
(ins GPR:$rs1, GPR:$rs2, byteselect:$bs),
|
||||
opcodestr, "$rd, $rs1, $rs2, $bs">{
|
||||
bits<2> bs;
|
||||
let Inst{31-30} = bs;
|
||||
|
@ -121,3 +128,76 @@ let Predicates = [HasStdExtZksh] in {
|
|||
def SM3P0 : RVKUnary<0b000100001000, 0b001, "sm3p0">;
|
||||
def SM3P1 : RVKUnary<0b000100001001, 0b001, "sm3p1">;
|
||||
} // Predicates = [HasStdExtZksh]
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Codegen patterns
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
class PatGprGprByteSelect<SDPatternOperator OpNode, RVInst Inst>
|
||||
: Pat<(OpNode GPR:$rs1, GPR:$rs2, i8:$imm),
|
||||
(Inst GPR:$rs1, GPR:$rs2, byteselect:$imm)>;
|
||||
|
||||
// Zknd
|
||||
let Predicates = [HasStdExtZknd, IsRV32] in {
|
||||
def : PatGprGprByteSelect<int_riscv_aes32dsi, AES32DSI>;
|
||||
def : PatGprGprByteSelect<int_riscv_aes32dsmi, AES32DSMI>;
|
||||
} // Predicates = [HasStdExtZknd, IsRV32]
|
||||
|
||||
let Predicates = [HasStdExtZknd, IsRV64] in {
|
||||
def : PatGprGpr<int_riscv_aes64ds, AES64DS>;
|
||||
def : PatGprGpr<int_riscv_aes64dsm, AES64DSM>;
|
||||
def : PatGpr<int_riscv_aes64im, AES64IM>;
|
||||
} // Predicates = [HasStdExtZknd, IsRV64]
|
||||
|
||||
let Predicates = [HasStdExtZkndOrZkne, IsRV64] in {
|
||||
def : PatGprGpr<int_riscv_aes64ks2, AES64KS2>;
|
||||
def : Pat<(int_riscv_aes64ks1i GPR:$rs1, i32:$rnum),
|
||||
(AES64KS1I GPR:$rs1, rnum:$rnum)>;
|
||||
} // Predicates = [HasStdExtZkndOrZkne, IsRV64]
|
||||
|
||||
// Zkne
|
||||
let Predicates = [HasStdExtZkne, IsRV32] in {
|
||||
def : PatGprGprByteSelect<int_riscv_aes32esi, AES32ESI>;
|
||||
def : PatGprGprByteSelect<int_riscv_aes32esmi, AES32ESMI>;
|
||||
} // Predicates = [HasStdExtZkne, IsRV32]
|
||||
|
||||
let Predicates = [HasStdExtZkne, IsRV64] in {
|
||||
def : PatGprGpr<int_riscv_aes64es, AES64ES>;
|
||||
def : PatGprGpr<int_riscv_aes64esm, AES64ESM>;
|
||||
} // Predicates = [HasStdExtZkne, IsRV64]
|
||||
|
||||
// Zknh
|
||||
let Predicates = [HasStdExtZknh] in {
|
||||
def : PatGpr<int_riscv_sha256sig0, SHA256SIG0>;
|
||||
def : PatGpr<int_riscv_sha256sig1, SHA256SIG1>;
|
||||
def : PatGpr<int_riscv_sha256sum0, SHA256SUM0>;
|
||||
def : PatGpr<int_riscv_sha256sum1, SHA256SUM1>;
|
||||
} // Predicates = [HasStdExtZknh]
|
||||
|
||||
let Predicates = [HasStdExtZknh, IsRV32] in {
|
||||
def : PatGprGpr<int_riscv_sha512sig0l, SHA512SIG0L>;
|
||||
def : PatGprGpr<int_riscv_sha512sig0h, SHA512SIG0H>;
|
||||
def : PatGprGpr<int_riscv_sha512sig1l, SHA512SIG1L>;
|
||||
def : PatGprGpr<int_riscv_sha512sig1h, SHA512SIG1H>;
|
||||
def : PatGprGpr<int_riscv_sha512sum0r, SHA512SUM0R>;
|
||||
def : PatGprGpr<int_riscv_sha512sum1r, SHA512SUM1R>;
|
||||
} // Predicates = [HasStdExtZknh, IsRV32]
|
||||
|
||||
let Predicates = [HasStdExtZknh, IsRV64] in {
|
||||
def : PatGpr<int_riscv_sha512sig0, SHA512SIG0>;
|
||||
def : PatGpr<int_riscv_sha512sig1, SHA512SIG1>;
|
||||
def : PatGpr<int_riscv_sha512sum0, SHA512SUM0>;
|
||||
def : PatGpr<int_riscv_sha512sum1, SHA512SUM1>;
|
||||
} // Predicates = [HasStdExtZknh, IsRV64]
|
||||
|
||||
// Zksed
|
||||
let Predicates = [HasStdExtZksed] in {
|
||||
def : PatGprGprByteSelect<int_riscv_sm4ks, SM4KS>;
|
||||
def : PatGprGprByteSelect<int_riscv_sm4ed, SM4ED>;
|
||||
} // Predicates = [HasStdExtZksed]
|
||||
|
||||
// Zksh
|
||||
let Predicates = [HasStdExtZksh] in {
|
||||
def : PatGpr<int_riscv_sm3p0, SM3P0>;
|
||||
def : PatGpr<int_riscv_sm3p1, SM3P1>;
|
||||
} // Predicates = [HasStdExtZksh]
|
||||
|
|
|
@ -0,0 +1,502 @@
|
|||
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
|
||||
; RUN: llc -mtriple=riscv32 -verify-machineinstrs < %s \
|
||||
; RUN: | FileCheck %s -check-prefixes=RV32I
|
||||
; RUN: llc -mtriple=riscv32 -mattr=+zbb -verify-machineinstrs < %s \
|
||||
; RUN: | FileCheck %s -check-prefixes=RV32ZBB-ZBP-ZBKB
|
||||
; RUN: llc -mtriple=riscv32 -mattr=+experimental-zbp -verify-machineinstrs < %s \
|
||||
; RUN: | FileCheck %s -check-prefixes=RV32ZBB-ZBP-ZBKB
|
||||
; RUN: llc -mtriple=riscv32 -mattr=+zbkb -verify-machineinstrs < %s \
|
||||
; RUN: | FileCheck %s -check-prefixes=RV32ZBB-ZBP-ZBKB
|
||||
|
||||
define i32 @andn_i32(i32 %a, i32 %b) nounwind {
|
||||
; RV32I-LABEL: andn_i32:
|
||||
; RV32I: # %bb.0:
|
||||
; RV32I-NEXT: not a1, a1
|
||||
; RV32I-NEXT: and a0, a1, a0
|
||||
; RV32I-NEXT: ret
|
||||
;
|
||||
; RV32ZBB-ZBP-ZBKB-LABEL: andn_i32:
|
||||
; RV32ZBB-ZBP-ZBKB: # %bb.0:
|
||||
; RV32ZBB-ZBP-ZBKB-NEXT: andn a0, a0, a1
|
||||
; RV32ZBB-ZBP-ZBKB-NEXT: ret
|
||||
%neg = xor i32 %b, -1
|
||||
%and = and i32 %neg, %a
|
||||
ret i32 %and
|
||||
}
|
||||
|
||||
define i64 @andn_i64(i64 %a, i64 %b) nounwind {
|
||||
; RV32I-LABEL: andn_i64:
|
||||
; RV32I: # %bb.0:
|
||||
; RV32I-NEXT: not a3, a3
|
||||
; RV32I-NEXT: not a2, a2
|
||||
; RV32I-NEXT: and a0, a2, a0
|
||||
; RV32I-NEXT: and a1, a3, a1
|
||||
; RV32I-NEXT: ret
|
||||
;
|
||||
; RV32ZBB-ZBP-ZBKB-LABEL: andn_i64:
|
||||
; RV32ZBB-ZBP-ZBKB: # %bb.0:
|
||||
; RV32ZBB-ZBP-ZBKB-NEXT: andn a0, a0, a2
|
||||
; RV32ZBB-ZBP-ZBKB-NEXT: andn a1, a1, a3
|
||||
; RV32ZBB-ZBP-ZBKB-NEXT: ret
|
||||
%neg = xor i64 %b, -1
|
||||
%and = and i64 %neg, %a
|
||||
ret i64 %and
|
||||
}
|
||||
|
||||
define i32 @orn_i32(i32 %a, i32 %b) nounwind {
|
||||
; RV32I-LABEL: orn_i32:
|
||||
; RV32I: # %bb.0:
|
||||
; RV32I-NEXT: not a1, a1
|
||||
; RV32I-NEXT: or a0, a1, a0
|
||||
; RV32I-NEXT: ret
|
||||
;
|
||||
; RV32ZBB-ZBP-ZBKB-LABEL: orn_i32:
|
||||
; RV32ZBB-ZBP-ZBKB: # %bb.0:
|
||||
; RV32ZBB-ZBP-ZBKB-NEXT: orn a0, a0, a1
|
||||
; RV32ZBB-ZBP-ZBKB-NEXT: ret
|
||||
%neg = xor i32 %b, -1
|
||||
%or = or i32 %neg, %a
|
||||
ret i32 %or
|
||||
}
|
||||
|
||||
define i64 @orn_i64(i64 %a, i64 %b) nounwind {
|
||||
; RV32I-LABEL: orn_i64:
|
||||
; RV32I: # %bb.0:
|
||||
; RV32I-NEXT: not a3, a3
|
||||
; RV32I-NEXT: not a2, a2
|
||||
; RV32I-NEXT: or a0, a2, a0
|
||||
; RV32I-NEXT: or a1, a3, a1
|
||||
; RV32I-NEXT: ret
|
||||
;
|
||||
; RV32ZBB-ZBP-ZBKB-LABEL: orn_i64:
|
||||
; RV32ZBB-ZBP-ZBKB: # %bb.0:
|
||||
; RV32ZBB-ZBP-ZBKB-NEXT: orn a0, a0, a2
|
||||
; RV32ZBB-ZBP-ZBKB-NEXT: orn a1, a1, a3
|
||||
; RV32ZBB-ZBP-ZBKB-NEXT: ret
|
||||
%neg = xor i64 %b, -1
|
||||
%or = or i64 %neg, %a
|
||||
ret i64 %or
|
||||
}
|
||||
|
||||
define i32 @xnor_i32(i32 %a, i32 %b) nounwind {
|
||||
; RV32I-LABEL: xnor_i32:
|
||||
; RV32I: # %bb.0:
|
||||
; RV32I-NEXT: xor a0, a0, a1
|
||||
; RV32I-NEXT: not a0, a0
|
||||
; RV32I-NEXT: ret
|
||||
;
|
||||
; RV32ZBB-ZBP-ZBKB-LABEL: xnor_i32:
|
||||
; RV32ZBB-ZBP-ZBKB: # %bb.0:
|
||||
; RV32ZBB-ZBP-ZBKB-NEXT: xnor a0, a0, a1
|
||||
; RV32ZBB-ZBP-ZBKB-NEXT: ret
|
||||
%neg = xor i32 %a, -1
|
||||
%xor = xor i32 %neg, %b
|
||||
ret i32 %xor
|
||||
}
|
||||
|
||||
define i64 @xnor_i64(i64 %a, i64 %b) nounwind {
|
||||
; RV32I-LABEL: xnor_i64:
|
||||
; RV32I: # %bb.0:
|
||||
; RV32I-NEXT: xor a1, a1, a3
|
||||
; RV32I-NEXT: xor a0, a0, a2
|
||||
; RV32I-NEXT: not a0, a0
|
||||
; RV32I-NEXT: not a1, a1
|
||||
; RV32I-NEXT: ret
|
||||
;
|
||||
; RV32ZBB-ZBP-ZBKB-LABEL: xnor_i64:
|
||||
; RV32ZBB-ZBP-ZBKB: # %bb.0:
|
||||
; RV32ZBB-ZBP-ZBKB-NEXT: xnor a0, a0, a2
|
||||
; RV32ZBB-ZBP-ZBKB-NEXT: xnor a1, a1, a3
|
||||
; RV32ZBB-ZBP-ZBKB-NEXT: ret
|
||||
%neg = xor i64 %a, -1
|
||||
%xor = xor i64 %neg, %b
|
||||
ret i64 %xor
|
||||
}
|
||||
|
||||
declare i32 @llvm.fshl.i32(i32, i32, i32)
|
||||
|
||||
define i32 @rol_i32(i32 %a, i32 %b) nounwind {
|
||||
; RV32I-LABEL: rol_i32:
|
||||
; RV32I: # %bb.0:
|
||||
; RV32I-NEXT: sll a2, a0, a1
|
||||
; RV32I-NEXT: neg a1, a1
|
||||
; RV32I-NEXT: srl a0, a0, a1
|
||||
; RV32I-NEXT: or a0, a2, a0
|
||||
; RV32I-NEXT: ret
|
||||
;
|
||||
; RV32ZBB-ZBP-ZBKB-LABEL: rol_i32:
|
||||
; RV32ZBB-ZBP-ZBKB: # %bb.0:
|
||||
; RV32ZBB-ZBP-ZBKB-NEXT: rol a0, a0, a1
|
||||
; RV32ZBB-ZBP-ZBKB-NEXT: ret
|
||||
%or = tail call i32 @llvm.fshl.i32(i32 %a, i32 %a, i32 %b)
|
||||
ret i32 %or
|
||||
}
|
||||
|
||||
; This test is presented here in case future expansions of the Bitmanip
|
||||
; extensions introduce instructions suitable for this pattern.
|
||||
|
||||
declare i64 @llvm.fshl.i64(i64, i64, i64)
|
||||
|
||||
define i64 @rol_i64(i64 %a, i64 %b) nounwind {
|
||||
; RV32I-LABEL: rol_i64:
|
||||
; RV32I: # %bb.0:
|
||||
; RV32I-NEXT: srli a3, a2, 5
|
||||
; RV32I-NEXT: andi a3, a3, 1
|
||||
; RV32I-NEXT: mv a4, a1
|
||||
; RV32I-NEXT: bnez a3, .LBB7_2
|
||||
; RV32I-NEXT: # %bb.1:
|
||||
; RV32I-NEXT: mv a4, a0
|
||||
; RV32I-NEXT: .LBB7_2:
|
||||
; RV32I-NEXT: sll a5, a4, a2
|
||||
; RV32I-NEXT: bnez a3, .LBB7_4
|
||||
; RV32I-NEXT: # %bb.3:
|
||||
; RV32I-NEXT: mv a0, a1
|
||||
; RV32I-NEXT: .LBB7_4:
|
||||
; RV32I-NEXT: srli a1, a0, 1
|
||||
; RV32I-NEXT: not a6, a2
|
||||
; RV32I-NEXT: srl a1, a1, a6
|
||||
; RV32I-NEXT: or a3, a5, a1
|
||||
; RV32I-NEXT: sll a0, a0, a2
|
||||
; RV32I-NEXT: srli a1, a4, 1
|
||||
; RV32I-NEXT: srl a1, a1, a6
|
||||
; RV32I-NEXT: or a1, a0, a1
|
||||
; RV32I-NEXT: mv a0, a3
|
||||
; RV32I-NEXT: ret
|
||||
;
|
||||
; RV32ZBB-ZBP-ZBKB-LABEL: rol_i64:
|
||||
; RV32ZBB-ZBP-ZBKB: # %bb.0:
|
||||
; RV32ZBB-ZBP-ZBKB-NEXT: srli a3, a2, 5
|
||||
; RV32ZBB-ZBP-ZBKB-NEXT: andi a3, a3, 1
|
||||
; RV32ZBB-ZBP-ZBKB-NEXT: mv a4, a1
|
||||
; RV32ZBB-ZBP-ZBKB-NEXT: bnez a3, .LBB7_2
|
||||
; RV32ZBB-ZBP-ZBKB-NEXT: # %bb.1:
|
||||
; RV32ZBB-ZBP-ZBKB-NEXT: mv a4, a0
|
||||
; RV32ZBB-ZBP-ZBKB-NEXT: .LBB7_2:
|
||||
; RV32ZBB-ZBP-ZBKB-NEXT: sll a5, a4, a2
|
||||
; RV32ZBB-ZBP-ZBKB-NEXT: bnez a3, .LBB7_4
|
||||
; RV32ZBB-ZBP-ZBKB-NEXT: # %bb.3:
|
||||
; RV32ZBB-ZBP-ZBKB-NEXT: mv a0, a1
|
||||
; RV32ZBB-ZBP-ZBKB-NEXT: .LBB7_4:
|
||||
; RV32ZBB-ZBP-ZBKB-NEXT: srli a1, a0, 1
|
||||
; RV32ZBB-ZBP-ZBKB-NEXT: not a6, a2
|
||||
; RV32ZBB-ZBP-ZBKB-NEXT: srl a1, a1, a6
|
||||
; RV32ZBB-ZBP-ZBKB-NEXT: or a3, a5, a1
|
||||
; RV32ZBB-ZBP-ZBKB-NEXT: sll a0, a0, a2
|
||||
; RV32ZBB-ZBP-ZBKB-NEXT: srli a1, a4, 1
|
||||
; RV32ZBB-ZBP-ZBKB-NEXT: srl a1, a1, a6
|
||||
; RV32ZBB-ZBP-ZBKB-NEXT: or a1, a0, a1
|
||||
; RV32ZBB-ZBP-ZBKB-NEXT: mv a0, a3
|
||||
; RV32ZBB-ZBP-ZBKB-NEXT: ret
|
||||
%or = tail call i64 @llvm.fshl.i64(i64 %a, i64 %a, i64 %b)
|
||||
ret i64 %or
|
||||
}
|
||||
|
||||
declare i32 @llvm.fshr.i32(i32, i32, i32)
|
||||
|
||||
define i32 @ror_i32(i32 %a, i32 %b) nounwind {
|
||||
; RV32I-LABEL: ror_i32:
|
||||
; RV32I: # %bb.0:
|
||||
; RV32I-NEXT: srl a2, a0, a1
|
||||
; RV32I-NEXT: neg a1, a1
|
||||
; RV32I-NEXT: sll a0, a0, a1
|
||||
; RV32I-NEXT: or a0, a2, a0
|
||||
; RV32I-NEXT: ret
|
||||
;
|
||||
; RV32ZBB-ZBP-ZBKB-LABEL: ror_i32:
|
||||
; RV32ZBB-ZBP-ZBKB: # %bb.0:
|
||||
; RV32ZBB-ZBP-ZBKB-NEXT: ror a0, a0, a1
|
||||
; RV32ZBB-ZBP-ZBKB-NEXT: ret
|
||||
%or = tail call i32 @llvm.fshr.i32(i32 %a, i32 %a, i32 %b)
|
||||
ret i32 %or
|
||||
}
|
||||
|
||||
; This test is presented here in case future expansions of the Bitmanip
|
||||
; extensions introduce instructions suitable for this pattern.
|
||||
|
||||
declare i64 @llvm.fshr.i64(i64, i64, i64)
|
||||
|
||||
define i64 @ror_i64(i64 %a, i64 %b) nounwind {
|
||||
; RV32I-LABEL: ror_i64:
|
||||
; RV32I: # %bb.0:
|
||||
; RV32I-NEXT: andi a4, a2, 32
|
||||
; RV32I-NEXT: mv a3, a0
|
||||
; RV32I-NEXT: beqz a4, .LBB9_2
|
||||
; RV32I-NEXT: # %bb.1:
|
||||
; RV32I-NEXT: mv a3, a1
|
||||
; RV32I-NEXT: .LBB9_2:
|
||||
; RV32I-NEXT: srl a5, a3, a2
|
||||
; RV32I-NEXT: beqz a4, .LBB9_4
|
||||
; RV32I-NEXT: # %bb.3:
|
||||
; RV32I-NEXT: mv a1, a0
|
||||
; RV32I-NEXT: .LBB9_4:
|
||||
; RV32I-NEXT: slli a0, a1, 1
|
||||
; RV32I-NEXT: not a4, a2
|
||||
; RV32I-NEXT: sll a0, a0, a4
|
||||
; RV32I-NEXT: or a0, a0, a5
|
||||
; RV32I-NEXT: srl a1, a1, a2
|
||||
; RV32I-NEXT: slli a2, a3, 1
|
||||
; RV32I-NEXT: sll a2, a2, a4
|
||||
; RV32I-NEXT: or a1, a2, a1
|
||||
; RV32I-NEXT: ret
|
||||
;
|
||||
; RV32ZBB-ZBP-ZBKB-LABEL: ror_i64:
|
||||
; RV32ZBB-ZBP-ZBKB: # %bb.0:
|
||||
; RV32ZBB-ZBP-ZBKB-NEXT: andi a4, a2, 32
|
||||
; RV32ZBB-ZBP-ZBKB-NEXT: mv a3, a0
|
||||
; RV32ZBB-ZBP-ZBKB-NEXT: beqz a4, .LBB9_2
|
||||
; RV32ZBB-ZBP-ZBKB-NEXT: # %bb.1:
|
||||
; RV32ZBB-ZBP-ZBKB-NEXT: mv a3, a1
|
||||
; RV32ZBB-ZBP-ZBKB-NEXT: .LBB9_2:
|
||||
; RV32ZBB-ZBP-ZBKB-NEXT: srl a5, a3, a2
|
||||
; RV32ZBB-ZBP-ZBKB-NEXT: beqz a4, .LBB9_4
|
||||
; RV32ZBB-ZBP-ZBKB-NEXT: # %bb.3:
|
||||
; RV32ZBB-ZBP-ZBKB-NEXT: mv a1, a0
|
||||
; RV32ZBB-ZBP-ZBKB-NEXT: .LBB9_4:
|
||||
; RV32ZBB-ZBP-ZBKB-NEXT: slli a0, a1, 1
|
||||
; RV32ZBB-ZBP-ZBKB-NEXT: not a4, a2
|
||||
; RV32ZBB-ZBP-ZBKB-NEXT: sll a0, a0, a4
|
||||
; RV32ZBB-ZBP-ZBKB-NEXT: or a0, a0, a5
|
||||
; RV32ZBB-ZBP-ZBKB-NEXT: srl a1, a1, a2
|
||||
; RV32ZBB-ZBP-ZBKB-NEXT: slli a2, a3, 1
|
||||
; RV32ZBB-ZBP-ZBKB-NEXT: sll a2, a2, a4
|
||||
; RV32ZBB-ZBP-ZBKB-NEXT: or a1, a2, a1
|
||||
; RV32ZBB-ZBP-ZBKB-NEXT: ret
|
||||
%or = tail call i64 @llvm.fshr.i64(i64 %a, i64 %a, i64 %b)
|
||||
ret i64 %or
|
||||
}
|
||||
|
||||
define i32 @rori_i32_fshl(i32 %a) nounwind {
|
||||
; RV32I-LABEL: rori_i32_fshl:
|
||||
; RV32I: # %bb.0:
|
||||
; RV32I-NEXT: srli a1, a0, 1
|
||||
; RV32I-NEXT: slli a0, a0, 31
|
||||
; RV32I-NEXT: or a0, a0, a1
|
||||
; RV32I-NEXT: ret
|
||||
;
|
||||
; RV32ZBB-ZBP-ZBKB-LABEL: rori_i32_fshl:
|
||||
; RV32ZBB-ZBP-ZBKB: # %bb.0:
|
||||
; RV32ZBB-ZBP-ZBKB-NEXT: rori a0, a0, 1
|
||||
; RV32ZBB-ZBP-ZBKB-NEXT: ret
|
||||
%1 = tail call i32 @llvm.fshl.i32(i32 %a, i32 %a, i32 31)
|
||||
ret i32 %1
|
||||
}
|
||||
|
||||
define i32 @rori_i32_fshr(i32 %a) nounwind {
|
||||
; RV32I-LABEL: rori_i32_fshr:
|
||||
; RV32I: # %bb.0:
|
||||
; RV32I-NEXT: slli a1, a0, 1
|
||||
; RV32I-NEXT: srli a0, a0, 31
|
||||
; RV32I-NEXT: or a0, a0, a1
|
||||
; RV32I-NEXT: ret
|
||||
;
|
||||
; RV32ZBB-ZBP-ZBKB-LABEL: rori_i32_fshr:
|
||||
; RV32ZBB-ZBP-ZBKB: # %bb.0:
|
||||
; RV32ZBB-ZBP-ZBKB-NEXT: rori a0, a0, 31
|
||||
; RV32ZBB-ZBP-ZBKB-NEXT: ret
|
||||
%1 = tail call i32 @llvm.fshr.i32(i32 %a, i32 %a, i32 31)
|
||||
ret i32 %1
|
||||
}
|
||||
|
||||
define i64 @rori_i64(i64 %a) nounwind {
|
||||
; RV32I-LABEL: rori_i64:
|
||||
; RV32I: # %bb.0:
|
||||
; RV32I-NEXT: srli a2, a0, 1
|
||||
; RV32I-NEXT: slli a3, a1, 31
|
||||
; RV32I-NEXT: or a2, a3, a2
|
||||
; RV32I-NEXT: srli a1, a1, 1
|
||||
; RV32I-NEXT: slli a0, a0, 31
|
||||
; RV32I-NEXT: or a1, a0, a1
|
||||
; RV32I-NEXT: mv a0, a2
|
||||
; RV32I-NEXT: ret
|
||||
;
|
||||
; RV32ZBB-ZBP-ZBKB-LABEL: rori_i64:
|
||||
; RV32ZBB-ZBP-ZBKB: # %bb.0:
|
||||
; RV32ZBB-ZBP-ZBKB-NEXT: srli a2, a0, 1
|
||||
; RV32ZBB-ZBP-ZBKB-NEXT: slli a3, a1, 31
|
||||
; RV32ZBB-ZBP-ZBKB-NEXT: or a2, a3, a2
|
||||
; RV32ZBB-ZBP-ZBKB-NEXT: srli a1, a1, 1
|
||||
; RV32ZBB-ZBP-ZBKB-NEXT: slli a0, a0, 31
|
||||
; RV32ZBB-ZBP-ZBKB-NEXT: or a1, a0, a1
|
||||
; RV32ZBB-ZBP-ZBKB-NEXT: mv a0, a2
|
||||
; RV32ZBB-ZBP-ZBKB-NEXT: ret
|
||||
%1 = tail call i64 @llvm.fshl.i64(i64 %a, i64 %a, i64 63)
|
||||
ret i64 %1
|
||||
}
|
||||
|
||||
define i64 @rori_i64_fshr(i64 %a) nounwind {
|
||||
; RV32I-LABEL: rori_i64_fshr:
|
||||
; RV32I: # %bb.0:
|
||||
; RV32I-NEXT: srli a2, a1, 31
|
||||
; RV32I-NEXT: slli a3, a0, 1
|
||||
; RV32I-NEXT: or a2, a3, a2
|
||||
; RV32I-NEXT: srli a0, a0, 31
|
||||
; RV32I-NEXT: slli a1, a1, 1
|
||||
; RV32I-NEXT: or a1, a1, a0
|
||||
; RV32I-NEXT: mv a0, a2
|
||||
; RV32I-NEXT: ret
|
||||
;
|
||||
; RV32ZBB-ZBP-ZBKB-LABEL: rori_i64_fshr:
|
||||
; RV32ZBB-ZBP-ZBKB: # %bb.0:
|
||||
; RV32ZBB-ZBP-ZBKB-NEXT: srli a2, a1, 31
|
||||
; RV32ZBB-ZBP-ZBKB-NEXT: slli a3, a0, 1
|
||||
; RV32ZBB-ZBP-ZBKB-NEXT: or a2, a3, a2
|
||||
; RV32ZBB-ZBP-ZBKB-NEXT: srli a0, a0, 31
|
||||
; RV32ZBB-ZBP-ZBKB-NEXT: slli a1, a1, 1
|
||||
; RV32ZBB-ZBP-ZBKB-NEXT: or a1, a1, a0
|
||||
; RV32ZBB-ZBP-ZBKB-NEXT: mv a0, a2
|
||||
; RV32ZBB-ZBP-ZBKB-NEXT: ret
|
||||
%1 = tail call i64 @llvm.fshr.i64(i64 %a, i64 %a, i64 63)
|
||||
ret i64 %1
|
||||
}
|
||||
|
||||
define i8 @srli_i8(i8 %a) nounwind {
|
||||
; RV32I-LABEL: srli_i8:
|
||||
; RV32I: # %bb.0:
|
||||
; RV32I-NEXT: slli a0, a0, 24
|
||||
; RV32I-NEXT: srli a0, a0, 30
|
||||
; RV32I-NEXT: ret
|
||||
;
|
||||
; RV32ZBB-ZBP-ZBKB-LABEL: srli_i8:
|
||||
; RV32ZBB-ZBP-ZBKB: # %bb.0:
|
||||
; RV32ZBB-ZBP-ZBKB-NEXT: slli a0, a0, 24
|
||||
; RV32ZBB-ZBP-ZBKB-NEXT: srli a0, a0, 30
|
||||
; RV32ZBB-ZBP-ZBKB-NEXT: ret
|
||||
%1 = lshr i8 %a, 6
|
||||
ret i8 %1
|
||||
}
|
||||
|
||||
; We could use sext.b+srai, but slli+srai offers more opportunities for
|
||||
; comppressed instructions.
|
||||
define i8 @srai_i8(i8 %a) nounwind {
|
||||
; RV32I-LABEL: srai_i8:
|
||||
; RV32I: # %bb.0:
|
||||
; RV32I-NEXT: slli a0, a0, 24
|
||||
; RV32I-NEXT: srai a0, a0, 29
|
||||
; RV32I-NEXT: ret
|
||||
;
|
||||
; RV32ZBB-ZBP-ZBKB-LABEL: srai_i8:
|
||||
; RV32ZBB-ZBP-ZBKB: # %bb.0:
|
||||
; RV32ZBB-ZBP-ZBKB-NEXT: slli a0, a0, 24
|
||||
; RV32ZBB-ZBP-ZBKB-NEXT: srai a0, a0, 29
|
||||
; RV32ZBB-ZBP-ZBKB-NEXT: ret
|
||||
%1 = ashr i8 %a, 5
|
||||
ret i8 %1
|
||||
}
|
||||
|
||||
; We could use zext.h+srli, but slli+srli offers more opportunities for
|
||||
; comppressed instructions.
|
||||
define i16 @srli_i16(i16 %a) nounwind {
|
||||
; RV32I-LABEL: srli_i16:
|
||||
; RV32I: # %bb.0:
|
||||
; RV32I-NEXT: slli a0, a0, 16
|
||||
; RV32I-NEXT: srli a0, a0, 22
|
||||
; RV32I-NEXT: ret
|
||||
;
|
||||
; RV32ZBB-ZBP-ZBKB-LABEL: srli_i16:
|
||||
; RV32ZBB-ZBP-ZBKB: # %bb.0:
|
||||
; RV32ZBB-ZBP-ZBKB-NEXT: slli a0, a0, 16
|
||||
; RV32ZBB-ZBP-ZBKB-NEXT: srli a0, a0, 22
|
||||
; RV32ZBB-ZBP-ZBKB-NEXT: ret
|
||||
%1 = lshr i16 %a, 6
|
||||
ret i16 %1
|
||||
}
|
||||
|
||||
; We could use sext.h+srai, but slli+srai offers more opportunities for
|
||||
; comppressed instructions.
|
||||
define i16 @srai_i16(i16 %a) nounwind {
|
||||
; RV32I-LABEL: srai_i16:
|
||||
; RV32I: # %bb.0:
|
||||
; RV32I-NEXT: slli a0, a0, 16
|
||||
; RV32I-NEXT: srai a0, a0, 25
|
||||
; RV32I-NEXT: ret
|
||||
;
|
||||
; RV32ZBB-ZBP-ZBKB-LABEL: srai_i16:
|
||||
; RV32ZBB-ZBP-ZBKB: # %bb.0:
|
||||
; RV32ZBB-ZBP-ZBKB-NEXT: slli a0, a0, 16
|
||||
; RV32ZBB-ZBP-ZBKB-NEXT: srai a0, a0, 25
|
||||
; RV32ZBB-ZBP-ZBKB-NEXT: ret
|
||||
%1 = ashr i16 %a, 9
|
||||
ret i16 %1
|
||||
}
|
||||
|
||||
define i1 @andn_seqz_i32(i32 %a, i32 %b) nounwind {
|
||||
; RV32I-LABEL: andn_seqz_i32:
|
||||
; RV32I: # %bb.0:
|
||||
; RV32I-NEXT: and a0, a0, a1
|
||||
; RV32I-NEXT: xor a0, a0, a1
|
||||
; RV32I-NEXT: seqz a0, a0
|
||||
; RV32I-NEXT: ret
|
||||
;
|
||||
; RV32ZBB-ZBP-ZBKB-LABEL: andn_seqz_i32:
|
||||
; RV32ZBB-ZBP-ZBKB: # %bb.0:
|
||||
; RV32ZBB-ZBP-ZBKB-NEXT: andn a0, a1, a0
|
||||
; RV32ZBB-ZBP-ZBKB-NEXT: seqz a0, a0
|
||||
; RV32ZBB-ZBP-ZBKB-NEXT: ret
|
||||
%and = and i32 %a, %b
|
||||
%cmpeq = icmp eq i32 %and, %b
|
||||
ret i1 %cmpeq
|
||||
}
|
||||
|
||||
define i1 @andn_seqz_i64(i64 %a, i64 %b) nounwind {
|
||||
; RV32I-LABEL: andn_seqz_i64:
|
||||
; RV32I: # %bb.0:
|
||||
; RV32I-NEXT: not a0, a0
|
||||
; RV32I-NEXT: not a1, a1
|
||||
; RV32I-NEXT: and a1, a1, a3
|
||||
; RV32I-NEXT: and a0, a0, a2
|
||||
; RV32I-NEXT: or a0, a0, a1
|
||||
; RV32I-NEXT: seqz a0, a0
|
||||
; RV32I-NEXT: ret
|
||||
;
|
||||
; RV32ZBB-ZBP-ZBKB-LABEL: andn_seqz_i64:
|
||||
; RV32ZBB-ZBP-ZBKB: # %bb.0:
|
||||
; RV32ZBB-ZBP-ZBKB-NEXT: andn a1, a3, a1
|
||||
; RV32ZBB-ZBP-ZBKB-NEXT: andn a0, a2, a0
|
||||
; RV32ZBB-ZBP-ZBKB-NEXT: or a0, a0, a1
|
||||
; RV32ZBB-ZBP-ZBKB-NEXT: seqz a0, a0
|
||||
; RV32ZBB-ZBP-ZBKB-NEXT: ret
|
||||
%and = and i64 %a, %b
|
||||
%cmpeq = icmp eq i64 %and, %b
|
||||
ret i1 %cmpeq
|
||||
}
|
||||
|
||||
define i1 @andn_snez_i32(i32 %a, i32 %b) nounwind {
|
||||
; RV32I-LABEL: andn_snez_i32:
|
||||
; RV32I: # %bb.0:
|
||||
; RV32I-NEXT: and a0, a0, a1
|
||||
; RV32I-NEXT: xor a0, a0, a1
|
||||
; RV32I-NEXT: snez a0, a0
|
||||
; RV32I-NEXT: ret
|
||||
;
|
||||
; RV32ZBB-ZBP-ZBKB-LABEL: andn_snez_i32:
|
||||
; RV32ZBB-ZBP-ZBKB: # %bb.0:
|
||||
; RV32ZBB-ZBP-ZBKB-NEXT: andn a0, a1, a0
|
||||
; RV32ZBB-ZBP-ZBKB-NEXT: snez a0, a0
|
||||
; RV32ZBB-ZBP-ZBKB-NEXT: ret
|
||||
%and = and i32 %a, %b
|
||||
%cmpeq = icmp ne i32 %and, %b
|
||||
ret i1 %cmpeq
|
||||
}
|
||||
|
||||
define i1 @andn_snez_i64(i64 %a, i64 %b) nounwind {
|
||||
; RV32I-LABEL: andn_snez_i64:
|
||||
; RV32I: # %bb.0:
|
||||
; RV32I-NEXT: not a0, a0
|
||||
; RV32I-NEXT: not a1, a1
|
||||
; RV32I-NEXT: and a1, a1, a3
|
||||
; RV32I-NEXT: and a0, a0, a2
|
||||
; RV32I-NEXT: or a0, a0, a1
|
||||
; RV32I-NEXT: snez a0, a0
|
||||
; RV32I-NEXT: ret
|
||||
;
|
||||
; RV32ZBB-ZBP-ZBKB-LABEL: andn_snez_i64:
|
||||
; RV32ZBB-ZBP-ZBKB: # %bb.0:
|
||||
; RV32ZBB-ZBP-ZBKB-NEXT: andn a1, a3, a1
|
||||
; RV32ZBB-ZBP-ZBKB-NEXT: andn a0, a2, a0
|
||||
; RV32ZBB-ZBP-ZBKB-NEXT: or a0, a0, a1
|
||||
; RV32ZBB-ZBP-ZBKB-NEXT: snez a0, a0
|
||||
; RV32ZBB-ZBP-ZBKB-NEXT: ret
|
||||
%and = and i64 %a, %b
|
||||
%cmpeq = icmp ne i64 %and, %b
|
||||
ret i1 %cmpeq
|
||||
}
|
|
@ -1,675 +0,0 @@
|
|||
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
|
||||
; RUN: llc -mtriple=riscv32 -verify-machineinstrs < %s \
|
||||
; RUN: | FileCheck %s -check-prefix=RV32I
|
||||
; RUN: llc -mtriple=riscv32 -mattr=+zbb -verify-machineinstrs < %s \
|
||||
; RUN: | FileCheck %s -check-prefix=RV32ZBB
|
||||
; RUN: llc -mtriple=riscv32 -mattr=+experimental-zbp -verify-machineinstrs < %s \
|
||||
; RUN: | FileCheck %s -check-prefix=RV32ZBP
|
||||
|
||||
define i32 @andn_i32(i32 %a, i32 %b) nounwind {
|
||||
; RV32I-LABEL: andn_i32:
|
||||
; RV32I: # %bb.0:
|
||||
; RV32I-NEXT: not a1, a1
|
||||
; RV32I-NEXT: and a0, a1, a0
|
||||
; RV32I-NEXT: ret
|
||||
;
|
||||
; RV32ZBB-LABEL: andn_i32:
|
||||
; RV32ZBB: # %bb.0:
|
||||
; RV32ZBB-NEXT: andn a0, a0, a1
|
||||
; RV32ZBB-NEXT: ret
|
||||
;
|
||||
; RV32ZBP-LABEL: andn_i32:
|
||||
; RV32ZBP: # %bb.0:
|
||||
; RV32ZBP-NEXT: andn a0, a0, a1
|
||||
; RV32ZBP-NEXT: ret
|
||||
%neg = xor i32 %b, -1
|
||||
%and = and i32 %neg, %a
|
||||
ret i32 %and
|
||||
}
|
||||
|
||||
define i64 @andn_i64(i64 %a, i64 %b) nounwind {
|
||||
; RV32I-LABEL: andn_i64:
|
||||
; RV32I: # %bb.0:
|
||||
; RV32I-NEXT: not a3, a3
|
||||
; RV32I-NEXT: not a2, a2
|
||||
; RV32I-NEXT: and a0, a2, a0
|
||||
; RV32I-NEXT: and a1, a3, a1
|
||||
; RV32I-NEXT: ret
|
||||
;
|
||||
; RV32ZBB-LABEL: andn_i64:
|
||||
; RV32ZBB: # %bb.0:
|
||||
; RV32ZBB-NEXT: andn a0, a0, a2
|
||||
; RV32ZBB-NEXT: andn a1, a1, a3
|
||||
; RV32ZBB-NEXT: ret
|
||||
;
|
||||
; RV32ZBP-LABEL: andn_i64:
|
||||
; RV32ZBP: # %bb.0:
|
||||
; RV32ZBP-NEXT: andn a0, a0, a2
|
||||
; RV32ZBP-NEXT: andn a1, a1, a3
|
||||
; RV32ZBP-NEXT: ret
|
||||
%neg = xor i64 %b, -1
|
||||
%and = and i64 %neg, %a
|
||||
ret i64 %and
|
||||
}
|
||||
|
||||
define i32 @orn_i32(i32 %a, i32 %b) nounwind {
|
||||
; RV32I-LABEL: orn_i32:
|
||||
; RV32I: # %bb.0:
|
||||
; RV32I-NEXT: not a1, a1
|
||||
; RV32I-NEXT: or a0, a1, a0
|
||||
; RV32I-NEXT: ret
|
||||
;
|
||||
; RV32ZBB-LABEL: orn_i32:
|
||||
; RV32ZBB: # %bb.0:
|
||||
; RV32ZBB-NEXT: orn a0, a0, a1
|
||||
; RV32ZBB-NEXT: ret
|
||||
;
|
||||
; RV32ZBP-LABEL: orn_i32:
|
||||
; RV32ZBP: # %bb.0:
|
||||
; RV32ZBP-NEXT: orn a0, a0, a1
|
||||
; RV32ZBP-NEXT: ret
|
||||
%neg = xor i32 %b, -1
|
||||
%or = or i32 %neg, %a
|
||||
ret i32 %or
|
||||
}
|
||||
|
||||
define i64 @orn_i64(i64 %a, i64 %b) nounwind {
|
||||
; RV32I-LABEL: orn_i64:
|
||||
; RV32I: # %bb.0:
|
||||
; RV32I-NEXT: not a3, a3
|
||||
; RV32I-NEXT: not a2, a2
|
||||
; RV32I-NEXT: or a0, a2, a0
|
||||
; RV32I-NEXT: or a1, a3, a1
|
||||
; RV32I-NEXT: ret
|
||||
;
|
||||
; RV32ZBB-LABEL: orn_i64:
|
||||
; RV32ZBB: # %bb.0:
|
||||
; RV32ZBB-NEXT: orn a0, a0, a2
|
||||
; RV32ZBB-NEXT: orn a1, a1, a3
|
||||
; RV32ZBB-NEXT: ret
|
||||
;
|
||||
; RV32ZBP-LABEL: orn_i64:
|
||||
; RV32ZBP: # %bb.0:
|
||||
; RV32ZBP-NEXT: orn a0, a0, a2
|
||||
; RV32ZBP-NEXT: orn a1, a1, a3
|
||||
; RV32ZBP-NEXT: ret
|
||||
%neg = xor i64 %b, -1
|
||||
%or = or i64 %neg, %a
|
||||
ret i64 %or
|
||||
}
|
||||
|
||||
define i32 @xnor_i32(i32 %a, i32 %b) nounwind {
|
||||
; RV32I-LABEL: xnor_i32:
|
||||
; RV32I: # %bb.0:
|
||||
; RV32I-NEXT: xor a0, a0, a1
|
||||
; RV32I-NEXT: not a0, a0
|
||||
; RV32I-NEXT: ret
|
||||
;
|
||||
; RV32ZBB-LABEL: xnor_i32:
|
||||
; RV32ZBB: # %bb.0:
|
||||
; RV32ZBB-NEXT: xnor a0, a0, a1
|
||||
; RV32ZBB-NEXT: ret
|
||||
;
|
||||
; RV32ZBP-LABEL: xnor_i32:
|
||||
; RV32ZBP: # %bb.0:
|
||||
; RV32ZBP-NEXT: xnor a0, a0, a1
|
||||
; RV32ZBP-NEXT: ret
|
||||
%neg = xor i32 %a, -1
|
||||
%xor = xor i32 %neg, %b
|
||||
ret i32 %xor
|
||||
}
|
||||
|
||||
define i64 @xnor_i64(i64 %a, i64 %b) nounwind {
|
||||
; RV32I-LABEL: xnor_i64:
|
||||
; RV32I: # %bb.0:
|
||||
; RV32I-NEXT: xor a1, a1, a3
|
||||
; RV32I-NEXT: xor a0, a0, a2
|
||||
; RV32I-NEXT: not a0, a0
|
||||
; RV32I-NEXT: not a1, a1
|
||||
; RV32I-NEXT: ret
|
||||
;
|
||||
; RV32ZBB-LABEL: xnor_i64:
|
||||
; RV32ZBB: # %bb.0:
|
||||
; RV32ZBB-NEXT: xnor a0, a0, a2
|
||||
; RV32ZBB-NEXT: xnor a1, a1, a3
|
||||
; RV32ZBB-NEXT: ret
|
||||
;
|
||||
; RV32ZBP-LABEL: xnor_i64:
|
||||
; RV32ZBP: # %bb.0:
|
||||
; RV32ZBP-NEXT: xnor a0, a0, a2
|
||||
; RV32ZBP-NEXT: xnor a1, a1, a3
|
||||
; RV32ZBP-NEXT: ret
|
||||
%neg = xor i64 %a, -1
|
||||
%xor = xor i64 %neg, %b
|
||||
ret i64 %xor
|
||||
}
|
||||
|
||||
declare i32 @llvm.fshl.i32(i32, i32, i32)
|
||||
|
||||
define i32 @rol_i32(i32 %a, i32 %b) nounwind {
|
||||
; RV32I-LABEL: rol_i32:
|
||||
; RV32I: # %bb.0:
|
||||
; RV32I-NEXT: sll a2, a0, a1
|
||||
; RV32I-NEXT: neg a1, a1
|
||||
; RV32I-NEXT: srl a0, a0, a1
|
||||
; RV32I-NEXT: or a0, a2, a0
|
||||
; RV32I-NEXT: ret
|
||||
;
|
||||
; RV32ZBB-LABEL: rol_i32:
|
||||
; RV32ZBB: # %bb.0:
|
||||
; RV32ZBB-NEXT: rol a0, a0, a1
|
||||
; RV32ZBB-NEXT: ret
|
||||
;
|
||||
; RV32ZBP-LABEL: rol_i32:
|
||||
; RV32ZBP: # %bb.0:
|
||||
; RV32ZBP-NEXT: rol a0, a0, a1
|
||||
; RV32ZBP-NEXT: ret
|
||||
%or = tail call i32 @llvm.fshl.i32(i32 %a, i32 %a, i32 %b)
|
||||
ret i32 %or
|
||||
}
|
||||
|
||||
; This test is presented here in case future expansions of the Bitmanip
|
||||
; extensions introduce instructions suitable for this pattern.
|
||||
|
||||
declare i64 @llvm.fshl.i64(i64, i64, i64)
|
||||
|
||||
define i64 @rol_i64(i64 %a, i64 %b) nounwind {
|
||||
; RV32I-LABEL: rol_i64:
|
||||
; RV32I: # %bb.0:
|
||||
; RV32I-NEXT: srli a3, a2, 5
|
||||
; RV32I-NEXT: andi a3, a3, 1
|
||||
; RV32I-NEXT: mv a4, a1
|
||||
; RV32I-NEXT: bnez a3, .LBB7_2
|
||||
; RV32I-NEXT: # %bb.1:
|
||||
; RV32I-NEXT: mv a4, a0
|
||||
; RV32I-NEXT: .LBB7_2:
|
||||
; RV32I-NEXT: sll a5, a4, a2
|
||||
; RV32I-NEXT: bnez a3, .LBB7_4
|
||||
; RV32I-NEXT: # %bb.3:
|
||||
; RV32I-NEXT: mv a0, a1
|
||||
; RV32I-NEXT: .LBB7_4:
|
||||
; RV32I-NEXT: srli a1, a0, 1
|
||||
; RV32I-NEXT: not a6, a2
|
||||
; RV32I-NEXT: srl a1, a1, a6
|
||||
; RV32I-NEXT: or a3, a5, a1
|
||||
; RV32I-NEXT: sll a0, a0, a2
|
||||
; RV32I-NEXT: srli a1, a4, 1
|
||||
; RV32I-NEXT: srl a1, a1, a6
|
||||
; RV32I-NEXT: or a1, a0, a1
|
||||
; RV32I-NEXT: mv a0, a3
|
||||
; RV32I-NEXT: ret
|
||||
;
|
||||
; RV32ZBB-LABEL: rol_i64:
|
||||
; RV32ZBB: # %bb.0:
|
||||
; RV32ZBB-NEXT: srli a3, a2, 5
|
||||
; RV32ZBB-NEXT: andi a3, a3, 1
|
||||
; RV32ZBB-NEXT: mv a4, a1
|
||||
; RV32ZBB-NEXT: bnez a3, .LBB7_2
|
||||
; RV32ZBB-NEXT: # %bb.1:
|
||||
; RV32ZBB-NEXT: mv a4, a0
|
||||
; RV32ZBB-NEXT: .LBB7_2:
|
||||
; RV32ZBB-NEXT: sll a5, a4, a2
|
||||
; RV32ZBB-NEXT: bnez a3, .LBB7_4
|
||||
; RV32ZBB-NEXT: # %bb.3:
|
||||
; RV32ZBB-NEXT: mv a0, a1
|
||||
; RV32ZBB-NEXT: .LBB7_4:
|
||||
; RV32ZBB-NEXT: srli a1, a0, 1
|
||||
; RV32ZBB-NEXT: not a6, a2
|
||||
; RV32ZBB-NEXT: srl a1, a1, a6
|
||||
; RV32ZBB-NEXT: or a3, a5, a1
|
||||
; RV32ZBB-NEXT: sll a0, a0, a2
|
||||
; RV32ZBB-NEXT: srli a1, a4, 1
|
||||
; RV32ZBB-NEXT: srl a1, a1, a6
|
||||
; RV32ZBB-NEXT: or a1, a0, a1
|
||||
; RV32ZBB-NEXT: mv a0, a3
|
||||
; RV32ZBB-NEXT: ret
|
||||
;
|
||||
; RV32ZBP-LABEL: rol_i64:
|
||||
; RV32ZBP: # %bb.0:
|
||||
; RV32ZBP-NEXT: srli a3, a2, 5
|
||||
; RV32ZBP-NEXT: andi a3, a3, 1
|
||||
; RV32ZBP-NEXT: mv a4, a1
|
||||
; RV32ZBP-NEXT: bnez a3, .LBB7_2
|
||||
; RV32ZBP-NEXT: # %bb.1:
|
||||
; RV32ZBP-NEXT: mv a4, a0
|
||||
; RV32ZBP-NEXT: .LBB7_2:
|
||||
; RV32ZBP-NEXT: sll a5, a4, a2
|
||||
; RV32ZBP-NEXT: bnez a3, .LBB7_4
|
||||
; RV32ZBP-NEXT: # %bb.3:
|
||||
; RV32ZBP-NEXT: mv a0, a1
|
||||
; RV32ZBP-NEXT: .LBB7_4:
|
||||
; RV32ZBP-NEXT: srli a1, a0, 1
|
||||
; RV32ZBP-NEXT: not a6, a2
|
||||
; RV32ZBP-NEXT: srl a1, a1, a6
|
||||
; RV32ZBP-NEXT: or a3, a5, a1
|
||||
; RV32ZBP-NEXT: sll a0, a0, a2
|
||||
; RV32ZBP-NEXT: srli a1, a4, 1
|
||||
; RV32ZBP-NEXT: srl a1, a1, a6
|
||||
; RV32ZBP-NEXT: or a1, a0, a1
|
||||
; RV32ZBP-NEXT: mv a0, a3
|
||||
; RV32ZBP-NEXT: ret
|
||||
%or = tail call i64 @llvm.fshl.i64(i64 %a, i64 %a, i64 %b)
|
||||
ret i64 %or
|
||||
}
|
||||
|
||||
declare i32 @llvm.fshr.i32(i32, i32, i32)
|
||||
|
||||
define i32 @ror_i32(i32 %a, i32 %b) nounwind {
|
||||
; RV32I-LABEL: ror_i32:
|
||||
; RV32I: # %bb.0:
|
||||
; RV32I-NEXT: srl a2, a0, a1
|
||||
; RV32I-NEXT: neg a1, a1
|
||||
; RV32I-NEXT: sll a0, a0, a1
|
||||
; RV32I-NEXT: or a0, a2, a0
|
||||
; RV32I-NEXT: ret
|
||||
;
|
||||
; RV32ZBB-LABEL: ror_i32:
|
||||
; RV32ZBB: # %bb.0:
|
||||
; RV32ZBB-NEXT: ror a0, a0, a1
|
||||
; RV32ZBB-NEXT: ret
|
||||
;
|
||||
; RV32ZBP-LABEL: ror_i32:
|
||||
; RV32ZBP: # %bb.0:
|
||||
; RV32ZBP-NEXT: ror a0, a0, a1
|
||||
; RV32ZBP-NEXT: ret
|
||||
%or = tail call i32 @llvm.fshr.i32(i32 %a, i32 %a, i32 %b)
|
||||
ret i32 %or
|
||||
}
|
||||
|
||||
; This test is presented here in case future expansions of the Bitmanip
|
||||
; extensions introduce instructions suitable for this pattern.
|
||||
|
||||
declare i64 @llvm.fshr.i64(i64, i64, i64)
|
||||
|
||||
define i64 @ror_i64(i64 %a, i64 %b) nounwind {
|
||||
; RV32I-LABEL: ror_i64:
|
||||
; RV32I: # %bb.0:
|
||||
; RV32I-NEXT: andi a4, a2, 32
|
||||
; RV32I-NEXT: mv a3, a0
|
||||
; RV32I-NEXT: beqz a4, .LBB9_2
|
||||
; RV32I-NEXT: # %bb.1:
|
||||
; RV32I-NEXT: mv a3, a1
|
||||
; RV32I-NEXT: .LBB9_2:
|
||||
; RV32I-NEXT: srl a5, a3, a2
|
||||
; RV32I-NEXT: beqz a4, .LBB9_4
|
||||
; RV32I-NEXT: # %bb.3:
|
||||
; RV32I-NEXT: mv a1, a0
|
||||
; RV32I-NEXT: .LBB9_4:
|
||||
; RV32I-NEXT: slli a0, a1, 1
|
||||
; RV32I-NEXT: not a4, a2
|
||||
; RV32I-NEXT: sll a0, a0, a4
|
||||
; RV32I-NEXT: or a0, a0, a5
|
||||
; RV32I-NEXT: srl a1, a1, a2
|
||||
; RV32I-NEXT: slli a2, a3, 1
|
||||
; RV32I-NEXT: sll a2, a2, a4
|
||||
; RV32I-NEXT: or a1, a2, a1
|
||||
; RV32I-NEXT: ret
|
||||
;
|
||||
; RV32ZBB-LABEL: ror_i64:
|
||||
; RV32ZBB: # %bb.0:
|
||||
; RV32ZBB-NEXT: andi a4, a2, 32
|
||||
; RV32ZBB-NEXT: mv a3, a0
|
||||
; RV32ZBB-NEXT: beqz a4, .LBB9_2
|
||||
; RV32ZBB-NEXT: # %bb.1:
|
||||
; RV32ZBB-NEXT: mv a3, a1
|
||||
; RV32ZBB-NEXT: .LBB9_2:
|
||||
; RV32ZBB-NEXT: srl a5, a3, a2
|
||||
; RV32ZBB-NEXT: beqz a4, .LBB9_4
|
||||
; RV32ZBB-NEXT: # %bb.3:
|
||||
; RV32ZBB-NEXT: mv a1, a0
|
||||
; RV32ZBB-NEXT: .LBB9_4:
|
||||
; RV32ZBB-NEXT: slli a0, a1, 1
|
||||
; RV32ZBB-NEXT: not a4, a2
|
||||
; RV32ZBB-NEXT: sll a0, a0, a4
|
||||
; RV32ZBB-NEXT: or a0, a0, a5
|
||||
; RV32ZBB-NEXT: srl a1, a1, a2
|
||||
; RV32ZBB-NEXT: slli a2, a3, 1
|
||||
; RV32ZBB-NEXT: sll a2, a2, a4
|
||||
; RV32ZBB-NEXT: or a1, a2, a1
|
||||
; RV32ZBB-NEXT: ret
|
||||
;
|
||||
; RV32ZBP-LABEL: ror_i64:
|
||||
; RV32ZBP: # %bb.0:
|
||||
; RV32ZBP-NEXT: andi a4, a2, 32
|
||||
; RV32ZBP-NEXT: mv a3, a0
|
||||
; RV32ZBP-NEXT: beqz a4, .LBB9_2
|
||||
; RV32ZBP-NEXT: # %bb.1:
|
||||
; RV32ZBP-NEXT: mv a3, a1
|
||||
; RV32ZBP-NEXT: .LBB9_2:
|
||||
; RV32ZBP-NEXT: srl a5, a3, a2
|
||||
; RV32ZBP-NEXT: beqz a4, .LBB9_4
|
||||
; RV32ZBP-NEXT: # %bb.3:
|
||||
; RV32ZBP-NEXT: mv a1, a0
|
||||
; RV32ZBP-NEXT: .LBB9_4:
|
||||
; RV32ZBP-NEXT: slli a0, a1, 1
|
||||
; RV32ZBP-NEXT: not a4, a2
|
||||
; RV32ZBP-NEXT: sll a0, a0, a4
|
||||
; RV32ZBP-NEXT: or a0, a0, a5
|
||||
; RV32ZBP-NEXT: srl a1, a1, a2
|
||||
; RV32ZBP-NEXT: slli a2, a3, 1
|
||||
; RV32ZBP-NEXT: sll a2, a2, a4
|
||||
; RV32ZBP-NEXT: or a1, a2, a1
|
||||
; RV32ZBP-NEXT: ret
|
||||
%or = tail call i64 @llvm.fshr.i64(i64 %a, i64 %a, i64 %b)
|
||||
ret i64 %or
|
||||
}
|
||||
|
||||
define i32 @rori_i32_fshl(i32 %a) nounwind {
|
||||
; RV32I-LABEL: rori_i32_fshl:
|
||||
; RV32I: # %bb.0:
|
||||
; RV32I-NEXT: srli a1, a0, 1
|
||||
; RV32I-NEXT: slli a0, a0, 31
|
||||
; RV32I-NEXT: or a0, a0, a1
|
||||
; RV32I-NEXT: ret
|
||||
;
|
||||
; RV32ZBB-LABEL: rori_i32_fshl:
|
||||
; RV32ZBB: # %bb.0:
|
||||
; RV32ZBB-NEXT: rori a0, a0, 1
|
||||
; RV32ZBB-NEXT: ret
|
||||
;
|
||||
; RV32ZBP-LABEL: rori_i32_fshl:
|
||||
; RV32ZBP: # %bb.0:
|
||||
; RV32ZBP-NEXT: rori a0, a0, 1
|
||||
; RV32ZBP-NEXT: ret
|
||||
%1 = tail call i32 @llvm.fshl.i32(i32 %a, i32 %a, i32 31)
|
||||
ret i32 %1
|
||||
}
|
||||
|
||||
define i32 @rori_i32_fshr(i32 %a) nounwind {
|
||||
; RV32I-LABEL: rori_i32_fshr:
|
||||
; RV32I: # %bb.0:
|
||||
; RV32I-NEXT: slli a1, a0, 1
|
||||
; RV32I-NEXT: srli a0, a0, 31
|
||||
; RV32I-NEXT: or a0, a0, a1
|
||||
; RV32I-NEXT: ret
|
||||
;
|
||||
; RV32ZBB-LABEL: rori_i32_fshr:
|
||||
; RV32ZBB: # %bb.0:
|
||||
; RV32ZBB-NEXT: rori a0, a0, 31
|
||||
; RV32ZBB-NEXT: ret
|
||||
;
|
||||
; RV32ZBP-LABEL: rori_i32_fshr:
|
||||
; RV32ZBP: # %bb.0:
|
||||
; RV32ZBP-NEXT: rori a0, a0, 31
|
||||
; RV32ZBP-NEXT: ret
|
||||
%1 = tail call i32 @llvm.fshr.i32(i32 %a, i32 %a, i32 31)
|
||||
ret i32 %1
|
||||
}
|
||||
|
||||
define i64 @rori_i64(i64 %a) nounwind {
|
||||
; RV32I-LABEL: rori_i64:
|
||||
; RV32I: # %bb.0:
|
||||
; RV32I-NEXT: srli a2, a0, 1
|
||||
; RV32I-NEXT: slli a3, a1, 31
|
||||
; RV32I-NEXT: or a2, a3, a2
|
||||
; RV32I-NEXT: srli a1, a1, 1
|
||||
; RV32I-NEXT: slli a0, a0, 31
|
||||
; RV32I-NEXT: or a1, a0, a1
|
||||
; RV32I-NEXT: mv a0, a2
|
||||
; RV32I-NEXT: ret
|
||||
;
|
||||
; RV32ZBB-LABEL: rori_i64:
|
||||
; RV32ZBB: # %bb.0:
|
||||
; RV32ZBB-NEXT: srli a2, a0, 1
|
||||
; RV32ZBB-NEXT: slli a3, a1, 31
|
||||
; RV32ZBB-NEXT: or a2, a3, a2
|
||||
; RV32ZBB-NEXT: srli a1, a1, 1
|
||||
; RV32ZBB-NEXT: slli a0, a0, 31
|
||||
; RV32ZBB-NEXT: or a1, a0, a1
|
||||
; RV32ZBB-NEXT: mv a0, a2
|
||||
; RV32ZBB-NEXT: ret
|
||||
;
|
||||
; RV32ZBP-LABEL: rori_i64:
|
||||
; RV32ZBP: # %bb.0:
|
||||
; RV32ZBP-NEXT: srli a2, a0, 1
|
||||
; RV32ZBP-NEXT: slli a3, a1, 31
|
||||
; RV32ZBP-NEXT: or a2, a3, a2
|
||||
; RV32ZBP-NEXT: srli a1, a1, 1
|
||||
; RV32ZBP-NEXT: slli a0, a0, 31
|
||||
; RV32ZBP-NEXT: or a1, a0, a1
|
||||
; RV32ZBP-NEXT: mv a0, a2
|
||||
; RV32ZBP-NEXT: ret
|
||||
%1 = tail call i64 @llvm.fshl.i64(i64 %a, i64 %a, i64 63)
|
||||
ret i64 %1
|
||||
}
|
||||
|
||||
define i64 @rori_i64_fshr(i64 %a) nounwind {
|
||||
; RV32I-LABEL: rori_i64_fshr:
|
||||
; RV32I: # %bb.0:
|
||||
; RV32I-NEXT: srli a2, a1, 31
|
||||
; RV32I-NEXT: slli a3, a0, 1
|
||||
; RV32I-NEXT: or a2, a3, a2
|
||||
; RV32I-NEXT: srli a0, a0, 31
|
||||
; RV32I-NEXT: slli a1, a1, 1
|
||||
; RV32I-NEXT: or a1, a1, a0
|
||||
; RV32I-NEXT: mv a0, a2
|
||||
; RV32I-NEXT: ret
|
||||
;
|
||||
; RV32ZBB-LABEL: rori_i64_fshr:
|
||||
; RV32ZBB: # %bb.0:
|
||||
; RV32ZBB-NEXT: srli a2, a1, 31
|
||||
; RV32ZBB-NEXT: slli a3, a0, 1
|
||||
; RV32ZBB-NEXT: or a2, a3, a2
|
||||
; RV32ZBB-NEXT: srli a0, a0, 31
|
||||
; RV32ZBB-NEXT: slli a1, a1, 1
|
||||
; RV32ZBB-NEXT: or a1, a1, a0
|
||||
; RV32ZBB-NEXT: mv a0, a2
|
||||
; RV32ZBB-NEXT: ret
|
||||
;
|
||||
; RV32ZBP-LABEL: rori_i64_fshr:
|
||||
; RV32ZBP: # %bb.0:
|
||||
; RV32ZBP-NEXT: srli a2, a1, 31
|
||||
; RV32ZBP-NEXT: slli a3, a0, 1
|
||||
; RV32ZBP-NEXT: or a2, a3, a2
|
||||
; RV32ZBP-NEXT: srli a0, a0, 31
|
||||
; RV32ZBP-NEXT: slli a1, a1, 1
|
||||
; RV32ZBP-NEXT: or a1, a1, a0
|
||||
; RV32ZBP-NEXT: mv a0, a2
|
||||
; RV32ZBP-NEXT: ret
|
||||
%1 = tail call i64 @llvm.fshr.i64(i64 %a, i64 %a, i64 63)
|
||||
ret i64 %1
|
||||
}
|
||||
|
||||
define i8 @srli_i8(i8 %a) nounwind {
|
||||
; RV32I-LABEL: srli_i8:
|
||||
; RV32I: # %bb.0:
|
||||
; RV32I-NEXT: slli a0, a0, 24
|
||||
; RV32I-NEXT: srli a0, a0, 30
|
||||
; RV32I-NEXT: ret
|
||||
;
|
||||
; RV32ZBB-LABEL: srli_i8:
|
||||
; RV32ZBB: # %bb.0:
|
||||
; RV32ZBB-NEXT: slli a0, a0, 24
|
||||
; RV32ZBB-NEXT: srli a0, a0, 30
|
||||
; RV32ZBB-NEXT: ret
|
||||
;
|
||||
; RV32ZBP-LABEL: srli_i8:
|
||||
; RV32ZBP: # %bb.0:
|
||||
; RV32ZBP-NEXT: slli a0, a0, 24
|
||||
; RV32ZBP-NEXT: srli a0, a0, 30
|
||||
; RV32ZBP-NEXT: ret
|
||||
%1 = lshr i8 %a, 6
|
||||
ret i8 %1
|
||||
}
|
||||
|
||||
; We could use sext.b+srai, but slli+srai offers more opportunities for
|
||||
; comppressed instructions.
|
||||
define i8 @srai_i8(i8 %a) nounwind {
|
||||
; RV32I-LABEL: srai_i8:
|
||||
; RV32I: # %bb.0:
|
||||
; RV32I-NEXT: slli a0, a0, 24
|
||||
; RV32I-NEXT: srai a0, a0, 29
|
||||
; RV32I-NEXT: ret
|
||||
;
|
||||
; RV32ZBB-LABEL: srai_i8:
|
||||
; RV32ZBB: # %bb.0:
|
||||
; RV32ZBB-NEXT: slli a0, a0, 24
|
||||
; RV32ZBB-NEXT: srai a0, a0, 29
|
||||
; RV32ZBB-NEXT: ret
|
||||
;
|
||||
; RV32ZBP-LABEL: srai_i8:
|
||||
; RV32ZBP: # %bb.0:
|
||||
; RV32ZBP-NEXT: slli a0, a0, 24
|
||||
; RV32ZBP-NEXT: srai a0, a0, 29
|
||||
; RV32ZBP-NEXT: ret
|
||||
%1 = ashr i8 %a, 5
|
||||
ret i8 %1
|
||||
}
|
||||
|
||||
; We could use zext.h+srli, but slli+srli offers more opportunities for
|
||||
; comppressed instructions.
|
||||
define i16 @srli_i16(i16 %a) nounwind {
|
||||
; RV32I-LABEL: srli_i16:
|
||||
; RV32I: # %bb.0:
|
||||
; RV32I-NEXT: slli a0, a0, 16
|
||||
; RV32I-NEXT: srli a0, a0, 22
|
||||
; RV32I-NEXT: ret
|
||||
;
|
||||
; RV32ZBB-LABEL: srli_i16:
|
||||
; RV32ZBB: # %bb.0:
|
||||
; RV32ZBB-NEXT: slli a0, a0, 16
|
||||
; RV32ZBB-NEXT: srli a0, a0, 22
|
||||
; RV32ZBB-NEXT: ret
|
||||
;
|
||||
; RV32ZBP-LABEL: srli_i16:
|
||||
; RV32ZBP: # %bb.0:
|
||||
; RV32ZBP-NEXT: slli a0, a0, 16
|
||||
; RV32ZBP-NEXT: srli a0, a0, 22
|
||||
; RV32ZBP-NEXT: ret
|
||||
%1 = lshr i16 %a, 6
|
||||
ret i16 %1
|
||||
}
|
||||
|
||||
; We could use sext.h+srai, but slli+srai offers more opportunities for
|
||||
; comppressed instructions.
|
||||
define i16 @srai_i16(i16 %a) nounwind {
|
||||
; RV32I-LABEL: srai_i16:
|
||||
; RV32I: # %bb.0:
|
||||
; RV32I-NEXT: slli a0, a0, 16
|
||||
; RV32I-NEXT: srai a0, a0, 25
|
||||
; RV32I-NEXT: ret
|
||||
;
|
||||
; RV32ZBB-LABEL: srai_i16:
|
||||
; RV32ZBB: # %bb.0:
|
||||
; RV32ZBB-NEXT: slli a0, a0, 16
|
||||
; RV32ZBB-NEXT: srai a0, a0, 25
|
||||
; RV32ZBB-NEXT: ret
|
||||
;
|
||||
; RV32ZBP-LABEL: srai_i16:
|
||||
; RV32ZBP: # %bb.0:
|
||||
; RV32ZBP-NEXT: slli a0, a0, 16
|
||||
; RV32ZBP-NEXT: srai a0, a0, 25
|
||||
; RV32ZBP-NEXT: ret
|
||||
%1 = ashr i16 %a, 9
|
||||
ret i16 %1
|
||||
}
|
||||
|
||||
define i1 @andn_seqz_i32(i32 %a, i32 %b) nounwind {
|
||||
; RV32I-LABEL: andn_seqz_i32:
|
||||
; RV32I: # %bb.0:
|
||||
; RV32I-NEXT: and a0, a0, a1
|
||||
; RV32I-NEXT: xor a0, a0, a1
|
||||
; RV32I-NEXT: seqz a0, a0
|
||||
; RV32I-NEXT: ret
|
||||
;
|
||||
; RV32ZBB-LABEL: andn_seqz_i32:
|
||||
; RV32ZBB: # %bb.0:
|
||||
; RV32ZBB-NEXT: andn a0, a1, a0
|
||||
; RV32ZBB-NEXT: seqz a0, a0
|
||||
; RV32ZBB-NEXT: ret
|
||||
;
|
||||
; RV32ZBP-LABEL: andn_seqz_i32:
|
||||
; RV32ZBP: # %bb.0:
|
||||
; RV32ZBP-NEXT: andn a0, a1, a0
|
||||
; RV32ZBP-NEXT: seqz a0, a0
|
||||
; RV32ZBP-NEXT: ret
|
||||
%and = and i32 %a, %b
|
||||
%cmpeq = icmp eq i32 %and, %b
|
||||
ret i1 %cmpeq
|
||||
}
|
||||
|
||||
define i1 @andn_seqz_i64(i64 %a, i64 %b) nounwind {
|
||||
; RV32I-LABEL: andn_seqz_i64:
|
||||
; RV32I: # %bb.0:
|
||||
; RV32I-NEXT: not a0, a0
|
||||
; RV32I-NEXT: not a1, a1
|
||||
; RV32I-NEXT: and a1, a1, a3
|
||||
; RV32I-NEXT: and a0, a0, a2
|
||||
; RV32I-NEXT: or a0, a0, a1
|
||||
; RV32I-NEXT: seqz a0, a0
|
||||
; RV32I-NEXT: ret
|
||||
;
|
||||
; RV32ZBB-LABEL: andn_seqz_i64:
|
||||
; RV32ZBB: # %bb.0:
|
||||
; RV32ZBB-NEXT: andn a1, a3, a1
|
||||
; RV32ZBB-NEXT: andn a0, a2, a0
|
||||
; RV32ZBB-NEXT: or a0, a0, a1
|
||||
; RV32ZBB-NEXT: seqz a0, a0
|
||||
; RV32ZBB-NEXT: ret
|
||||
;
|
||||
; RV32ZBP-LABEL: andn_seqz_i64:
|
||||
; RV32ZBP: # %bb.0:
|
||||
; RV32ZBP-NEXT: andn a1, a3, a1
|
||||
; RV32ZBP-NEXT: andn a0, a2, a0
|
||||
; RV32ZBP-NEXT: or a0, a0, a1
|
||||
; RV32ZBP-NEXT: seqz a0, a0
|
||||
; RV32ZBP-NEXT: ret
|
||||
%and = and i64 %a, %b
|
||||
%cmpeq = icmp eq i64 %and, %b
|
||||
ret i1 %cmpeq
|
||||
}
|
||||
|
||||
define i1 @andn_snez_i32(i32 %a, i32 %b) nounwind {
|
||||
; RV32I-LABEL: andn_snez_i32:
|
||||
; RV32I: # %bb.0:
|
||||
; RV32I-NEXT: and a0, a0, a1
|
||||
; RV32I-NEXT: xor a0, a0, a1
|
||||
; RV32I-NEXT: snez a0, a0
|
||||
; RV32I-NEXT: ret
|
||||
;
|
||||
; RV32ZBB-LABEL: andn_snez_i32:
|
||||
; RV32ZBB: # %bb.0:
|
||||
; RV32ZBB-NEXT: andn a0, a1, a0
|
||||
; RV32ZBB-NEXT: snez a0, a0
|
||||
; RV32ZBB-NEXT: ret
|
||||
;
|
||||
; RV32ZBP-LABEL: andn_snez_i32:
|
||||
; RV32ZBP: # %bb.0:
|
||||
; RV32ZBP-NEXT: andn a0, a1, a0
|
||||
; RV32ZBP-NEXT: snez a0, a0
|
||||
; RV32ZBP-NEXT: ret
|
||||
%and = and i32 %a, %b
|
||||
%cmpeq = icmp ne i32 %and, %b
|
||||
ret i1 %cmpeq
|
||||
}
|
||||
|
||||
define i1 @andn_snez_i64(i64 %a, i64 %b) nounwind {
|
||||
; RV32I-LABEL: andn_snez_i64:
|
||||
; RV32I: # %bb.0:
|
||||
; RV32I-NEXT: not a0, a0
|
||||
; RV32I-NEXT: not a1, a1
|
||||
; RV32I-NEXT: and a1, a1, a3
|
||||
; RV32I-NEXT: and a0, a0, a2
|
||||
; RV32I-NEXT: or a0, a0, a1
|
||||
; RV32I-NEXT: snez a0, a0
|
||||
; RV32I-NEXT: ret
|
||||
;
|
||||
; RV32ZBB-LABEL: andn_snez_i64:
|
||||
; RV32ZBB: # %bb.0:
|
||||
; RV32ZBB-NEXT: andn a1, a3, a1
|
||||
; RV32ZBB-NEXT: andn a0, a2, a0
|
||||
; RV32ZBB-NEXT: or a0, a0, a1
|
||||
; RV32ZBB-NEXT: snez a0, a0
|
||||
; RV32ZBB-NEXT: ret
|
||||
;
|
||||
; RV32ZBP-LABEL: andn_snez_i64:
|
||||
; RV32ZBP: # %bb.0:
|
||||
; RV32ZBP-NEXT: andn a1, a3, a1
|
||||
; RV32ZBP-NEXT: andn a0, a2, a0
|
||||
; RV32ZBP-NEXT: or a0, a0, a1
|
||||
; RV32ZBP-NEXT: snez a0, a0
|
||||
; RV32ZBP-NEXT: ret
|
||||
%and = and i64 %a, %b
|
||||
%cmpeq = icmp ne i64 %and, %b
|
||||
ret i1 %cmpeq
|
||||
}
|
|
@ -2,28 +2,6 @@
|
|||
; RUN: llc -mtriple=riscv32 -mattr=+zbc -verify-machineinstrs < %s \
|
||||
; RUN: | FileCheck %s -check-prefix=RV32ZBC
|
||||
|
||||
declare i32 @llvm.riscv.clmul.i32(i32 %a, i32 %b)
|
||||
|
||||
define i32 @clmul32(i32 %a, i32 %b) nounwind {
|
||||
; RV32ZBC-LABEL: clmul32:
|
||||
; RV32ZBC: # %bb.0:
|
||||
; RV32ZBC-NEXT: clmul a0, a0, a1
|
||||
; RV32ZBC-NEXT: ret
|
||||
%tmp = call i32 @llvm.riscv.clmul.i32(i32 %a, i32 %b)
|
||||
ret i32 %tmp
|
||||
}
|
||||
|
||||
declare i32 @llvm.riscv.clmulh.i32(i32 %a, i32 %b)
|
||||
|
||||
define i32 @clmul32h(i32 %a, i32 %b) nounwind {
|
||||
; RV32ZBC-LABEL: clmul32h:
|
||||
; RV32ZBC: # %bb.0:
|
||||
; RV32ZBC-NEXT: clmulh a0, a0, a1
|
||||
; RV32ZBC-NEXT: ret
|
||||
%tmp = call i32 @llvm.riscv.clmulh.i32(i32 %a, i32 %b)
|
||||
ret i32 %tmp
|
||||
}
|
||||
|
||||
declare i32 @llvm.riscv.clmulr.i32(i32 %a, i32 %b)
|
||||
|
||||
define i32 @clmul32r(i32 %a, i32 %b) nounwind {
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
|
||||
; RUN: llc -mtriple=riscv32 -mattr=+zbc -verify-machineinstrs < %s \
|
||||
; RUN: | FileCheck %s -check-prefix=RV32ZBC-ZBKC
|
||||
; RUN: llc -mtriple=riscv32 -mattr=+zbkc -verify-machineinstrs < %s \
|
||||
; RUN: | FileCheck %s -check-prefix=RV32ZBC-ZBKC
|
||||
|
||||
declare i32 @llvm.riscv.clmul.i32(i32 %a, i32 %b)
|
||||
|
||||
define i32 @clmul32(i32 %a, i32 %b) nounwind {
|
||||
; RV32ZBC-ZBKC-LABEL: clmul32:
|
||||
; RV32ZBC-ZBKC: # %bb.0:
|
||||
; RV32ZBC-ZBKC-NEXT: clmul a0, a0, a1
|
||||
; RV32ZBC-ZBKC-NEXT: ret
|
||||
%tmp = call i32 @llvm.riscv.clmul.i32(i32 %a, i32 %b)
|
||||
ret i32 %tmp
|
||||
}
|
||||
|
||||
declare i32 @llvm.riscv.clmulh.i32(i32 %a, i32 %b)
|
||||
|
||||
define i32 @clmul32h(i32 %a, i32 %b) nounwind {
|
||||
; RV32ZBC-ZBKC-LABEL: clmul32h:
|
||||
; RV32ZBC-ZBKC: # %bb.0:
|
||||
; RV32ZBC-ZBKC-NEXT: clmulh a0, a0, a1
|
||||
; RV32ZBC-ZBKC-NEXT: ret
|
||||
%tmp = call i32 @llvm.riscv.clmulh.i32(i32 %a, i32 %b)
|
||||
ret i32 %tmp
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
|
||||
; RUN: llc -mtriple=riscv32 -mattr=+zbkb -verify-machineinstrs < %s \
|
||||
; RUN: | FileCheck %s -check-prefix=RV32ZBKB
|
||||
|
||||
declare i32 @llvm.riscv.brev8(i32);
|
||||
|
||||
define i32 @brev8(i32 %a) nounwind {
|
||||
; RV32ZBKB-LABEL: brev8:
|
||||
; RV32ZBKB: # %bb.0:
|
||||
; RV32ZBKB-NEXT: brev8 a0, a0
|
||||
; RV32ZBKB-NEXT: ret
|
||||
%val = call i32 @llvm.riscv.brev8(i32 %a)
|
||||
ret i32 %val
|
||||
}
|
||||
|
||||
declare i32 @llvm.bswap.i32(i32)
|
||||
|
||||
define i32 @rev8_i32(i32 %a) nounwind {
|
||||
; RV32ZBKB-LABEL: rev8_i32:
|
||||
; RV32ZBKB: # %bb.0:
|
||||
; RV32ZBKB-NEXT: rev8 a0, a0
|
||||
; RV32ZBKB-NEXT: ret
|
||||
%1 = tail call i32 @llvm.bswap.i32(i32 %a)
|
||||
ret i32 %1
|
||||
}
|
||||
|
||||
declare i32 @llvm.riscv.zip(i32);
|
||||
|
||||
define i32 @zip(i32 %a) nounwind {
|
||||
; RV32ZBKB-LABEL: zip:
|
||||
; RV32ZBKB: # %bb.0:
|
||||
; RV32ZBKB-NEXT: zip a0, a0
|
||||
; RV32ZBKB-NEXT: ret
|
||||
%val = call i32 @llvm.riscv.zip(i32 %a)
|
||||
ret i32 %val
|
||||
}
|
||||
|
||||
declare i32 @llvm.riscv.unzip(i32);
|
||||
|
||||
define i32 @unzip(i32 %a) nounwind {
|
||||
; RV32ZBKB-LABEL: unzip:
|
||||
; RV32ZBKB: # %bb.0:
|
||||
; RV32ZBKB-NEXT: unzip a0, a0
|
||||
; RV32ZBKB-NEXT: ret
|
||||
%val = call i32 @llvm.riscv.unzip(i32 %a)
|
||||
ret i32 %val
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
; RUN: llc -mtriple=riscv32 -mattr=+zbkx -verify-machineinstrs < %s \
|
||||
; RUN: | FileCheck %s -check-prefix=RV32ZBKX
|
||||
|
||||
declare i32 @llvm.riscv.xperm8.i32(i32 %a, i32 %b)
|
||||
|
||||
define i32 @xperm8(i32 %a, i32 %b) nounwind {
|
||||
; RV32ZBKX-LABEL: xperm8:
|
||||
; RV32ZBKX: # %bb.0:
|
||||
; RV32ZBKX-NEXT: xperm8 a0, a0, a1
|
||||
; RV32ZBKX-NEXT: ret
|
||||
%tmp = call i32 @llvm.riscv.xperm8.i32(i32 %a, i32 %b)
|
||||
ret i32 %tmp
|
||||
}
|
||||
|
||||
declare i32 @llvm.riscv.xperm4.i32(i32 %a, i32 %b)
|
||||
|
||||
define i32 @xperm4(i32 %a, i32 %b) nounwind {
|
||||
; RV32ZBKX-LABEL: xperm4:
|
||||
; RV32ZBKX: # %bb.0:
|
||||
; RV32ZBKX-NEXT: xperm4 a0, a0, a1
|
||||
; RV32ZBKX-NEXT: ret
|
||||
%tmp = call i32 @llvm.riscv.xperm4.i32(i32 %a, i32 %b)
|
||||
ret i32 %tmp
|
||||
}
|
|
@ -0,0 +1,149 @@
|
|||
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
|
||||
; RUN: llc -mtriple=riscv32 -verify-machineinstrs < %s \
|
||||
; RUN: | FileCheck %s -check-prefix=RV32I
|
||||
; RUN: llc -mtriple=riscv32 -mattr=+experimental-zbp -verify-machineinstrs < %s \
|
||||
; RUN: | FileCheck %s -check-prefix=RV32ZBP-ZBKB
|
||||
; RUN: llc -mtriple=riscv32 -mattr=+zbkb -verify-machineinstrs < %s \
|
||||
; RUN: | FileCheck %s -check-prefix=RV32ZBP-ZBKB
|
||||
|
||||
define i32 @pack_i32(i32 %a, i32 %b) nounwind {
|
||||
; RV32I-LABEL: pack_i32:
|
||||
; RV32I: # %bb.0:
|
||||
; RV32I-NEXT: slli a0, a0, 16
|
||||
; RV32I-NEXT: srli a0, a0, 16
|
||||
; RV32I-NEXT: slli a1, a1, 16
|
||||
; RV32I-NEXT: or a0, a1, a0
|
||||
; RV32I-NEXT: ret
|
||||
%shl = and i32 %a, 65535
|
||||
%shl1 = shl i32 %b, 16
|
||||
%or = or i32 %shl1, %shl
|
||||
ret i32 %or
|
||||
}
|
||||
|
||||
; As we are not matching directly i64 code patterns on RV32 some i64 patterns
|
||||
; don't have yet any matching bit manipulation instructions on RV32.
|
||||
; This test is presented here in case future expansions of the Bitmanip
|
||||
; extensions introduce instructions suitable for this pattern.
|
||||
|
||||
define i64 @pack_i64(i64 %a, i64 %b) nounwind {
|
||||
; RV32I-LABEL: pack_i64:
|
||||
; RV32I: # %bb.0:
|
||||
; RV32I-NEXT: mv a1, a2
|
||||
; RV32I-NEXT: ret
|
||||
;
|
||||
; RV32ZBP-ZBKB-LABEL: pack_i64:
|
||||
; RV32ZBP-ZBKB: # %bb.0:
|
||||
; RV32ZBP-ZBKB-NEXT: mv a1, a2
|
||||
; RV32ZBP-ZBKB-NEXT: ret
|
||||
%shl = and i64 %a, 4294967295
|
||||
%shl1 = shl i64 %b, 32
|
||||
%or = or i64 %shl1, %shl
|
||||
ret i64 %or
|
||||
}
|
||||
|
||||
; As we are not matching directly i64 code patterns on RV32 some i64 patterns
|
||||
; don't have yet any matching bit manipulation instructions on RV32.
|
||||
; This test is presented here in case future expansions of the Bitmanip
|
||||
; extensions introduce instructions suitable for this pattern.
|
||||
|
||||
define i64 @packu_i64(i64 %a, i64 %b) nounwind {
|
||||
; RV32I-LABEL: packu_i64:
|
||||
; RV32I: # %bb.0:
|
||||
; RV32I-NEXT: mv a0, a1
|
||||
; RV32I-NEXT: mv a1, a3
|
||||
; RV32I-NEXT: ret
|
||||
;
|
||||
; RV32ZBP-ZBKB-LABEL: packu_i64:
|
||||
; RV32ZBP-ZBKB: # %bb.0:
|
||||
; RV32ZBP-ZBKB-NEXT: mv a0, a1
|
||||
; RV32ZBP-ZBKB-NEXT: mv a1, a3
|
||||
; RV32ZBP-ZBKB-NEXT: ret
|
||||
%shr = lshr i64 %a, 32
|
||||
%shr1 = and i64 %b, -4294967296
|
||||
%or = or i64 %shr1, %shr
|
||||
ret i64 %or
|
||||
}
|
||||
|
||||
define i32 @packh_i32(i32 %a, i32 %b) nounwind {
|
||||
; RV32I-LABEL: packh_i32:
|
||||
; RV32I: # %bb.0:
|
||||
; RV32I-NEXT: andi a0, a0, 255
|
||||
; RV32I-NEXT: slli a1, a1, 24
|
||||
; RV32I-NEXT: srli a1, a1, 16
|
||||
; RV32I-NEXT: or a0, a1, a0
|
||||
; RV32I-NEXT: ret
|
||||
;
|
||||
; RV32ZBP-ZBKB-LABEL: packh_i32:
|
||||
; RV32ZBP-ZBKB: # %bb.0:
|
||||
; RV32ZBP-ZBKB-NEXT: packh a0, a0, a1
|
||||
; RV32ZBP-ZBKB-NEXT: ret
|
||||
%and = and i32 %a, 255
|
||||
%and1 = shl i32 %b, 8
|
||||
%shl = and i32 %and1, 65280
|
||||
%or = or i32 %shl, %and
|
||||
ret i32 %or
|
||||
}
|
||||
|
||||
define i32 @packh_i32_2(i32 %a, i32 %b) nounwind {
|
||||
; RV32I-LABEL: packh_i32_2:
|
||||
; RV32I: # %bb.0:
|
||||
; RV32I-NEXT: andi a0, a0, 255
|
||||
; RV32I-NEXT: andi a1, a1, 255
|
||||
; RV32I-NEXT: slli a1, a1, 8
|
||||
; RV32I-NEXT: or a0, a1, a0
|
||||
; RV32I-NEXT: ret
|
||||
;
|
||||
; RV32ZBP-ZBKB-LABEL: packh_i32_2:
|
||||
; RV32ZBP-ZBKB: # %bb.0:
|
||||
; RV32ZBP-ZBKB-NEXT: packh a0, a0, a1
|
||||
; RV32ZBP-ZBKB-NEXT: ret
|
||||
%and = and i32 %a, 255
|
||||
%and1 = and i32 %b, 255
|
||||
%shl = shl i32 %and1, 8
|
||||
%or = or i32 %shl, %and
|
||||
ret i32 %or
|
||||
}
|
||||
|
||||
define i64 @packh_i64(i64 %a, i64 %b) nounwind {
|
||||
; RV32I-LABEL: packh_i64:
|
||||
; RV32I: # %bb.0:
|
||||
; RV32I-NEXT: andi a0, a0, 255
|
||||
; RV32I-NEXT: slli a1, a2, 24
|
||||
; RV32I-NEXT: srli a1, a1, 16
|
||||
; RV32I-NEXT: or a0, a1, a0
|
||||
; RV32I-NEXT: li a1, 0
|
||||
; RV32I-NEXT: ret
|
||||
;
|
||||
; RV32ZBP-ZBKB-LABEL: packh_i64:
|
||||
; RV32ZBP-ZBKB: # %bb.0:
|
||||
; RV32ZBP-ZBKB-NEXT: packh a0, a0, a2
|
||||
; RV32ZBP-ZBKB-NEXT: li a1, 0
|
||||
; RV32ZBP-ZBKB-NEXT: ret
|
||||
%and = and i64 %a, 255
|
||||
%and1 = shl i64 %b, 8
|
||||
%shl = and i64 %and1, 65280
|
||||
%or = or i64 %shl, %and
|
||||
ret i64 %or
|
||||
}
|
||||
|
||||
define i64 @packh_i64_2(i64 %a, i64 %b) nounwind {
|
||||
; RV32I-LABEL: packh_i64_2:
|
||||
; RV32I: # %bb.0:
|
||||
; RV32I-NEXT: andi a0, a0, 255
|
||||
; RV32I-NEXT: andi a1, a2, 255
|
||||
; RV32I-NEXT: slli a1, a1, 8
|
||||
; RV32I-NEXT: or a0, a1, a0
|
||||
; RV32I-NEXT: li a1, 0
|
||||
; RV32I-NEXT: ret
|
||||
;
|
||||
; RV32ZBP-ZBKB-LABEL: packh_i64_2:
|
||||
; RV32ZBP-ZBKB: # %bb.0:
|
||||
; RV32ZBP-ZBKB-NEXT: packh a0, a0, a2
|
||||
; RV32ZBP-ZBKB-NEXT: li a1, 0
|
||||
; RV32ZBP-ZBKB-NEXT: ret
|
||||
%and = and i64 %a, 255
|
||||
%and1 = and i64 %b, 255
|
||||
%shl = shl i64 %and1, 8
|
||||
%or = or i64 %shl, %and
|
||||
ret i64 %or
|
||||
}
|
|
@ -2773,46 +2773,6 @@ define i64 @shfl8_i64(i64 %a, i64 %b) nounwind {
|
|||
ret i64 %or3
|
||||
}
|
||||
|
||||
define i32 @pack_i32(i32 %a, i32 %b) nounwind {
|
||||
; RV32I-LABEL: pack_i32:
|
||||
; RV32I: # %bb.0:
|
||||
; RV32I-NEXT: slli a0, a0, 16
|
||||
; RV32I-NEXT: srli a0, a0, 16
|
||||
; RV32I-NEXT: slli a1, a1, 16
|
||||
; RV32I-NEXT: or a0, a1, a0
|
||||
; RV32I-NEXT: ret
|
||||
;
|
||||
; RV32ZBP-LABEL: pack_i32:
|
||||
; RV32ZBP: # %bb.0:
|
||||
; RV32ZBP-NEXT: pack a0, a0, a1
|
||||
; RV32ZBP-NEXT: ret
|
||||
%shl = and i32 %a, 65535
|
||||
%shl1 = shl i32 %b, 16
|
||||
%or = or i32 %shl1, %shl
|
||||
ret i32 %or
|
||||
}
|
||||
|
||||
; As we are not matching directly i64 code patterns on RV32 some i64 patterns
|
||||
; don't have yet any matching bit manipulation instructions on RV32.
|
||||
; This test is presented here in case future expansions of the Bitmanip
|
||||
; extensions introduce instructions suitable for this pattern.
|
||||
|
||||
define i64 @pack_i64(i64 %a, i64 %b) nounwind {
|
||||
; RV32I-LABEL: pack_i64:
|
||||
; RV32I: # %bb.0:
|
||||
; RV32I-NEXT: mv a1, a2
|
||||
; RV32I-NEXT: ret
|
||||
;
|
||||
; RV32ZBP-LABEL: pack_i64:
|
||||
; RV32ZBP: # %bb.0:
|
||||
; RV32ZBP-NEXT: mv a1, a2
|
||||
; RV32ZBP-NEXT: ret
|
||||
%shl = and i64 %a, 4294967295
|
||||
%shl1 = shl i64 %b, 32
|
||||
%or = or i64 %shl1, %shl
|
||||
ret i64 %or
|
||||
}
|
||||
|
||||
define i32 @packu_i32(i32 %a, i32 %b) nounwind {
|
||||
; RV32I-LABEL: packu_i32:
|
||||
; RV32I: # %bb.0:
|
||||
|
@ -2832,113 +2792,6 @@ define i32 @packu_i32(i32 %a, i32 %b) nounwind {
|
|||
ret i32 %or
|
||||
}
|
||||
|
||||
; As we are not matching directly i64 code patterns on RV32 some i64 patterns
|
||||
; don't have yet any matching bit manipulation instructions on RV32.
|
||||
; This test is presented here in case future expansions of the Bitmanip
|
||||
; extensions introduce instructions suitable for this pattern.
|
||||
|
||||
define i64 @packu_i64(i64 %a, i64 %b) nounwind {
|
||||
; RV32I-LABEL: packu_i64:
|
||||
; RV32I: # %bb.0:
|
||||
; RV32I-NEXT: mv a0, a1
|
||||
; RV32I-NEXT: mv a1, a3
|
||||
; RV32I-NEXT: ret
|
||||
;
|
||||
; RV32ZBP-LABEL: packu_i64:
|
||||
; RV32ZBP: # %bb.0:
|
||||
; RV32ZBP-NEXT: mv a0, a1
|
||||
; RV32ZBP-NEXT: mv a1, a3
|
||||
; RV32ZBP-NEXT: ret
|
||||
%shr = lshr i64 %a, 32
|
||||
%shr1 = and i64 %b, -4294967296
|
||||
%or = or i64 %shr1, %shr
|
||||
ret i64 %or
|
||||
}
|
||||
|
||||
define i32 @packh_i32(i32 %a, i32 %b) nounwind {
|
||||
; RV32I-LABEL: packh_i32:
|
||||
; RV32I: # %bb.0:
|
||||
; RV32I-NEXT: andi a0, a0, 255
|
||||
; RV32I-NEXT: slli a1, a1, 24
|
||||
; RV32I-NEXT: srli a1, a1, 16
|
||||
; RV32I-NEXT: or a0, a1, a0
|
||||
; RV32I-NEXT: ret
|
||||
;
|
||||
; RV32ZBP-LABEL: packh_i32:
|
||||
; RV32ZBP: # %bb.0:
|
||||
; RV32ZBP-NEXT: packh a0, a0, a1
|
||||
; RV32ZBP-NEXT: ret
|
||||
%and = and i32 %a, 255
|
||||
%and1 = shl i32 %b, 8
|
||||
%shl = and i32 %and1, 65280
|
||||
%or = or i32 %shl, %and
|
||||
ret i32 %or
|
||||
}
|
||||
|
||||
define i32 @packh_i32_2(i32 %a, i32 %b) nounwind {
|
||||
; RV32I-LABEL: packh_i32_2:
|
||||
; RV32I: # %bb.0:
|
||||
; RV32I-NEXT: andi a0, a0, 255
|
||||
; RV32I-NEXT: andi a1, a1, 255
|
||||
; RV32I-NEXT: slli a1, a1, 8
|
||||
; RV32I-NEXT: or a0, a1, a0
|
||||
; RV32I-NEXT: ret
|
||||
;
|
||||
; RV32ZBP-LABEL: packh_i32_2:
|
||||
; RV32ZBP: # %bb.0:
|
||||
; RV32ZBP-NEXT: packh a0, a0, a1
|
||||
; RV32ZBP-NEXT: ret
|
||||
%and = and i32 %a, 255
|
||||
%and1 = and i32 %b, 255
|
||||
%shl = shl i32 %and1, 8
|
||||
%or = or i32 %shl, %and
|
||||
ret i32 %or
|
||||
}
|
||||
|
||||
define i64 @packh_i64(i64 %a, i64 %b) nounwind {
|
||||
; RV32I-LABEL: packh_i64:
|
||||
; RV32I: # %bb.0:
|
||||
; RV32I-NEXT: andi a0, a0, 255
|
||||
; RV32I-NEXT: slli a1, a2, 24
|
||||
; RV32I-NEXT: srli a1, a1, 16
|
||||
; RV32I-NEXT: or a0, a1, a0
|
||||
; RV32I-NEXT: li a1, 0
|
||||
; RV32I-NEXT: ret
|
||||
;
|
||||
; RV32ZBP-LABEL: packh_i64:
|
||||
; RV32ZBP: # %bb.0:
|
||||
; RV32ZBP-NEXT: packh a0, a0, a2
|
||||
; RV32ZBP-NEXT: li a1, 0
|
||||
; RV32ZBP-NEXT: ret
|
||||
%and = and i64 %a, 255
|
||||
%and1 = shl i64 %b, 8
|
||||
%shl = and i64 %and1, 65280
|
||||
%or = or i64 %shl, %and
|
||||
ret i64 %or
|
||||
}
|
||||
|
||||
define i64 @packh_i64_2(i64 %a, i64 %b) nounwind {
|
||||
; RV32I-LABEL: packh_i64_2:
|
||||
; RV32I: # %bb.0:
|
||||
; RV32I-NEXT: andi a0, a0, 255
|
||||
; RV32I-NEXT: andi a1, a2, 255
|
||||
; RV32I-NEXT: slli a1, a1, 8
|
||||
; RV32I-NEXT: or a0, a1, a0
|
||||
; RV32I-NEXT: li a1, 0
|
||||
; RV32I-NEXT: ret
|
||||
;
|
||||
; RV32ZBP-LABEL: packh_i64_2:
|
||||
; RV32ZBP: # %bb.0:
|
||||
; RV32ZBP-NEXT: packh a0, a0, a2
|
||||
; RV32ZBP-NEXT: li a1, 0
|
||||
; RV32ZBP-NEXT: ret
|
||||
%and = and i64 %a, 255
|
||||
%and1 = and i64 %b, 255
|
||||
%shl = shl i64 %and1, 8
|
||||
%or = or i64 %shl, %and
|
||||
ret i64 %or
|
||||
}
|
||||
|
||||
define i32 @zexth_i32(i32 %a) nounwind {
|
||||
; RV32I-LABEL: zexth_i32:
|
||||
; RV32I: # %bb.0:
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
|
||||
; RUN: llc -mtriple=riscv32 -mattr=+zknd -verify-machineinstrs < %s \
|
||||
; RUN: | FileCheck %s -check-prefix=RV32ZKND
|
||||
|
||||
declare i32 @llvm.riscv.aes32dsi(i32, i32, i8);
|
||||
|
||||
define i32 @aes32dsi(i32 %a, i32 %b) nounwind {
|
||||
; RV32ZKND-LABEL: aes32dsi
|
||||
; RV32ZKND: # %bb.0:
|
||||
; RV32ZKND-NEXT: aes32dsi a0, a0, a1, 0
|
||||
; RV32ZKND-NEXT: ret
|
||||
%val = call i32 @llvm.riscv.aes32dsi(i32 %a, i32 %b, i8 0)
|
||||
ret i32 %val
|
||||
}
|
||||
|
||||
declare i32 @llvm.riscv.aes32dsmi(i32, i32, i8);
|
||||
|
||||
define i32 @aes32dsmi(i32 %a, i32 %b) nounwind {
|
||||
; RV32ZKND-LABEL: aes32dsmi
|
||||
; RV32ZKND: # %bb.0:
|
||||
; RV32ZKND-NEXT: aes32dsmi a0, a0, a1, 1
|
||||
; RV32ZKND-NEXT: ret
|
||||
%val = call i32 @llvm.riscv.aes32dsmi(i32 %a, i32 %b, i8 1)
|
||||
ret i32 %val
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
|
||||
; RUN: llc -mtriple=riscv32 -mattr=+zkne -verify-machineinstrs < %s \
|
||||
; RUN: | FileCheck %s -check-prefix=RV32ZKNE
|
||||
|
||||
declare i32 @llvm.riscv.aes32esi(i32, i32, i8);
|
||||
|
||||
define i32 @aes32esi(i32 %a, i32 %b) nounwind {
|
||||
; RV32ZKNE-LABEL: aes32esi
|
||||
; RV32ZKNE: # %bb.0:
|
||||
; RV32ZKNE-NEXT: aes32esi a0, a0, a1, 2
|
||||
; RV32ZKNE-NEXT: ret
|
||||
%val = call i32 @llvm.riscv.aes32esi(i32 %a, i32 %b, i8 2)
|
||||
ret i32 %val
|
||||
}
|
||||
|
||||
declare i32 @llvm.riscv.aes32esmi(i32, i32, i8);
|
||||
|
||||
define i32 @aes32esmi(i32 %a, i32 %b) nounwind {
|
||||
; RV32ZKNE-LABEL: aes32esmi
|
||||
; RV32ZKNE: # %bb.0:
|
||||
; RV32ZKNE-NEXT: aes32esmi a0, a0, a1, 3
|
||||
; RV32ZKNE-NEXT: ret
|
||||
%val = call i32 @llvm.riscv.aes32esmi(i32 %a, i32 %b, i8 3)
|
||||
ret i32 %val
|
||||
}
|
|
@ -0,0 +1,114 @@
|
|||
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
|
||||
; RUN: llc -mtriple=riscv32 -mattr=+zknh -verify-machineinstrs < %s \
|
||||
; RUN: | FileCheck %s -check-prefix=RV32ZKNH
|
||||
|
||||
|
||||
declare i32 @llvm.riscv.sha256sig0.i32(i32);
|
||||
|
||||
define i32 @sha256sig0_i32(i32 %a) nounwind {
|
||||
; RV32ZKNH-LABEL: sha256sig0_i32
|
||||
; RV32ZKNH: # %bb.0:
|
||||
; RV32ZKNH-NEXT: sha256sig0 a0, a0
|
||||
; RV32ZKNH-NEXT: ret
|
||||
%val = call i32 @llvm.riscv.sha256sig0.i32(i32 %a)
|
||||
ret i32 %val
|
||||
}
|
||||
|
||||
declare i32 @llvm.riscv.sha256sig1.i32(i32);
|
||||
|
||||
define i32 @sha256sig1_i32(i32 %a) nounwind {
|
||||
; RV32ZKNH-LABEL: sha256sig1_i32
|
||||
; RV32ZKNH: # %bb.0:
|
||||
; RV32ZKNH-NEXT: sha256sig1 a0, a0
|
||||
; RV32ZKNH-NEXT: ret
|
||||
%val = call i32 @llvm.riscv.sha256sig1.i32(i32 %a)
|
||||
ret i32 %val
|
||||
}
|
||||
|
||||
declare i32 @llvm.riscv.sha256sum0.i32(i32);
|
||||
|
||||
define i32 @sha256sum0_i32(i32 %a) nounwind {
|
||||
; RV32ZKNH-LABEL: sha256sum0_i32
|
||||
; RV32ZKNH: # %bb.0:
|
||||
; RV32ZKNH-NEXT: sha256sum0 a0, a0
|
||||
; RV32ZKNH-NEXT: ret
|
||||
%val = call i32 @llvm.riscv.sha256sum0.i32(i32 %a)
|
||||
ret i32 %val
|
||||
}
|
||||
|
||||
declare i32 @llvm.riscv.sha256sum1.i32(i32);
|
||||
|
||||
define i32 @sha256sum1_i32(i32 %a) nounwind {
|
||||
; RV32ZKNH-LABEL: sha256sum1_i32
|
||||
; RV32ZKNH: # %bb.0:
|
||||
; RV32ZKNH-NEXT: sha256sum1 a0, a0
|
||||
; RV32ZKNH-NEXT: ret
|
||||
%val = call i32 @llvm.riscv.sha256sum1.i32(i32 %a)
|
||||
ret i32 %val
|
||||
}
|
||||
|
||||
declare i32 @llvm.riscv.sha512sig0l(i32, i32);
|
||||
|
||||
define i32 @sha512sig0l(i32 %a, i32 %b) nounwind {
|
||||
; RV32ZKNH-LABEL: sha512sig0l
|
||||
; RV32ZKNH: # %bb.0:
|
||||
; RV32ZKNH-NEXT: sha512sig0l a0, a0, a1
|
||||
; RV32ZKNH-NEXT: ret
|
||||
%val = call i32 @llvm.riscv.sha512sig0l(i32 %a, i32 %b)
|
||||
ret i32 %val
|
||||
}
|
||||
|
||||
declare i32 @llvm.riscv.sha512sig0h(i32, i32);
|
||||
|
||||
define i32 @sha512sig0h(i32 %a, i32 %b) nounwind {
|
||||
; RV32ZKNH-LABEL: sha512sig0h
|
||||
; RV32ZKNH: # %bb.0:
|
||||
; RV32ZKNH-NEXT: sha512sig0h a0, a0, a1
|
||||
; RV32ZKNH-NEXT: ret
|
||||
%val = call i32 @llvm.riscv.sha512sig0h(i32 %a, i32 %b)
|
||||
ret i32 %val
|
||||
}
|
||||
|
||||
declare i32 @llvm.riscv.sha512sig1l(i32, i32);
|
||||
|
||||
define i32 @sha512sig1l(i32 %a, i32 %b) nounwind {
|
||||
; RV32ZKNH-LABEL: sha512sig1l
|
||||
; RV32ZKNH: # %bb.0:
|
||||
; RV32ZKNH-NEXT: sha512sig1l a0, a0, a1
|
||||
; RV32ZKNH-NEXT: ret
|
||||
%val = call i32 @llvm.riscv.sha512sig1l(i32 %a, i32 %b)
|
||||
ret i32 %val
|
||||
}
|
||||
|
||||
declare i32 @llvm.riscv.sha512sig1h(i32, i32);
|
||||
|
||||
define i32 @sha512sig1h(i32 %a, i32 %b) nounwind {
|
||||
; RV32ZKNH-LABEL: sha512sig1h
|
||||
; RV32ZKNH: # %bb.0:
|
||||
; RV32ZKNH-NEXT: sha512sig1h a0, a0, a1
|
||||
; RV32ZKNH-NEXT: ret
|
||||
%val = call i32 @llvm.riscv.sha512sig1h(i32 %a, i32 %b)
|
||||
ret i32 %val
|
||||
}
|
||||
|
||||
declare i32 @llvm.riscv.sha512sum0r(i32, i32);
|
||||
|
||||
define i32 @sha512sum0r(i32 %a, i32 %b) nounwind {
|
||||
; RV32ZKNH-LABEL: sha512sum0r
|
||||
; RV32ZKNH: # %bb.0:
|
||||
; RV32ZKNH-NEXT: sha512sum0r a0, a0, a1
|
||||
; RV32ZKNH-NEXT: ret
|
||||
%val = call i32 @llvm.riscv.sha512sum0r(i32 %a, i32 %b)
|
||||
ret i32 %val
|
||||
}
|
||||
|
||||
declare i32 @llvm.riscv.sha512sum1r(i32, i32);
|
||||
|
||||
define i32 @sha512sum1r(i32 %a, i32 %b) nounwind {
|
||||
; RV32ZKNH-LABEL: sha512sum1r
|
||||
; RV32ZKNH: # %bb.0:
|
||||
; RV32ZKNH-NEXT: sha512sum1r a0, a0, a1
|
||||
; RV32ZKNH-NEXT: ret
|
||||
%val = call i32 @llvm.riscv.sha512sum1r(i32 %a, i32 %b)
|
||||
ret i32 %val
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
|
||||
; RUN: llc -mtriple=riscv32 -mattr=+zksed -verify-machineinstrs < %s \
|
||||
; RUN: | FileCheck %s -check-prefix=RV32ZKSED
|
||||
|
||||
declare i32 @llvm.riscv.sm4ks.i32(i32, i32, i8);
|
||||
|
||||
define i32 @sm4ks_i32(i32 %a, i32 %b) nounwind {
|
||||
; RV32ZKSED-LABEL: sm4ks_i32:
|
||||
; RV32ZKSED: # %bb.0:
|
||||
; RV32ZKSED-NEXT: sm4ks a0, a0, a1, 2
|
||||
; RV32ZKSED-NEXT: ret
|
||||
%val = call i32 @llvm.riscv.sm4ks.i32(i32 %a, i32 %b, i8 2)
|
||||
ret i32 %val
|
||||
}
|
||||
|
||||
declare i32 @llvm.riscv.sm4ed.i32(i32, i32, i8);
|
||||
|
||||
define i32 @sm4ed_i32(i32 %a, i32 %b) nounwind {
|
||||
; RV32ZKSED-LABEL: sm4ed_i32:
|
||||
; RV32ZKSED: # %bb.0:
|
||||
; RV32ZKSED-NEXT: sm4ed a0, a0, a1, 3
|
||||
; RV32ZKSED-NEXT: ret
|
||||
%val = call i32 @llvm.riscv.sm4ed.i32(i32 %a, i32 %b, i8 3)
|
||||
ret i32 %val
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
|
||||
; RUN: llc -mtriple=riscv32 -mattr=+zksh -verify-machineinstrs < %s \
|
||||
; RUN: | FileCheck %s -check-prefix=RV32ZKSH
|
||||
|
||||
declare i32 @llvm.riscv.sm3p0.i32(i32);
|
||||
|
||||
define i32 @sm3p0_i32(i32 %a) nounwind {
|
||||
; RV32ZKSH-LABEL: sm3p0_i32:
|
||||
; RV32ZKSH: # %bb.0:
|
||||
; RV32ZKSH-NEXT: sm3p0 a0, a0
|
||||
; RV32ZKSH-NEXT: ret
|
||||
%val = call i32 @llvm.riscv.sm3p0.i32(i32 %a)
|
||||
ret i32 %val
|
||||
}
|
||||
|
||||
declare i32 @llvm.riscv.sm3p1.i32(i32);
|
||||
|
||||
define i32 @sm3p1_i32(i32 %a) nounwind {
|
||||
; RV32ZKSH-LABEL: sm3p1_i32:
|
||||
; RV32ZKSH: # %bb.0:
|
||||
; RV32ZKSH-NEXT: sm3p1 a0, a0
|
||||
; RV32ZKSH-NEXT: ret
|
||||
%val = call i32 @llvm.riscv.sm3p1.i32(i32 %a)
|
||||
ret i32 %val
|
||||
}
|
|
@ -1,10 +1,12 @@
|
|||
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
|
||||
; RUN: llc -mtriple=riscv64 -verify-machineinstrs < %s \
|
||||
; RUN: | FileCheck %s -check-prefix=RV64I
|
||||
; RUN: | FileCheck %s -check-prefixes=RV64I
|
||||
; RUN: llc -mtriple=riscv64 -mattr=+zbb -verify-machineinstrs < %s \
|
||||
; RUN: | FileCheck %s -check-prefix=RV64ZBB
|
||||
; RUN: | FileCheck %s -check-prefixes=RV64ZBB-ZBP-ZBKB
|
||||
; RUN: llc -mtriple=riscv64 -mattr=+experimental-zbp -verify-machineinstrs < %s \
|
||||
; RUN: | FileCheck %s -check-prefix=RV64ZBP
|
||||
; RUN: | FileCheck %s -check-prefixes=RV64ZBB-ZBP-ZBKB
|
||||
; RUN: llc -mtriple=riscv64 -mattr=+zbkb -verify-machineinstrs < %s \
|
||||
; RUN: | FileCheck %s -check-prefixes=RV64ZBB-ZBP-ZBKB
|
||||
|
||||
define signext i32 @andn_i32(i32 signext %a, i32 signext %b) nounwind {
|
||||
; RV64I-LABEL: andn_i32:
|
||||
|
@ -13,15 +15,10 @@ define signext i32 @andn_i32(i32 signext %a, i32 signext %b) nounwind {
|
|||
; RV64I-NEXT: and a0, a1, a0
|
||||
; RV64I-NEXT: ret
|
||||
;
|
||||
; RV64ZBB-LABEL: andn_i32:
|
||||
; RV64ZBB: # %bb.0:
|
||||
; RV64ZBB-NEXT: andn a0, a0, a1
|
||||
; RV64ZBB-NEXT: ret
|
||||
;
|
||||
; RV64ZBP-LABEL: andn_i32:
|
||||
; RV64ZBP: # %bb.0:
|
||||
; RV64ZBP-NEXT: andn a0, a0, a1
|
||||
; RV64ZBP-NEXT: ret
|
||||
; RV64ZBB-ZBP-ZBKB-LABEL: andn_i32:
|
||||
; RV64ZBB-ZBP-ZBKB: # %bb.0:
|
||||
; RV64ZBB-ZBP-ZBKB-NEXT: andn a0, a0, a1
|
||||
; RV64ZBB-ZBP-ZBKB-NEXT: ret
|
||||
%neg = xor i32 %b, -1
|
||||
%and = and i32 %neg, %a
|
||||
ret i32 %and
|
||||
|
@ -34,15 +31,10 @@ define i64 @andn_i64(i64 %a, i64 %b) nounwind {
|
|||
; RV64I-NEXT: and a0, a1, a0
|
||||
; RV64I-NEXT: ret
|
||||
;
|
||||
; RV64ZBB-LABEL: andn_i64:
|
||||
; RV64ZBB: # %bb.0:
|
||||
; RV64ZBB-NEXT: andn a0, a0, a1
|
||||
; RV64ZBB-NEXT: ret
|
||||
;
|
||||
; RV64ZBP-LABEL: andn_i64:
|
||||
; RV64ZBP: # %bb.0:
|
||||
; RV64ZBP-NEXT: andn a0, a0, a1
|
||||
; RV64ZBP-NEXT: ret
|
||||
; RV64ZBB-ZBP-ZBKB-LABEL: andn_i64:
|
||||
; RV64ZBB-ZBP-ZBKB: # %bb.0:
|
||||
; RV64ZBB-ZBP-ZBKB-NEXT: andn a0, a0, a1
|
||||
; RV64ZBB-ZBP-ZBKB-NEXT: ret
|
||||
%neg = xor i64 %b, -1
|
||||
%and = and i64 %neg, %a
|
||||
ret i64 %and
|
||||
|
@ -55,15 +47,10 @@ define signext i32 @orn_i32(i32 signext %a, i32 signext %b) nounwind {
|
|||
; RV64I-NEXT: or a0, a1, a0
|
||||
; RV64I-NEXT: ret
|
||||
;
|
||||
; RV64ZBB-LABEL: orn_i32:
|
||||
; RV64ZBB: # %bb.0:
|
||||
; RV64ZBB-NEXT: orn a0, a0, a1
|
||||
; RV64ZBB-NEXT: ret
|
||||
;
|
||||
; RV64ZBP-LABEL: orn_i32:
|
||||
; RV64ZBP: # %bb.0:
|
||||
; RV64ZBP-NEXT: orn a0, a0, a1
|
||||
; RV64ZBP-NEXT: ret
|
||||
; RV64ZBB-ZBP-ZBKB-LABEL: orn_i32:
|
||||
; RV64ZBB-ZBP-ZBKB: # %bb.0:
|
||||
; RV64ZBB-ZBP-ZBKB-NEXT: orn a0, a0, a1
|
||||
; RV64ZBB-ZBP-ZBKB-NEXT: ret
|
||||
%neg = xor i32 %b, -1
|
||||
%or = or i32 %neg, %a
|
||||
ret i32 %or
|
||||
|
@ -76,15 +63,10 @@ define i64 @orn_i64(i64 %a, i64 %b) nounwind {
|
|||
; RV64I-NEXT: or a0, a1, a0
|
||||
; RV64I-NEXT: ret
|
||||
;
|
||||
; RV64ZBB-LABEL: orn_i64:
|
||||
; RV64ZBB: # %bb.0:
|
||||
; RV64ZBB-NEXT: orn a0, a0, a1
|
||||
; RV64ZBB-NEXT: ret
|
||||
;
|
||||
; RV64ZBP-LABEL: orn_i64:
|
||||
; RV64ZBP: # %bb.0:
|
||||
; RV64ZBP-NEXT: orn a0, a0, a1
|
||||
; RV64ZBP-NEXT: ret
|
||||
; RV64ZBB-ZBP-ZBKB-LABEL: orn_i64:
|
||||
; RV64ZBB-ZBP-ZBKB: # %bb.0:
|
||||
; RV64ZBB-ZBP-ZBKB-NEXT: orn a0, a0, a1
|
||||
; RV64ZBB-ZBP-ZBKB-NEXT: ret
|
||||
%neg = xor i64 %b, -1
|
||||
%or = or i64 %neg, %a
|
||||
ret i64 %or
|
||||
|
@ -97,15 +79,10 @@ define signext i32 @xnor_i32(i32 signext %a, i32 signext %b) nounwind {
|
|||
; RV64I-NEXT: not a0, a0
|
||||
; RV64I-NEXT: ret
|
||||
;
|
||||
; RV64ZBB-LABEL: xnor_i32:
|
||||
; RV64ZBB: # %bb.0:
|
||||
; RV64ZBB-NEXT: xnor a0, a0, a1
|
||||
; RV64ZBB-NEXT: ret
|
||||
;
|
||||
; RV64ZBP-LABEL: xnor_i32:
|
||||
; RV64ZBP: # %bb.0:
|
||||
; RV64ZBP-NEXT: xnor a0, a0, a1
|
||||
; RV64ZBP-NEXT: ret
|
||||
; RV64ZBB-ZBP-ZBKB-LABEL: xnor_i32:
|
||||
; RV64ZBB-ZBP-ZBKB: # %bb.0:
|
||||
; RV64ZBB-ZBP-ZBKB-NEXT: xnor a0, a0, a1
|
||||
; RV64ZBB-ZBP-ZBKB-NEXT: ret
|
||||
%neg = xor i32 %a, -1
|
||||
%xor = xor i32 %neg, %b
|
||||
ret i32 %xor
|
||||
|
@ -118,15 +95,10 @@ define i64 @xnor_i64(i64 %a, i64 %b) nounwind {
|
|||
; RV64I-NEXT: not a0, a0
|
||||
; RV64I-NEXT: ret
|
||||
;
|
||||
; RV64ZBB-LABEL: xnor_i64:
|
||||
; RV64ZBB: # %bb.0:
|
||||
; RV64ZBB-NEXT: xnor a0, a0, a1
|
||||
; RV64ZBB-NEXT: ret
|
||||
;
|
||||
; RV64ZBP-LABEL: xnor_i64:
|
||||
; RV64ZBP: # %bb.0:
|
||||
; RV64ZBP-NEXT: xnor a0, a0, a1
|
||||
; RV64ZBP-NEXT: ret
|
||||
; RV64ZBB-ZBP-ZBKB-LABEL: xnor_i64:
|
||||
; RV64ZBB-ZBP-ZBKB: # %bb.0:
|
||||
; RV64ZBB-ZBP-ZBKB-NEXT: xnor a0, a0, a1
|
||||
; RV64ZBB-ZBP-ZBKB-NEXT: ret
|
||||
%neg = xor i64 %a, -1
|
||||
%xor = xor i64 %neg, %b
|
||||
ret i64 %xor
|
||||
|
@ -143,15 +115,10 @@ define signext i32 @rol_i32(i32 signext %a, i32 signext %b) nounwind {
|
|||
; RV64I-NEXT: or a0, a2, a0
|
||||
; RV64I-NEXT: ret
|
||||
;
|
||||
; RV64ZBB-LABEL: rol_i32:
|
||||
; RV64ZBB: # %bb.0:
|
||||
; RV64ZBB-NEXT: rolw a0, a0, a1
|
||||
; RV64ZBB-NEXT: ret
|
||||
;
|
||||
; RV64ZBP-LABEL: rol_i32:
|
||||
; RV64ZBP: # %bb.0:
|
||||
; RV64ZBP-NEXT: rolw a0, a0, a1
|
||||
; RV64ZBP-NEXT: ret
|
||||
; RV64ZBB-ZBP-ZBKB-LABEL: rol_i32:
|
||||
; RV64ZBB-ZBP-ZBKB: # %bb.0:
|
||||
; RV64ZBB-ZBP-ZBKB-NEXT: rolw a0, a0, a1
|
||||
; RV64ZBB-ZBP-ZBKB-NEXT: ret
|
||||
%1 = tail call i32 @llvm.fshl.i32(i32 %a, i32 %a, i32 %b)
|
||||
ret i32 %1
|
||||
}
|
||||
|
@ -167,17 +134,11 @@ define void @rol_i32_nosext(i32 signext %a, i32 signext %b, i32* %x) nounwind {
|
|||
; RV64I-NEXT: sw a0, 0(a2)
|
||||
; RV64I-NEXT: ret
|
||||
;
|
||||
; RV64ZBB-LABEL: rol_i32_nosext:
|
||||
; RV64ZBB: # %bb.0:
|
||||
; RV64ZBB-NEXT: rolw a0, a0, a1
|
||||
; RV64ZBB-NEXT: sw a0, 0(a2)
|
||||
; RV64ZBB-NEXT: ret
|
||||
;
|
||||
; RV64ZBP-LABEL: rol_i32_nosext:
|
||||
; RV64ZBP: # %bb.0:
|
||||
; RV64ZBP-NEXT: rolw a0, a0, a1
|
||||
; RV64ZBP-NEXT: sw a0, 0(a2)
|
||||
; RV64ZBP-NEXT: ret
|
||||
; RV64ZBB-ZBP-ZBKB-LABEL: rol_i32_nosext:
|
||||
; RV64ZBB-ZBP-ZBKB: # %bb.0:
|
||||
; RV64ZBB-ZBP-ZBKB-NEXT: rolw a0, a0, a1
|
||||
; RV64ZBB-ZBP-ZBKB-NEXT: sw a0, 0(a2)
|
||||
; RV64ZBB-ZBP-ZBKB-NEXT: ret
|
||||
%1 = tail call i32 @llvm.fshl.i32(i32 %a, i32 %a, i32 %b)
|
||||
store i32 %1, i32* %x
|
||||
ret void
|
||||
|
@ -193,17 +154,11 @@ define signext i32 @rol_i32_neg_constant_rhs(i32 signext %a) nounwind {
|
|||
; RV64I-NEXT: or a0, a2, a0
|
||||
; RV64I-NEXT: ret
|
||||
;
|
||||
; RV64ZBB-LABEL: rol_i32_neg_constant_rhs:
|
||||
; RV64ZBB: # %bb.0:
|
||||
; RV64ZBB-NEXT: li a1, -2
|
||||
; RV64ZBB-NEXT: rolw a0, a1, a0
|
||||
; RV64ZBB-NEXT: ret
|
||||
;
|
||||
; RV64ZBP-LABEL: rol_i32_neg_constant_rhs:
|
||||
; RV64ZBP: # %bb.0:
|
||||
; RV64ZBP-NEXT: li a1, -2
|
||||
; RV64ZBP-NEXT: rolw a0, a1, a0
|
||||
; RV64ZBP-NEXT: ret
|
||||
; RV64ZBB-ZBP-ZBKB-LABEL: rol_i32_neg_constant_rhs:
|
||||
; RV64ZBB-ZBP-ZBKB: # %bb.0:
|
||||
; RV64ZBB-ZBP-ZBKB-NEXT: li a1, -2
|
||||
; RV64ZBB-ZBP-ZBKB-NEXT: rolw a0, a1, a0
|
||||
; RV64ZBB-ZBP-ZBKB-NEXT: ret
|
||||
%1 = tail call i32 @llvm.fshl.i32(i32 -2, i32 -2, i32 %a)
|
||||
ret i32 %1
|
||||
}
|
||||
|
@ -219,15 +174,10 @@ define i64 @rol_i64(i64 %a, i64 %b) nounwind {
|
|||
; RV64I-NEXT: or a0, a2, a0
|
||||
; RV64I-NEXT: ret
|
||||
;
|
||||
; RV64ZBB-LABEL: rol_i64:
|
||||
; RV64ZBB: # %bb.0:
|
||||
; RV64ZBB-NEXT: rol a0, a0, a1
|
||||
; RV64ZBB-NEXT: ret
|
||||
;
|
||||
; RV64ZBP-LABEL: rol_i64:
|
||||
; RV64ZBP: # %bb.0:
|
||||
; RV64ZBP-NEXT: rol a0, a0, a1
|
||||
; RV64ZBP-NEXT: ret
|
||||
; RV64ZBB-ZBP-ZBKB-LABEL: rol_i64:
|
||||
; RV64ZBB-ZBP-ZBKB: # %bb.0:
|
||||
; RV64ZBB-ZBP-ZBKB-NEXT: rol a0, a0, a1
|
||||
; RV64ZBB-ZBP-ZBKB-NEXT: ret
|
||||
%or = tail call i64 @llvm.fshl.i64(i64 %a, i64 %a, i64 %b)
|
||||
ret i64 %or
|
||||
}
|
||||
|
@ -243,15 +193,10 @@ define signext i32 @ror_i32(i32 signext %a, i32 signext %b) nounwind {
|
|||
; RV64I-NEXT: or a0, a2, a0
|
||||
; RV64I-NEXT: ret
|
||||
;
|
||||
; RV64ZBB-LABEL: ror_i32:
|
||||
; RV64ZBB: # %bb.0:
|
||||
; RV64ZBB-NEXT: rorw a0, a0, a1
|
||||
; RV64ZBB-NEXT: ret
|
||||
;
|
||||
; RV64ZBP-LABEL: ror_i32:
|
||||
; RV64ZBP: # %bb.0:
|
||||
; RV64ZBP-NEXT: rorw a0, a0, a1
|
||||
; RV64ZBP-NEXT: ret
|
||||
; RV64ZBB-ZBP-ZBKB-LABEL: ror_i32:
|
||||
; RV64ZBB-ZBP-ZBKB: # %bb.0:
|
||||
; RV64ZBB-ZBP-ZBKB-NEXT: rorw a0, a0, a1
|
||||
; RV64ZBB-ZBP-ZBKB-NEXT: ret
|
||||
%1 = tail call i32 @llvm.fshr.i32(i32 %a, i32 %a, i32 %b)
|
||||
ret i32 %1
|
||||
}
|
||||
|
@ -267,17 +212,11 @@ define void @ror_i32_nosext(i32 signext %a, i32 signext %b, i32* %x) nounwind {
|
|||
; RV64I-NEXT: sw a0, 0(a2)
|
||||
; RV64I-NEXT: ret
|
||||
;
|
||||
; RV64ZBB-LABEL: ror_i32_nosext:
|
||||
; RV64ZBB: # %bb.0:
|
||||
; RV64ZBB-NEXT: rorw a0, a0, a1
|
||||
; RV64ZBB-NEXT: sw a0, 0(a2)
|
||||
; RV64ZBB-NEXT: ret
|
||||
;
|
||||
; RV64ZBP-LABEL: ror_i32_nosext:
|
||||
; RV64ZBP: # %bb.0:
|
||||
; RV64ZBP-NEXT: rorw a0, a0, a1
|
||||
; RV64ZBP-NEXT: sw a0, 0(a2)
|
||||
; RV64ZBP-NEXT: ret
|
||||
; RV64ZBB-ZBP-ZBKB-LABEL: ror_i32_nosext:
|
||||
; RV64ZBB-ZBP-ZBKB: # %bb.0:
|
||||
; RV64ZBB-ZBP-ZBKB-NEXT: rorw a0, a0, a1
|
||||
; RV64ZBB-ZBP-ZBKB-NEXT: sw a0, 0(a2)
|
||||
; RV64ZBB-ZBP-ZBKB-NEXT: ret
|
||||
%1 = tail call i32 @llvm.fshr.i32(i32 %a, i32 %a, i32 %b)
|
||||
store i32 %1, i32* %x
|
||||
ret void
|
||||
|
@ -293,17 +232,11 @@ define signext i32 @ror_i32_neg_constant_rhs(i32 signext %a) nounwind {
|
|||
; RV64I-NEXT: or a0, a2, a0
|
||||
; RV64I-NEXT: ret
|
||||
;
|
||||
; RV64ZBB-LABEL: ror_i32_neg_constant_rhs:
|
||||
; RV64ZBB: # %bb.0:
|
||||
; RV64ZBB-NEXT: li a1, -2
|
||||
; RV64ZBB-NEXT: rorw a0, a1, a0
|
||||
; RV64ZBB-NEXT: ret
|
||||
;
|
||||
; RV64ZBP-LABEL: ror_i32_neg_constant_rhs:
|
||||
; RV64ZBP: # %bb.0:
|
||||
; RV64ZBP-NEXT: li a1, -2
|
||||
; RV64ZBP-NEXT: rorw a0, a1, a0
|
||||
; RV64ZBP-NEXT: ret
|
||||
; RV64ZBB-ZBP-ZBKB-LABEL: ror_i32_neg_constant_rhs:
|
||||
; RV64ZBB-ZBP-ZBKB: # %bb.0:
|
||||
; RV64ZBB-ZBP-ZBKB-NEXT: li a1, -2
|
||||
; RV64ZBB-ZBP-ZBKB-NEXT: rorw a0, a1, a0
|
||||
; RV64ZBB-ZBP-ZBKB-NEXT: ret
|
||||
%1 = tail call i32 @llvm.fshr.i32(i32 -2, i32 -2, i32 %a)
|
||||
ret i32 %1
|
||||
}
|
||||
|
@ -319,15 +252,10 @@ define i64 @ror_i64(i64 %a, i64 %b) nounwind {
|
|||
; RV64I-NEXT: or a0, a2, a0
|
||||
; RV64I-NEXT: ret
|
||||
;
|
||||
; RV64ZBB-LABEL: ror_i64:
|
||||
; RV64ZBB: # %bb.0:
|
||||
; RV64ZBB-NEXT: ror a0, a0, a1
|
||||
; RV64ZBB-NEXT: ret
|
||||
;
|
||||
; RV64ZBP-LABEL: ror_i64:
|
||||
; RV64ZBP: # %bb.0:
|
||||
; RV64ZBP-NEXT: ror a0, a0, a1
|
||||
; RV64ZBP-NEXT: ret
|
||||
; RV64ZBB-ZBP-ZBKB-LABEL: ror_i64:
|
||||
; RV64ZBB-ZBP-ZBKB: # %bb.0:
|
||||
; RV64ZBB-ZBP-ZBKB-NEXT: ror a0, a0, a1
|
||||
; RV64ZBB-ZBP-ZBKB-NEXT: ret
|
||||
%or = tail call i64 @llvm.fshr.i64(i64 %a, i64 %a, i64 %b)
|
||||
ret i64 %or
|
||||
}
|
||||
|
@ -340,15 +268,10 @@ define signext i32 @rori_i32_fshl(i32 signext %a) nounwind {
|
|||
; RV64I-NEXT: or a0, a0, a1
|
||||
; RV64I-NEXT: ret
|
||||
;
|
||||
; RV64ZBB-LABEL: rori_i32_fshl:
|
||||
; RV64ZBB: # %bb.0:
|
||||
; RV64ZBB-NEXT: roriw a0, a0, 1
|
||||
; RV64ZBB-NEXT: ret
|
||||
;
|
||||
; RV64ZBP-LABEL: rori_i32_fshl:
|
||||
; RV64ZBP: # %bb.0:
|
||||
; RV64ZBP-NEXT: roriw a0, a0, 1
|
||||
; RV64ZBP-NEXT: ret
|
||||
; RV64ZBB-ZBP-ZBKB-LABEL: rori_i32_fshl:
|
||||
; RV64ZBB-ZBP-ZBKB: # %bb.0:
|
||||
; RV64ZBB-ZBP-ZBKB-NEXT: roriw a0, a0, 1
|
||||
; RV64ZBB-ZBP-ZBKB-NEXT: ret
|
||||
%1 = tail call i32 @llvm.fshl.i32(i32 %a, i32 %a, i32 31)
|
||||
ret i32 %1
|
||||
}
|
||||
|
@ -363,17 +286,11 @@ define void @rori_i32_fshl_nosext(i32 signext %a, i32* %x) nounwind {
|
|||
; RV64I-NEXT: sw a0, 0(a1)
|
||||
; RV64I-NEXT: ret
|
||||
;
|
||||
; RV64ZBB-LABEL: rori_i32_fshl_nosext:
|
||||
; RV64ZBB: # %bb.0:
|
||||
; RV64ZBB-NEXT: roriw a0, a0, 1
|
||||
; RV64ZBB-NEXT: sw a0, 0(a1)
|
||||
; RV64ZBB-NEXT: ret
|
||||
;
|
||||
; RV64ZBP-LABEL: rori_i32_fshl_nosext:
|
||||
; RV64ZBP: # %bb.0:
|
||||
; RV64ZBP-NEXT: roriw a0, a0, 1
|
||||
; RV64ZBP-NEXT: sw a0, 0(a1)
|
||||
; RV64ZBP-NEXT: ret
|
||||
; RV64ZBB-ZBP-ZBKB-LABEL: rori_i32_fshl_nosext:
|
||||
; RV64ZBB-ZBP-ZBKB: # %bb.0:
|
||||
; RV64ZBB-ZBP-ZBKB-NEXT: roriw a0, a0, 1
|
||||
; RV64ZBB-ZBP-ZBKB-NEXT: sw a0, 0(a1)
|
||||
; RV64ZBB-ZBP-ZBKB-NEXT: ret
|
||||
%1 = tail call i32 @llvm.fshl.i32(i32 %a, i32 %a, i32 31)
|
||||
store i32 %1, i32* %x
|
||||
ret void
|
||||
|
@ -387,15 +304,10 @@ define signext i32 @rori_i32_fshr(i32 signext %a) nounwind {
|
|||
; RV64I-NEXT: or a0, a0, a1
|
||||
; RV64I-NEXT: ret
|
||||
;
|
||||
; RV64ZBB-LABEL: rori_i32_fshr:
|
||||
; RV64ZBB: # %bb.0:
|
||||
; RV64ZBB-NEXT: roriw a0, a0, 31
|
||||
; RV64ZBB-NEXT: ret
|
||||
;
|
||||
; RV64ZBP-LABEL: rori_i32_fshr:
|
||||
; RV64ZBP: # %bb.0:
|
||||
; RV64ZBP-NEXT: roriw a0, a0, 31
|
||||
; RV64ZBP-NEXT: ret
|
||||
; RV64ZBB-ZBP-ZBKB-LABEL: rori_i32_fshr:
|
||||
; RV64ZBB-ZBP-ZBKB: # %bb.0:
|
||||
; RV64ZBB-ZBP-ZBKB-NEXT: roriw a0, a0, 31
|
||||
; RV64ZBB-ZBP-ZBKB-NEXT: ret
|
||||
%1 = tail call i32 @llvm.fshr.i32(i32 %a, i32 %a, i32 31)
|
||||
ret i32 %1
|
||||
}
|
||||
|
@ -410,17 +322,11 @@ define void @rori_i32_fshr_nosext(i32 signext %a, i32* %x) nounwind {
|
|||
; RV64I-NEXT: sw a0, 0(a1)
|
||||
; RV64I-NEXT: ret
|
||||
;
|
||||
; RV64ZBB-LABEL: rori_i32_fshr_nosext:
|
||||
; RV64ZBB: # %bb.0:
|
||||
; RV64ZBB-NEXT: roriw a0, a0, 31
|
||||
; RV64ZBB-NEXT: sw a0, 0(a1)
|
||||
; RV64ZBB-NEXT: ret
|
||||
;
|
||||
; RV64ZBP-LABEL: rori_i32_fshr_nosext:
|
||||
; RV64ZBP: # %bb.0:
|
||||
; RV64ZBP-NEXT: roriw a0, a0, 31
|
||||
; RV64ZBP-NEXT: sw a0, 0(a1)
|
||||
; RV64ZBP-NEXT: ret
|
||||
; RV64ZBB-ZBP-ZBKB-LABEL: rori_i32_fshr_nosext:
|
||||
; RV64ZBB-ZBP-ZBKB: # %bb.0:
|
||||
; RV64ZBB-ZBP-ZBKB-NEXT: roriw a0, a0, 31
|
||||
; RV64ZBB-ZBP-ZBKB-NEXT: sw a0, 0(a1)
|
||||
; RV64ZBB-ZBP-ZBKB-NEXT: ret
|
||||
%1 = tail call i32 @llvm.fshr.i32(i32 %a, i32 %a, i32 31)
|
||||
store i32 %1, i32* %x
|
||||
ret void
|
||||
|
@ -437,19 +343,12 @@ define signext i32 @not_rori_i32(i32 signext %x, i32 signext %y) nounwind {
|
|||
; RV64I-NEXT: or a0, a0, a1
|
||||
; RV64I-NEXT: ret
|
||||
;
|
||||
; RV64ZBB-LABEL: not_rori_i32:
|
||||
; RV64ZBB: # %bb.0:
|
||||
; RV64ZBB-NEXT: slliw a0, a0, 31
|
||||
; RV64ZBB-NEXT: srliw a1, a1, 1
|
||||
; RV64ZBB-NEXT: or a0, a0, a1
|
||||
; RV64ZBB-NEXT: ret
|
||||
;
|
||||
; RV64ZBP-LABEL: not_rori_i32:
|
||||
; RV64ZBP: # %bb.0:
|
||||
; RV64ZBP-NEXT: slliw a0, a0, 31
|
||||
; RV64ZBP-NEXT: srliw a1, a1, 1
|
||||
; RV64ZBP-NEXT: or a0, a0, a1
|
||||
; RV64ZBP-NEXT: ret
|
||||
; RV64ZBB-ZBP-ZBKB-LABEL: not_rori_i32:
|
||||
; RV64ZBB-ZBP-ZBKB: # %bb.0:
|
||||
; RV64ZBB-ZBP-ZBKB-NEXT: slliw a0, a0, 31
|
||||
; RV64ZBB-ZBP-ZBKB-NEXT: srliw a1, a1, 1
|
||||
; RV64ZBB-ZBP-ZBKB-NEXT: or a0, a0, a1
|
||||
; RV64ZBB-ZBP-ZBKB-NEXT: ret
|
||||
%a = shl i32 %x, 31
|
||||
%b = lshr i32 %y, 1
|
||||
%c = or i32 %a, %b
|
||||
|
@ -470,25 +369,15 @@ define i64 @roriw_bug(i64 %x) nounwind {
|
|||
; RV64I-NEXT: xor a0, a0, a1
|
||||
; RV64I-NEXT: ret
|
||||
;
|
||||
; RV64ZBB-LABEL: roriw_bug:
|
||||
; RV64ZBB: # %bb.0:
|
||||
; RV64ZBB-NEXT: slli a1, a0, 31
|
||||
; RV64ZBB-NEXT: andi a0, a0, -2
|
||||
; RV64ZBB-NEXT: srli a2, a0, 1
|
||||
; RV64ZBB-NEXT: or a1, a1, a2
|
||||
; RV64ZBB-NEXT: sext.w a1, a1
|
||||
; RV64ZBB-NEXT: xor a0, a0, a1
|
||||
; RV64ZBB-NEXT: ret
|
||||
;
|
||||
; RV64ZBP-LABEL: roriw_bug:
|
||||
; RV64ZBP: # %bb.0:
|
||||
; RV64ZBP-NEXT: slli a1, a0, 31
|
||||
; RV64ZBP-NEXT: andi a0, a0, -2
|
||||
; RV64ZBP-NEXT: srli a2, a0, 1
|
||||
; RV64ZBP-NEXT: or a1, a1, a2
|
||||
; RV64ZBP-NEXT: sext.w a1, a1
|
||||
; RV64ZBP-NEXT: xor a0, a0, a1
|
||||
; RV64ZBP-NEXT: ret
|
||||
; RV64ZBB-ZBP-ZBKB-LABEL: roriw_bug:
|
||||
; RV64ZBB-ZBP-ZBKB: # %bb.0:
|
||||
; RV64ZBB-ZBP-ZBKB-NEXT: slli a1, a0, 31
|
||||
; RV64ZBB-ZBP-ZBKB-NEXT: andi a0, a0, -2
|
||||
; RV64ZBB-ZBP-ZBKB-NEXT: srli a2, a0, 1
|
||||
; RV64ZBB-ZBP-ZBKB-NEXT: or a1, a1, a2
|
||||
; RV64ZBB-ZBP-ZBKB-NEXT: sext.w a1, a1
|
||||
; RV64ZBB-ZBP-ZBKB-NEXT: xor a0, a0, a1
|
||||
; RV64ZBB-ZBP-ZBKB-NEXT: ret
|
||||
%a = shl i64 %x, 31
|
||||
%b = and i64 %x, 18446744073709551614
|
||||
%c = lshr i64 %b, 1
|
||||
|
@ -507,15 +396,10 @@ define i64 @rori_i64_fshl(i64 %a) nounwind {
|
|||
; RV64I-NEXT: or a0, a0, a1
|
||||
; RV64I-NEXT: ret
|
||||
;
|
||||
; RV64ZBB-LABEL: rori_i64_fshl:
|
||||
; RV64ZBB: # %bb.0:
|
||||
; RV64ZBB-NEXT: rori a0, a0, 1
|
||||
; RV64ZBB-NEXT: ret
|
||||
;
|
||||
; RV64ZBP-LABEL: rori_i64_fshl:
|
||||
; RV64ZBP: # %bb.0:
|
||||
; RV64ZBP-NEXT: rori a0, a0, 1
|
||||
; RV64ZBP-NEXT: ret
|
||||
; RV64ZBB-ZBP-ZBKB-LABEL: rori_i64_fshl:
|
||||
; RV64ZBB-ZBP-ZBKB: # %bb.0:
|
||||
; RV64ZBB-ZBP-ZBKB-NEXT: rori a0, a0, 1
|
||||
; RV64ZBB-ZBP-ZBKB-NEXT: ret
|
||||
%1 = tail call i64 @llvm.fshl.i64(i64 %a, i64 %a, i64 63)
|
||||
ret i64 %1
|
||||
}
|
||||
|
@ -528,15 +412,10 @@ define i64 @rori_i64_fshr(i64 %a) nounwind {
|
|||
; RV64I-NEXT: or a0, a0, a1
|
||||
; RV64I-NEXT: ret
|
||||
;
|
||||
; RV64ZBB-LABEL: rori_i64_fshr:
|
||||
; RV64ZBB: # %bb.0:
|
||||
; RV64ZBB-NEXT: rori a0, a0, 63
|
||||
; RV64ZBB-NEXT: ret
|
||||
;
|
||||
; RV64ZBP-LABEL: rori_i64_fshr:
|
||||
; RV64ZBP: # %bb.0:
|
||||
; RV64ZBP-NEXT: rori a0, a0, 63
|
||||
; RV64ZBP-NEXT: ret
|
||||
; RV64ZBB-ZBP-ZBKB-LABEL: rori_i64_fshr:
|
||||
; RV64ZBB-ZBP-ZBKB: # %bb.0:
|
||||
; RV64ZBB-ZBP-ZBKB-NEXT: rori a0, a0, 63
|
||||
; RV64ZBB-ZBP-ZBKB-NEXT: ret
|
||||
%1 = tail call i64 @llvm.fshr.i64(i64 %a, i64 %a, i64 63)
|
||||
ret i64 %1
|
||||
}
|
||||
|
@ -548,17 +427,11 @@ define i8 @srli_i8(i8 %a) nounwind {
|
|||
; RV64I-NEXT: srli a0, a0, 62
|
||||
; RV64I-NEXT: ret
|
||||
;
|
||||
; RV64ZBB-LABEL: srli_i8:
|
||||
; RV64ZBB: # %bb.0:
|
||||
; RV64ZBB-NEXT: slli a0, a0, 56
|
||||
; RV64ZBB-NEXT: srli a0, a0, 62
|
||||
; RV64ZBB-NEXT: ret
|
||||
;
|
||||
; RV64ZBP-LABEL: srli_i8:
|
||||
; RV64ZBP: # %bb.0:
|
||||
; RV64ZBP-NEXT: slli a0, a0, 56
|
||||
; RV64ZBP-NEXT: srli a0, a0, 62
|
||||
; RV64ZBP-NEXT: ret
|
||||
; RV64ZBB-ZBP-ZBKB-LABEL: srli_i8:
|
||||
; RV64ZBB-ZBP-ZBKB: # %bb.0:
|
||||
; RV64ZBB-ZBP-ZBKB-NEXT: slli a0, a0, 56
|
||||
; RV64ZBB-ZBP-ZBKB-NEXT: srli a0, a0, 62
|
||||
; RV64ZBB-ZBP-ZBKB-NEXT: ret
|
||||
%1 = lshr i8 %a, 6
|
||||
ret i8 %1
|
||||
}
|
||||
|
@ -572,17 +445,11 @@ define i8 @srai_i8(i8 %a) nounwind {
|
|||
; RV64I-NEXT: srai a0, a0, 61
|
||||
; RV64I-NEXT: ret
|
||||
;
|
||||
; RV64ZBB-LABEL: srai_i8:
|
||||
; RV64ZBB: # %bb.0:
|
||||
; RV64ZBB-NEXT: slli a0, a0, 56
|
||||
; RV64ZBB-NEXT: srai a0, a0, 61
|
||||
; RV64ZBB-NEXT: ret
|
||||
;
|
||||
; RV64ZBP-LABEL: srai_i8:
|
||||
; RV64ZBP: # %bb.0:
|
||||
; RV64ZBP-NEXT: slli a0, a0, 56
|
||||
; RV64ZBP-NEXT: srai a0, a0, 61
|
||||
; RV64ZBP-NEXT: ret
|
||||
; RV64ZBB-ZBP-ZBKB-LABEL: srai_i8:
|
||||
; RV64ZBB-ZBP-ZBKB: # %bb.0:
|
||||
; RV64ZBB-ZBP-ZBKB-NEXT: slli a0, a0, 56
|
||||
; RV64ZBB-ZBP-ZBKB-NEXT: srai a0, a0, 61
|
||||
; RV64ZBB-ZBP-ZBKB-NEXT: ret
|
||||
%1 = ashr i8 %a, 5
|
||||
ret i8 %1
|
||||
}
|
||||
|
@ -596,17 +463,11 @@ define i16 @srli_i16(i16 %a) nounwind {
|
|||
; RV64I-NEXT: srli a0, a0, 54
|
||||
; RV64I-NEXT: ret
|
||||
;
|
||||
; RV64ZBB-LABEL: srli_i16:
|
||||
; RV64ZBB: # %bb.0:
|
||||
; RV64ZBB-NEXT: slli a0, a0, 48
|
||||
; RV64ZBB-NEXT: srli a0, a0, 54
|
||||
; RV64ZBB-NEXT: ret
|
||||
;
|
||||
; RV64ZBP-LABEL: srli_i16:
|
||||
; RV64ZBP: # %bb.0:
|
||||
; RV64ZBP-NEXT: slli a0, a0, 48
|
||||
; RV64ZBP-NEXT: srli a0, a0, 54
|
||||
; RV64ZBP-NEXT: ret
|
||||
; RV64ZBB-ZBP-ZBKB-LABEL: srli_i16:
|
||||
; RV64ZBB-ZBP-ZBKB: # %bb.0:
|
||||
; RV64ZBB-ZBP-ZBKB-NEXT: slli a0, a0, 48
|
||||
; RV64ZBB-ZBP-ZBKB-NEXT: srli a0, a0, 54
|
||||
; RV64ZBB-ZBP-ZBKB-NEXT: ret
|
||||
%1 = lshr i16 %a, 6
|
||||
ret i16 %1
|
||||
}
|
||||
|
@ -620,17 +481,11 @@ define i16 @srai_i16(i16 %a) nounwind {
|
|||
; RV64I-NEXT: srai a0, a0, 57
|
||||
; RV64I-NEXT: ret
|
||||
;
|
||||
; RV64ZBB-LABEL: srai_i16:
|
||||
; RV64ZBB: # %bb.0:
|
||||
; RV64ZBB-NEXT: slli a0, a0, 48
|
||||
; RV64ZBB-NEXT: srai a0, a0, 57
|
||||
; RV64ZBB-NEXT: ret
|
||||
;
|
||||
; RV64ZBP-LABEL: srai_i16:
|
||||
; RV64ZBP: # %bb.0:
|
||||
; RV64ZBP-NEXT: slli a0, a0, 48
|
||||
; RV64ZBP-NEXT: srai a0, a0, 57
|
||||
; RV64ZBP-NEXT: ret
|
||||
; RV64ZBB-ZBP-ZBKB-LABEL: srai_i16:
|
||||
; RV64ZBB-ZBP-ZBKB: # %bb.0:
|
||||
; RV64ZBB-ZBP-ZBKB-NEXT: slli a0, a0, 48
|
||||
; RV64ZBB-ZBP-ZBKB-NEXT: srai a0, a0, 57
|
||||
; RV64ZBB-ZBP-ZBKB-NEXT: ret
|
||||
%1 = ashr i16 %a, 9
|
||||
ret i16 %1
|
||||
}
|
||||
|
@ -643,17 +498,11 @@ define i1 @andn_seqz_i32(i32 signext %a, i32 signext %b) nounwind {
|
|||
; RV64I-NEXT: seqz a0, a0
|
||||
; RV64I-NEXT: ret
|
||||
;
|
||||
; RV64ZBB-LABEL: andn_seqz_i32:
|
||||
; RV64ZBB: # %bb.0:
|
||||
; RV64ZBB-NEXT: andn a0, a1, a0
|
||||
; RV64ZBB-NEXT: seqz a0, a0
|
||||
; RV64ZBB-NEXT: ret
|
||||
;
|
||||
; RV64ZBP-LABEL: andn_seqz_i32:
|
||||
; RV64ZBP: # %bb.0:
|
||||
; RV64ZBP-NEXT: andn a0, a1, a0
|
||||
; RV64ZBP-NEXT: seqz a0, a0
|
||||
; RV64ZBP-NEXT: ret
|
||||
; RV64ZBB-ZBP-ZBKB-LABEL: andn_seqz_i32:
|
||||
; RV64ZBB-ZBP-ZBKB: # %bb.0:
|
||||
; RV64ZBB-ZBP-ZBKB-NEXT: andn a0, a1, a0
|
||||
; RV64ZBB-ZBP-ZBKB-NEXT: seqz a0, a0
|
||||
; RV64ZBB-ZBP-ZBKB-NEXT: ret
|
||||
%and = and i32 %a, %b
|
||||
%cmpeq = icmp eq i32 %and, %b
|
||||
ret i1 %cmpeq
|
||||
|
@ -667,17 +516,11 @@ define i1 @andn_seqz_i64(i64 %a, i64 %b) nounwind {
|
|||
; RV64I-NEXT: seqz a0, a0
|
||||
; RV64I-NEXT: ret
|
||||
;
|
||||
; RV64ZBB-LABEL: andn_seqz_i64:
|
||||
; RV64ZBB: # %bb.0:
|
||||
; RV64ZBB-NEXT: andn a0, a1, a0
|
||||
; RV64ZBB-NEXT: seqz a0, a0
|
||||
; RV64ZBB-NEXT: ret
|
||||
;
|
||||
; RV64ZBP-LABEL: andn_seqz_i64:
|
||||
; RV64ZBP: # %bb.0:
|
||||
; RV64ZBP-NEXT: andn a0, a1, a0
|
||||
; RV64ZBP-NEXT: seqz a0, a0
|
||||
; RV64ZBP-NEXT: ret
|
||||
; RV64ZBB-ZBP-ZBKB-LABEL: andn_seqz_i64:
|
||||
; RV64ZBB-ZBP-ZBKB: # %bb.0:
|
||||
; RV64ZBB-ZBP-ZBKB-NEXT: andn a0, a1, a0
|
||||
; RV64ZBB-ZBP-ZBKB-NEXT: seqz a0, a0
|
||||
; RV64ZBB-ZBP-ZBKB-NEXT: ret
|
||||
%and = and i64 %a, %b
|
||||
%cmpeq = icmp eq i64 %and, %b
|
||||
ret i1 %cmpeq
|
||||
|
@ -691,17 +534,11 @@ define i1 @andn_snez_i32(i32 signext %a, i32 signext %b) nounwind {
|
|||
; RV64I-NEXT: snez a0, a0
|
||||
; RV64I-NEXT: ret
|
||||
;
|
||||
; RV64ZBB-LABEL: andn_snez_i32:
|
||||
; RV64ZBB: # %bb.0:
|
||||
; RV64ZBB-NEXT: andn a0, a1, a0
|
||||
; RV64ZBB-NEXT: snez a0, a0
|
||||
; RV64ZBB-NEXT: ret
|
||||
;
|
||||
; RV64ZBP-LABEL: andn_snez_i32:
|
||||
; RV64ZBP: # %bb.0:
|
||||
; RV64ZBP-NEXT: andn a0, a1, a0
|
||||
; RV64ZBP-NEXT: snez a0, a0
|
||||
; RV64ZBP-NEXT: ret
|
||||
; RV64ZBB-ZBP-ZBKB-LABEL: andn_snez_i32:
|
||||
; RV64ZBB-ZBP-ZBKB: # %bb.0:
|
||||
; RV64ZBB-ZBP-ZBKB-NEXT: andn a0, a1, a0
|
||||
; RV64ZBB-ZBP-ZBKB-NEXT: snez a0, a0
|
||||
; RV64ZBB-ZBP-ZBKB-NEXT: ret
|
||||
%and = and i32 %a, %b
|
||||
%cmpeq = icmp ne i32 %and, %b
|
||||
ret i1 %cmpeq
|
||||
|
@ -715,17 +552,11 @@ define i1 @andn_snez_i64(i64 %a, i64 %b) nounwind {
|
|||
; RV64I-NEXT: snez a0, a0
|
||||
; RV64I-NEXT: ret
|
||||
;
|
||||
; RV64ZBB-LABEL: andn_snez_i64:
|
||||
; RV64ZBB: # %bb.0:
|
||||
; RV64ZBB-NEXT: andn a0, a1, a0
|
||||
; RV64ZBB-NEXT: snez a0, a0
|
||||
; RV64ZBB-NEXT: ret
|
||||
;
|
||||
; RV64ZBP-LABEL: andn_snez_i64:
|
||||
; RV64ZBP: # %bb.0:
|
||||
; RV64ZBP-NEXT: andn a0, a1, a0
|
||||
; RV64ZBP-NEXT: snez a0, a0
|
||||
; RV64ZBP-NEXT: ret
|
||||
; RV64ZBB-ZBP-ZBKB-LABEL: andn_snez_i64:
|
||||
; RV64ZBB-ZBP-ZBKB: # %bb.0:
|
||||
; RV64ZBB-ZBP-ZBKB-NEXT: andn a0, a1, a0
|
||||
; RV64ZBB-ZBP-ZBKB-NEXT: snez a0, a0
|
||||
; RV64ZBB-ZBP-ZBKB-NEXT: ret
|
||||
%and = and i64 %a, %b
|
||||
%cmpeq = icmp ne i64 %and, %b
|
||||
ret i1 %cmpeq
|
|
@ -2,28 +2,6 @@
|
|||
; RUN: llc -mtriple=riscv64 -mattr=+zbc -verify-machineinstrs < %s \
|
||||
; RUN: | FileCheck %s -check-prefix=RV64ZBC
|
||||
|
||||
declare i64 @llvm.riscv.clmul.i64(i64 %a, i64 %b)
|
||||
|
||||
define i64 @clmul64(i64 %a, i64 %b) nounwind {
|
||||
; RV64ZBC-LABEL: clmul64:
|
||||
; RV64ZBC: # %bb.0:
|
||||
; RV64ZBC-NEXT: clmul a0, a0, a1
|
||||
; RV64ZBC-NEXT: ret
|
||||
%tmp = call i64 @llvm.riscv.clmul.i64(i64 %a, i64 %b)
|
||||
ret i64 %tmp
|
||||
}
|
||||
|
||||
declare i64 @llvm.riscv.clmulh.i64(i64 %a, i64 %b)
|
||||
|
||||
define i64 @clmul64h(i64 %a, i64 %b) nounwind {
|
||||
; RV64ZBC-LABEL: clmul64h:
|
||||
; RV64ZBC: # %bb.0:
|
||||
; RV64ZBC-NEXT: clmulh a0, a0, a1
|
||||
; RV64ZBC-NEXT: ret
|
||||
%tmp = call i64 @llvm.riscv.clmulh.i64(i64 %a, i64 %b)
|
||||
ret i64 %tmp
|
||||
}
|
||||
|
||||
declare i64 @llvm.riscv.clmulr.i64(i64 %a, i64 %b)
|
||||
|
||||
define i64 @clmul64r(i64 %a, i64 %b) nounwind {
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
|
||||
; RUN: llc -mtriple=riscv64 -mattr=+zbc -verify-machineinstrs < %s \
|
||||
; RUN: | FileCheck %s -check-prefix=RV64ZBC-ZBKC
|
||||
; RUN: llc -mtriple=riscv64 -mattr=+zbkc -verify-machineinstrs < %s \
|
||||
; RUN: | FileCheck %s -check-prefix=RV64ZBC-ZBKC
|
||||
|
||||
declare i64 @llvm.riscv.clmul.i64(i64 %a, i64 %b)
|
||||
|
||||
define i64 @clmul64(i64 %a, i64 %b) nounwind {
|
||||
; RV64ZBC-ZBKC-LABEL: clmul64:
|
||||
; RV64ZBC-ZBKC: # %bb.0:
|
||||
; RV64ZBC-ZBKC-NEXT: clmul a0, a0, a1
|
||||
; RV64ZBC-ZBKC-NEXT: ret
|
||||
%tmp = call i64 @llvm.riscv.clmul.i64(i64 %a, i64 %b)
|
||||
ret i64 %tmp
|
||||
}
|
||||
|
||||
declare i64 @llvm.riscv.clmulh.i64(i64 %a, i64 %b)
|
||||
|
||||
define i64 @clmul64h(i64 %a, i64 %b) nounwind {
|
||||
; RV64ZBC-ZBKC-LABEL: clmul64h:
|
||||
; RV64ZBC-ZBKC: # %bb.0:
|
||||
; RV64ZBC-ZBKC-NEXT: clmulh a0, a0, a1
|
||||
; RV64ZBC-ZBKC-NEXT: ret
|
||||
%tmp = call i64 @llvm.riscv.clmulh.i64(i64 %a, i64 %b)
|
||||
ret i64 %tmp
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
|
||||
; RUN: llc -mtriple=riscv64 -mattr=+zbkb -verify-machineinstrs < %s \
|
||||
; RUN: | FileCheck %s -check-prefix=RV64ZBKB
|
||||
|
||||
declare i64 @llvm.riscv.brev8(i64)
|
||||
|
||||
define i64 @brev8(i64 %a) nounwind {
|
||||
; RV64ZBKB-LABEL: brev8:
|
||||
; RV64ZBKB: # %bb.0:
|
||||
; RV64ZBKB-NEXT: brev8 a0, a0
|
||||
; RV64ZBKB-NEXT: ret
|
||||
%val = call i64 @llvm.riscv.brev8(i64 %a)
|
||||
ret i64 %val
|
||||
}
|
||||
|
||||
declare i64 @llvm.bswap.i64(i64)
|
||||
|
||||
define i64 @rev8_i64(i64 %a) {
|
||||
; RV64ZBKB-LABEL: rev8_i64:
|
||||
; RV64ZBKB: # %bb.0:
|
||||
; RV64ZBKB-NEXT: rev8 a0, a0
|
||||
; RV64ZBKB-NEXT: ret
|
||||
%1 = call i64 @llvm.bswap.i64(i64 %a)
|
||||
ret i64 %1
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
; RUN: llc -mtriple=riscv64 -mattr=+zbkx -verify-machineinstrs < %s \
|
||||
; RUN: | FileCheck %s -check-prefix=RV64ZBKX
|
||||
|
||||
declare i64 @llvm.riscv.xperm8.i64(i64 %a, i64 %b)
|
||||
|
||||
define i64 @xperm8(i64 %a, i64 %b) nounwind {
|
||||
; RV64ZBKX-LABEL: xperm8:
|
||||
; RV64ZBKX: # %bb.0:
|
||||
; RV64ZBKX-NEXT: xperm8 a0, a0, a1
|
||||
; RV64ZBKX-NEXT: ret
|
||||
%tmp = call i64 @llvm.riscv.xperm8.i64(i64 %a, i64 %b)
|
||||
ret i64 %tmp
|
||||
}
|
||||
|
||||
declare i64 @llvm.riscv.xperm4.i64(i64 %a, i64 %b)
|
||||
|
||||
define i64 @xperm4(i64 %a, i64 %b) nounwind {
|
||||
; RV64ZBKX-LABEL: xperm4:
|
||||
; RV64ZBKX: # %bb.0:
|
||||
; RV64ZBKX-NEXT: xperm4 a0, a0, a1
|
||||
; RV64ZBKX-NEXT: ret
|
||||
%tmp = call i64 @llvm.riscv.xperm4.i64(i64 %a, i64 %b)
|
||||
ret i64 %tmp
|
||||
}
|
|
@ -0,0 +1,125 @@
|
|||
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
|
||||
; RUN: llc -mtriple=riscv64 -verify-machineinstrs < %s \
|
||||
; RUN: | FileCheck %s -check-prefix=RV64I
|
||||
; RUN: llc -mtriple=riscv64 -mattr=+experimental-zbp -verify-machineinstrs < %s \
|
||||
; RUN: | FileCheck %s -check-prefix=RV64ZBP-ZBKB
|
||||
; RUN: llc -mtriple=riscv64 -mattr=+zbkb -verify-machineinstrs < %s \
|
||||
; RUN: | FileCheck %s -check-prefix=RV64ZBP-ZBKB
|
||||
|
||||
define signext i32 @pack_i32(i32 signext %a, i32 signext %b) nounwind {
|
||||
; RV64I-LABEL: pack_i32:
|
||||
; RV64I: # %bb.0:
|
||||
; RV64I-NEXT: slli a0, a0, 48
|
||||
; RV64I-NEXT: srli a0, a0, 48
|
||||
; RV64I-NEXT: slliw a1, a1, 16
|
||||
; RV64I-NEXT: or a0, a1, a0
|
||||
; RV64I-NEXT: ret
|
||||
;
|
||||
; RV64ZBP-ZBKB-LABEL: pack_i32:
|
||||
; RV64ZBP-ZBKB: # %bb.0:
|
||||
; RV64ZBP-ZBKB-NEXT: packw a0, a0, a1
|
||||
; RV64ZBP-ZBKB-NEXT: ret
|
||||
%shl = and i32 %a, 65535
|
||||
%shl1 = shl i32 %b, 16
|
||||
%or = or i32 %shl1, %shl
|
||||
ret i32 %or
|
||||
}
|
||||
|
||||
define i64 @pack_i64(i64 %a, i64 %b) nounwind {
|
||||
; RV64I-LABEL: pack_i64:
|
||||
; RV64I: # %bb.0:
|
||||
; RV64I-NEXT: slli a0, a0, 32
|
||||
; RV64I-NEXT: srli a0, a0, 32
|
||||
; RV64I-NEXT: slli a1, a1, 32
|
||||
; RV64I-NEXT: or a0, a1, a0
|
||||
; RV64I-NEXT: ret
|
||||
;
|
||||
; RV64ZBP-ZBKB-LABEL: pack_i64:
|
||||
; RV64ZBP-ZBKB: # %bb.0:
|
||||
; RV64ZBP-ZBKB-NEXT: pack a0, a0, a1
|
||||
; RV64ZBP-ZBKB-NEXT: ret
|
||||
%shl = and i64 %a, 4294967295
|
||||
%shl1 = shl i64 %b, 32
|
||||
%or = or i64 %shl1, %shl
|
||||
ret i64 %or
|
||||
}
|
||||
|
||||
define signext i32 @packh_i32(i32 signext %a, i32 signext %b) nounwind {
|
||||
; RV64I-LABEL: packh_i32:
|
||||
; RV64I: # %bb.0:
|
||||
; RV64I-NEXT: andi a0, a0, 255
|
||||
; RV64I-NEXT: slli a1, a1, 56
|
||||
; RV64I-NEXT: srli a1, a1, 48
|
||||
; RV64I-NEXT: or a0, a1, a0
|
||||
; RV64I-NEXT: ret
|
||||
;
|
||||
; RV64ZBP-ZBKB-LABEL: packh_i32:
|
||||
; RV64ZBP-ZBKB: # %bb.0:
|
||||
; RV64ZBP-ZBKB-NEXT: packh a0, a0, a1
|
||||
; RV64ZBP-ZBKB-NEXT: ret
|
||||
%and = and i32 %a, 255
|
||||
%and1 = shl i32 %b, 8
|
||||
%shl = and i32 %and1, 65280
|
||||
%or = or i32 %shl, %and
|
||||
ret i32 %or
|
||||
}
|
||||
|
||||
define i32 @packh_i32_2(i32 %a, i32 %b) nounwind {
|
||||
; RV64I-LABEL: packh_i32_2:
|
||||
; RV64I: # %bb.0:
|
||||
; RV64I-NEXT: andi a0, a0, 255
|
||||
; RV64I-NEXT: andi a1, a1, 255
|
||||
; RV64I-NEXT: slli a1, a1, 8
|
||||
; RV64I-NEXT: or a0, a1, a0
|
||||
; RV64I-NEXT: ret
|
||||
;
|
||||
; RV64ZBP-ZBKB-LABEL: packh_i32_2:
|
||||
; RV64ZBP-ZBKB: # %bb.0:
|
||||
; RV64ZBP-ZBKB-NEXT: packh a0, a0, a1
|
||||
; RV64ZBP-ZBKB-NEXT: ret
|
||||
%and = and i32 %a, 255
|
||||
%and1 = and i32 %b, 255
|
||||
%shl = shl i32 %and1, 8
|
||||
%or = or i32 %shl, %and
|
||||
ret i32 %or
|
||||
}
|
||||
|
||||
define i64 @packh_i64(i64 %a, i64 %b) nounwind {
|
||||
; RV64I-LABEL: packh_i64:
|
||||
; RV64I: # %bb.0:
|
||||
; RV64I-NEXT: andi a0, a0, 255
|
||||
; RV64I-NEXT: slli a1, a1, 56
|
||||
; RV64I-NEXT: srli a1, a1, 48
|
||||
; RV64I-NEXT: or a0, a1, a0
|
||||
; RV64I-NEXT: ret
|
||||
;
|
||||
; RV64ZBP-ZBKB-LABEL: packh_i64:
|
||||
; RV64ZBP-ZBKB: # %bb.0:
|
||||
; RV64ZBP-ZBKB-NEXT: packh a0, a0, a1
|
||||
; RV64ZBP-ZBKB-NEXT: ret
|
||||
%and = and i64 %a, 255
|
||||
%and1 = shl i64 %b, 8
|
||||
%shl = and i64 %and1, 65280
|
||||
%or = or i64 %shl, %and
|
||||
ret i64 %or
|
||||
}
|
||||
|
||||
define i64 @packh_i64_2(i64 %a, i64 %b) nounwind {
|
||||
; RV64I-LABEL: packh_i64_2:
|
||||
; RV64I: # %bb.0:
|
||||
; RV64I-NEXT: andi a0, a0, 255
|
||||
; RV64I-NEXT: andi a1, a1, 255
|
||||
; RV64I-NEXT: slli a1, a1, 8
|
||||
; RV64I-NEXT: or a0, a1, a0
|
||||
; RV64I-NEXT: ret
|
||||
;
|
||||
; RV64ZBP-ZBKB-LABEL: packh_i64_2:
|
||||
; RV64ZBP-ZBKB: # %bb.0:
|
||||
; RV64ZBP-ZBKB-NEXT: packh a0, a0, a1
|
||||
; RV64ZBP-ZBKB-NEXT: ret
|
||||
%and = and i64 %a, 255
|
||||
%and1 = and i64 %b, 255
|
||||
%shl = shl i64 %and1, 8
|
||||
%or = or i64 %shl, %and
|
||||
ret i64 %or
|
||||
}
|
|
@ -2713,44 +2713,6 @@ define i64 @shfl16(i64 %a, i64 %b) nounwind {
|
|||
ret i64 %or3
|
||||
}
|
||||
|
||||
define signext i32 @pack_i32(i32 signext %a, i32 signext %b) nounwind {
|
||||
; RV64I-LABEL: pack_i32:
|
||||
; RV64I: # %bb.0:
|
||||
; RV64I-NEXT: slli a0, a0, 48
|
||||
; RV64I-NEXT: srli a0, a0, 48
|
||||
; RV64I-NEXT: slliw a1, a1, 16
|
||||
; RV64I-NEXT: or a0, a1, a0
|
||||
; RV64I-NEXT: ret
|
||||
;
|
||||
; RV64ZBP-LABEL: pack_i32:
|
||||
; RV64ZBP: # %bb.0:
|
||||
; RV64ZBP-NEXT: packw a0, a0, a1
|
||||
; RV64ZBP-NEXT: ret
|
||||
%shl = and i32 %a, 65535
|
||||
%shl1 = shl i32 %b, 16
|
||||
%or = or i32 %shl1, %shl
|
||||
ret i32 %or
|
||||
}
|
||||
|
||||
define i64 @pack_i64(i64 %a, i64 %b) nounwind {
|
||||
; RV64I-LABEL: pack_i64:
|
||||
; RV64I: # %bb.0:
|
||||
; RV64I-NEXT: slli a0, a0, 32
|
||||
; RV64I-NEXT: srli a0, a0, 32
|
||||
; RV64I-NEXT: slli a1, a1, 32
|
||||
; RV64I-NEXT: or a0, a1, a0
|
||||
; RV64I-NEXT: ret
|
||||
;
|
||||
; RV64ZBP-LABEL: pack_i64:
|
||||
; RV64ZBP: # %bb.0:
|
||||
; RV64ZBP-NEXT: pack a0, a0, a1
|
||||
; RV64ZBP-NEXT: ret
|
||||
%shl = and i64 %a, 4294967295
|
||||
%shl1 = shl i64 %b, 32
|
||||
%or = or i64 %shl1, %shl
|
||||
ret i64 %or
|
||||
}
|
||||
|
||||
define signext i32 @packu_i32(i32 signext %a, i32 signext %b) nounwind {
|
||||
; RV64I-LABEL: packu_i32:
|
||||
; RV64I: # %bb.0:
|
||||
|
@ -2790,86 +2752,6 @@ define i64 @packu_i64(i64 %a, i64 %b) nounwind {
|
|||
ret i64 %or
|
||||
}
|
||||
|
||||
define signext i32 @packh_i32(i32 signext %a, i32 signext %b) nounwind {
|
||||
; RV64I-LABEL: packh_i32:
|
||||
; RV64I: # %bb.0:
|
||||
; RV64I-NEXT: andi a0, a0, 255
|
||||
; RV64I-NEXT: slli a1, a1, 56
|
||||
; RV64I-NEXT: srli a1, a1, 48
|
||||
; RV64I-NEXT: or a0, a1, a0
|
||||
; RV64I-NEXT: ret
|
||||
;
|
||||
; RV64ZBP-LABEL: packh_i32:
|
||||
; RV64ZBP: # %bb.0:
|
||||
; RV64ZBP-NEXT: packh a0, a0, a1
|
||||
; RV64ZBP-NEXT: ret
|
||||
%and = and i32 %a, 255
|
||||
%and1 = shl i32 %b, 8
|
||||
%shl = and i32 %and1, 65280
|
||||
%or = or i32 %shl, %and
|
||||
ret i32 %or
|
||||
}
|
||||
|
||||
define i32 @packh_i32_2(i32 %a, i32 %b) nounwind {
|
||||
; RV64I-LABEL: packh_i32_2:
|
||||
; RV64I: # %bb.0:
|
||||
; RV64I-NEXT: andi a0, a0, 255
|
||||
; RV64I-NEXT: andi a1, a1, 255
|
||||
; RV64I-NEXT: slli a1, a1, 8
|
||||
; RV64I-NEXT: or a0, a1, a0
|
||||
; RV64I-NEXT: ret
|
||||
;
|
||||
; RV64ZBP-LABEL: packh_i32_2:
|
||||
; RV64ZBP: # %bb.0:
|
||||
; RV64ZBP-NEXT: packh a0, a0, a1
|
||||
; RV64ZBP-NEXT: ret
|
||||
%and = and i32 %a, 255
|
||||
%and1 = and i32 %b, 255
|
||||
%shl = shl i32 %and1, 8
|
||||
%or = or i32 %shl, %and
|
||||
ret i32 %or
|
||||
}
|
||||
|
||||
define i64 @packh_i64(i64 %a, i64 %b) nounwind {
|
||||
; RV64I-LABEL: packh_i64:
|
||||
; RV64I: # %bb.0:
|
||||
; RV64I-NEXT: andi a0, a0, 255
|
||||
; RV64I-NEXT: slli a1, a1, 56
|
||||
; RV64I-NEXT: srli a1, a1, 48
|
||||
; RV64I-NEXT: or a0, a1, a0
|
||||
; RV64I-NEXT: ret
|
||||
;
|
||||
; RV64ZBP-LABEL: packh_i64:
|
||||
; RV64ZBP: # %bb.0:
|
||||
; RV64ZBP-NEXT: packh a0, a0, a1
|
||||
; RV64ZBP-NEXT: ret
|
||||
%and = and i64 %a, 255
|
||||
%and1 = shl i64 %b, 8
|
||||
%shl = and i64 %and1, 65280
|
||||
%or = or i64 %shl, %and
|
||||
ret i64 %or
|
||||
}
|
||||
|
||||
define i64 @packh_i64_2(i64 %a, i64 %b) nounwind {
|
||||
; RV64I-LABEL: packh_i64_2:
|
||||
; RV64I: # %bb.0:
|
||||
; RV64I-NEXT: andi a0, a0, 255
|
||||
; RV64I-NEXT: andi a1, a1, 255
|
||||
; RV64I-NEXT: slli a1, a1, 8
|
||||
; RV64I-NEXT: or a0, a1, a0
|
||||
; RV64I-NEXT: ret
|
||||
;
|
||||
; RV64ZBP-LABEL: packh_i64_2:
|
||||
; RV64ZBP: # %bb.0:
|
||||
; RV64ZBP-NEXT: packh a0, a0, a1
|
||||
; RV64ZBP-NEXT: ret
|
||||
%and = and i64 %a, 255
|
||||
%and1 = and i64 %b, 255
|
||||
%shl = shl i64 %and1, 8
|
||||
%or = or i64 %shl, %and
|
||||
ret i64 %or
|
||||
}
|
||||
|
||||
define i32 @zexth_i32(i32 %a) nounwind {
|
||||
; RV64I-LABEL: zexth_i32:
|
||||
; RV64I: # %bb.0:
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
|
||||
; RUN: llc -mtriple=riscv64 -mattr=+zknd -verify-machineinstrs < %s \
|
||||
; RUN: | FileCheck %s -check-prefix=RV64ZKND
|
||||
|
||||
declare i64 @llvm.riscv.aes64ds(i64, i64);
|
||||
|
||||
define i64 @aes64ds(i64 %a, i64 %b) nounwind {
|
||||
; RV64ZKND-LABEL: aes64ds
|
||||
; RV64ZKND: # %bb.0:
|
||||
; RV64ZKND-NEXT: aes64ds a0, a0, a1
|
||||
; RV64ZKND-NEXT: ret
|
||||
%val = call i64 @llvm.riscv.aes64ds(i64 %a, i64 %b)
|
||||
ret i64 %val
|
||||
}
|
||||
|
||||
declare i64 @llvm.riscv.aes64dsm(i64, i64);
|
||||
|
||||
define i64 @aes64dsm(i64 %a, i64 %b) nounwind {
|
||||
; RV64ZKND-LABEL: aes64dsm
|
||||
; RV64ZKND: # %bb.0:
|
||||
; RV64ZKND-NEXT: aes64dsm a0, a0, a1
|
||||
; RV64ZKND-NEXT: ret
|
||||
%val = call i64 @llvm.riscv.aes64dsm(i64 %a, i64 %b)
|
||||
ret i64 %val
|
||||
}
|
||||
|
||||
declare i64 @llvm.riscv.aes64im(i64);
|
||||
|
||||
define i64 @aes64im(i64 %a) nounwind {
|
||||
; RV64ZKND-LABEL: aes64im
|
||||
; RV64ZKND: # %bb.0:
|
||||
; RV64ZKND-NEXT: aes64im a0, a0
|
||||
; RV64ZKND-NEXT: ret
|
||||
%val = call i64 @llvm.riscv.aes64im(i64 %a)
|
||||
ret i64 %val
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
|
||||
; RUN: llc -mtriple=riscv64 -mattr=+zknd -verify-machineinstrs < %s \
|
||||
; RUN: | FileCheck %s -check-prefix=RV64ZKND-ZKNE
|
||||
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
|
||||
; RUN: llc -mtriple=riscv64 -mattr=+zkne -verify-machineinstrs < %s \
|
||||
; RUN: | FileCheck %s -check-prefix=RV64ZKND-ZKNE
|
||||
|
||||
declare i64 @llvm.riscv.aes64ks2(i64, i64);
|
||||
|
||||
define i64 @aes64ks2(i64 %a, i64 %b) nounwind {
|
||||
; RV64ZKND-ZKNE-LABEL: aes64ks2
|
||||
; RV64ZKND-ZKNE: # %bb.0:
|
||||
; RV64ZKND-ZKNE-NEXT: aes64ks2 a0, a0, a1
|
||||
; RV64ZKND-ZKNE-NEXT: ret
|
||||
%val = call i64 @llvm.riscv.aes64ks2(i64 %a, i64 %b)
|
||||
ret i64 %val
|
||||
}
|
||||
|
||||
declare i64 @llvm.riscv.aes64ks1i(i64, i32);
|
||||
|
||||
define i64 @aes64ks1i(i64 %a) nounwind {
|
||||
; RV64ZKND-ZKNE-LABEL: aes64ks1i
|
||||
; RV64ZKND-ZKNE: # %bb.0:
|
||||
; RV64ZKND-ZKNE-NEXT: aes64ks1i a0, a0, 10
|
||||
; RV64ZKND-ZKNE-NEXT: ret
|
||||
%val = call i64 @llvm.riscv.aes64ks1i(i64 %a, i32 10)
|
||||
ret i64 %val
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
|
||||
; RUN: llc -mtriple=riscv64 -mattr=+zkne -verify-machineinstrs < %s \
|
||||
; RUN: | FileCheck %s -check-prefix=RV64ZKNE
|
||||
|
||||
declare i64 @llvm.riscv.aes64es(i64, i64);
|
||||
|
||||
define i64 @aes64es(i64 %a, i64 %b) nounwind {
|
||||
; RV64ZKNE-LABEL: aes64es
|
||||
; RV64ZKNE: # %bb.0:
|
||||
; RV64ZKNE-NEXT: aes64es a0, a0, a1
|
||||
; RV64ZKNE-NEXT: ret
|
||||
%val = call i64 @llvm.riscv.aes64es(i64 %a, i64 %b)
|
||||
ret i64 %val
|
||||
}
|
||||
|
||||
declare i64 @llvm.riscv.aes64esm(i64, i64);
|
||||
|
||||
define i64 @aes64esm(i64 %a, i64 %b) nounwind {
|
||||
; RV64ZKNE-LABEL: aes64esm
|
||||
; RV64ZKNE: # %bb.0:
|
||||
; RV64ZKNE-NEXT: aes64esm a0, a0, a1
|
||||
; RV64ZKNE-NEXT: ret
|
||||
%val = call i64 @llvm.riscv.aes64esm(i64 %a, i64 %b)
|
||||
ret i64 %val
|
||||
}
|
|
@ -0,0 +1,92 @@
|
|||
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
|
||||
; RUN: llc -mtriple=riscv64 -mattr=+zknh -verify-machineinstrs < %s \
|
||||
; RUN: | FileCheck %s -check-prefix=RV64ZKNH
|
||||
|
||||
|
||||
declare i64 @llvm.riscv.sha256sig0.i64(i64);
|
||||
|
||||
define i64 @sha256sig0_i64(i64 %a) nounwind {
|
||||
; RV64ZKNH-LABEL: sha256sig0_i64
|
||||
; RV64ZKNH: # %bb.0:
|
||||
; RV64ZKNH-NEXT: sha256sig0 a0, a0
|
||||
; RV64ZKNH-NEXT: ret
|
||||
%val = call i64 @llvm.riscv.sha256sig0.i64(i64 %a)
|
||||
ret i64 %val
|
||||
}
|
||||
|
||||
declare i64 @llvm.riscv.sha256sig1.i64(i64);
|
||||
|
||||
define i64 @sha256sig1_i64(i64 %a) nounwind {
|
||||
; RV64ZKNH-LABEL: sha256sig1_i64
|
||||
; RV64ZKNH: # %bb.0:
|
||||
; RV64ZKNH-NEXT: sha256sig1 a0, a0
|
||||
; RV64ZKNH-NEXT: ret
|
||||
%val = call i64 @llvm.riscv.sha256sig1.i64(i64 %a)
|
||||
ret i64 %val
|
||||
}
|
||||
|
||||
declare i64 @llvm.riscv.sha256sum0.i64(i64);
|
||||
|
||||
define i64 @sha256sum0_i64(i64 %a) nounwind {
|
||||
; RV64ZKNH-LABEL: sha256sum0_i64
|
||||
; RV64ZKNH: # %bb.0:
|
||||
; RV64ZKNH-NEXT: sha256sum0 a0, a0
|
||||
; RV64ZKNH-NEXT: ret
|
||||
%val = call i64 @llvm.riscv.sha256sum0.i64(i64 %a)
|
||||
ret i64 %val
|
||||
}
|
||||
|
||||
declare i64 @llvm.riscv.sha256sum1.i64(i64);
|
||||
|
||||
define i64 @sha256sum1_i64(i64 %a) nounwind {
|
||||
; RV64ZKNH-LABEL: sha256sum1_i64
|
||||
; RV64ZKNH: # %bb.0:
|
||||
; RV64ZKNH-NEXT: sha256sum1 a0, a0
|
||||
; RV64ZKNH-NEXT: ret
|
||||
%val = call i64 @llvm.riscv.sha256sum1.i64(i64 %a)
|
||||
ret i64 %val
|
||||
}
|
||||
|
||||
declare i64 @llvm.riscv.sha512sig0(i64);
|
||||
|
||||
define i64 @sha512sig0(i64 %a) nounwind {
|
||||
; RV64ZKNH-LABEL: sha512sig0
|
||||
; RV64ZKNH: # %bb.0:
|
||||
; RV64ZKNH-NEXT: sha512sig0 a0, a0
|
||||
; RV64ZKNH-NEXT: ret
|
||||
%val = call i64 @llvm.riscv.sha512sig0(i64 %a)
|
||||
ret i64 %val
|
||||
}
|
||||
|
||||
declare i64 @llvm.riscv.sha512sig1(i64);
|
||||
|
||||
define i64 @sha512sig1(i64 %a) nounwind {
|
||||
; RV64ZKNH-LABEL: sha512sig1
|
||||
; RV64ZKNH: # %bb.0:
|
||||
; RV64ZKNH-NEXT: sha512sig1 a0, a0
|
||||
; RV64ZKNH-NEXT: ret
|
||||
%val = call i64 @llvm.riscv.sha512sig1(i64 %a)
|
||||
ret i64 %val
|
||||
}
|
||||
|
||||
declare i64 @llvm.riscv.sha512sum0(i64);
|
||||
|
||||
define i64 @sha512sum0(i64 %a) nounwind {
|
||||
; RV64ZKNH-LABEL: sha512sum0
|
||||
; RV64ZKNH: # %bb.0:
|
||||
; RV64ZKNH-NEXT: sha512sum0 a0, a0
|
||||
; RV64ZKNH-NEXT: ret
|
||||
%val = call i64 @llvm.riscv.sha512sum0(i64 %a)
|
||||
ret i64 %val
|
||||
}
|
||||
|
||||
declare i64 @llvm.riscv.sha512sum1(i64);
|
||||
|
||||
define i64 @sha512sum1(i64 %a) nounwind {
|
||||
; RV64ZKNH-LABEL: sha512sum1
|
||||
; RV64ZKNH: # %bb.0:
|
||||
; RV64ZKNH-NEXT: sha512sum1 a0, a0
|
||||
; RV64ZKNH-NEXT: ret
|
||||
%val = call i64 @llvm.riscv.sha512sum1(i64 %a)
|
||||
ret i64 %val
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
|
||||
; RUN: llc -mtriple=riscv64 -mattr=+zksed -verify-machineinstrs < %s \
|
||||
; RUN: | FileCheck %s -check-prefix=RV64ZKSED
|
||||
|
||||
declare i64 @llvm.riscv.sm4ks.i64(i64, i64, i8);
|
||||
|
||||
define i64 @sm4ks_i64(i64 %a, i64 %b) nounwind {
|
||||
; RV64ZKSED-LABEL: sm4ks_i64:
|
||||
; RV64ZKSED: # %bb.0:
|
||||
; RV64ZKSED-NEXT: sm4ks a0, a0, a1, 0
|
||||
; RV64ZKSED-NEXT: ret
|
||||
%val = call i64 @llvm.riscv.sm4ks.i64(i64 %a, i64 %b, i8 0)
|
||||
ret i64 %val
|
||||
}
|
||||
|
||||
declare i64 @llvm.riscv.sm4ed.i64(i64, i64, i8);
|
||||
|
||||
define i64 @sm4ed_i64(i64 %a, i64 %b) nounwind {
|
||||
; RV64ZKSED-LABEL: sm4ed_i64:
|
||||
; RV64ZKSED: # %bb.0:
|
||||
; RV64ZKSED-NEXT: sm4ed a0, a0, a1, 1
|
||||
; RV64ZKSED-NEXT: ret
|
||||
%val = call i64 @llvm.riscv.sm4ed.i64(i64 %a, i64 %b, i8 1)
|
||||
ret i64 %val
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
|
||||
; RUN: llc -mtriple=riscv64 -mattr=+zksh -verify-machineinstrs < %s \
|
||||
; RUN: | FileCheck %s -check-prefix=RV64ZKSH
|
||||
|
||||
declare i64 @llvm.riscv.sm3p0.i64(i64);
|
||||
|
||||
define i64 @sm3p0_i64(i64 %a) nounwind {
|
||||
; RV64ZKSH-LABEL: sm3p0_i64:
|
||||
; RV64ZKSH: # %bb.0:
|
||||
; RV64ZKSH-NEXT: sm3p0 a0, a0
|
||||
; RV64ZKSH-NEXT: ret
|
||||
%val = call i64 @llvm.riscv.sm3p0.i64(i64 %a)
|
||||
ret i64 %val
|
||||
}
|
||||
|
||||
declare i64 @llvm.riscv.sm3p1.i64(i64);
|
||||
|
||||
define i64 @sm3p1_i64(i64 %a) nounwind {
|
||||
; RV64ZKSH-LABEL: sm3p1_i64:
|
||||
; RV64ZKSH: # %bb.0:
|
||||
; RV64ZKSH-NEXT: sm3p1 a0, a0
|
||||
; RV64ZKSH-NEXT: ret
|
||||
%val = call i64 @llvm.riscv.sm3p1.i64(i64 %a)
|
||||
ret i64 %val
|
||||
}
|
Loading…
Reference in New Issue