diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.h b/llvm/lib/Target/RISCV/RISCVISelLowering.h
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.h
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.h
@@ -108,6 +108,11 @@
   BCOMPRESSW,
   BDECOMPRESS,
   BDECOMPRESSW,
+  // Packed SIMD Extension
+  BSWAPH,
+  BSWAPW,
+  BSWAP,
+  BITREVI,
   // Vector Extension
   // VMV_V_X_VL matches the semantics of vmv.v.x but includes an extra operand
   // for the VL value to be used for the operation.
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
@@ -841,10 +841,20 @@
       AddPromotedToType(ISD::STORE, VT, PromotedBitwiseVT);
     };
 
+    setOperationAction(ISD::BITREVERSE, XLenVT, Custom);
+    setOperationAction(ISD::BSWAP, XLenVT, Custom);
+    setOperationAction(ISD::BITREVERSE, MVT::i8, Custom);
+    // BSWAP i8 doesn't exist.
+    setOperationAction(ISD::BITREVERSE, MVT::i16, Custom);
+    setOperationAction(ISD::BSWAP, MVT::i16, Custom);
+
     if (Subtarget.is64Bit()) {
       addTypeForP(MVT::v8i8, MVT::i64);
       addTypeForP(MVT::v4i16, MVT::i64);
       addTypeForP(MVT::v2i32, MVT::i64);
+
+      setOperationAction(ISD::BITREVERSE, MVT::i32, Custom);
+      setOperationAction(ISD::BSWAP, MVT::i32, Custom);
     } else {
       addTypeForP(MVT::v4i8, MVT::i32);
       addTypeForP(MVT::v2i16, MVT::i32);
@@ -2091,15 +2101,21 @@
   case ISD::BSWAP:
   case ISD::BITREVERSE: {
     // Convert BSWAP/BITREVERSE to GREVI to enable GREVI combinining.
-    assert(Subtarget.hasStdExtZbp() && "Unexpected custom legalisation");
+    assert((Subtarget.hasStdExtZbp() || Subtarget.hasStdExtZpn()) &&
+           "Unexpected custom legalisation");
     MVT VT = Op.getSimpleValueType();
     SDLoc DL(Op);
+    // Only RVP is enabled, lower BSWAP to customized BSWAP.
+    if (!Subtarget.hasStdExtZbp() && Op.getOpcode() == ISD::BSWAP)
+      return DAG.getNode(RISCVISD::BSWAP, DL, VT, Op.getOperand(0));
     // Start with the maximum immediate value which is the bitwidth - 1.
     unsigned Imm = VT.getSizeInBits() - 1;
     // If this is BSWAP rather than BITREVERSE, clear the lower 3 bits.
     if (Op.getOpcode() == ISD::BSWAP)
       Imm &= ~0x7U;
-    return DAG.getNode(RISCVISD::GREV, DL, VT, Op.getOperand(0),
+    unsigned Opc =
+        Subtarget.hasStdExtZbp() ? RISCVISD::GREV : RISCVISD::BITREVI;
+    return DAG.getNode(Opc, DL, VT, Op.getOperand(0),
                        DAG.getConstant(Imm, DL, VT));
   }
   case ISD::FSHL:
@@ -4992,18 +5008,29 @@
     MVT XLenVT = Subtarget.getXLenVT();
     assert((VT == MVT::i8 || VT == MVT::i16 ||
             (VT == MVT::i32 && Subtarget.is64Bit())) &&
-           Subtarget.hasStdExtZbp() && "Unexpected custom legalisation");
+           (Subtarget.hasStdExtZbp() || Subtarget.hasStdExtZpn()) &&
+           "Unexpected custom legalisation");
     SDValue NewOp0 = DAG.getNode(ISD::ANY_EXTEND, DL, XLenVT, N->getOperand(0));
-    unsigned Imm = VT.getSizeInBits() - 1;
-    // If this is BSWAP rather than BITREVERSE, clear the lower 3 bits.
-    if (N->getOpcode() == ISD::BSWAP)
-      Imm &= ~0x7U;
-    unsigned Opc = Subtarget.is64Bit() ? RISCVISD::GREVW : RISCVISD::GREV;
-    SDValue GREVI =
-        DAG.getNode(Opc, DL, XLenVT, NewOp0, DAG.getConstant(Imm, DL, XLenVT));
+    SDValue NewOp;
+    // Only RVP is enabled, lower BSWAP to customized BSWAP.
+    if (!Subtarget.hasStdExtZbp() && N->getOpcode() == ISD::BSWAP)
+      NewOp = DAG.getNode(VT == MVT::i16 ? RISCVISD::BSWAPH : RISCVISD::BSWAPW,
+                          DL, XLenVT, NewOp0);
+    else {
+      unsigned Imm = VT.getSizeInBits() - 1;
+      // If this is BSWAP rather than BITREVERSE, clear the lower 3 bits.
+      if (N->getOpcode() == ISD::BSWAP)
+        Imm &= ~0x7U;
+      unsigned Opc =
+          Subtarget.hasStdExtZbp()
+              ? Subtarget.is64Bit() ? RISCVISD::GREVW : RISCVISD::GREV
+              : RISCVISD::BITREVI;
+      NewOp = DAG.getNode(Opc, DL, XLenVT, NewOp0,
+                          DAG.getConstant(Imm, DL, XLenVT));
+    }
     // ReplaceNodeResults requires we maintain the same type for the return
     // value.
-    Results.push_back(DAG.getNode(ISD::TRUNCATE, DL, VT, GREVI));
+    Results.push_back(DAG.getNode(ISD::TRUNCATE, DL, VT, NewOp));
     break;
   }
   case ISD::FSHL:
@@ -6293,6 +6320,14 @@
     }
     break;
   }
+  case RISCVISD::BSWAPH:
+    Known.Zero.setBitsFrom(16);
+    break;
+  case RISCVISD::BITREVI: {
+    unsigned Imm = Op.getConstantOperandVal(1);
+    Known.Zero.setBitsFrom(Imm);
+    break;
+  }
   case RISCVISD::READ_VLENB:
     // We assume VLENB is at least 16 bytes.
     Known.Zero.setLowBits(4);
@@ -8064,6 +8099,10 @@
   NODE_NAME_CASE(BCOMPRESSW)
   NODE_NAME_CASE(BDECOMPRESS)
   NODE_NAME_CASE(BDECOMPRESSW)
+  NODE_NAME_CASE(BSWAPH)
+  NODE_NAME_CASE(BSWAPW)
+  NODE_NAME_CASE(BSWAP)
+  NODE_NAME_CASE(BITREVI)
   NODE_NAME_CASE(VMV_V_X_VL)
   NODE_NAME_CASE(VFMV_V_F_VL)
   NODE_NAME_CASE(VMV_X_S)
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.td b/llvm/lib/Target/RISCV/RISCVInstrInfo.td
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.td
@@ -34,6 +34,9 @@
                                              SDTCisInt<2>]>;
 def SDT_RISCVReadCycleWide : SDTypeProfile<2, 0, [SDTCisVT<0, i32>,
                                                   SDTCisVT<1, i32>]>;
+def SDT_RISCVIntUnaryOp : SDTypeProfile<1, 1, [
+  SDTCisSameAs<0, 1>, SDTCisVT<0, XLenVT>
+]>;
 def SDT_RISCVIntUnaryOpW : SDTypeProfile<1, 1, [
   SDTCisSameAs<0, 1>, SDTCisVT<0, i64>
 ]>;
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoP.td b/llvm/lib/Target/RISCV/RISCVInstrInfoP.td
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoP.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoP.td
@@ -17,6 +17,11 @@
 // Operand and SDNode transformation definitions.
 //===----------------------------------------------------------------------===//
 
+def riscv_bswaph  : SDNode<"RISCVISD::BSWAPH", SDT_RISCVIntUnaryOp>;
+def riscv_bswapw  : SDNode<"RISCVISD::BSWAPW", SDT_RISCVIntUnaryOpW>;
+def riscv_bswap   : SDNode<"RISCVISD::BSWAP", SDT_RISCVIntUnaryOp>;
+def riscv_bitrevi : SDNode<"RISCVISD::BITREVI", SDT_RISCVIntBinOp>;
+
 def uimm3 : Operand<XLenVT>, ImmLeaf<XLenVT, [{return isUInt<3>(Imm);}]> {
   let ParserMatchClass = UImmAsmOperand<3>;
   let DecoderMethod = "decodeUImmOperand<3>";
@@ -1282,3 +1287,23 @@
 def : PatALU32I<or, ORI>;
 def : PatALU32I<xor, XORI>;
 } // [HasStdExtZpn, IsRV64]
+
+// bswap
+let Predicates = [HasStdExtZpn] in
+def : Pat<(riscv_bswaph GPR:$rs1), (SWAP8 GPR:$rs1)>;
+
+let Predicates = [HasStdExtZpn, IsRV32] in
+def : Pat<(riscv_bswap i32:$rs1), (PKBT16 (SWAP8 GPR:$rs1), (SWAP8 GPR:$rs1))>;
+
+let Predicates = [HasStdExtZpn, IsRV64] in {
+def : Pat<(riscv_bswapw GPR:$rs1),
+          (PKBT16 (SWAP8 GPR:$rs1), (SWAP8 GPR:$rs1))>;
+def : Pat<(riscv_bswap i64:$rs1),
+          (PKBT32 (PKBT16 (SWAP8 GPR:$rs1), (SWAP8 GPR:$rs1)),
+                  (PKBT16 (SWAP8 GPR:$rs1), (SWAP8 GPR:$rs1)))>;
+}
+
+// bitreverse
+let Predicates = [HasStdExtZpn] in
+def : Pat<(riscv_bitrevi GPR:$rs1, uimmlog2xlen:$imm),
+          (BITREVI GPR:$rs1, uimmlog2xlen:$imm)>;
diff --git a/llvm/test/CodeGen/RISCV/rv32zpn-bitreverse.ll b/llvm/test/CodeGen/RISCV/rv32zpn-bitreverse.ll
--- a/llvm/test/CodeGen/RISCV/rv32zpn-bitreverse.ll
+++ b/llvm/test/CodeGen/RISCV/rv32zpn-bitreverse.ll
@@ -21,38 +21,12 @@
 ;
 ; RV32IP-LABEL: bitreverse_i8:
 ; RV32IP:       # %bb.0:
