diff --git a/llvm/include/llvm/IR/IntrinsicsRISCV.td b/llvm/include/llvm/IR/IntrinsicsRISCV.td --- a/llvm/include/llvm/IR/IntrinsicsRISCV.td +++ b/llvm/include/llvm/IR/IntrinsicsRISCV.td @@ -88,9 +88,11 @@ // 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 @@ // 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 @@ llvm_anyint_ty, LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>], [NoCapture>, 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>]>; + +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>, Returned>]>; + +// 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>]>; + +// 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" diff --git a/llvm/lib/Target/RISCV/RISCV.td b/llvm/lib/Target/RISCV/RISCV.td --- a/llvm/lib/Target/RISCV/RISCV.td +++ b/llvm/lib/Target/RISCV/RISCV.td @@ -169,6 +169,12 @@ "'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), diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp --- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp @@ -250,7 +250,8 @@ 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 @@ // 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 @@ if (VT.isVector()) return false; - return (Subtarget.hasStdExtZbb() || Subtarget.hasStdExtZbp()) && + return (Subtarget.hasStdExtZbb() || Subtarget.hasStdExtZbp() || + Subtarget.hasStdExtZbkb()) && !isa(Y); } diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoZb.td b/llvm/lib/Target/RISCV/RISCVInstrInfoZb.td --- a/llvm/lib/Target/RISCV/RISCVInstrInfoZb.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoZb.td @@ -794,16 +794,16 @@ // 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; def : PatGprGpr; -} // Predicates = [HasStdExtZbbOrZbp] +} // Predicates = [HasStdExtZbbOrZbpOrZbkb] let Predicates = [HasStdExtZbs] in { def : Pat<(and (not (shiftop 1, GPR:$rs2)), GPR:$rs1), @@ -854,7 +854,7 @@ // 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; def : Pat<(rotl GPR:$rs1, uimmlog2xlen:$shamt), (RORI GPR:$rs1, (ImmSubFromXLen uimmlog2xlen:$shamt))>; @@ -960,35 +960,38 @@ def : PatGprGpr; } // 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 @@ (SH3ADDUW GPR:$rs1, GPR:$rs2)>; } // Predicates = [HasStdExtZba, IsRV64] -let Predicates = [HasStdExtZbbOrZbp, IsRV64] in { +let Predicates = [HasStdExtZbbOrZbpOrZbkb, IsRV64] in { def : PatGprGpr; def : PatGprGpr; def : PatGprImm; 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 : 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 (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; def : PatGprGpr; +} // Predicates = [HasStdExtZbcOrZbkc] + +let Predicates = [HasStdExtZbc] in def : PatGprGpr; -} // Predicates = [HasStdExtZbc] let Predicates = [HasStdExtZbe] in { def : PatGprGpr; @@ -1177,3 +1185,17 @@ let Predicates = [HasStdExtZbf, IsRV64] in def : PatGprGpr; + +let Predicates = [HasStdExtZbkb] in { +def : PatGpr; +} // Predicates = [HasStdExtZbkb] + +let Predicates = [HasStdExtZbkb, IsRV32] in { +def : PatGpr; +def : PatGpr; +} // Predicates = [HasStdExtZbkb, IsRV32] + +let Predicates = [HasStdExtZbkx] in { +def : PatGprGpr; +def : PatGprGpr; +} diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoZk.td b/llvm/lib/Target/RISCV/RISCVInstrInfoZk.td --- a/llvm/lib/Target/RISCV/RISCVInstrInfoZk.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoZk.td @@ -21,7 +21,7 @@ let DiagnosticType = "InvalidRnumArg"; } -def rnum : Operand, ImmLeaf= 0 && Imm <= 10);}]> { +def rnum : Operand, TImmLeaf= 0 && Imm <= 10);}]> { let ParserMatchClass = RnumArg; let EncoderMethod = "getImmOpValue"; let DecoderMethod = "decodeUImmOperand<4>"; @@ -29,6 +29,13 @@ let OperandNamespace = "RISCVOp"; } +def byteselect : Operand, TImmLeaf(Imm);}]> { + let ParserMatchClass = UImmAsmOperand<2>; + let DecoderMethod = "decodeUImmOperand<2>"; + let OperandType = "OPERAND_UIMM2"; + let OperandNamespace = "RISCVOp"; +} + //===----------------------------------------------------------------------===// // Instruction class templates //===----------------------------------------------------------------------===// @@ -42,7 +49,7 @@ let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in class RVKByteSelect 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 @@ def SM3P0 : RVKUnary<0b000100001000, 0b001, "sm3p0">; def SM3P1 : RVKUnary<0b000100001001, 0b001, "sm3p1">; } // Predicates = [HasStdExtZksh] + +//===----------------------------------------------------------------------===// +// Codegen patterns +//===----------------------------------------------------------------------===// + +class PatGprGprByteSelect + : Pat<(OpNode GPR:$rs1, GPR:$rs2, i8:$imm), + (Inst GPR:$rs1, GPR:$rs2, byteselect:$imm)>; + +// Zknd +let Predicates = [HasStdExtZknd, IsRV32] in { +def : PatGprGprByteSelect; +def : PatGprGprByteSelect; +} // Predicates = [HasStdExtZknd, IsRV32] + +let Predicates = [HasStdExtZknd, IsRV64] in { +def : PatGprGpr; +def : PatGprGpr; +def : PatGpr; +} // Predicates = [HasStdExtZknd, IsRV64] + +let Predicates = [HasStdExtZkndOrZkne, IsRV64] in { +def : PatGprGpr; +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; +def : PatGprGprByteSelect; +} // Predicates = [HasStdExtZkne, IsRV32] + +let Predicates = [HasStdExtZkne, IsRV64] in { +def : PatGprGpr; +def : PatGprGpr; +} // Predicates = [HasStdExtZkne, IsRV64] + +// Zknh +let Predicates = [HasStdExtZknh] in { +def : PatGpr; +def : PatGpr; +def : PatGpr; +def : PatGpr; +} // Predicates = [HasStdExtZknh] + +let Predicates = [HasStdExtZknh, IsRV32] in { +def : PatGprGpr; +def : PatGprGpr; +def : PatGprGpr; +def : PatGprGpr; +def : PatGprGpr; +def : PatGprGpr; +} // Predicates = [HasStdExtZknh, IsRV32] + +let Predicates = [HasStdExtZknh, IsRV64] in { +def : PatGpr; +def : PatGpr; +def : PatGpr; +def : PatGpr; +} // Predicates = [HasStdExtZknh, IsRV64] + +// Zksed +let Predicates = [HasStdExtZksed] in { +def : PatGprGprByteSelect; +def : PatGprGprByteSelect; +} // Predicates = [HasStdExtZksed] + +// Zksh +let Predicates = [HasStdExtZksh] in { +def : PatGpr; +def : PatGpr; +} // Predicates = [HasStdExtZksh] diff --git a/llvm/test/CodeGen/RISCV/rv32zbb-zbp-zbkb.ll b/llvm/test/CodeGen/RISCV/rv32zbb-zbp-zbkb.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/RISCV/rv32zbb-zbp-zbkb.ll @@ -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 +} diff --git a/llvm/test/CodeGen/RISCV/rv32zbb-zbp.ll b/llvm/test/CodeGen/RISCV/rv32zbb-zbp.ll deleted file mode 100644 --- a/llvm/test/CodeGen/RISCV/rv32zbb-zbp.ll +++ /dev/null @@ -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 -} diff --git a/llvm/test/CodeGen/RISCV/rv32zbc-intrinsic.ll b/llvm/test/CodeGen/RISCV/rv32zbc-intrinsic.ll --- a/llvm/test/CodeGen/RISCV/rv32zbc-intrinsic.ll +++ b/llvm/test/CodeGen/RISCV/rv32zbc-intrinsic.ll @@ -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 { diff --git a/llvm/test/CodeGen/RISCV/rv32zbc-zbkc-intrinsic.ll b/llvm/test/CodeGen/RISCV/rv32zbc-zbkc-intrinsic.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/RISCV/rv32zbc-zbkc-intrinsic.ll @@ -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 +} diff --git a/llvm/test/CodeGen/RISCV/rv32zbkb-intrinsic.ll b/llvm/test/CodeGen/RISCV/rv32zbkb-intrinsic.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/RISCV/rv32zbkb-intrinsic.ll @@ -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 +} diff --git a/llvm/test/CodeGen/RISCV/rv32zbkx-intrinsic.ll b/llvm/test/CodeGen/RISCV/rv32zbkx-intrinsic.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/RISCV/rv32zbkx-intrinsic.ll @@ -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 +} diff --git a/llvm/test/CodeGen/RISCV/rv32zbp-zbkb.ll b/llvm/test/CodeGen/RISCV/rv32zbp-zbkb.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/RISCV/rv32zbp-zbkb.ll @@ -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 +} diff --git a/llvm/test/CodeGen/RISCV/rv32zbp.ll b/llvm/test/CodeGen/RISCV/rv32zbp.ll --- a/llvm/test/CodeGen/RISCV/rv32zbp.ll +++ b/llvm/test/CodeGen/RISCV/rv32zbp.ll @@ -2773,46 +2773,6 @@ 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 @@ 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: diff --git a/llvm/test/CodeGen/RISCV/rv32zknd-intrinsic.ll b/llvm/test/CodeGen/RISCV/rv32zknd-intrinsic.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/RISCV/rv32zknd-intrinsic.ll @@ -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 +} diff --git a/llvm/test/CodeGen/RISCV/rv32zkne-intrinsic.ll b/llvm/test/CodeGen/RISCV/rv32zkne-intrinsic.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/RISCV/rv32zkne-intrinsic.ll @@ -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 +} diff --git a/llvm/test/CodeGen/RISCV/rv32zknh-intrinsic.ll b/llvm/test/CodeGen/RISCV/rv32zknh-intrinsic.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/RISCV/rv32zknh-intrinsic.ll @@ -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 +} diff --git a/llvm/test/CodeGen/RISCV/rv32zksed-intrinsic.ll b/llvm/test/CodeGen/RISCV/rv32zksed-intrinsic.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/RISCV/rv32zksed-intrinsic.ll @@ -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 +} diff --git a/llvm/test/CodeGen/RISCV/rv32zksh-intrinsic.ll b/llvm/test/CodeGen/RISCV/rv32zksh-intrinsic.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/RISCV/rv32zksh-intrinsic.ll @@ -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 +} diff --git a/llvm/test/CodeGen/RISCV/rv64zbb-zbp.ll b/llvm/test/CodeGen/RISCV/rv64zbb-zbp-zbkb.ll rename from llvm/test/CodeGen/RISCV/rv64zbb-zbp.ll rename to llvm/test/CodeGen/RISCV/rv64zbb-zbp-zbkb.ll --- a/llvm/test/CodeGen/RISCV/rv64zbb-zbp.ll +++ b/llvm/test/CodeGen/RISCV/rv64zbb-zbp-zbkb.ll @@ -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 @@ ; 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 @@ ; 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 @@ ; 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 @@ ; 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 @@ ; 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 @@ ; 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 @@ ; 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 @@ ; 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 @@ ; 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 @@ ; 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 @@ ; 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 @@ ; 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 @@ ; 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 @@ ; 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 @@ ; 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 @@ ; 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 @@ ; 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 @@ ; 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 @@ ; 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 @@ ; 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 @@ ; 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 @@ ; 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 @@ ; 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 @@ ; 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 @@ ; 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 @@ ; 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 @@ ; 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 @@ ; 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 @@ ; 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 @@ ; 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 diff --git a/llvm/test/CodeGen/RISCV/rv64zbc-intrinsic.ll b/llvm/test/CodeGen/RISCV/rv64zbc-intrinsic.ll --- a/llvm/test/CodeGen/RISCV/rv64zbc-intrinsic.ll +++ b/llvm/test/CodeGen/RISCV/rv64zbc-intrinsic.ll @@ -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 { diff --git a/llvm/test/CodeGen/RISCV/rv64zbc-zbkc-intrinsic.ll b/llvm/test/CodeGen/RISCV/rv64zbc-zbkc-intrinsic.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/RISCV/rv64zbc-zbkc-intrinsic.ll @@ -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 +} + diff --git a/llvm/test/CodeGen/RISCV/rv64zbkb-intrinsic.ll b/llvm/test/CodeGen/RISCV/rv64zbkb-intrinsic.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/RISCV/rv64zbkb-intrinsic.ll @@ -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 +} diff --git a/llvm/test/CodeGen/RISCV/rv64zbkx-intrinsic.ll b/llvm/test/CodeGen/RISCV/rv64zbkx-intrinsic.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/RISCV/rv64zbkx-intrinsic.ll @@ -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 +} diff --git a/llvm/test/CodeGen/RISCV/rv64zbp-zbkb.ll b/llvm/test/CodeGen/RISCV/rv64zbp-zbkb.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/RISCV/rv64zbp-zbkb.ll @@ -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 +} diff --git a/llvm/test/CodeGen/RISCV/rv64zbp.ll b/llvm/test/CodeGen/RISCV/rv64zbp.ll --- a/llvm/test/CodeGen/RISCV/rv64zbp.ll +++ b/llvm/test/CodeGen/RISCV/rv64zbp.ll @@ -2713,44 +2713,6 @@ 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 @@ 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: diff --git a/llvm/test/CodeGen/RISCV/rv64zknd-intrinsic.ll b/llvm/test/CodeGen/RISCV/rv64zknd-intrinsic.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/RISCV/rv64zknd-intrinsic.ll @@ -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 +} diff --git a/llvm/test/CodeGen/RISCV/rv64zknd-zkne-intrinsic.ll b/llvm/test/CodeGen/RISCV/rv64zknd-zkne-intrinsic.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/RISCV/rv64zknd-zkne-intrinsic.ll @@ -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 +} diff --git a/llvm/test/CodeGen/RISCV/rv64zkne-intrinsic.ll b/llvm/test/CodeGen/RISCV/rv64zkne-intrinsic.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/RISCV/rv64zkne-intrinsic.ll @@ -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 +} diff --git a/llvm/test/CodeGen/RISCV/rv64zknh-intrinsic.ll b/llvm/test/CodeGen/RISCV/rv64zknh-intrinsic.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/RISCV/rv64zknh-intrinsic.ll @@ -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 +} diff --git a/llvm/test/CodeGen/RISCV/rv64zksed-intrinsic.ll b/llvm/test/CodeGen/RISCV/rv64zksed-intrinsic.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/RISCV/rv64zksed-intrinsic.ll @@ -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 +} diff --git a/llvm/test/CodeGen/RISCV/rv64zksh-intrinsic.ll b/llvm/test/CodeGen/RISCV/rv64zksh-intrinsic.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/RISCV/rv64zksh-intrinsic.ll @@ -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 +}