-; RV32IP-NEXT:    srli a1, a0, 4
-; RV32IP-NEXT:    andi a0, a0, 15
-; RV32IP-NEXT:    slli a0, a0, 4
-; RV32IP-NEXT:    or a0, a1, a0
-; RV32IP-NEXT:    andi a1, a0, 51
-; RV32IP-NEXT:    slli a1, a1, 2
-; RV32IP-NEXT:    andi a0, a0, 204
-; RV32IP-NEXT:    srli a0, a0, 2
-; RV32IP-NEXT:    or a0, a0, a1
-; RV32IP-NEXT:    andi a1, a0, 85
-; RV32IP-NEXT:    slli a1, a1, 1
-; RV32IP-NEXT:    andi a0, a0, 170
-; RV32IP-NEXT:    srli a0, a0, 1
-; RV32IP-NEXT:    or a0, a0, a1
+; RV32IP-NEXT:    bitrevi a0, a0, 7
 ; RV32IP-NEXT:    ret
 ;
 ; RV32IPN-LABEL: bitreverse_i8:
 ; RV32IPN:       # %bb.0:
-; RV32IPN-NEXT:    srli a1, a0, 4
-; RV32IPN-NEXT:    andi a0, a0, 15
-; RV32IPN-NEXT:    slli a0, a0, 4
-; RV32IPN-NEXT:    or a0, a1, a0
-; RV32IPN-NEXT:    andi a1, a0, 51
-; RV32IPN-NEXT:    slli a1, a1, 2
-; RV32IPN-NEXT:    andi a0, a0, 204
-; RV32IPN-NEXT:    srli a0, a0, 2
-; RV32IPN-NEXT:    or a0, a0, a1
-; RV32IPN-NEXT:    andi a1, a0, 85
-; RV32IPN-NEXT:    slli a1, a1, 1
-; RV32IPN-NEXT:    andi a0, a0, 170
-; RV32IPN-NEXT:    srli a0, a0, 1
-; RV32IPN-NEXT:    or a0, a0, a1
+; RV32IPN-NEXT:    bitrevi a0, a0, 7
 ; RV32IPN-NEXT:    ret
 ;
 ; RV32IBP-LABEL: bitreverse_i8:
@@ -71,70 +45,12 @@
 ;
 ; RV32IP-LABEL: bitreverse_i16:
 ; RV32IP:       # %bb.0:
-; RV32IP-NEXT:    srli a1, a0, 8
-; RV32IP-NEXT:    slli a0, a0, 8
-; RV32IP-NEXT:    or a0, a0, a1
-; RV32IP-NEXT:    lui a1, 1
-; RV32IP-NEXT:    addi a1, a1, -241
-; RV32IP-NEXT:    and a1, a0, a1
-; RV32IP-NEXT:    slli a1, a1, 4
-; RV32IP-NEXT:    lui a2, 15
-; RV32IP-NEXT:    addi a2, a2, 240
-; RV32IP-NEXT:    and a0, a0, a2
-; RV32IP-NEXT:    srli a0, a0, 4
-; RV32IP-NEXT:    or a0, a0, a1
-; RV32IP-NEXT:    lui a1, 3
-; RV32IP-NEXT:    addi a1, a1, 819
-; RV32IP-NEXT:    and a1, a0, a1
-; RV32IP-NEXT:    slli a1, a1, 2
-; RV32IP-NEXT:    lui a2, 13
-; RV32IP-NEXT:    addi a2, a2, -820
-; RV32IP-NEXT:    and a0, a0, a2
-; RV32IP-NEXT:    srli a0, a0, 2
-; RV32IP-NEXT:    or a0, a0, a1
-; RV32IP-NEXT:    lui a1, 5
-; RV32IP-NEXT:    addi a1, a1, 1365
-; RV32IP-NEXT:    and a1, a0, a1
-; RV32IP-NEXT:    slli a1, a1, 1
-; RV32IP-NEXT:    lui a2, 11
-; RV32IP-NEXT:    addi a2, a2, -1366
-; RV32IP-NEXT:    and a0, a0, a2
-; RV32IP-NEXT:    srli a0, a0, 1
-; RV32IP-NEXT:    or a0, a0, a1
+; RV32IP-NEXT:    bitrevi a0, a0, 15
 ; RV32IP-NEXT:    ret
 ;
 ; RV32IPN-LABEL: bitreverse_i16:
 ; RV32IPN:       # %bb.0:
-; RV32IPN-NEXT:    srli a1, a0, 8
-; RV32IPN-NEXT:    slli a0, a0, 8
-; RV32IPN-NEXT:    or a0, a0, a1
-; RV32IPN-NEXT:    lui a1, 1
-; RV32IPN-NEXT:    addi a1, a1, -241
-; RV32IPN-NEXT:    and a1, a0, a1
-; RV32IPN-NEXT:    slli a1, a1, 4
-; RV32IPN-NEXT:    lui a2, 15
-; RV32IPN-NEXT:    addi a2, a2, 240
-; RV32IPN-NEXT:    and a0, a0, a2
-; RV32IPN-NEXT:    srli a0, a0, 4
-; RV32IPN-NEXT:    or a0, a0, a1
-; RV32IPN-NEXT:    lui a1, 3
-; RV32IPN-NEXT:    addi a1, a1, 819
-; RV32IPN-NEXT:    and a1, a0, a1
-; RV32IPN-NEXT:    slli a1, a1, 2
-; RV32IPN-NEXT:    lui a2, 13
-; RV32IPN-NEXT:    addi a2, a2, -820
-; RV32IPN-NEXT:    and a0, a0, a2
-; RV32IPN-NEXT:    srli a0, a0, 2
-; RV32IPN-NEXT:    or a0, a0, a1
-; RV32IPN-NEXT:    lui a1, 5
-; RV32IPN-NEXT:    addi a1, a1, 1365
-; RV32IPN-NEXT:    and a1, a0, a1
-; RV32IPN-NEXT:    slli a1, a1, 1
-; RV32IPN-NEXT:    lui a2, 11
-; RV32IPN-NEXT:    addi a2, a2, -1366
-; RV32IPN-NEXT:    and a0, a0, a2
-; RV32IPN-NEXT:    srli a0, a0, 1
-; RV32IPN-NEXT:    or a0, a0, a1
+; RV32IPN-NEXT:    bitrevi a0, a0, 15
 ; RV32IPN-NEXT:    ret
 ;
 ; RV32IBP-LABEL: bitreverse_i16:
@@ -153,88 +69,12 @@
 ;
 ; RV32IP-LABEL: bitreverse_i32:
 ; RV32IP:       # %bb.0:
-; RV32IP-NEXT:    srli a1, a0, 8
-; RV32IP-NEXT:    lui a2, 16
-; RV32IP-NEXT:    addi a2, a2, -256
-; RV32IP-NEXT:    and a1, a1, a2
-; RV32IP-NEXT:    srli a2, a0, 24
-; RV32IP-NEXT:    or a1, a1, a2
-; RV32IP-NEXT:    slli a2, a0, 8
-; RV32IP-NEXT:    lui a3, 4080
-; RV32IP-NEXT:    and a2, a2, a3
-; RV32IP-NEXT:    slli a0, a0, 24
-; RV32IP-NEXT:    or a0, a0, a2
-; RV32IP-NEXT:    or a0, a0, a1
-; RV32IP-NEXT:    lui a1, 61681
-; RV32IP-NEXT:    addi a1, a1, -241
-; RV32IP-NEXT:    and a1, a0, a1
-; RV32IP-NEXT:    slli a1, a1, 4
-; RV32IP-NEXT:    lui a2, 986895
-; RV32IP-NEXT:    addi a2, a2, 240
-; RV32IP-NEXT:    and a0, a0, a2
-; RV32IP-NEXT:    srli a0, a0, 4
-; RV32IP-NEXT:    or a0, a0, a1
-; RV32IP-NEXT:    lui a1, 209715
-; RV32IP-NEXT:    addi a1, a1, 819
-; RV32IP-NEXT:    and a1, a0, a1
-; RV32IP-NEXT:    slli a1, a1, 2
-; RV32IP-NEXT:    lui a2, 838861
-; RV32IP-NEXT:    addi a2, a2, -820
-; RV32IP-NEXT:    and a0, a0, a2
-; RV32IP-NEXT:    srli a0, a0, 2
-; RV32IP-NEXT:    or a0, a0, a1
-; RV32IP-NEXT:    lui a1, 349525
-; RV32IP-NEXT:    addi a1, a1, 1365
-; RV32IP-NEXT:    and a1, a0, a1
-; RV32IP-NEXT:    slli a1, a1, 1
-; RV32IP-NEXT:    lui a2, 699051
-; RV32IP-NEXT:    addi a2, a2, -1366
-; RV32IP-NEXT:    and a0, a0, a2
-; RV32IP-NEXT:    srli a0, a0, 1
-; RV32IP-NEXT:    or a0, a0, a1
+; RV32IP-NEXT:    bitrevi a0, a0, 31
 ; RV32IP-NEXT:    ret
 ;
 ; RV32IPN-LABEL: bitreverse_i32:
 ; RV32IPN:       # %bb.0:
-; RV32IPN-NEXT:    srli a1, a0, 8
-; RV32IPN-NEXT:    lui a2, 16
-; RV32IPN-NEXT:    addi a2, a2, -256
-; RV32IPN-NEXT:    and a1, a1, a2
-; RV32IPN-NEXT:    srli a2, a0, 24
-; RV32IPN-NEXT:    or a1, a1, a2
-; RV32IPN-NEXT:    slli a2, a0, 8
-; RV32IPN-NEXT:    lui a3, 4080
-; RV32IPN-NEXT:    and a2, a2, a3
-; RV32IPN-NEXT:    slli a0, a0, 24
-; RV32IPN-NEXT:    or a0, a0, a2
-; RV32IPN-NEXT:    or a0, a0, a1
-; RV32IPN-NEXT:    lui a1, 61681
-; RV32IPN-NEXT:    addi a1, a1, -241
-; RV32IPN-NEXT:    and a1, a0, a1
-; RV32IPN-NEXT:    slli a1, a1, 4
-; RV32IPN-NEXT:    lui a2, 986895
-; RV32IPN-NEXT:    addi a2, a2, 240
-; RV32IPN-NEXT:    and a0, a0, a2
-; RV32IPN-NEXT:    srli a0, a0, 4
-; RV32IPN-NEXT:    or a0, a0, a1
-; RV32IPN-NEXT:    lui a1, 209715
-; RV32IPN-NEXT:    addi a1, a1, 819
-; RV32IPN-NEXT:    and a1, a0, a1
-; RV32IPN-NEXT:    slli a1, a1, 2
-; RV32IPN-NEXT:    lui a2, 838861
-; RV32IPN-NEXT:    addi a2, a2, -820
-; RV32IPN-NEXT:    and a0, a0, a2
-; RV32IPN-NEXT:    srli a0, a0, 2
-; RV32IPN-NEXT:    or a0, a0, a1
-; RV32IPN-NEXT:    lui a1, 349525
-; RV32IPN-NEXT:    addi a1, a1, 1365
-; RV32IPN-NEXT:    and a1, a0, a1
-; RV32IPN-NEXT:    slli a1, a1, 1
-; RV32IPN-NEXT:    lui a2, 699051
-; RV32IPN-NEXT:    addi a2, a2, -1366
-; RV32IPN-NEXT:    and a0, a0, a2
-; RV32IPN-NEXT:    srli a0, a0, 1
-; RV32IPN-NEXT:    or a0, a0, a1
+; RV32IPN-NEXT:    bitrevi a0, a0, 31
 ; RV32IPN-NEXT:    ret
 ;
 ; RV32IBP-LABEL: bitreverse_i32:
@@ -255,138 +95,16 @@
 ;
 ; RV32IP-LABEL: bitreverse_i64:
 ; RV32IP:       # %bb.0:
-; RV32IP-NEXT:    srli a2, a1, 8
-; RV32IP-NEXT:    lui a3, 16
-; RV32IP-NEXT:    addi t0, a3, -256
-; RV32IP-NEXT:    and a2, a2, t0
-; RV32IP-NEXT:    srli a4, a1, 24
-; RV32IP-NEXT:    or a2, a2, a4
-; RV32IP-NEXT:    slli a4, a1, 8
-; RV32IP-NEXT:    lui a6, 4080
-; RV32IP-NEXT:    and a4, a4, a6
-; RV32IP-NEXT:    slli a1, a1, 24
-; RV32IP-NEXT:    or a1, a1, a4
-; RV32IP-NEXT:    or a1, a1, a2
-; RV32IP-NEXT:    lui a2, 61681
-; RV32IP-NEXT:    addi t1, a2, -241
-; RV32IP-NEXT:    and a2, a1, t1
-; RV32IP-NEXT:    slli a2, a2, 4
-; RV32IP-NEXT:    lui a5, 986895
-; RV32IP-NEXT:    addi t2, a5, 240
-; RV32IP-NEXT:    and a1, a1, t2
-; RV32IP-NEXT:    srli a1, a1, 4
-; RV32IP-NEXT:    or a1, a1, a2
-; RV32IP-NEXT:    lui a2, 209715
-; RV32IP-NEXT:    addi t3, a2, 819
-; RV32IP-NEXT:    and a3, a1, t3
-; RV32IP-NEXT:    slli a3, a3, 2
-; RV32IP-NEXT:    lui a4, 838861
-; RV32IP-NEXT:    addi a4, a4, -820
-; RV32IP-NEXT:    and a1, a1, a4
-; RV32IP-NEXT:    srli a1, a1, 2
-; RV32IP-NEXT:    or a1, a1, a3
-; RV32IP-NEXT:    lui a3, 349525
-; RV32IP-NEXT:    addi a3, a3, 1365
-; RV32IP-NEXT:    and a5, a1, a3
-; RV32IP-NEXT:    slli a5, a5, 1
-; RV32IP-NEXT:    lui a2, 699051
-; RV32IP-NEXT:    addi a2, a2, -1366
-; RV32IP-NEXT:    and a1, a1, a2
-; RV32IP-NEXT:    srli a1, a1, 1
-; RV32IP-NEXT:    or a7, a1, a5
-; RV32IP-NEXT:    srli a1, a0, 8
-; RV32IP-NEXT:    and a1, a1, t0
-; RV32IP-NEXT:    srli a5, a0, 24
-; RV32IP-NEXT:    or a1, a1, a5
-; RV32IP-NEXT:    slli a5, a0, 8
-; RV32IP-NEXT:    and a5, a5, a6
-; RV32IP-NEXT:    slli a0, a0, 24
-; RV32IP-NEXT:    or a0, a0, a5
-; RV32IP-NEXT:    or a0, a0, a1
-; RV32IP-NEXT:    and a1, a0, t1
-; RV32IP-NEXT:    slli a1, a1, 4
-; RV32IP-NEXT:    and a0, a0, t2
-; RV32IP-NEXT:    srli a0, a0, 4
-; RV32IP-NEXT:    or a0, a0, a1
-; RV32IP-NEXT:    and a1, a0, t3
-; RV32IP-NEXT:    slli a1, a1, 2
-; RV32IP-NEXT:    and a0, a0, a4
-; RV32IP-NEXT:    srli a0, a0, 2
-; RV32IP-NEXT:    or a0, a0, a1
-; RV32IP-NEXT:    and a1, a0, a3
-; RV32IP-NEXT:    slli a1, a1, 1
-; RV32IP-NEXT:    and a0, a0, a2
-; RV32IP-NEXT:    srli a0, a0, 1
-; RV32IP-NEXT:    or a1, a0, a1
-; RV32IP-NEXT:    mv a0, a7
+; RV32IP-NEXT:    bitrevi a2, a1, 31
+; RV32IP-NEXT:    bitrevi a1, a0, 31
+; RV32IP-NEXT:    mv a0, a2
 ; RV32IP-NEXT:    ret
 ;
 ; RV32IPN-LABEL: bitreverse_i64:
 ; RV32IPN:       # %bb.0:
-; RV32IPN-NEXT:    srli a2, a1, 8
-; RV32IPN-NEXT:    lui a3, 16
-; RV32IPN-NEXT:    addi t0, a3, -256
-; RV32IPN-NEXT:    and a2, a2, t0
-; RV32IPN-NEXT:    srli a4, a1, 24
-; RV32IPN-NEXT:    or a2, a2, a4
-; RV32IPN-NEXT:    slli a4, a1, 8
-; RV32IPN-NEXT:    lui a6, 4080
-; RV32IPN-NEXT:    and a4, a4, a6
-; RV32IPN-NEXT:    slli a1, a1, 24
-; RV32IPN-NEXT:    or a1, a1, a4
-; RV32IPN-NEXT:    or a1, a1, a2
-; RV32IPN-NEXT:    lui a2, 61681
-; RV32IPN-NEXT:    addi t1, a2, -241
-; RV32IPN-NEXT:    and a2, a1, t1
-; RV32IPN-NEXT:    slli a2, a2, 4
-; RV32IPN-NEXT:    lui a5, 986895
-; RV32IPN-NEXT:    addi t2, a5, 240
-; RV32IPN-NEXT:    and a1, a1, t2
-; RV32IPN-NEXT:    srli a1, a1, 4
-; RV32IPN-NEXT:    or a1, a1, a2
-; RV32IPN-NEXT:    lui a2, 209715
-; RV32IPN-NEXT:    addi t3, a2, 819
-; RV32IPN-NEXT:    and a3, a1, t3
-; RV32IPN-NEXT:    slli a3, a3, 2
-; RV32IPN-NEXT:    lui a4, 838861
-; RV32IPN-NEXT:    addi a4, a4, -820
-; RV32IPN-NEXT:    and a1, a1, a4
-; RV32IPN-NEXT:    srli a1, a1, 2
-; RV32IPN-NEXT:    or a1, a1, a3
-; RV32IPN-NEXT:    lui a3, 349525
-; RV32IPN-NEXT:    addi a3, a3, 1365
-; RV32IPN-NEXT:    and a5, a1, a3
-; RV32IPN-NEXT:    slli a5, a5, 1
-; RV32IPN-NEXT:    lui a2, 699051
-; RV32IPN-NEXT:    addi a2, a2, -1366
-; RV32IPN-NEXT:    and a1, a1, a2
-; RV32IPN-NEXT:    srli a1, a1, 1
-; RV32IPN-NEXT:    or a7, a1, a5
-; RV32IPN-NEXT:    srli a1, a0, 8
-; RV32IPN-NEXT:    and a1, a1, t0
-; RV32IPN-NEXT:    srli a5, a0, 24
-; RV32IPN-NEXT:    or a1, a1, a5
-; RV32IPN-NEXT:    slli a5, a0, 8
-; RV32IPN-NEXT:    and a5, a5, a6
-; RV32IPN-NEXT:    slli a0, a0, 24
-; RV32IPN-NEXT:    or a0, a0, a5
-; RV32IPN-NEXT:    or a0, a0, a1
-; RV32IPN-NEXT:    and a1, a0, t1
-; RV32IPN-NEXT:    slli a1, a1, 4
-; RV32IPN-NEXT:    and a0, a0, t2
-; RV32IPN-NEXT:    srli a0, a0, 4
-; RV32IPN-NEXT:    or a0, a0, a1
-; RV32IPN-NEXT:    and a1, a0, t3
-; RV32IPN-NEXT:    slli a1, a1, 2
-; RV32IPN-NEXT:    and a0, a0, a4
-; RV32IPN-NEXT:    srli a0, a0, 2
-; RV32IPN-NEXT:    or a0, a0, a1
-; RV32IPN-NEXT:    and a1, a0, a3
-; RV32IPN-NEXT:    slli a1, a1, 1
-; RV32IPN-NEXT:    and a0, a0, a2
-; RV32IPN-NEXT:    srli a0, a0, 1
-; RV32IPN-NEXT:    or a1, a0, a1
-; RV32IPN-NEXT:    mv a0, a7
+; RV32IPN-NEXT:    bitrevi a2, a1, 31
+; RV32IPN-NEXT:    bitrevi a1, a0, 31
+; RV32IPN-NEXT:    mv a0, a2
 ; RV32IPN-NEXT:    ret
 ;
 ; RV32IBP-LABEL: bitreverse_i64:
diff --git a/llvm/test/CodeGen/RISCV/rv32zpn-bswap.ll b/llvm/test/CodeGen/RISCV/rv32zpn-bswap.ll
--- a/llvm/test/CodeGen/RISCV/rv32zpn-bswap.ll
+++ b/llvm/test/CodeGen/RISCV/rv32zpn-bswap.ll
@@ -20,22 +20,12 @@
 ;
 ; RV32IP-LABEL: bswap_i16:
 ; RV32IP:       # %bb.0:
-; RV32IP-NEXT:    srli a1, a0, 8
-; RV32IP-NEXT:    slli a0, a0, 8
-; RV32IP-NEXT:    or a0, a0, a1
-; RV32IP-NEXT:    lui a1, 16
-; RV32IP-NEXT:    addi a1, a1, -1
-; RV32IP-NEXT:    and a0, a0, a1
+; RV32IP-NEXT:    swap8 a0, a0
 ; RV32IP-NEXT:    ret
 ;
 ; RV32IPN-LABEL: bswap_i16:
 ; RV32IPN:       # %bb.0:
-; RV32IPN-NEXT:    srli a1, a0, 8
-; RV32IPN-NEXT:    slli a0, a0, 8
-; RV32IPN-NEXT:    or a0, a0, a1
-; RV32IPN-NEXT:    lui a1, 16
-; RV32IPN-NEXT:    addi a1, a1, -1
-; RV32IPN-NEXT:    and a0, a0, a1
+; RV32IPN-NEXT:    swap8 a0, a0
 ; RV32IPN-NEXT:    ret
 ;
 ; RV32IBP-LABEL: bswap_i16:
@@ -54,34 +44,14 @@
 ;
 ; RV32IP-LABEL: bswap_i32:
 ; RV32IP:       # %bb.0:
-; RV32IP-NEXT:    srli a1, a0, 8
-; RV32IP-NEXT:    lui a2, 16
-; RV32IP-NEXT:    addi a2, a2, -256
-; RV32IP-NEXT:    and a1, a1, a2
-; RV32IP-NEXT:    srli a2, a0, 24
-; RV32IP-NEXT:    or a1, a1, a2
-; RV32IP-NEXT:    slli a2, a0, 8
-; RV32IP-NEXT:    lui a3, 4080
-; RV32IP-NEXT:    and a2, a2, a3
-; RV32IP-NEXT:    slli a0, a0, 24
-; RV32IP-NEXT:    or a0, a0, a2
-; RV32IP-NEXT:    or a0, a0, a1
+; RV32IP-NEXT:    swap8 a0, a0
+; RV32IP-NEXT:    swap16 a0, a0
 ; RV32IP-NEXT:    ret
 ;
 ; RV32IPN-LABEL: bswap_i32:
 ; RV32IPN:       # %bb.0:
-; RV32IPN-NEXT:    srli a1, a0, 8
-; RV32IPN-NEXT:    lui a2, 16
-; RV32IPN-NEXT:    addi a2, a2, -256
-; RV32IPN-NEXT:    and a1, a1, a2
-; RV32IPN-NEXT:    srli a2, a0, 24
-; RV32IPN-NEXT:    or a1, a1, a2
-; RV32IPN-NEXT:    slli a2, a0, 8
-; RV32IPN-NEXT:    lui a3, 4080
-; RV32IPN-NEXT:    and a2, a2, a3
-; RV32IPN-NEXT:    slli a0, a0, 24
-; RV32IPN-NEXT:    or a0, a0, a2
-; RV32IPN-NEXT:    or a0, a0, a1
+; RV32IPN-NEXT:    swap8 a0, a0
+; RV32IPN-NEXT:    swap16 a0, a0
 ; RV32IPN-NEXT:    ret
 ;
 ; RV32IBP-LABEL: bswap_i32:
@@ -102,53 +72,19 @@
 ;
 ; RV32IP-LABEL: bswap_i64:
 ; RV32IP:       # %bb.0:
-; RV32IP-NEXT:    srli a2, a1, 8
-; RV32IP-NEXT:    lui a3, 16
-; RV32IP-NEXT:    addi a3, a3, -256
-; RV32IP-NEXT:    and a2, a2, a3
-; RV32IP-NEXT:    srli a4, a1, 24
-; RV32IP-NEXT:    or a2, a2, a4
-; RV32IP-NEXT:    slli a4, a1, 8
-; RV32IP-NEXT:    lui a5, 4080
-; RV32IP-NEXT:    and a4, a4, a5
-; RV32IP-NEXT:    slli a1, a1, 24
-; RV32IP-NEXT:    or a1, a1, a4
-; RV32IP-NEXT:    or a2, a1, a2
-; RV32IP-NEXT:    srli a1, a0, 8
-; RV32IP-NEXT:    and a1, a1, a3
-; RV32IP-NEXT:    srli a3, a0, 24
-; RV32IP-NEXT:    or a1, a1, a3
-; RV32IP-NEXT:    slli a3, a0, 8
-; RV32IP-NEXT:    and a3, a3, a5
-; RV32IP-NEXT:    slli a0, a0, 24
-; RV32IP-NEXT:    or a0, a0, a3
-; RV32IP-NEXT:    or a1, a0, a1
+; RV32IP-NEXT:    swap8 a1, a1
+; RV32IP-NEXT:    swap16 a2, a1
+; RV32IP-NEXT:    swap8 a0, a0
+; RV32IP-NEXT:    swap16 a1, a0
 ; RV32IP-NEXT:    mv a0, a2
 ; RV32IP-NEXT:    ret
 ;
 ; RV32IPN-LABEL: bswap_i64:
 ; RV32IPN:       # %bb.0:
-; RV32IPN-NEXT:    srli a2, a1, 8
-; RV32IPN-NEXT:    lui a3, 16
-; RV32IPN-NEXT:    addi a3, a3, -256
-; RV32IPN-NEXT:    and a2, a2, a3
-; RV32IPN-NEXT:    srli a4, a1, 24
-; RV32IPN-NEXT:    or a2, a2, a4
-; RV32IPN-NEXT:    slli a4, a1, 8
-; RV32IPN-NEXT:    lui a5, 4080
-; RV32IPN-NEXT:    and a4, a4, a5
-; RV32IPN-NEXT:    slli a1, a1, 24
-; RV32IPN-NEXT:    or a1, a1, a4
-; RV32IPN-NEXT:    or a2, a1, a2
-; RV32IPN-NEXT:    srli a1, a0, 8
-; RV32IPN-NEXT:    and a1, a1, a3
-; RV32IPN-NEXT:    srli a3, a0, 24
-; RV32IPN-NEXT:    or a1, a1, a3
-; RV32IPN-NEXT:    slli a3, a0, 8
-; RV32IPN-NEXT:    and a3, a3, a5
-; RV32IPN-NEXT:    slli a0, a0, 24
-; RV32IPN-NEXT:    or a0, a0, a3
-; RV32IPN-NEXT:    or a1, a0, a1
+; RV32IPN-NEXT:    swap8 a1, a1
+; RV32IPN-NEXT:    swap16 a2, a1
+; RV32IPN-NEXT:    swap8 a0, a0
+; RV32IPN-NEXT:    swap16 a1, a0
 ; RV32IPN-NEXT:    mv a0, a2
 ; RV32IPN-NEXT:    ret
 ;
diff --git a/llvm/test/CodeGen/RISCV/rv64zpn-bitreverse.ll b/llvm/test/CodeGen/RISCV/rv64zpn-bitreverse.ll
--- a/llvm/test/CodeGen/RISCV/rv64zpn-bitreverse.ll
+++ b/llvm/test/CodeGen/RISCV/rv64zpn-bitreverse.ll
@@ -21,38 +21,12 @@
 ;
 ; RV64IP-LABEL: bitreverse_i8:
 ; RV64IP:       # %bb.0:
-; RV64IP-NEXT:    srli a1, a0, 4
-; RV64IP-NEXT:    andi a0, a0, 15
-; RV64IP-NEXT:    slli a0, a0, 4
-; RV64IP-NEXT:    or a0, a1, a0
-; RV64IP-NEXT:    andi a1, a0, 51
-; RV64IP-NEXT:    slli a1, a1, 2
-; RV64IP-NEXT:    andi a0, a0, 204
-; RV64IP-NEXT:    srli a0, a0, 2
-; RV64IP-NEXT:    or a0, a0, a1
-; RV64IP-NEXT:    andi a1, a0, 85
-; RV64IP-NEXT:    slli a1, a1, 1
-; RV64IP-NEXT:    andi a0, a0, 170
-; RV64IP-NEXT:    srli a0, a0, 1
-; RV64IP-NEXT:    or a0, a0, a1
+; RV64IP-NEXT:    bitrevi a0, a0, 7
 ; RV64IP-NEXT:    ret
 ;
 ; RV64IPN-LABEL: bitreverse_i8:
 ; RV64IPN:       # %bb.0:
-; RV64IPN-NEXT:    srli a1, a0, 4
-; RV64IPN-NEXT:    andi a0, a0, 15
-; RV64IPN-NEXT:    slli a0, a0, 4
-; RV64IPN-NEXT:    or a0, a1, a0
-; RV64IPN-NEXT:    andi a1, a0, 51
-; RV64IPN-NEXT:    slli a1, a1, 2
-; RV64IPN-NEXT:    andi a0, a0, 204
-; RV64IPN-NEXT:    srli a0, a0, 2
-; RV64IPN-NEXT:    or a0, a0, a1
-; RV64IPN-NEXT:    andi a1, a0, 85
-; RV64IPN-NEXT:    slli a1, a1, 1
-; RV64IPN-NEXT:    andi a0, a0, 170
-; RV64IPN-NEXT:    srli a0, a0, 1
-; RV64IPN-NEXT:    or a0, a0, a1
+; RV64IPN-NEXT:    bitrevi a0, a0, 7
 ; RV64IPN-NEXT:    ret
 ;
 ; RV64IBP-LABEL: bitreverse_i8:
@@ -71,70 +45,12 @@
 ;
 ; RV64IP-LABEL: bitreverse_i16:
 ; RV64IP:       # %bb.0:
-; RV64IP-NEXT:    srli a1, a0, 8
-; RV64IP-NEXT:    slli a0, a0, 8
-; RV64IP-NEXT:    or a0, a0, a1
-; RV64IP-NEXT:    lui a1, 1
-; RV64IP-NEXT:    addiw a1, a1, -241
-; RV64IP-NEXT:    and a1, a0, a1
-; RV64IP-NEXT:    slli a1, a1, 4
-; RV64IP-NEXT:    lui a2, 15
-; RV64IP-NEXT:    addiw a2, a2, 240
-; RV64IP-NEXT:    and a0, a0, a2
-; RV64IP-NEXT:    srli a0, a0, 4
-; RV64IP-NEXT:    or a0, a0, a1
-; RV64IP-NEXT:    lui a1, 3
-; RV64IP-NEXT:    addiw a1, a1, 819
-; RV64IP-NEXT:    and a1, a0, a1
-; RV64IP-NEXT:    slli a1, a1, 2
-; RV64IP-NEXT:    lui a2, 13
-; RV64IP-NEXT:    addiw a2, a2, -820
-; RV64IP-NEXT:    and a0, a0, a2
-; RV64IP-NEXT:    srli a0, a0, 2
-; RV64IP-NEXT:    or a0, a0, a1
-; RV64IP-NEXT:    lui a1, 5
-; RV64IP-NEXT:    addiw a1, a1, 1365
-; RV64IP-NEXT:    and a1, a0, a1
-; RV64IP-NEXT:    slli a1, a1, 1
-; RV64IP-NEXT:    lui a2, 11
-; RV64IP-NEXT:    addiw a2, a2, -1366
-; RV64IP-NEXT:    and a0, a0, a2
-; RV64IP-NEXT:    srli a0, a0, 1
-; RV64IP-NEXT:    or a0, a0, a1
+; RV64IP-NEXT:    bitrevi a0, a0, 15
 ; RV64IP-NEXT:    ret
 ;
 ; RV64IPN-LABEL: bitreverse_i16:
 ; RV64IPN:       # %bb.0:
-; RV64IPN-NEXT:    srli a1, a0, 8
-; RV64IPN-NEXT:    slli a0, a0, 8
-; RV64IPN-NEXT:    or a0, a0, a1
-; RV64IPN-NEXT:    lui a1, 1
-; RV64IPN-NEXT:    addiw a1, a1, -241
-; RV64IPN-NEXT:    and a1, a0, a1
-; RV64IPN-NEXT:    slli a1, a1, 4
-; RV64IPN-NEXT:    lui a2, 15
-; RV64IPN-NEXT:    addiw a2, a2, 240
-; RV64IPN-NEXT:    and a0, a0, a2
-; RV64IPN-NEXT:    srli a0, a0, 4
-; RV64IPN-NEXT:    or a0, a0, a1
-; RV64IPN-NEXT:    lui a1, 3
-; RV64IPN-NEXT:    addiw a1, a1, 819
-; RV64IPN-NEXT:    and a1, a0, a1
-; RV64IPN-NEXT:    slli a1, a1, 2
-; RV64IPN-NEXT:    lui a2, 13
-; RV64IPN-NEXT:    addiw a2, a2, -820
-; RV64IPN-NEXT:    and a0, a0, a2
-; RV64IPN-NEXT:    srli a0, a0, 2
-; RV64IPN-NEXT:    or a0, a0, a1
-; RV64IPN-NEXT:    lui a1, 5
-; RV64IPN-NEXT:    addiw a1, a1, 1365
-; RV64IPN-NEXT:    and a1, a0, a1
-; RV64IPN-NEXT:    slli a1, a1, 1
-; RV64IPN-NEXT:    lui a2, 11
-; RV64IPN-NEXT:    addiw a2, a2, -1366
-; RV64IPN-NEXT:    and a0, a0, a2
-; RV64IPN-NEXT:    srli a0, a0, 1
-; RV64IPN-NEXT:    or a0, a0, a1
+; RV64IPN-NEXT:    bitrevi a0, a0, 15
 ; RV64IPN-NEXT:    ret
 ;
 ; RV64IBP-LABEL: bitreverse_i16:
@@ -153,94 +69,12 @@
 ;
 ; RV64IP-LABEL: bitreverse_i32:
 ; RV64IP:       # %bb.0:
-; RV64IP-NEXT:    srliw a1, a0, 8
-; RV64IP-NEXT:    lui a2, 16
-; RV64IP-NEXT:    addiw a2, a2, -256
-; RV64IP-NEXT:    and a1, a1, a2
-; RV64IP-NEXT:    srliw a2, a0, 24
-; RV64IP-NEXT:    or a1, a1, a2
-; RV64IP-NEXT:    slli a2, a0, 8
-; RV64IP-NEXT:    lui a3, 4080
-; RV64IP-NEXT:    and a2, a2, a3
-; RV64IP-NEXT:    slli a0, a0, 24
-; RV64IP-NEXT:    or a0, a0, a2
-; RV64IP-NEXT:    or a0, a0, a1
-; RV64IP-NEXT:    lui a1, 61681
-; RV64IP-NEXT:    addiw a1, a1, -241
-; RV64IP-NEXT:    and a1, a0, a1
-; RV64IP-NEXT:    slli a1, a1, 4
-; RV64IP-NEXT:    lui a2, 241
-; RV64IP-NEXT:    addiw a2, a2, -241
-; RV64IP-NEXT:    slli a2, a2, 12
-; RV64IP-NEXT:    addi a2, a2, 240
-; RV64IP-NEXT:    and a0, a0, a2
-; RV64IP-NEXT:    srli a0, a0, 4
-; RV64IP-NEXT:    or a0, a0, a1
-; RV64IP-NEXT:    lui a1, 209715
-; RV64IP-NEXT:    addiw a1, a1, 819
-; RV64IP-NEXT:    and a1, a0, a1
-; RV64IP-NEXT:    slli a1, a1, 2
-; RV64IP-NEXT:    lui a2, 838861
-; RV64IP-NEXT:    addiw a2, a2, -820
-; RV64IP-NEXT:    and a0, a0, a2
-; RV64IP-NEXT:    srli a0, a0, 2
-; RV64IP-NEXT:    or a0, a0, a1
-; RV64IP-NEXT:    lui a1, 349525
-; RV64IP-NEXT:    addiw a1, a1, 1365
-; RV64IP-NEXT:    and a1, a0, a1
-; RV64IP-NEXT:    slli a1, a1, 1
-; RV64IP-NEXT:    lui a2, 699051
-; RV64IP-NEXT:    addiw a2, a2, -1366
-; RV64IP-NEXT:    and a0, a0, a2
-; RV64IP-NEXT:    srli a0, a0, 1
-; RV64IP-NEXT:    or a0, a0, a1
-; RV64IP-NEXT:    sext.w a0, a0
+; RV64IP-NEXT:    bitrevi a0, a0, 31
 ; RV64IP-NEXT:    ret
 ;
 ; RV64IPN-LABEL: bitreverse_i32:
 ; RV64IPN:       # %bb.0:
-; RV64IPN-NEXT:    srliw a1, a0, 8
-; RV64IPN-NEXT:    lui a2, 16
-; RV64IPN-NEXT:    addiw a2, a2, -256
-; RV64IPN-NEXT:    and a1, a1, a2
-; RV64IPN-NEXT:    srliw a2, a0, 24
-; RV64IPN-NEXT:    or a1, a1, a2
-; RV64IPN-NEXT:    slli a2, a0, 8
-; RV64IPN-NEXT:    lui a3, 4080
-; RV64IPN-NEXT:    and a2, a2, a3
-; RV64IPN-NEXT:    slli a0, a0, 24
-; RV64IPN-NEXT:    or a0, a0, a2
-; RV64IPN-NEXT:    or a0, a0, a1
-; RV64IPN-NEXT:    lui a1, 61681
-; RV64IPN-NEXT:    addiw a1, a1, -241
-; RV64IPN-NEXT:    and a1, a0, a1
-; RV64IPN-NEXT:    slli a1, a1, 4
-; RV64IPN-NEXT:    lui a2, 241
-; RV64IPN-NEXT:    addiw a2, a2, -241
-; RV64IPN-NEXT:    slli a2, a2, 12
-; RV64IPN-NEXT:    addi a2, a2, 240
-; RV64IPN-NEXT:    and a0, a0, a2
-; RV64IPN-NEXT:    srli a0, a0, 4
-; RV64IPN-NEXT:    or a0, a0, a1
-; RV64IPN-NEXT:    lui a1, 209715
-; RV64IPN-NEXT:    addiw a1, a1, 819
-; RV64IPN-NEXT:    and a1, a0, a1
-; RV64IPN-NEXT:    slli a1, a1, 2
-; RV64IPN-NEXT:    lui a2, 838861
-; RV64IPN-NEXT:    addiw a2, a2, -820
-; RV64IPN-NEXT:    and a0, a0, a2
-; RV64IPN-NEXT:    srli a0, a0, 2
-; RV64IPN-NEXT:    or a0, a0, a1
-; RV64IPN-NEXT:    lui a1, 349525
-; RV64IPN-NEXT:    addiw a1, a1, 1365
-; RV64IPN-NEXT:    and a1, a0, a1
-; RV64IPN-NEXT:    slli a1, a1, 1
-; RV64IPN-NEXT:    lui a2, 699051
-; RV64IPN-NEXT:    addiw a2, a2, -1366
-; RV64IPN-NEXT:    and a0, a0, a2
-; RV64IPN-NEXT:    srli a0, a0, 1
-; RV64IPN-NEXT:    or a0, a0, a1
-; RV64IPN-NEXT:    sext.w a0, a0
+; RV64IPN-NEXT:    bitrevi a0, a0, 31
 ; RV64IPN-NEXT:    ret
 ;
 ; RV64IBP-LABEL: bitreverse_i32:
@@ -261,93 +95,13 @@
 ;
 ; RV64IP-LABEL: bitreverse_i32_nosext:
 ; RV64IP:       # %bb.0:
-; RV64IP-NEXT:    srliw a2, a0, 8
-; RV64IP-NEXT:    lui a3, 16
-; RV64IP-NEXT:    addiw a3, a3, -256
-; RV64IP-NEXT:    and a2, a2, a3
-; RV64IP-NEXT:    srliw a3, a0, 24
-; RV64IP-NEXT:    or a2, a2, a3
-; RV64IP-NEXT:    slli a3, a0, 8
-; RV64IP-NEXT:    lui a4, 4080
-; RV64IP-NEXT:    and a3, a3, a4
-; RV64IP-NEXT:    slli a0, a0, 24
-; RV64IP-NEXT:    or a0, a0, a3
-; RV64IP-NEXT:    or a0, a0, a2
-; RV64IP-NEXT:    lui a2, 61681
-; RV64IP-NEXT:    addiw a2, a2, -241
-; RV64IP-NEXT:    and a2, a0, a2
-; RV64IP-NEXT:    slli a2, a2, 4
-; RV64IP-NEXT:    lui a3, 241
-; RV64IP-NEXT:    addiw a3, a3, -241
-; RV64IP-NEXT:    slli a3, a3, 12
-; RV64IP-NEXT:    addi a3, a3, 240
-; RV64IP-NEXT:    and a0, a0, a3
-; RV64IP-NEXT:    srli a0, a0, 4
-; RV64IP-NEXT:    or a0, a0, a2
-; RV64IP-NEXT:    lui a2, 209715
-; RV64IP-NEXT:    addiw a2, a2, 819
-; RV64IP-NEXT:    and a2, a0, a2
-; RV64IP-NEXT:    slli a2, a2, 2
-; RV64IP-NEXT:    lui a3, 838861
-; RV64IP-NEXT:    addiw a3, a3, -820
-; RV64IP-NEXT:    and a0, a0, a3
-; RV64IP-NEXT:    srli a0, a0, 2
-; RV64IP-NEXT:    or a0, a0, a2
-; RV64IP-NEXT:    lui a2, 349525
-; RV64IP-NEXT:    addiw a2, a2, 1365
-; RV64IP-NEXT:    and a2, a0, a2
-; RV64IP-NEXT:    slli a2, a2, 1
-; RV64IP-NEXT:    lui a3, 699051
-; RV64IP-NEXT:    addiw a3, a3, -1366
-; RV64IP-NEXT:    and a0, a0, a3
-; RV64IP-NEXT:    srli a0, a0, 1
-; RV64IP-NEXT:    or a0, a0, a2
+; RV64IP-NEXT:    bitrevi a0, a0, 31
 ; RV64IP-NEXT:    sw a0, 0(a1)
 ; RV64IP-NEXT:    ret
 ;
 ; RV64IPN-LABEL: bitreverse_i32_nosext:
 ; RV64IPN:       # %bb.0:
-; RV64IPN-NEXT:    srliw a2, a0, 8
-; RV64IPN-NEXT:    lui a3, 16
-; RV64IPN-NEXT:    addiw a3, a3, -256
-; RV64IPN-NEXT:    and a2, a2, a3
-; RV64IPN-NEXT:    srliw a3, a0, 24
-; RV64IPN-NEXT:    or a2, a2, a3
-; RV64IPN-NEXT:    slli a3, a0, 8
-; RV64IPN-NEXT:    lui a4, 4080
-; RV64IPN-NEXT:    and a3, a3, a4
-; RV64IPN-NEXT:    slli a0, a0, 24
-; RV64IPN-NEXT:    or a0, a0, a3
-; RV64IPN-NEXT:    or a0, a0, a2
-; RV64IPN-NEXT:    lui a2, 61681
-; RV64IPN-NEXT:    addiw a2, a2, -241
-; RV64IPN-NEXT:    and a2, a0, a2
-; RV64IPN-NEXT:    slli a2, a2, 4
-; RV64IPN-NEXT:    lui a3, 241
-; RV64IPN-NEXT:    addiw a3, a3, -241
-; RV64IPN-NEXT:    slli a3, a3, 12
-; RV64IPN-NEXT:    addi a3, a3, 240
-; RV64IPN-NEXT:    and a0, a0, a3
-; RV64IPN-NEXT:    srli a0, a0, 4
-; RV64IPN-NEXT:    or a0, a0, a2
-; RV64IPN-NEXT:    lui a2, 209715
-; RV64IPN-NEXT:    addiw a2, a2, 819
-; RV64IPN-NEXT:    and a2, a0, a2
-; RV64IPN-NEXT:    slli a2, a2, 2
-; RV64IPN-NEXT:    lui a3, 838861
-; RV64IPN-NEXT:    addiw a3, a3, -820
-; RV64IPN-NEXT:    and a0, a0, a3
-; RV64IPN-NEXT:    srli a0, a0, 2
-; RV64IPN-NEXT:    or a0, a0, a2
-; RV64IPN-NEXT:    lui a2, 349525
-; RV64IPN-NEXT:    addiw a2, a2, 1365
-; RV64IPN-NEXT:    and a2, a0, a2
-; RV64IPN-NEXT:    slli a2, a2, 1
-; RV64IPN-NEXT:    lui a3, 699051
-; RV64IPN-NEXT:    addiw a3, a3, -1366
-; RV64IPN-NEXT:    and a0, a0, a3
-; RV64IPN-NEXT:    srli a0, a0, 1
-; RV64IPN-NEXT:    or a0, a0, a2
+; RV64IPN-NEXT:    bitrevi a0, a0, 31
 ; RV64IPN-NEXT:    sw a0, 0(a1)
 ; RV64IPN-NEXT:    ret
 ;
@@ -369,194 +123,12 @@
 ;
 ; RV64IP-LABEL: bitreverse_i64:
 ; RV64IP:       # %bb.0:
-; RV64IP-NEXT:    srli a1, a0, 24
-; RV64IP-NEXT:    lui a2, 4080
-; RV64IP-NEXT:    and a1, a1, a2
-; RV64IP-NEXT:    srli a2, a0, 8
-; RV64IP-NEXT:    addi a3, zero, 255
-; RV64IP-NEXT:    slli a4, a3, 24
-; RV64IP-NEXT:    and a2, a2, a4
-; RV64IP-NEXT:    or a1, a2, a1
-; RV64IP-NEXT:    srli a2, a0, 40
-; RV64IP-NEXT:    lui a4, 16
-; RV64IP-NEXT:    addiw a4, a4, -256
-; RV64IP-NEXT:    and a2, a2, a4
-; RV64IP-NEXT:    srli a4, a0, 56
-; RV64IP-NEXT:    or a2, a2, a4
-; RV64IP-NEXT:    or a1, a1, a2
-; RV64IP-NEXT:    slli a2, a0, 8
-; RV64IP-NEXT:    slli a4, a3, 32
-; RV64IP-NEXT:    and a2, a2, a4
-; RV64IP-NEXT:    slli a4, a0, 24
-; RV64IP-NEXT:    slli a5, a3, 40
-; RV64IP-NEXT:    and a4, a4, a5
-; RV64IP-NEXT:    or a2, a4, a2
-; RV64IP-NEXT:    slli a4, a0, 40
-; RV64IP-NEXT:    slli a3, a3, 48
-; RV64IP-NEXT:    and a3, a4, a3
-; RV64IP-NEXT:    slli a0, a0, 56
-; RV64IP-NEXT:    or a0, a0, a3
-; RV64IP-NEXT:    or a0, a0, a2
-; RV64IP-NEXT:    or a0, a0, a1
-; RV64IP-NEXT:    lui a1, 3855
-; RV64IP-NEXT:    addiw a1, a1, 241
-; RV64IP-NEXT:    slli a1, a1, 12
-; RV64IP-NEXT:    addi a1, a1, -241
-; RV64IP-NEXT:    slli a1, a1, 12
-; RV64IP-NEXT:    addi a1, a1, 241
-; RV64IP-NEXT:    slli a1, a1, 12
-; RV64IP-NEXT:    addi a1, a1, -241
-; RV64IP-NEXT:    and a1, a0, a1
-; RV64IP-NEXT:    slli a1, a1, 4
-; RV64IP-NEXT:    lui a2, 1044721
-; RV64IP-NEXT:    addiw a2, a2, -241
-; RV64IP-NEXT:    slli a2, a2, 12
-; RV64IP-NEXT:    addi a2, a2, 241
-; RV64IP-NEXT:    slli a2, a2, 12
-; RV64IP-NEXT:    addi a2, a2, -241
-; RV64IP-NEXT:    slli a2, a2, 12
-; RV64IP-NEXT:    addi a2, a2, 240
-; RV64IP-NEXT:    and a0, a0, a2
-; RV64IP-NEXT:    srli a0, a0, 4
-; RV64IP-NEXT:    or a0, a0, a1
-; RV64IP-NEXT:    lui a1, 13107
-; RV64IP-NEXT:    addiw a1, a1, 819
-; RV64IP-NEXT:    slli a1, a1, 12
-; RV64IP-NEXT:    addi a1, a1, 819
-; RV64IP-NEXT:    slli a1, a1, 12
-; RV64IP-NEXT:    addi a1, a1, 819
-; RV64IP-NEXT:    slli a1, a1, 12
-; RV64IP-NEXT:    addi a1, a1, 819
-; RV64IP-NEXT:    and a1, a0, a1
-; RV64IP-NEXT:    slli a1, a1, 2
-; RV64IP-NEXT:    lui a2, 1035469
-; RV64IP-NEXT:    addiw a2, a2, -819
-; RV64IP-NEXT:    slli a2, a2, 12
-; RV64IP-NEXT:    addi a2, a2, -819
-; RV64IP-NEXT:    slli a2, a2, 12
-; RV64IP-NEXT:    addi a2, a2, -819
-; RV64IP-NEXT:    slli a2, a2, 12
-; RV64IP-NEXT:    addi a2, a2, -820
-; RV64IP-NEXT:    and a0, a0, a2
-; RV64IP-NEXT:    srli a0, a0, 2
-; RV64IP-NEXT:    or a0, a0, a1
-; RV64IP-NEXT:    lui a1, 21845
-; RV64IP-NEXT:    addiw a1, a1, 1365
-; RV64IP-NEXT:    slli a1, a1, 12
-; RV64IP-NEXT:    addi a1, a1, 1365
-; RV64IP-NEXT:    slli a1, a1, 12
-; RV64IP-NEXT:    addi a1, a1, 1365
-; RV64IP-NEXT:    slli a1, a1, 12
-; RV64IP-NEXT:    addi a1, a1, 1365
-; RV64IP-NEXT:    and a1, a0, a1
-; RV64IP-NEXT:    slli a1, a1, 1
-; RV64IP-NEXT:    lui a2, 1026731
-; RV64IP-NEXT:    addiw a2, a2, -1365
-; RV64IP-NEXT:    slli a2, a2, 12
-; RV64IP-NEXT:    addi a2, a2, -1365
-; RV64IP-NEXT:    slli a2, a2, 12
-; RV64IP-NEXT:    addi a2, a2, -1365
-; RV64IP-NEXT:    slli a2, a2, 12
-; RV64IP-NEXT:    addi a2, a2, -1366
-; RV64IP-NEXT:    and a0, a0, a2
-; RV64IP-NEXT:    srli a0, a0, 1
-; RV64IP-NEXT:    or a0, a0, a1
+; RV64IP-NEXT:    bitrevi a0, a0, 63
 ; RV64IP-NEXT:    ret
 ;
 ; RV64IPN-LABEL: bitreverse_i64:
 ; RV64IPN:       # %bb.0:
-; RV64IPN-NEXT:    srli a1, a0, 24
-; RV64IPN-NEXT:    lui a2, 4080
-; RV64IPN-NEXT:    and a1, a1, a2
-; RV64IPN-NEXT:    srli a2, a0, 8
-; RV64IPN-NEXT:    addi a3, zero, 255
-; RV64IPN-NEXT:    slli a4, a3, 24
-; RV64IPN-NEXT:    and a2, a2, a4
-; RV64IPN-NEXT:    or a1, a2, a1
-; RV64IPN-NEXT:    srli a2, a0, 40
-; RV64IPN-NEXT:    lui a4, 16
-; RV64IPN-NEXT:    addiw a4, a4, -256
-; RV64IPN-NEXT:    and a2, a2, a4
-; RV64IPN-NEXT:    srli a4, a0, 56
-; RV64IPN-NEXT:    or a2, a2, a4
-; RV64IPN-NEXT:    or a1, a1, a2
-; RV64IPN-NEXT:    slli a2, a0, 8
-; RV64IPN-NEXT:    slli a4, a3, 32
-; RV64IPN-NEXT:    and a2, a2, a4
-; RV64IPN-NEXT:    slli a4, a0, 24
-; RV64IPN-NEXT:    slli a5, a3, 40
-; RV64IPN-NEXT:    and a4, a4, a5
-; RV64IPN-NEXT:    or a2, a4, a2
-; RV64IPN-NEXT:    slli a4, a0, 40
-; RV64IPN-NEXT:    slli a3, a3, 48
-; RV64IPN-NEXT:    and a3, a4, a3
-; RV64IPN-NEXT:    slli a0, a0, 56
-; RV64IPN-NEXT:    or a0, a0, a3
-; RV64IPN-NEXT:    or a0, a0, a2
-; RV64IPN-NEXT:    or a0, a0, a1
-; RV64IPN-NEXT:    lui a1, 3855
-; RV64IPN-NEXT:    addiw a1, a1, 241
-; RV64IPN-NEXT:    slli a1, a1, 12
-; RV64IPN-NEXT:    addi a1, a1, -241
-; RV64IPN-NEXT:    slli a1, a1, 12
-; RV64IPN-NEXT:    addi a1, a1, 241
-; RV64IPN-NEXT:    slli a1, a1, 12
-; RV64IPN-NEXT:    addi a1, a1, -241
-; RV64IPN-NEXT:    and a1, a0, a1
-; RV64IPN-NEXT:    slli a1, a1, 4
-; RV64IPN-NEXT:    lui a2, 1044721
-; RV64IPN-NEXT:    addiw a2, a2, -241
-; RV64IPN-NEXT:    slli a2, a2, 12
-; RV64IPN-NEXT:    addi a2, a2, 241
-; RV64IPN-NEXT:    slli a2, a2, 12
-; RV64IPN-NEXT:    addi a2, a2, -241
-; RV64IPN-NEXT:    slli a2, a2, 12
-; RV64IPN-NEXT:    addi a2, a2, 240
-; RV64IPN-NEXT:    and a0, a0, a2
-; RV64IPN-NEXT:    srli a0, a0, 4
-; RV64IPN-NEXT:    or a0, a0, a1
-; RV64IPN-NEXT:    lui a1, 13107
-; RV64IPN-NEXT:    addiw a1, a1, 819
-; RV64IPN-NEXT:    slli a1, a1, 12
-; RV64IPN-NEXT:    addi a1, a1, 819
-; RV64IPN-NEXT:    slli a1, a1, 12
-; RV64IPN-NEXT:    addi a1, a1, 819
-; RV64IPN-NEXT:    slli a1, a1, 12
-; RV64IPN-NEXT:    addi a1, a1, 819
-; RV64IPN-NEXT:    and a1, a0, a1
-; RV64IPN-NEXT:    slli a1, a1, 2
-; RV64IPN-NEXT:    lui a2, 1035469
-; RV64IPN-NEXT:    addiw a2, a2, -819
-; RV64IPN-NEXT:    slli a2, a2, 12
-; RV64IPN-NEXT:    addi a2, a2, -819
-; RV64IPN-NEXT:    slli a2, a2, 12
-; RV64IPN-NEXT:    addi a2, a2, -819
-; RV64IPN-NEXT:    slli a2, a2, 12
-; RV64IPN-NEXT:    addi a2, a2, -820
-; RV64IPN-NEXT:    and a0, a0, a2
-; RV64IPN-NEXT:    srli a0, a0, 2
-; RV64IPN-NEXT:    or a0, a0, a1
-; RV64IPN-NEXT:    lui a1, 21845
-; RV64IPN-NEXT:    addiw a1, a1, 1365
-; RV64IPN-NEXT:    slli a1, a1, 12
-; RV64IPN-NEXT:    addi a1, a1, 1365
-; RV64IPN-NEXT:    slli a1, a1, 12
-; RV64IPN-NEXT:    addi a1, a1, 1365
-; RV64IPN-NEXT:    slli a1, a1, 12
-; RV64IPN-NEXT:    addi a1, a1, 1365
-; RV64IPN-NEXT:    and a1, a0, a1
-; RV64IPN-NEXT:    slli a1, a1, 1
-; RV64IPN-NEXT:    lui a2, 1026731
-; RV64IPN-NEXT:    addiw a2, a2, -1365
-; RV64IPN-NEXT:    slli a2, a2, 12
-; RV64IPN-NEXT:    addi a2, a2, -1365
-; RV64IPN-NEXT:    slli a2, a2, 12
-; RV64IPN-NEXT:    addi a2, a2, -1365
-; RV64IPN-NEXT:    slli a2, a2, 12
-; RV64IPN-NEXT:    addi a2, a2, -1366
-; RV64IPN-NEXT:    and a0, a0, a2
-; RV64IPN-NEXT:    srli a0, a0, 1
-; RV64IPN-NEXT:    or a0, a0, a1
+; RV64IPN-NEXT:    bitrevi a0, a0, 63
 ; RV64IPN-NEXT:    ret
 ;
 ; RV64IBP-LABEL: bitreverse_i64:
diff --git a/llvm/test/CodeGen/RISCV/rv64zpn-bswap.ll b/llvm/test/CodeGen/RISCV/rv64zpn-bswap.ll
--- a/llvm/test/CodeGen/RISCV/rv64zpn-bswap.ll
+++ b/llvm/test/CodeGen/RISCV/rv64zpn-bswap.ll
@@ -20,22 +20,12 @@
 ;
 ; RV64IP-LABEL: bswap_i16:
 ; RV64IP:       # %bb.0:
-; RV64IP-NEXT:    srli a1, a0, 8
-; RV64IP-NEXT:    slli a0, a0, 8
-; RV64IP-NEXT:    or a0, a0, a1
-; RV64IP-NEXT:    lui a1, 16
-; RV64IP-NEXT:    addiw a1, a1, -1
-; RV64IP-NEXT:    and a0, a0, a1
+; RV64IP-NEXT:    swap8 a0, a0
 ; RV64IP-NEXT:    ret
 ;
 ; RV64IPN-LABEL: bswap_i16:
 ; RV64IPN:       # %bb.0:
-; RV64IPN-NEXT:    srli a1, a0, 8
-; RV64IPN-NEXT:    slli a0, a0, 8
-; RV64IPN-NEXT:    or a0, a0, a1
-; RV64IPN-NEXT:    lui a1, 16
-; RV64IPN-NEXT:    addiw a1, a1, -1
-; RV64IPN-NEXT:    and a0, a0, a1
+; RV64IPN-NEXT:    swap8 a0, a0
 ; RV64IPN-NEXT:    ret
 ;
 ; RV64IBP-LABEL: bswap_i16:
@@ -54,35 +44,15 @@
 ;
 ; RV64IP-LABEL: bswap_i32:
 ; RV64IP:       # %bb.0:
-; RV64IP-NEXT:    srliw a1, a0, 8
-; RV64IP-NEXT:    lui a2, 16
-; RV64IP-NEXT:    addiw a2, a2, -256
-; RV64IP-NEXT:    and a1, a1, a2
-; RV64IP-NEXT:    srliw a2, a0, 24
-; RV64IP-NEXT:    or a1, a1, a2
-; RV64IP-NEXT:    slli a2, a0, 8
-; RV64IP-NEXT:    lui a3, 4080
-; RV64IP-NEXT:    and a2, a2, a3
-; RV64IP-NEXT:    slli a0, a0, 24
-; RV64IP-NEXT:    or a0, a0, a2
-; RV64IP-NEXT:    or a0, a0, a1
+; RV64IP-NEXT:    swap8 a0, a0
+; RV64IP-NEXT:    swap16 a0, a0
 ; RV64IP-NEXT:    sext.w a0, a0
 ; RV64IP-NEXT:    ret
 ;
 ; RV64IPN-LABEL: bswap_i32:
 ; RV64IPN:       # %bb.0:
-; RV64IPN-NEXT:    srliw a1, a0, 8
-; RV64IPN-NEXT:    lui a2, 16
-; RV64IPN-NEXT:    addiw a2, a2, -256
-; RV64IPN-NEXT:    and a1, a1, a2
-; RV64IPN-NEXT:    srliw a2, a0, 24
-; RV64IPN-NEXT:    or a1, a1, a2
-; RV64IPN-NEXT:    slli a2, a0, 8
-; RV64IPN-NEXT:    lui a3, 4080
-; RV64IPN-NEXT:    and a2, a2, a3
-; RV64IPN-NEXT:    slli a0, a0, 24
-; RV64IPN-NEXT:    or a0, a0, a2
-; RV64IPN-NEXT:    or a0, a0, a1
+; RV64IPN-NEXT:    swap8 a0, a0
+; RV64IPN-NEXT:    swap16 a0, a0
 ; RV64IPN-NEXT:    sext.w a0, a0
 ; RV64IPN-NEXT:    ret
 ;
@@ -104,35 +74,15 @@
 ;
 ; RV64IP-LABEL: bswap_i32_nosext:
 ; RV64IP:       # %bb.0:
-; RV64IP-NEXT:    srliw a2, a0, 8
-; RV64IP-NEXT:    lui a3, 16
-; RV64IP-NEXT:    addiw a3, a3, -256
-; RV64IP-NEXT:    and a2, a2, a3
-; RV64IP-NEXT:    srliw a3, a0, 24
-; RV64IP-NEXT:    or a2, a2, a3
-; RV64IP-NEXT:    slli a3, a0, 8
-; RV64IP-NEXT:    lui a4, 4080
-; RV64IP-NEXT:    and a3, a3, a4
-; RV64IP-NEXT:    slli a0, a0, 24
-; RV64IP-NEXT:    or a0, a0, a3
-; RV64IP-NEXT:    or a0, a0, a2
+; RV64IP-NEXT:    swap8 a0, a0
+; RV64IP-NEXT:    swap16 a0, a0
 ; RV64IP-NEXT:    sw a0, 0(a1)
 ; RV64IP-NEXT:    ret
 ;
 ; RV64IPN-LABEL: bswap_i32_nosext:
 ; RV64IPN:       # %bb.0:
-; RV64IPN-NEXT:    srliw a2, a0, 8
-; RV64IPN-NEXT:    lui a3, 16
-; RV64IPN-NEXT:    addiw a3, a3, -256
-; RV64IPN-NEXT:    and a2, a2, a3
-; RV64IPN-NEXT:    srliw a3, a0, 24
-; RV64IPN-NEXT:    or a2, a2, a3
-; RV64IPN-NEXT:    slli a3, a0, 8
-; RV64IPN-NEXT:    lui a4, 4080
-; RV64IPN-NEXT:    and a3, a3, a4
-; RV64IPN-NEXT:    slli a0, a0, 24
-; RV64IPN-NEXT:    or a0, a0, a3
-; RV64IPN-NEXT:    or a0, a0, a2
+; RV64IPN-NEXT:    swap8 a0, a0
+; RV64IPN-NEXT:    swap16 a0, a0
 ; RV64IPN-NEXT:    sw a0, 0(a1)
 ; RV64IPN-NEXT:    ret
 ;
@@ -154,68 +104,16 @@
 ;
 ; RV64IP-LABEL: bswap_i64:
 ; RV64IP:       # %bb.0:
-; RV64IP-NEXT:    srli a1, a0, 24
-; RV64IP-NEXT:    lui a2, 4080
-; RV64IP-NEXT:    and a1, a1, a2
-; RV64IP-NEXT:    srli a2, a0, 8
-; RV64IP-NEXT:    addi a3, zero, 255
-; RV64IP-NEXT:    slli a4, a3, 24
-; RV64IP-NEXT:    and a2, a2, a4
-; RV64IP-NEXT:    or a1, a2, a1
-; RV64IP-NEXT:    srli a2, a0, 40
-; RV64IP-NEXT:    lui a4, 16
-; RV64IP-NEXT:    addiw a4, a4, -256
-; RV64IP-NEXT:    and a2, a2, a4
-; RV64IP-NEXT:    srli a4, a0, 56
-; RV64IP-NEXT:    or a2, a2, a4
-; RV64IP-NEXT:    or a1, a1, a2
-; RV64IP-NEXT:    slli a2, a0, 8
-; RV64IP-NEXT:    slli a4, a3, 32
-; RV64IP-NEXT:    and a2, a2, a4
-; RV64IP-NEXT:    slli a4, a0, 24
-; RV64IP-NEXT:    slli a5, a3, 40
-; RV64IP-NEXT:    and a4, a4, a5
-; RV64IP-NEXT:    or a2, a4, a2
-; RV64IP-NEXT:    slli a4, a0, 40
-; RV64IP-NEXT:    slli a3, a3, 48
-; RV64IP-NEXT:    and a3, a4, a3
-; RV64IP-NEXT:    slli a0, a0, 56
-; RV64IP-NEXT:    or a0, a0, a3
-; RV64IP-NEXT:    or a0, a0, a2
-; RV64IP-NEXT:    or a0, a0, a1
+; RV64IP-NEXT:    swap8 a0, a0
+; RV64IP-NEXT:    swap16 a0, a0
+; RV64IP-NEXT:    pkbt32 a0, a0, a0
 ; RV64IP-NEXT:    ret
 ;
 ; RV64IPN-LABEL: bswap_i64:
 ; RV64IPN:       # %bb.0:
-; RV64IPN-NEXT:    srli a1, a0, 24
-; RV64IPN-NEXT:    lui a2, 4080
-; RV64IPN-NEXT:    and a1, a1, a2
-; RV64IPN-NEXT:    srli a2, a0, 8
-; RV64IPN-NEXT:    addi a3, zero, 255
-; RV64IPN-NEXT:    slli a4, a3, 24
-; RV64IPN-NEXT:    and a2, a2, a4
-; RV64IPN-NEXT:    or a1, a2, a1
-; RV64IPN-NEXT:    srli a2, a0, 40
-; RV64IPN-NEXT:    lui a4, 16
-; RV64IPN-NEXT:    addiw a4, a4, -256
-; RV64IPN-NEXT:    and a2, a2, a4
-; RV64IPN-NEXT:    srli a4, a0, 56
-; RV64IPN-NEXT:    or a2, a2, a4
-; RV64IPN-NEXT:    or a1, a1, a2
-; RV64IPN-NEXT:    slli a2, a0, 8
-; RV64IPN-NEXT:    slli a4, a3, 32
-; RV64IPN-NEXT:    and a2, a2, a4
-; RV64IPN-NEXT:    slli a4, a0, 24
-; RV64IPN-NEXT:    slli a5, a3, 40
-; RV64IPN-NEXT:    and a4, a4, a5
-; RV64IPN-NEXT:    or a2, a4, a2
-; RV64IPN-NEXT:    slli a4, a0, 40
-; RV64IPN-NEXT:    slli a3, a3, 48
-; RV64IPN-NEXT:    and a3, a4, a3
-; RV64IPN-NEXT:    slli a0, a0, 56
-; RV64IPN-NEXT:    or a0, a0, a3
-; RV64IPN-NEXT:    or a0, a0, a2
-; RV64IPN-NEXT:    or a0, a0, a1
+; RV64IPN-NEXT:    swap8 a0, a0
+; RV64IPN-NEXT:    swap16 a0, a0
+; RV64IPN-NEXT:    pkbt32 a0, a0, a0
 ; RV64IPN-NEXT:    ret
 ;
 ; RV64IBP-LABEL: bswap_i64: