[llvm] [RISCV][P-ext] Add initial 64-bit support for RV32. (PR #197093)

Craig Topper via llvm-commits llvm-commits at lists.llvm.org
Mon May 11 22:47:12 PDT 2026


https://github.com/topperc updated https://github.com/llvm/llvm-project/pull/197093

>From c059a3e81787d29cf22eb7117272a37ef7ef0fa3 Mon Sep 17 00:00:00 2001
From: Craig Topper <craig.topper at sifive.com>
Date: Fri, 24 Apr 2026 23:52:45 -0700
Subject: [PATCH 1/3] [RISCV][P-ext] Add initial 64-bit support for RV32.

Most operations are set to expand. A few operations that were easy
to support using isel patterns have been added. concat_vectors and
extract_subvector are supported in order to allow type legalization
to split 64-bit vectors into 32-bit vectors around the supported
operations.

Loads and stores are custom split into two i32 scalars or two
v4i8/v2i16 vectors.

I've added new opcodes to build and split vectors into 2 GPRs at
function arguments and returns. These are similar to BuildPairF64
and SplitF64 nodes we use for RV32D soft float. Long term we might
want to use concat_vectors/build_vector and
extract_subvector/extract_vectorelt.
---
 .../SelectionDAG/LegalizeVectorOps.cpp        |    3 +
 llvm/lib/Target/RISCV/RISCVCallingConv.cpp    |    8 +-
 llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp   |   72 +-
 llvm/lib/Target/RISCV/RISCVISelLowering.cpp   |  258 +-
 llvm/lib/Target/RISCV/RISCVInstrInfoP.td      |   80 +
 llvm/lib/Target/RISCV/RISCVRegisterInfo.td    |   12 +-
 llvm/lib/Target/RISCV/RISCVSubtarget.cpp      |   10 +-
 .../RISCV/calling-conv-p-ext-vector.ll        |  124 +-
 .../RISCV/rvp-narrowing-shift-trunc.ll        |   24 +-
 llvm/test/CodeGen/RISCV/rvp-simd-64.ll        | 3521 ++++++++++++-----
 .../CodeGen/RISCV/rvp-unaligned-load-store.ll |  144 +-
 11 files changed, 3092 insertions(+), 1164 deletions(-)

diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp
index eb89a0f129df4..162b6f69edb81 100644
--- a/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp
@@ -1394,6 +1394,9 @@ void VectorLegalizer::Expand(SDNode *Node, SmallVectorImpl<SDValue> &Results) {
     Results.push_back(ExpandLOOP_DEPENDENCE_MASK(Node));
     return;
 
+  case ISD::AND:
+  case ISD::OR:
+  case ISD::XOR:
   case ISD::FADD:
   case ISD::FMUL:
   case ISD::FMA:
diff --git a/llvm/lib/Target/RISCV/RISCVCallingConv.cpp b/llvm/lib/Target/RISCV/RISCVCallingConv.cpp
index 872a879dcf9c4..f6c7df5b6bc63 100644
--- a/llvm/lib/Target/RISCV/RISCVCallingConv.cpp
+++ b/llvm/lib/Target/RISCV/RISCVCallingConv.cpp
@@ -524,9 +524,11 @@ static bool CC_RISCV_Impl(unsigned ValNo, MVT ValVT, MVT LocVT,
          "PendingLocs and PendingArgFlags out of sync");
 
   // Handle passing f64 on RV32D with a soft float ABI or when floating point
-  // registers are exhausted.
-  if (XLen == 32 && LocVT == MVT::f64) {
-    assert(PendingLocs.empty() && "Can't lower f64 if it is split");
+  // registers are exhausted. Or 64-bit P extension vectors on RV32.
+  if (XLen == 32 && (LocVT == MVT::f64 || (Subtarget.isPExtPackedType(LocVT) &&
+                                           LocVT.getSizeInBits() == 64))) {
+    assert(PendingLocs.empty() &&
+           "Can't lower f64 or P extension vector if it is split");
     // Depending on available argument GPRS, f64 may be passed in a pair of
     // GPRs, split between a GPR and the stack, or passed completely on the
     // stack. LowerCall/LowerFormalArguments/LowerReturn must recognise these
diff --git a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
index 359ba913589a6..777a833ddd3ba 100644
--- a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
@@ -1237,11 +1237,12 @@ void RISCVDAGToDAGISel::Select(SDNode *Node) {
     return;
   }
   case RISCVISD::BuildGPRPair:
-  case RISCVISD::BuildPairF64: {
+  case RISCVISD::BuildPairF64:
+  case RISCVISD::BuildPairGPRVec: {
     if (Opcode == RISCVISD::BuildPairF64 && !Subtarget->hasStdExtZdinx())
       break;
 
-    assert((!Subtarget->is64Bit() || Opcode == RISCVISD::BuildGPRPair) &&
+    assert((!Subtarget->is64Bit() || Opcode != RISCVISD::BuildPairF64) &&
            "BuildPairF64 only handled here on rv32i_zdinx");
 
     SDValue N =
@@ -1250,9 +1251,10 @@ void RISCVDAGToDAGISel::Select(SDNode *Node) {
     return;
   }
   case RISCVISD::SplitGPRPair:
-  case RISCVISD::SplitF64: {
+  case RISCVISD::SplitF64:
+  case RISCVISD::SplitGPRVec: {
     if (Subtarget->hasStdExtZdinx() || Opcode != RISCVISD::SplitF64) {
-      assert((!Subtarget->is64Bit() || Opcode == RISCVISD::SplitGPRPair) &&
+      assert((!Subtarget->is64Bit() || Opcode != RISCVISD::SplitF64) &&
              "SplitF64 only handled here on rv32i_zdinx");
 
       if (!SDValue(Node, 0).use_empty()) {
@@ -1272,9 +1274,6 @@ void RISCVDAGToDAGISel::Select(SDNode *Node) {
       return;
     }
 
-    assert(Opcode != RISCVISD::SplitGPRPair &&
-           "SplitGPRPair should already be handled");
-
     if (!Subtarget->hasStdExtZfa())
       break;
     assert(Subtarget->hasStdExtD() && !Subtarget->is64Bit() &&
@@ -3009,6 +3008,49 @@ void RISCVDAGToDAGISel::Select(SDNode *Node) {
 
     break;
   }
+  case ISD::BUILD_VECTOR: {
+    if (Subtarget->hasStdExtP() && !Subtarget->is64Bit() && VT == MVT::v2i32) {
+      SDValue Pair = buildGPRPair(CurDAG, DL, VT, Node->getOperand(0),
+                                  Node->getOperand(1));
+      ReplaceNode(Node, Pair.getNode());
+      return;
+    }
+    break;
+  }
+  case ISD::CONCAT_VECTORS: {
+    if (Subtarget->hasStdExtP() && !Subtarget->is64Bit() &&
+        (VT == MVT::v4i16 || VT == MVT::v8i8)) {
+      assert(Node->getNumOperands() == 2);
+      SDValue Lo = Node->getOperand(0);
+      SDValue Hi = Node->getOperand(1);
+      SDValue Pair = buildGPRPair(CurDAG, DL, VT, Lo, Hi);
+      ReplaceNode(Node, Pair.getNode());
+      return;
+    }
+    break;
+  }
+  case ISD::EXTRACT_VECTOR_ELT: {
+    if (Subtarget->hasStdExtP() && !Subtarget->is64Bit()) {
+      MVT SrcVT = Node->getOperand(0).getSimpleValueType();
+      if (VT == MVT::i32 && SrcVT == MVT::v2i32) {
+        auto *IdxC = dyn_cast<ConstantSDNode>(Node->getOperand(1));
+        if (!IdxC)
+          break;
+        unsigned Idx = IdxC->getZExtValue();
+        if (Idx > 1)
+          break;
+
+        unsigned SubRegIdx =
+            Idx == 0 ? RISCV::sub_gpr_even : RISCV::sub_gpr_odd;
+        SDValue Src = Node->getOperand(0);
+        SDValue Extract =
+            CurDAG->getTargetExtractSubreg(SubRegIdx, DL, VT, Src);
+        ReplaceNode(Node, Extract.getNode());
+        return;
+      }
+    }
+    break;
+  }
   case ISD::SCALAR_TO_VECTOR:
     if (Subtarget->hasStdExtP()) {
       MVT SrcVT = Node->getOperand(0).getSimpleValueType();
@@ -3092,6 +3134,22 @@ void RISCVDAGToDAGISel::Select(SDNode *Node) {
     SDValue V = Node->getOperand(0);
     auto Idx = Node->getConstantOperandVal(1);
     MVT InVT = V.getSimpleValueType();
+
+    // Handle P-extension extract_subvector for v2i16 from v4i16 and v4i8 from
+    // v8i8
+    if (Subtarget->hasStdExtP() && !Subtarget->is64Bit() &&
+        ((InVT == MVT::v4i16 && VT == MVT::v2i16) ||
+         (InVT == MVT::v8i8 && VT == MVT::v4i8))) {
+      unsigned NumElts = VT.getVectorNumElements();
+      if (Idx != 0 && Idx != NumElts)
+        break;
+
+      unsigned SubRegIdx = Idx == 0 ? RISCV::sub_gpr_even : RISCV::sub_gpr_odd;
+      SDValue Extract = CurDAG->getTargetExtractSubreg(SubRegIdx, DL, VT, V);
+      ReplaceNode(Node, Extract.getNode());
+      return;
+    }
+
     SDLoc DL(V);
 
     const RISCVTargetLowering &TLI = *Subtarget->getTargetLowering();
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 93e820b4713ec..faa0db7086c36 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -296,6 +296,10 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
     } else {
       addRegisterClass(MVT::v2i16, &RISCV::GPRRegClass);
       addRegisterClass(MVT::v4i8, &RISCV::GPRRegClass);
+
+      addRegisterClass(MVT::v2i32, &RISCV::GPRPairRegClass);
+      addRegisterClass(MVT::v4i16, &RISCV::GPRPairRegClass);
+      addRegisterClass(MVT::v8i8, &RISCV::GPRPairRegClass);
     }
   }
 
@@ -540,11 +544,11 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
       ISD::FCANONICALIZE};
 
   if (Subtarget.hasStdExtP()) {
-    static const MVT RV32VTs[] = {MVT::v2i16, MVT::v4i8};
-    static const MVT RV64VTs[] = {MVT::v2i32, MVT::v4i16, MVT::v8i8};
+    static const MVT P32VecVTs[] = {MVT::v2i16, MVT::v4i8};
+    static const MVT P64VecVTs[] = {MVT::v2i32, MVT::v4i16, MVT::v8i8};
     ArrayRef<MVT> VTs;
     if (Subtarget.is64Bit()) {
-      VTs = RV64VTs;
+      VTs = P64VecVTs;
       // There's no instruction for vector shamt in P extension so we unroll to
       // scalar instructions. Vector VTs that are 32-bit are widened to 64-bit
       // vector, e.g. v2i16 -> v4i16, before getting unrolled, so we need custom
@@ -552,7 +556,7 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
       setOperationAction({ISD::SHL, ISD::SRL, ISD::SRA},
                          {MVT::v2i16, MVT::v4i8}, Custom);
     } else {
-      VTs = RV32VTs;
+      VTs = P32VecVTs;
     }
     // By default everything must be expanded.
     for (unsigned Op = 0; Op < ISD::BUILTIN_OP_END; ++Op)
@@ -603,6 +607,34 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
 
     // P extension vector comparisons produce all 1s for true, all 0s for false
     setBooleanVectorContents(ZeroOrNegativeOneBooleanContent);
+
+    if (!Subtarget.is64Bit()) {
+      // By default everything must be expanded.
+      for (unsigned Op = 0; Op < ISD::BUILTIN_OP_END; ++Op)
+        setOperationAction(Op, P64VecVTs, Expand);
+
+      for (MVT VT : P64VecVTs) {
+        for (MVT OtherVT : MVT::integer_fixedlen_vector_valuetypes()) {
+          setTruncStoreAction(VT, OtherVT, Expand);
+          setLoadExtAction({ISD::EXTLOAD, ISD::SEXTLOAD, ISD::ZEXTLOAD}, VT,
+                           OtherVT, Expand);
+        }
+      }
+
+      setOperationAction({ISD::LOAD, ISD::STORE}, P64VecVTs, Custom);
+      setOperationAction({ISD::ADD, ISD::SUB}, P64VecVTs, Legal);
+      setOperationAction(
+          {ISD::UADDSAT, ISD::SADDSAT, ISD::USUBSAT, ISD::SSUBSAT}, P64VecVTs,
+          Legal);
+      setOperationAction({ISD::AVGFLOORS, ISD::AVGFLOORU}, P64VecVTs, Legal);
+      setOperationAction({ISD::SMIN, ISD::UMIN, ISD::SMAX, ISD::UMAX},
+                         P64VecVTs, Legal);
+      setOperationAction(ISD::BUILD_VECTOR, MVT::v2i32, Legal);
+      setOperationAction(ISD::EXTRACT_VECTOR_ELT, MVT::v2i32, Legal);
+      setOperationAction(ISD::CONCAT_VECTORS, {MVT::v4i16, MVT::v8i8}, Legal);
+      setOperationAction(ISD::EXTRACT_SUBVECTOR, {MVT::v2i16, MVT::v4i8},
+                         Legal);
+    }
   }
 
   if (Subtarget.hasStdExtZfbfmin()) {
@@ -2685,6 +2717,9 @@ bool RISCVTargetLowering::isFPImmLegal(const APFloat &Imm, EVT VT,
 // TODO: This is very conservative.
 bool RISCVTargetLowering::isExtractSubvectorCheap(EVT ResVT, EVT SrcVT,
                                                   unsigned Index) const {
+  if (!Subtarget.hasVInstructions())
+    return false;
+
   if (!isOperationLegalOrCustom(ISD::EXTRACT_SUBVECTOR, ResVT))
     return false;
 
@@ -3047,6 +3082,10 @@ RISCVTargetLowering::decomposeSubvectorInsertExtractToSubRegs(
 // Permit combining of mask vectors as BUILD_VECTOR never expands to scalar
 // stores for those types.
 bool RISCVTargetLowering::mergeStoresAfterLegalization(EVT VT) const {
+  if (Subtarget.hasStdExtP() && !Subtarget.is64Bit() &&
+      (VT == MVT::i32 || VT == MVT::v2i16 || VT == MVT::v4i8))
+    return false;
+
   return !Subtarget.useRVVForFixedLengthVectors() ||
          (VT.isFixedLengthVector() && VT.getVectorElementType() == MVT::i1);
 }
@@ -8501,6 +8540,50 @@ SDValue RISCVTargetLowering::LowerOperation(SDValue Op,
       return DAG.getMergeValues({Pair, Chain}, DL);
     }
 
+    if (Subtarget.hasStdExtP() && !Subtarget.is64Bit() &&
+        (VT == MVT::v2i32 || VT == MVT::v4i16 || VT == MVT::v8i8)) {
+      assert(!Subtarget.is64Bit() && "Unexpected custom legalisation");
+
+      // Determine the half-size type
+      MVT HalfVT;
+      if (VT == MVT::v2i32)
+        HalfVT = MVT::i32;
+      else if (VT == MVT::v4i16)
+        HalfVT = MVT::v2i16;
+      else // VT == MVT::v8i8
+        HalfVT = MVT::v4i8;
+
+      SDLoc DL(Op);
+      SDValue BasePtr = Load->getBasePtr();
+      SDValue Chain = Load->getChain();
+
+      // Create two loads for the lower and upper halves
+      SDValue Lo =
+          DAG.getLoad(HalfVT, DL, Chain, BasePtr, Load->getPointerInfo(),
+                      Load->getBaseAlign(), Load->getMemOperand()->getFlags());
+      unsigned HalfSize = HalfVT.getStoreSize();
+      BasePtr =
+          DAG.getObjectPtrOffset(DL, BasePtr, TypeSize::getFixed(HalfSize));
+      SDValue Hi =
+          DAG.getLoad(HalfVT, DL, Chain, BasePtr,
+                      Load->getPointerInfo().getWithOffset(HalfSize),
+                      Load->getBaseAlign(), Load->getMemOperand()->getFlags());
+      Chain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, Lo.getValue(1),
+                          Hi.getValue(1));
+
+      // Combine the two halves into the result vector
+      SDValue Result;
+      if (VT == MVT::v2i32) {
+        // For v2i32, build vector from two i32 scalars
+        Result = DAG.getNode(ISD::BUILD_VECTOR, DL, VT, Lo, Hi);
+      } else {
+        // For v4i16 and v8i8, use CONCAT_VECTORS
+        Result = DAG.getNode(ISD::CONCAT_VECTORS, DL, VT, Lo, Hi);
+      }
+
+      return DAG.getMergeValues({Result, Chain}, DL);
+    }
+
     if (VT == MVT::bf16)
       return lowerXAndesBfHCvtBFloat16Load(Op, DAG);
 
@@ -8596,6 +8679,58 @@ SDValue RISCVTargetLowering::LowerOperation(SDValue Op,
           Store->getMemOperand());
     }
 
+    if (Subtarget.hasStdExtP() && !Subtarget.is64Bit() &&
+        (VT == MVT::v2i32 || VT == MVT::v4i16 || VT == MVT::v8i8)) {
+      assert(!Subtarget.is64Bit() && "Unexpected custom legalisation");
+
+      auto *Store = cast<StoreSDNode>(Op);
+      SDValue Val = Store->getValue();
+
+      // Determine the half-size type
+      MVT HalfVT;
+      if (VT == MVT::v2i32)
+        HalfVT = MVT::i32;
+      else if (VT == MVT::v4i16)
+        HalfVT = MVT::v2i16;
+      else // VT == MVT::v8i8
+        HalfVT = MVT::v4i8;
+
+      SDLoc DL(Op);
+      SDValue BasePtr = Store->getBasePtr();
+      SDValue Chain = Store->getChain();
+
+      // Extract the two halves from the vector
+      SDValue Lo, Hi;
+      if (VT == MVT::v2i32) {
+        // For v2i32, extract two i32 scalars
+        Lo = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, MVT::i32, Val,
+                         DAG.getVectorIdxConstant(0, DL));
+        Hi = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, MVT::i32, Val,
+                         DAG.getVectorIdxConstant(1, DL));
+      } else {
+        // For v4i16 and v8i8, extract two vector halves
+        Lo = DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, HalfVT, Val,
+                         DAG.getVectorIdxConstant(0, DL));
+        unsigned HalfNumElts = HalfVT.getVectorNumElements();
+        Hi = DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, HalfVT, Val,
+                         DAG.getVectorIdxConstant(HalfNumElts, DL));
+      }
+
+      // Create two stores for the lower and upper halves
+      SDValue LoStore = DAG.getStore(
+          Chain, DL, Lo, BasePtr, Store->getPointerInfo(),
+          Store->getBaseAlign(), Store->getMemOperand()->getFlags());
+      unsigned HalfSize = HalfVT.getStoreSize();
+      BasePtr =
+          DAG.getObjectPtrOffset(DL, BasePtr, TypeSize::getFixed(HalfSize));
+      SDValue HiStore = DAG.getStore(
+          Chain, DL, Hi, BasePtr,
+          Store->getPointerInfo().getWithOffset(HalfSize),
+          Store->getBaseAlign(), Store->getMemOperand()->getFlags());
+
+      return DAG.getNode(ISD::TokenFactor, DL, MVT::Other, LoStore, HiStore);
+    }
+
     if (VT == MVT::bf16)
       return lowerXAndesBfHCvtBFloat16Store(Op, DAG);
 
@@ -16404,10 +16539,6 @@ static SDValue combinePExtTruncate(SDNode *N, SelectionDAG &DAG,
       VT != MVT::v4i8 && VT != MVT::v2i32)
     return SDValue();
 
-  // We only support XLen or smaller vectors.
-  if (VT.getSizeInBits() > Subtarget.getXLen())
-    return SDValue();
-
   // Check if shift amount is a splat constant
   SDValue ShAmt = N0.getOperand(1);
   if (ShAmt.getOpcode() != ISD::BUILD_VECTOR)
@@ -16484,6 +16615,8 @@ static SDValue combinePExtTruncate(SDNode *N, SelectionDAG &DAG,
     // MULH*/MULHR*: shift amount must be element size, only for i16/i32
     if (ShAmtVal != EltBits || (EltBits != 16 && EltBits != 32))
       return SDValue();
+    if (!Subtarget.is64Bit() && (VT == MVT::v2i32 || VT == MVT::v4i16))
+      return SDValue();
     if (IsRounding) {
       if (LHSIsSExt && RHSIsSExt) {
         Opc = RISCVISD::MULHR;
@@ -23978,6 +24111,36 @@ static SDValue unpackF64OnRV32DSoftABI(SelectionDAG &DAG, SDValue Chain,
   return DAG.getNode(RISCVISD::BuildPairF64, DL, MVT::f64, Lo, Hi);
 }
 
+static SDValue unpackGPRVecOnRV32(SelectionDAG &DAG, SDValue Chain,
+                                  const CCValAssign &VA,
+                                  const CCValAssign &HiVA, const SDLoc &DL) {
+  MachineFunction &MF = DAG.getMachineFunction();
+  MachineFrameInfo &MFI = MF.getFrameInfo();
+  MachineRegisterInfo &RegInfo = MF.getRegInfo();
+
+  assert(VA.isRegLoc() && "Expected register VA assignment");
+
+  Register LoVReg = RegInfo.createVirtualRegister(&RISCV::GPRRegClass);
+  RegInfo.addLiveIn(VA.getLocReg(), LoVReg);
+  SDValue Lo = DAG.getCopyFromReg(Chain, DL, LoVReg, MVT::i32);
+  SDValue Hi;
+  if (HiVA.isMemLoc()) {
+    // Second half of f64 is passed on the stack.
+    int FI = MFI.CreateFixedObject(4, HiVA.getLocMemOffset(),
+                                   /*IsImmutable=*/true);
+    SDValue FIN = DAG.getFrameIndex(FI, MVT::i32);
+    Hi = DAG.getLoad(MVT::i32, DL, Chain, FIN,
+                     MachinePointerInfo::getFixedStack(MF, FI));
+  } else {
+    // Second half of f64 is passed in another GPR.
+    Register HiVReg = RegInfo.createVirtualRegister(&RISCV::GPRRegClass);
+    RegInfo.addLiveIn(HiVA.getLocReg(), HiVReg);
+    Hi = DAG.getCopyFromReg(Chain, DL, HiVReg, MVT::i32);
+  }
+
+  return DAG.getNode(RISCVISD::BuildPairGPRVec, DL, VA.getValVT(), Lo, Hi);
+}
+
 // Transform physical registers into virtual registers.
 SDValue RISCVTargetLowering::LowerFormalArguments(
     SDValue Chain, CallingConv::ID CallConv, bool IsVarArg,
@@ -24076,6 +24239,11 @@ SDValue RISCVTargetLowering::LowerFormalArguments(
     if (VA.getLocVT() == MVT::i32 && VA.getValVT() == MVT::f64) {
       assert(VA.needsCustom());
       ArgValue = unpackF64OnRV32DSoftABI(DAG, Chain, VA, ArgLocs[++i], DL);
+    } else if (VA.getLocVT() == MVT::i32 &&
+               Subtarget.isPExtPackedType(VA.getValVT()) &&
+               VA.getValVT().getSizeInBits() == 64) {
+      assert(VA.needsCustom());
+      ArgValue = unpackGPRVecOnRV32(DAG, Chain, VA, ArgLocs[++i], DL);
     } else if (VA.isRegLoc())
       ArgValue = unpackFromRegLoc(DAG, Chain, VA, DL, Ins[InsIdx], *this);
     else
@@ -24369,6 +24537,43 @@ SDValue RISCVTargetLowering::LowerCall(CallLoweringInfo &CLI,
       continue;
     }
 
+    // Handle passing 64-bit vector on RV32 as a special case.
+    if (VA.getLocVT() == MVT::i32 &&
+        Subtarget.isPExtPackedType(VA.getValVT()) &&
+        VA.getValVT().getSizeInBits() == 64) {
+      assert(VA.isRegLoc() && "Expected register VA assignment");
+      assert(VA.needsCustom());
+      SDValue SplitGPRVec =
+          DAG.getNode(RISCVISD::SplitGPRVec, DL,
+                      DAG.getVTList(MVT::i32, MVT::i32), ArgValue);
+      SDValue Lo = SplitGPRVec.getValue(0);
+      SDValue Hi = SplitGPRVec.getValue(1);
+
+      Register RegLo = VA.getLocReg();
+      RegsToPass.push_back(std::make_pair(RegLo, Lo));
+
+      // Get the CCValAssign for the Hi part.
+      CCValAssign &HiVA = ArgLocs[++i];
+
+      if (HiVA.isMemLoc()) {
+        // Second half of vector is passed on the stack.
+        if (!StackPtr.getNode())
+          StackPtr = DAG.getCopyFromReg(Chain, DL, RISCV::X2, PtrVT);
+        SDValue Address =
+            DAG.getNode(ISD::ADD, DL, PtrVT, StackPtr,
+                        DAG.getIntPtrConstant(HiVA.getLocMemOffset(), DL));
+        // Emit the store.
+        MemOpChains.push_back(DAG.getStore(
+            Chain, DL, Hi, Address,
+            MachinePointerInfo::getStack(MF, HiVA.getLocMemOffset())));
+      } else {
+        // Second half of vector is passed in another GPR.
+        Register RegHigh = HiVA.getLocReg();
+        RegsToPass.push_back(std::make_pair(RegHigh, Hi));
+      }
+      continue;
+    }
+
     // Promote the value if needed.
     // For now, only handle fully promoted and indirect arguments.
     if (VA.getLocInfo() == CCValAssign::Indirect) {
@@ -24579,6 +24784,17 @@ SDValue RISCVTargetLowering::LowerCall(CallLoweringInfo &CLI,
         std::swap(Lo, Hi);
 
       RetValue = DAG.getNode(RISCVISD::BuildPairF64, DL, MVT::f64, Lo, Hi);
+    } else if (VA.getLocVT() == MVT::i32 &&
+               Subtarget.isPExtPackedType(VA.getValVT()) &&
+               VA.getValVT().getSizeInBits() == 64) {
+      assert(VA.needsCustom());
+      SDValue RetValue2 = DAG.getCopyFromReg(Chain, DL, RVLocs[++i].getLocReg(),
+                                             MVT::i32, Glue);
+      Chain = RetValue2.getValue(1);
+      Glue = RetValue2.getValue(2);
+
+      RetValue = DAG.getNode(RISCVISD::BuildPairGPRVec, DL, VA.getValVT(),
+                             RetValue, RetValue2);
     } else
       RetValue = convertLocVTToValVT(DAG, RetValue, VA, DL, Subtarget);
 
@@ -24642,6 +24858,32 @@ RISCVTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,
       Register RegLo = VA.getLocReg();
       Register RegHi = RVLocs[++i].getLocReg();
 
+      if (Subtarget.isRegisterReservedByUser(RegLo) ||
+          Subtarget.isRegisterReservedByUser(RegHi))
+        MF.getFunction().getContext().diagnose(DiagnosticInfoUnsupported{
+            MF.getFunction(),
+            "Return value register required, but has been reserved."});
+
+      Chain = DAG.getCopyToReg(Chain, DL, RegLo, Lo, Glue);
+      Glue = Chain.getValue(1);
+      RetOps.push_back(DAG.getRegister(RegLo, MVT::i32));
+      Chain = DAG.getCopyToReg(Chain, DL, RegHi, Hi, Glue);
+      Glue = Chain.getValue(1);
+      RetOps.push_back(DAG.getRegister(RegHi, MVT::i32));
+    } else if (VA.getLocVT() == MVT::i32 &&
+               Subtarget.isPExtPackedType(VA.getValVT()) &&
+               VA.getValVT().getSizeInBits() == 64) {
+      // Handle returning 64-bit vector on RV32.
+      assert(VA.isRegLoc() && "Expected return via registers");
+      assert(VA.needsCustom());
+      SDValue SplitGPRVec = DAG.getNode(RISCVISD::SplitGPRVec, DL,
+                                        DAG.getVTList(MVT::i32, MVT::i32), Val);
+      SDValue Lo = SplitGPRVec.getValue(0);
+      SDValue Hi = SplitGPRVec.getValue(1);
+
+      Register RegLo = VA.getLocReg();
+      Register RegHi = RVLocs[++i].getLocReg();
+
       if (Subtarget.isRegisterReservedByUser(RegLo) ||
           Subtarget.isRegisterReservedByUser(RegHi))
         MF.getFunction().getContext().diagnose(DiagnosticInfoUnsupported{
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoP.td b/llvm/lib/Target/RISCV/RISCVInstrInfoP.td
index eb943e8e9569d..67b8a045f7870 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoP.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoP.td
@@ -1840,6 +1840,11 @@ let Predicates = [HasStdExtP, IsRV32] in {
 // Codegen patterns
 //===----------------------------------------------------------------------===//
 
+// Pattern class for GPRPair operations
+class PatGprPairGprPair<SDPatternOperator OpNode, RVInst Inst, ValueType vt>
+    : Pat<(vt (OpNode (vt GPRPair:$rs1), (vt GPRPair:$rs2))),
+          (Inst GPR:$rs1, GPR:$rs2)>;
+
 def riscv_absw : RVSDNode<"ABSW", SDT_RISCVIntUnaryOpW>;
 def riscv_clsw : RVSDNode<"CLSW", SDT_RISCVIntUnaryOpW>;
 
@@ -1937,6 +1942,19 @@ def IncImm : SDNodeXForm<imm, [{
                                      N->getValueType(0));
 }]>;
 
+def SDT_RISCVBuildPairGPRVec : SDTypeProfile<1, 2, [SDTCisSubVecOfVec<1, 0>,
+                                                    SDTCisSameAs<1, 2>]>;
+def SDT_RISCVSplitGPRVec : SDTypeProfile<2, 1, [SDTCisSubVecOfVec<0, 2>,
+                                                SDTCisSameAs<0, 1>]>;
+
+// These nodes are used to handle 64-bit vectors on R32. They're equivalent to
+// concat_vectors and a pair of extract_subvectors. We're using custom nodes to
+// prevent some generic DAG combines from pushing the extract_subvectors
+// through 64-bit operations. These may be temporary.
+def RISCVBuildPairGPRVec : RVSDNode<"BuildPairGPRVec",
+                                    SDT_RISCVBuildPairGPRVec>;
+def RISCVSplitGPRVec     : RVSDNode<"SplitGPRVec", SDT_RISCVSplitGPRVec>;
+
 let Predicates = [HasStdExtP] in {
 
   def : PatGpr<abs, ABS>;
@@ -2187,6 +2205,68 @@ let Predicates = [HasStdExtP, IsRV32] in {
   // Build vector patterns
   def : Pat<(v2i16 (build_vector (XLenVT GPR:$a), (XLenVT GPR:$b))),
             (PACK GPR:$a, GPR:$b)>;
+
+  // Basic 8-bit arithmetic patterns
+  def : PatGprPairGprPair<add, PADD_DB, v8i8>;
+  def : PatGprPairGprPair<sub, PSUB_DB, v8i8>;
+
+  // Basic 16-bit arithmetic patterns
+  def : PatGprPairGprPair<add, PADD_DH, v4i16>;
+  def : PatGprPairGprPair<sub, PSUB_DH, v4i16>;
+
+  // Basic 32-bit arithmetic patterns
+  def : PatGprPairGprPair<add, PADD_DW, v2i32>;
+  def : PatGprPairGprPair<sub, PSUB_DW, v2i32>;
+
+  // 8-bit saturating add/sub patterns
+  def : PatGprPairGprPair<saddsat, PSADD_DB, v8i8>;
+  def : PatGprPairGprPair<uaddsat, PSADDU_DB, v8i8>;
+  def : PatGprPairGprPair<ssubsat, PSSUB_DB, v8i8>;
+  def : PatGprPairGprPair<usubsat, PSSUBU_DB, v8i8>;
+
+  // 16-bit saturating add/sub patterns
+  def : PatGprPairGprPair<saddsat, PSADD_DH, v4i16>;
+  def : PatGprPairGprPair<uaddsat, PSADDU_DH, v4i16>;
+  def : PatGprPairGprPair<ssubsat, PSSUB_DH, v4i16>;
+  def : PatGprPairGprPair<usubsat, PSSUBU_DH, v4i16>;
+
+  // 32-bit saturating add/sub patterns
+  def : PatGprPairGprPair<saddsat, PSADD_DW, v2i32>;
+  def : PatGprPairGprPair<uaddsat, PSADDU_DW, v2i32>;
+  def : PatGprPairGprPair<ssubsat, PSSUB_DW, v2i32>;
+  def : PatGprPairGprPair<usubsat, PSSUBU_DW, v2i32>;
+
+  // 8-bit averaging patterns
+  def : PatGprPairGprPair<avgfloors, PAADD_DB, v8i8>;
+  def : PatGprPairGprPair<avgflooru, PAADDU_DB, v8i8>;
+  def : PatGprPairGprPair<riscv_asub, PASUB_DB, v8i8>;
+  def : PatGprPairGprPair<riscv_asubu, PASUBU_DB, v8i8>;
+
+  // 16-bit averaging patterns
+  def : PatGprPairGprPair<avgfloors, PAADD_DH, v4i16>;
+  def : PatGprPairGprPair<avgflooru, PAADDU_DH, v4i16>;
+  def : PatGprPairGprPair<riscv_asub, PASUB_DH, v4i16>;
+  def : PatGprPairGprPair<riscv_asubu, PASUBU_DH, v4i16>;
+
+  // 32-bit averaging patterns
+  def : PatGprPairGprPair<avgfloors, PAADD_DW, v2i32>;
+  def : PatGprPairGprPair<avgflooru, PAADDU_DW, v2i32>;
+  def : PatGprPairGprPair<riscv_asub, PASUB_DW, v2i32>;
+  def : PatGprPairGprPair<riscv_asubu, PASUBU_DW, v2i32>;
+
+  // [s|u]min/[s|u]max patterns
+  def : PatGprPairGprPair<smin, PMIN_DB, v8i8>;
+  def : PatGprPairGprPair<umin, PMINU_DB, v8i8>;
+  def : PatGprPairGprPair<smin, PMIN_DH, v4i16>;
+  def : PatGprPairGprPair<umin, PMINU_DH, v4i16>;
+  def : PatGprPairGprPair<smin, PMIN_DW, v2i32>;
+  def : PatGprPairGprPair<umin, PMINU_DW, v2i32>;
+  def : PatGprPairGprPair<smax, PMAX_DB, v8i8>;
+  def : PatGprPairGprPair<umax, PMAXU_DB, v8i8>;
+  def : PatGprPairGprPair<smax, PMAX_DH, v4i16>;
+  def : PatGprPairGprPair<umax, PMAXU_DH, v4i16>;
+  def : PatGprPairGprPair<smax, PMAX_DW, v2i32>;
+  def : PatGprPairGprPair<umax, PMAXU_DW, v2i32>;
 } // Predicates = [HasStdExtP, IsRV32]
 
 let Predicates = [HasStdExtP, IsRV64] in {
diff --git a/llvm/lib/Target/RISCV/RISCVRegisterInfo.td b/llvm/lib/Target/RISCV/RISCVRegisterInfo.td
index d3a387d57b338..58af1f863f7bf 100644
--- a/llvm/lib/Target/RISCV/RISCVRegisterInfo.td
+++ b/llvm/lib/Target/RISCV/RISCVRegisterInfo.td
@@ -273,6 +273,12 @@ def XLenFVT : ValueTypeByHwMode<[RV64],
                                 [f64]>;
 def XLenPairFVT : ValueTypeByHwMode<[RV32],
                                     [f64]>;
+def XLenPairVecI8VT : ValueTypeByHwMode<[RV32],
+                                        [v8i8]>;
+def XLenPairVecI16VT : ValueTypeByHwMode<[RV32],
+                                         [v4i16]>;
+def XLenPairVecI32VT : ValueTypeByHwMode<[RV32],
+                                         [v2i32]>;
 
 // P extension
 def XLenVecI8VT : ValueTypeByHwMode<[RV32, RV64],
@@ -436,7 +442,7 @@ let RegAltNameIndices = [ABIRegAltName] in {
 }
 
 let RegInfos = XLenPairRI, CopyCost = 2 in {
-def GPRPair : RISCVRegisterClass<[XLenPairVT, XLenPairFVT], 64, (add
+def GPRPair : RISCVRegisterClass<[XLenPairVT, XLenPairFVT, XLenPairVecI8VT, XLenPairVecI16VT, XLenPairVecI32VT], 64, (add
     X10_X11, X12_X13, X14_X15, X16_X17,
     X6_X7,
     X28_X29, X30_X31,
@@ -445,9 +451,9 @@ def GPRPair : RISCVRegisterClass<[XLenPairVT, XLenPairFVT], 64, (add
     X0_Pair, X2_X3, X4_X5
 )>;
 
-def GPRPairNoX0 : RISCVRegisterClass<[XLenPairVT, XLenPairFVT], 64, (sub GPRPair, X0_Pair)>;
+def GPRPairNoX0 : RISCVRegisterClass<[XLenPairVT, XLenPairFVT, XLenPairVecI8VT, XLenPairVecI16VT, XLenPairVecI32VT], 64, (sub GPRPair, X0_Pair)>;
 
-def GPRPairC : RISCVRegisterClass<[XLenPairVT, XLenPairFVT], 64, (add
+def GPRPairC : RISCVRegisterClass<[XLenPairVT, XLenPairFVT, XLenPairVecI8VT, XLenPairVecI16VT, XLenPairVecI32VT], 64, (add
   X10_X11, X12_X13, X14_X15, X8_X9
 )>;
 } // let RegInfos = XLenPairRI, CopyCost = 2
diff --git a/llvm/lib/Target/RISCV/RISCVSubtarget.cpp b/llvm/lib/Target/RISCV/RISCVSubtarget.cpp
index ab342cb5215e3..b36492cbb27d6 100644
--- a/llvm/lib/Target/RISCV/RISCVSubtarget.cpp
+++ b/llvm/lib/Target/RISCV/RISCVSubtarget.cpp
@@ -166,14 +166,16 @@ bool RISCVSubtarget::useConstantPoolForLargeInts() const {
   return !RISCVDisableUsingConstantPoolForLargeInts;
 }
 
-// Returns true if VT is a P extension packed SIMD type that fits in XLen.
+// Returns true if VT is a P extension packed SIMD type.
 bool RISCVSubtarget::isPExtPackedType(MVT VT) const {
   if (!HasStdExtP)
     return false;
 
-  if (is64Bit())
-    return VT == MVT::v8i8 || VT == MVT::v4i16 || VT == MVT::v2i32;
-  return VT == MVT::v4i8 || VT == MVT::v2i16;
+  // RV32 supports 32-bit and 64-bit vectors. RV64 only support 64-bit vectors.
+  if (!is64Bit() && (VT == MVT::v4i8 || VT == MVT::v2i16))
+    return true;
+
+  return VT == MVT::v8i8 || VT == MVT::v4i16 || VT == MVT::v2i32;
 }
 
 unsigned RISCVSubtarget::getMaxBuildIntsCost() const {
diff --git a/llvm/test/CodeGen/RISCV/calling-conv-p-ext-vector.ll b/llvm/test/CodeGen/RISCV/calling-conv-p-ext-vector.ll
index 9455a285924f2..6e5da4ee5b94e 100644
--- a/llvm/test/CodeGen/RISCV/calling-conv-p-ext-vector.ll
+++ b/llvm/test/CodeGen/RISCV/calling-conv-p-ext-vector.ll
@@ -27,8 +27,7 @@ define <2 x i16> @test_cc_v2i16(<2 x i16> %a, <2 x i16> %b) {
 define <8 x i8> @test_cc_v8i8(<8 x i8> %a, <8 x i8> %b) {
 ; RV32-LABEL: test_cc_v8i8:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    padd.b a0, a0, a2
-; RV32-NEXT:    padd.b a1, a1, a3
+; RV32-NEXT:    padd.db a0, a0, a2
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_cc_v8i8:
@@ -42,8 +41,7 @@ define <8 x i8> @test_cc_v8i8(<8 x i8> %a, <8 x i8> %b) {
 define <4 x i16> @test_cc_v4i16(<4 x i16> %a, <4 x i16> %b) {
 ; RV32-LABEL: test_cc_v4i16:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    padd.h a0, a0, a2
-; RV32-NEXT:    padd.h a1, a1, a3
+; RV32-NEXT:    padd.dh a0, a0, a2
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_cc_v4i16:
@@ -57,8 +55,7 @@ define <4 x i16> @test_cc_v4i16(<4 x i16> %a, <4 x i16> %b) {
 define <2 x i32> @test_cc_v2i32(<2 x i32> %a, <2 x i32> %b) {
 ; RV32-LABEL: test_cc_v2i32:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    add a0, a0, a2
-; RV32-NEXT:    add a1, a1, a3
+; RV32-NEXT:    padd.dw a0, a0, a2
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_cc_v2i32:
@@ -73,22 +70,8 @@ define <2 x i32> @test_cc_v2i32(<2 x i32> %a, <2 x i32> %b) {
 define <16 x i8> @test_cc_v16i8(<16 x i8> %a, <16 x i8> %b) {
 ; RV32-LABEL: test_cc_v16i8:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    lw a3, 0(a2)
-; RV32-NEXT:    lw a4, 4(a2)
-; RV32-NEXT:    lw a5, 8(a2)
-; RV32-NEXT:    lw a2, 12(a2)
-; RV32-NEXT:    lw a6, 0(a1)
-; RV32-NEXT:    lw a7, 4(a1)
-; RV32-NEXT:    lw t0, 8(a1)
-; RV32-NEXT:    lw a1, 12(a1)
-; RV32-NEXT:    padd.b a3, a6, a3
-; RV32-NEXT:    padd.b a4, a7, a4
-; RV32-NEXT:    padd.b a5, t0, a5
-; RV32-NEXT:    padd.b a1, a1, a2
-; RV32-NEXT:    sw a3, 0(a0)
-; RV32-NEXT:    sw a4, 4(a0)
-; RV32-NEXT:    sw a5, 8(a0)
-; RV32-NEXT:    sw a1, 12(a0)
+; RV32-NEXT:    padd.db a0, a0, a4
+; RV32-NEXT:    padd.db a2, a2, a6
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_cc_v16i8:
@@ -103,22 +86,8 @@ define <16 x i8> @test_cc_v16i8(<16 x i8> %a, <16 x i8> %b) {
 define <8 x i16> @test_cc_v8i16(<8 x i16> %a, <8 x i16> %b) {
 ; RV32-LABEL: test_cc_v8i16:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    lw a3, 0(a2)
-; RV32-NEXT:    lw a4, 4(a2)
-; RV32-NEXT:    lw a5, 8(a2)
-; RV32-NEXT:    lw a2, 12(a2)
-; RV32-NEXT:    lw a6, 0(a1)
-; RV32-NEXT:    lw a7, 4(a1)
-; RV32-NEXT:    lw t0, 8(a1)
-; RV32-NEXT:    lw a1, 12(a1)
-; RV32-NEXT:    padd.h a3, a6, a3
-; RV32-NEXT:    padd.h a4, a7, a4
-; RV32-NEXT:    padd.h a5, t0, a5
-; RV32-NEXT:    padd.h a1, a1, a2
-; RV32-NEXT:    sw a3, 0(a0)
-; RV32-NEXT:    sw a4, 4(a0)
-; RV32-NEXT:    sw a5, 8(a0)
-; RV32-NEXT:    sw a1, 12(a0)
+; RV32-NEXT:    padd.dh a0, a0, a4
+; RV32-NEXT:    padd.dh a2, a2, a6
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_cc_v8i16:
@@ -133,22 +102,8 @@ define <8 x i16> @test_cc_v8i16(<8 x i16> %a, <8 x i16> %b) {
 define <4 x i32> @test_cc_v4i32(<4 x i32> %a, <4 x i32> %b) {
 ; RV32-LABEL: test_cc_v4i32:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    lw a3, 0(a2)
-; RV32-NEXT:    lw a4, 4(a2)
-; RV32-NEXT:    lw a5, 8(a2)
-; RV32-NEXT:    lw a2, 12(a2)
-; RV32-NEXT:    lw a6, 0(a1)
-; RV32-NEXT:    lw a7, 4(a1)
-; RV32-NEXT:    lw t0, 8(a1)
-; RV32-NEXT:    lw a1, 12(a1)
-; RV32-NEXT:    add a3, a6, a3
-; RV32-NEXT:    add a4, a7, a4
-; RV32-NEXT:    add a5, t0, a5
-; RV32-NEXT:    add a1, a1, a2
-; RV32-NEXT:    sw a3, 0(a0)
-; RV32-NEXT:    sw a4, 4(a0)
-; RV32-NEXT:    sw a5, 8(a0)
-; RV32-NEXT:    sw a1, 12(a0)
+; RV32-NEXT:    padd.dw a0, a0, a4
+; RV32-NEXT:    padd.dw a2, a2, a6
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_cc_v4i32:
@@ -246,46 +201,24 @@ declare <16 x i8> @external_v16i8(<16 x i8>, <16 x i8>)
 define <16 x i8> @test_call_v16i8(<16 x i8> %a, <16 x i8> %b) {
 ; RV32-LABEL: test_call_v16i8:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    addi sp, sp, -64
-; RV32-NEXT:    .cfi_def_cfa_offset 64
-; RV32-NEXT:    sw ra, 60(sp) # 4-byte Folded Spill
-; RV32-NEXT:    sw s0, 56(sp) # 4-byte Folded Spill
+; RV32-NEXT:    addi sp, sp, -16
+; RV32-NEXT:    .cfi_def_cfa_offset 16
+; RV32-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
 ; RV32-NEXT:    .cfi_offset ra, -4
-; RV32-NEXT:    .cfi_offset s0, -8
-; RV32-NEXT:    lw a3, 0(a2)
-; RV32-NEXT:    lw a4, 4(a2)
-; RV32-NEXT:    lw a5, 8(a2)
-; RV32-NEXT:    lw a6, 12(a2)
-; RV32-NEXT:    lw a2, 0(a1)
-; RV32-NEXT:    lw a7, 4(a1)
-; RV32-NEXT:    lw t0, 8(a1)
-; RV32-NEXT:    lw a1, 12(a1)
-; RV32-NEXT:    mv s0, a0
-; RV32-NEXT:    sw a2, 0(sp)
-; RV32-NEXT:    sw a7, 4(sp)
-; RV32-NEXT:    sw t0, 8(sp)
-; RV32-NEXT:    sw a1, 12(sp)
-; RV32-NEXT:    addi a0, sp, 32
-; RV32-NEXT:    addi a1, sp, 16
-; RV32-NEXT:    mv a2, sp
-; RV32-NEXT:    sw a3, 16(sp)
-; RV32-NEXT:    sw a4, 20(sp)
-; RV32-NEXT:    sw a5, 24(sp)
-; RV32-NEXT:    sw a6, 28(sp)
+; RV32-NEXT:    mv t0, a3
+; RV32-NEXT:    mv t1, a2
+; RV32-NEXT:    mv t2, a1
+; RV32-NEXT:    mv t3, a0
+; RV32-NEXT:    padd.dw a0, a4, zero
+; RV32-NEXT:    padd.dw a2, a6, zero
+; RV32-NEXT:    mv a4, t3
+; RV32-NEXT:    mv a5, t2
+; RV32-NEXT:    mv a6, t1
+; RV32-NEXT:    mv a7, t0
 ; RV32-NEXT:    call external_v16i8
-; RV32-NEXT:    lw a0, 32(sp)
-; RV32-NEXT:    lw a1, 36(sp)
-; RV32-NEXT:    lw a2, 40(sp)
-; RV32-NEXT:    lw a3, 44(sp)
-; RV32-NEXT:    sw a0, 0(s0)
-; RV32-NEXT:    sw a1, 4(s0)
-; RV32-NEXT:    sw a2, 8(s0)
-; RV32-NEXT:    sw a3, 12(s0)
-; RV32-NEXT:    lw ra, 60(sp) # 4-byte Folded Reload
-; RV32-NEXT:    lw s0, 56(sp) # 4-byte Folded Reload
+; RV32-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
 ; RV32-NEXT:    .cfi_restore ra
-; RV32-NEXT:    .cfi_restore s0
-; RV32-NEXT:    addi sp, sp, 64
+; RV32-NEXT:    addi sp, sp, 16
 ; RV32-NEXT:    .cfi_def_cfa_offset 0
 ; RV32-NEXT:    ret
 ;
@@ -329,9 +262,9 @@ define <2 x i16> @test_exhaust(i64 %dummy, i64 %dummy2, i64 %dummy3, i64 %dummy4
 define <4 x i16> @test_exhaust_2xlen_rv32(i64 %dummy, i64 %dummy2, i64 %dummy3, i32 %dummy4, <4 x i16> %b) {
 ; RV32-LABEL: test_exhaust_2xlen_rv32:
 ; RV32:       # %bb.0:
+; RV32-NEXT:    mv a0, a7
 ; RV32-NEXT:    lw a1, 0(sp)
-; RV32-NEXT:    padd.h a0, a7, a7
-; RV32-NEXT:    padd.h a1, a1, a1
+; RV32-NEXT:    padd.dh a0, a0, a0
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_exhaust_2xlen_rv32:
@@ -345,10 +278,9 @@ define <4 x i16> @test_exhaust_2xlen_rv32(i64 %dummy, i64 %dummy2, i64 %dummy3,
 define <4 x i16> @test_exhaust_2xlen_rv32_2(i64 %dummy, i64 %dummy2, i64 %dummy3, i64 %dummy4, <4 x i16> %b) {
 ; RV32-LABEL: test_exhaust_2xlen_rv32_2:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    lw a0, 0(sp)
 ; RV32-NEXT:    lw a1, 4(sp)
-; RV32-NEXT:    padd.h a0, a0, a0
-; RV32-NEXT:    padd.h a1, a1, a1
+; RV32-NEXT:    lw a0, 0(sp)
+; RV32-NEXT:    padd.dh a0, a0, a0
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_exhaust_2xlen_rv32_2:
diff --git a/llvm/test/CodeGen/RISCV/rvp-narrowing-shift-trunc.ll b/llvm/test/CodeGen/RISCV/rvp-narrowing-shift-trunc.ll
index 4fe4ed66fa842..0f0e70324fb92 100644
--- a/llvm/test/CodeGen/RISCV/rvp-narrowing-shift-trunc.ll
+++ b/llvm/test/CodeGen/RISCV/rvp-narrowing-shift-trunc.ll
@@ -54,12 +54,26 @@ define i32 @trunc_ashr_v2i32_to_v2i16(i64 %a.coerce) {
 define i32 @trunc_lshr_v4i16_to_v4i8(i64 %a.coerce) {
 ; CHECK-RV32-LABEL: trunc_lshr_v4i16_to_v4i8:
 ; CHECK-RV32:       # %bb.0:
-; CHECK-RV32-NEXT:    psrli.h a1, a1, 4
-; CHECK-RV32-NEXT:    psrli.h a0, a0, 4
-; CHECK-RV32-NEXT:    srli a3, a1, 16
-; CHECK-RV32-NEXT:    srli a2, a0, 16
-; CHECK-RV32-NEXT:    ppaire.db a0, a0, a2
+; CHECK-RV32-NEXT:    addi sp, sp, -16
+; CHECK-RV32-NEXT:    .cfi_def_cfa_offset 16
+; CHECK-RV32-NEXT:    sw a0, 0(sp)
+; CHECK-RV32-NEXT:    sw a1, 4(sp)
+; CHECK-RV32-NEXT:    lw a0, 0(sp)
+; CHECK-RV32-NEXT:    lw a1, 4(sp)
+; CHECK-RV32-NEXT:    sw a0, 8(sp)
+; CHECK-RV32-NEXT:    sw a1, 12(sp)
+; CHECK-RV32-NEXT:    lhu a0, 12(sp)
+; CHECK-RV32-NEXT:    lhu a1, 8(sp)
+; CHECK-RV32-NEXT:    lhu a2, 14(sp)
+; CHECK-RV32-NEXT:    lhu a3, 10(sp)
+; CHECK-RV32-NEXT:    srli a5, a0, 4
+; CHECK-RV32-NEXT:    srli a4, a1, 4
+; CHECK-RV32-NEXT:    srli a1, a2, 4
+; CHECK-RV32-NEXT:    srli a0, a3, 4
+; CHECK-RV32-NEXT:    ppaire.db a0, a4, a0
 ; CHECK-RV32-NEXT:    pack a0, a0, a1
+; CHECK-RV32-NEXT:    addi sp, sp, 16
+; CHECK-RV32-NEXT:    .cfi_def_cfa_offset 0
 ; CHECK-RV32-NEXT:    ret
 ;
 ; CHECK-RV64-LABEL: trunc_lshr_v4i16_to_v4i8:
diff --git a/llvm/test/CodeGen/RISCV/rvp-simd-64.ll b/llvm/test/CodeGen/RISCV/rvp-simd-64.ll
index 4d12032dd0c80..bba99b9a0cd64 100644
--- a/llvm/test/CodeGen/RISCV/rvp-simd-64.ll
+++ b/llvm/test/CodeGen/RISCV/rvp-simd-64.ll
@@ -10,8 +10,7 @@
 define <4 x i16> @test_padd_h(<4 x i16> %a, <4 x i16> %b) {
 ; RV32-LABEL: test_padd_h:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    padd.h a0, a0, a2
-; RV32-NEXT:    padd.h a1, a1, a3
+; RV32-NEXT:    padd.dh a0, a0, a2
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_padd_h:
@@ -25,8 +24,7 @@ define <4 x i16> @test_padd_h(<4 x i16> %a, <4 x i16> %b) {
 define <4 x i16> @test_psub_h(<4 x i16> %a, <4 x i16> %b) {
 ; RV32-LABEL: test_psub_h:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    psub.h a0, a0, a2
-; RV32-NEXT:    psub.h a1, a1, a3
+; RV32-NEXT:    psub.dh a0, a0, a2
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_psub_h:
@@ -41,8 +39,7 @@ define <4 x i16> @test_psub_h(<4 x i16> %a, <4 x i16> %b) {
 define <8 x i8> @test_padd_b(<8 x i8> %a, <8 x i8> %b) {
 ; RV32-LABEL: test_padd_b:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    padd.b a0, a0, a2
-; RV32-NEXT:    padd.b a1, a1, a3
+; RV32-NEXT:    padd.db a0, a0, a2
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_padd_b:
@@ -56,8 +53,7 @@ define <8 x i8> @test_padd_b(<8 x i8> %a, <8 x i8> %b) {
 define <8 x i8> @test_psub_b(<8 x i8> %a, <8 x i8> %b) {
 ; RV32-LABEL: test_psub_b:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    psub.b a0, a0, a2
-; RV32-NEXT:    psub.b a1, a1, a3
+; RV32-NEXT:    psub.db a0, a0, a2
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_psub_b:
@@ -72,8 +68,8 @@ define <8 x i8> @test_psub_b(<8 x i8> %a, <8 x i8> %b) {
 define <4 x i16> @test_and_h(<4 x i16> %a, <4 x i16> %b) {
 ; RV32-LABEL: test_and_h:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    and a0, a0, a2
 ; RV32-NEXT:    and a1, a1, a3
+; RV32-NEXT:    and a0, a0, a2
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_and_h:
@@ -87,8 +83,8 @@ define <4 x i16> @test_and_h(<4 x i16> %a, <4 x i16> %b) {
 define <4 x i16> @test_or_h(<4 x i16> %a, <4 x i16> %b) {
 ; RV32-LABEL: test_or_h:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    or a0, a0, a2
 ; RV32-NEXT:    or a1, a1, a3
+; RV32-NEXT:    or a0, a0, a2
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_or_h:
@@ -102,8 +98,8 @@ define <4 x i16> @test_or_h(<4 x i16> %a, <4 x i16> %b) {
 define <4 x i16> @test_xor_h(<4 x i16> %a, <4 x i16> %b) {
 ; RV32-LABEL: test_xor_h:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    xor a0, a0, a2
 ; RV32-NEXT:    xor a1, a1, a3
+; RV32-NEXT:    xor a0, a0, a2
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_xor_h:
@@ -117,8 +113,8 @@ define <4 x i16> @test_xor_h(<4 x i16> %a, <4 x i16> %b) {
 define <4 x i16> @test_andn_h(<4 x i16> %a, <4 x i16> %b) {
 ; RV32-LABEL: test_andn_h:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    andn a0, a0, a2
 ; RV32-NEXT:    andn a1, a1, a3
+; RV32-NEXT:    andn a0, a0, a2
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_andn_h:
@@ -133,8 +129,8 @@ define <4 x i16> @test_andn_h(<4 x i16> %a, <4 x i16> %b) {
 define <4 x i16> @test_orn_h(<4 x i16> %a, <4 x i16> %b) {
 ; RV32-LABEL: test_orn_h:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    orn a0, a0, a2
 ; RV32-NEXT:    orn a1, a1, a3
+; RV32-NEXT:    orn a0, a0, a2
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_orn_h:
@@ -149,8 +145,8 @@ define <4 x i16> @test_orn_h(<4 x i16> %a, <4 x i16> %b) {
 define <4 x i16> @test_xnor_h(<4 x i16> %a, <4 x i16> %b) {
 ; RV32-LABEL: test_xnor_h:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    xnor a0, a2, a0
 ; RV32-NEXT:    xnor a1, a3, a1
+; RV32-NEXT:    xnor a0, a2, a0
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_xnor_h:
@@ -166,8 +162,8 @@ define <4 x i16> @test_xnor_h(<4 x i16> %a, <4 x i16> %b) {
 define <8 x i8> @test_and_b(<8 x i8> %a, <8 x i8> %b) {
 ; RV32-LABEL: test_and_b:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    and a0, a0, a2
 ; RV32-NEXT:    and a1, a1, a3
+; RV32-NEXT:    and a0, a0, a2
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_and_b:
@@ -181,8 +177,8 @@ define <8 x i8> @test_and_b(<8 x i8> %a, <8 x i8> %b) {
 define <8 x i8> @test_or_b(<8 x i8> %a, <8 x i8> %b) {
 ; RV32-LABEL: test_or_b:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    or a0, a0, a2
 ; RV32-NEXT:    or a1, a1, a3
+; RV32-NEXT:    or a0, a0, a2
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_or_b:
@@ -196,8 +192,8 @@ define <8 x i8> @test_or_b(<8 x i8> %a, <8 x i8> %b) {
 define <8 x i8> @test_xor_b(<8 x i8> %a, <8 x i8> %b) {
 ; RV32-LABEL: test_xor_b:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    xor a0, a0, a2
 ; RV32-NEXT:    xor a1, a1, a3
+; RV32-NEXT:    xor a0, a0, a2
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_xor_b:
@@ -211,8 +207,8 @@ define <8 x i8> @test_xor_b(<8 x i8> %a, <8 x i8> %b) {
 define <8 x i8> @test_andn_b(<8 x i8> %a, <8 x i8> %b) {
 ; RV32-LABEL: test_andn_b:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    andn a0, a0, a2
 ; RV32-NEXT:    andn a1, a1, a3
+; RV32-NEXT:    andn a0, a0, a2
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_andn_b:
@@ -227,8 +223,8 @@ define <8 x i8> @test_andn_b(<8 x i8> %a, <8 x i8> %b) {
 define <8 x i8> @test_orn_b(<8 x i8> %a, <8 x i8> %b) {
 ; RV32-LABEL: test_orn_b:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    orn a0, a0, a2
 ; RV32-NEXT:    orn a1, a1, a3
+; RV32-NEXT:    orn a0, a0, a2
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_orn_b:
@@ -243,8 +239,8 @@ define <8 x i8> @test_orn_b(<8 x i8> %a, <8 x i8> %b) {
 define <8 x i8> @test_xnor_b(<8 x i8> %a, <8 x i8> %b) {
 ; RV32-LABEL: test_xnor_b:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    xnor a0, a2, a0
 ; RV32-NEXT:    xnor a1, a3, a1
+; RV32-NEXT:    xnor a0, a2, a0
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_xnor_b:
@@ -260,8 +256,8 @@ define <8 x i8> @test_xnor_b(<8 x i8> %a, <8 x i8> %b) {
 define <2 x i32> @test_and_w(<2 x i32> %a, <2 x i32> %b) {
 ; RV32-LABEL: test_and_w:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    and a0, a0, a2
 ; RV32-NEXT:    and a1, a1, a3
+; RV32-NEXT:    and a0, a0, a2
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_and_w:
@@ -275,8 +271,8 @@ define <2 x i32> @test_and_w(<2 x i32> %a, <2 x i32> %b) {
 define <2 x i32> @test_or_w(<2 x i32> %a, <2 x i32> %b) {
 ; RV32-LABEL: test_or_w:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    or a0, a0, a2
 ; RV32-NEXT:    or a1, a1, a3
+; RV32-NEXT:    or a0, a0, a2
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_or_w:
@@ -290,8 +286,8 @@ define <2 x i32> @test_or_w(<2 x i32> %a, <2 x i32> %b) {
 define <2 x i32> @test_xor_w(<2 x i32> %a, <2 x i32> %b) {
 ; RV32-LABEL: test_xor_w:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    xor a0, a0, a2
 ; RV32-NEXT:    xor a1, a1, a3
+; RV32-NEXT:    xor a0, a0, a2
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_xor_w:
@@ -305,8 +301,8 @@ define <2 x i32> @test_xor_w(<2 x i32> %a, <2 x i32> %b) {
 define <2 x i32> @test_andn_w(<2 x i32> %a, <2 x i32> %b) {
 ; RV32-LABEL: test_andn_w:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    andn a0, a0, a2
 ; RV32-NEXT:    andn a1, a1, a3
+; RV32-NEXT:    andn a0, a0, a2
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_andn_w:
@@ -321,8 +317,8 @@ define <2 x i32> @test_andn_w(<2 x i32> %a, <2 x i32> %b) {
 define <2 x i32> @test_orn_w(<2 x i32> %a, <2 x i32> %b) {
 ; RV32-LABEL: test_orn_w:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    orn a0, a0, a2
 ; RV32-NEXT:    orn a1, a1, a3
+; RV32-NEXT:    orn a0, a0, a2
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_orn_w:
@@ -337,8 +333,8 @@ define <2 x i32> @test_orn_w(<2 x i32> %a, <2 x i32> %b) {
 define <2 x i32> @test_xnor_w(<2 x i32> %a, <2 x i32> %b) {
 ; RV32-LABEL: test_xnor_w:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    xnor a0, a2, a0
 ; RV32-NEXT:    xnor a1, a3, a1
+; RV32-NEXT:    xnor a0, a2, a0
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_xnor_w:
@@ -353,8 +349,8 @@ define <2 x i32> @test_xnor_w(<2 x i32> %a, <2 x i32> %b) {
 define <4 x i16> @test_not_h(<4 x i16> %a) {
 ; RV32-LABEL: test_not_h:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    not a0, a0
 ; RV32-NEXT:    not a1, a1
+; RV32-NEXT:    not a0, a0
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_not_h:
@@ -368,8 +364,8 @@ define <4 x i16> @test_not_h(<4 x i16> %a) {
 define <8 x i8> @test_not_b(<8 x i8> %a) {
 ; RV32-LABEL: test_not_b:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    not a0, a0
 ; RV32-NEXT:    not a1, a1
+; RV32-NEXT:    not a0, a0
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_not_b:
@@ -383,8 +379,8 @@ define <8 x i8> @test_not_b(<8 x i8> %a) {
 define <2 x i32> @test_not_w(<2 x i32> %a) {
 ; RV32-LABEL: test_not_w:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    not a0, a0
 ; RV32-NEXT:    not a1, a1
+; RV32-NEXT:    not a0, a0
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_not_w:
@@ -399,8 +395,7 @@ define <2 x i32> @test_not_w(<2 x i32> %a) {
 define <4 x i16> @test_psadd_h(<4 x i16> %a, <4 x i16> %b) {
 ; RV32-LABEL: test_psadd_h:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    psadd.h a0, a0, a2
-; RV32-NEXT:    psadd.h a1, a1, a3
+; RV32-NEXT:    psadd.dh a0, a0, a2
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_psadd_h:
@@ -414,8 +409,7 @@ define <4 x i16> @test_psadd_h(<4 x i16> %a, <4 x i16> %b) {
 define <4 x i16> @test_psaddu_h(<4 x i16> %a, <4 x i16> %b) {
 ; RV32-LABEL: test_psaddu_h:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    psaddu.h a0, a0, a2
-; RV32-NEXT:    psaddu.h a1, a1, a3
+; RV32-NEXT:    psaddu.dh a0, a0, a2
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_psaddu_h:
@@ -430,8 +424,7 @@ define <4 x i16> @test_psaddu_h(<4 x i16> %a, <4 x i16> %b) {
 define <4 x i16> @test_pssub_h(<4 x i16> %a, <4 x i16> %b) {
 ; RV32-LABEL: test_pssub_h:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    pssub.h a0, a0, a2
-; RV32-NEXT:    pssub.h a1, a1, a3
+; RV32-NEXT:    pssub.dh a0, a0, a2
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_pssub_h:
@@ -445,8 +438,7 @@ define <4 x i16> @test_pssub_h(<4 x i16> %a, <4 x i16> %b) {
 define <4 x i16> @test_pssubu_h(<4 x i16> %a, <4 x i16> %b) {
 ; RV32-LABEL: test_pssubu_h:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    pssubu.h a0, a0, a2
-; RV32-NEXT:    pssubu.h a1, a1, a3
+; RV32-NEXT:    pssubu.dh a0, a0, a2
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_pssubu_h:
@@ -461,8 +453,7 @@ define <4 x i16> @test_pssubu_h(<4 x i16> %a, <4 x i16> %b) {
 define <8 x i8> @test_psadd_b(<8 x i8> %a, <8 x i8> %b) {
 ; RV32-LABEL: test_psadd_b:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    psadd.b a0, a0, a2
-; RV32-NEXT:    psadd.b a1, a1, a3
+; RV32-NEXT:    psadd.db a0, a0, a2
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_psadd_b:
@@ -476,8 +467,7 @@ define <8 x i8> @test_psadd_b(<8 x i8> %a, <8 x i8> %b) {
 define <8 x i8> @test_psaddu_b(<8 x i8> %a, <8 x i8> %b) {
 ; RV32-LABEL: test_psaddu_b:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    psaddu.b a0, a0, a2
-; RV32-NEXT:    psaddu.b a1, a1, a3
+; RV32-NEXT:    psaddu.db a0, a0, a2
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_psaddu_b:
@@ -492,8 +482,7 @@ define <8 x i8> @test_psaddu_b(<8 x i8> %a, <8 x i8> %b) {
 define <8 x i8> @test_pssub_b(<8 x i8> %a, <8 x i8> %b) {
 ; RV32-LABEL: test_pssub_b:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    pssub.b a0, a0, a2
-; RV32-NEXT:    pssub.b a1, a1, a3
+; RV32-NEXT:    pssub.db a0, a0, a2
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_pssub_b:
@@ -507,8 +496,7 @@ define <8 x i8> @test_pssub_b(<8 x i8> %a, <8 x i8> %b) {
 define <8 x i8> @test_pssubu_b(<8 x i8> %a, <8 x i8> %b) {
 ; RV32-LABEL: test_pssubu_b:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    pssubu.b a0, a0, a2
-; RV32-NEXT:    pssubu.b a1, a1, a3
+; RV32-NEXT:    pssubu.db a0, a0, a2
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_pssubu_b:
@@ -524,8 +512,7 @@ define <8 x i8> @test_pssubu_b(<8 x i8> %a, <8 x i8> %b) {
 define <4 x i16> @test_paadd_h(<4 x i16> %a, <4 x i16> %b) {
 ; RV32-LABEL: test_paadd_h:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    paadd.h a0, a0, a2
-; RV32-NEXT:    paadd.h a1, a1, a3
+; RV32-NEXT:    paadd.dh a0, a0, a2
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_paadd_h:
@@ -545,8 +532,7 @@ define <4 x i16> @test_paadd_h(<4 x i16> %a, <4 x i16> %b) {
 define <4 x i16> @test_paaddu_h(<4 x i16> %a, <4 x i16> %b) {
 ; RV32-LABEL: test_paaddu_h:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    paaddu.h a0, a0, a2
-; RV32-NEXT:    paaddu.h a1, a1, a3
+; RV32-NEXT:    paaddu.dh a0, a0, a2
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_paaddu_h:
@@ -564,8 +550,7 @@ define <4 x i16> @test_paaddu_h(<4 x i16> %a, <4 x i16> %b) {
 define <8 x i8> @test_paadd_b(<8 x i8> %a, <8 x i8> %b) {
 ; RV32-LABEL: test_paadd_b:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    paadd.b a0, a0, a2
-; RV32-NEXT:    paadd.b a1, a1, a3
+; RV32-NEXT:    paadd.db a0, a0, a2
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_paadd_b:
@@ -584,8 +569,7 @@ define <8 x i8> @test_paadd_b(<8 x i8> %a, <8 x i8> %b) {
 define <8 x i8> @test_paaddu_b(<8 x i8> %a, <8 x i8> %b) {
 ; RV32-LABEL: test_paaddu_b:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    paaddu.b a0, a0, a2
-; RV32-NEXT:    paaddu.b a1, a1, a3
+; RV32-NEXT:    paaddu.db a0, a0, a2
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_paaddu_b:
@@ -602,8 +586,10 @@ define <8 x i8> @test_paaddu_b(<8 x i8> %a, <8 x i8> %b) {
 define <2 x i32> @test_pabs_w(<2 x i32> %a) {
 ; RV32-LABEL: test_pabs_w:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    abs a0, a0
-; RV32-NEXT:    abs a1, a1
+; RV32-NEXT:    li a2, 0
+; RV32-NEXT:    li a3, 0
+; RV32-NEXT:    psub.dw a2, a2, a0
+; RV32-NEXT:    pmax.dw a0, a0, a2
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_pabs_w:
@@ -618,8 +604,12 @@ define <2 x i32> @test_pabs_w(<2 x i32> %a) {
 define <4 x i16> @test_pabs_h(<4 x i16> %a) {
 ; RV32-LABEL: test_pabs_h:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    pabs.h a0, a0
-; RV32-NEXT:    pabs.h a1, a1
+; RV32-NEXT:    lui a2, %hi(.LCPI38_0)
+; RV32-NEXT:    lw a4, %lo(.LCPI38_0)(a2)
+; RV32-NEXT:    addi a2, a2, %lo(.LCPI38_0)
+; RV32-NEXT:    lw a5, 4(a2)
+; RV32-NEXT:    psub.dh a2, a4, a0
+; RV32-NEXT:    pmax.dh a0, a0, a2
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_pabs_h:
@@ -633,8 +623,12 @@ define <4 x i16> @test_pabs_h(<4 x i16> %a) {
 define <8 x i8> @test_pabs_b(<8 x i8> %a) {
 ; RV32-LABEL: test_pabs_b:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    pabs.b a0, a0
-; RV32-NEXT:    pabs.b a1, a1
+; RV32-NEXT:    lui a2, %hi(.LCPI39_0)
+; RV32-NEXT:    lw a4, %lo(.LCPI39_0)(a2)
+; RV32-NEXT:    addi a2, a2, %lo(.LCPI39_0)
+; RV32-NEXT:    lw a5, 4(a2)
+; RV32-NEXT:    psub.db a2, a4, a0
+; RV32-NEXT:    pmax.db a0, a0, a2
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_pabs_b:
@@ -650,12 +644,9 @@ define <8 x i8> @test_pabs_b(<8 x i8> %a) {
 define <2 x i32> @test_pdif_w(<2 x i32> %a, <2 x i32> %b) {
 ; RV32-LABEL: test_pdif_w:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    min a4, a0, a2
-; RV32-NEXT:    max a0, a0, a2
-; RV32-NEXT:    min a2, a1, a3
-; RV32-NEXT:    max a1, a1, a3
-; RV32-NEXT:    sub a0, a0, a4
-; RV32-NEXT:    sub a1, a1, a2
+; RV32-NEXT:    pmin.dw a4, a0, a2
+; RV32-NEXT:    pmax.dw a0, a0, a2
+; RV32-NEXT:    psub.dw a0, a0, a4
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_pdif_w:
@@ -675,12 +666,9 @@ define <2 x i32> @test_pdif_w(<2 x i32> %a, <2 x i32> %b) {
 define <2 x i32> @test_pdifu_w(<2 x i32> %a, <2 x i32> %b) {
 ; RV32-LABEL: test_pdifu_w:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    minu a4, a0, a2
-; RV32-NEXT:    maxu a0, a0, a2
-; RV32-NEXT:    minu a2, a1, a3
-; RV32-NEXT:    maxu a1, a1, a3
-; RV32-NEXT:    sub a0, a0, a4
-; RV32-NEXT:    sub a1, a1, a2
+; RV32-NEXT:    pminu.dw a4, a0, a2
+; RV32-NEXT:    pmaxu.dw a0, a0, a2
+; RV32-NEXT:    psub.dw a0, a0, a4
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_pdifu_w:
@@ -700,8 +688,9 @@ define <2 x i32> @test_pdifu_w(<2 x i32> %a, <2 x i32> %b) {
 define <4 x i16> @test_pdif_h(<4 x i16> %a, <4 x i16> %b) {
 ; RV32-LABEL: test_pdif_h:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    pabd.h a0, a0, a2
-; RV32-NEXT:    pabd.h a1, a1, a3
+; RV32-NEXT:    pmin.dh a4, a0, a2
+; RV32-NEXT:    pmax.dh a0, a0, a2
+; RV32-NEXT:    psub.dh a0, a0, a4
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_pdif_h:
@@ -719,8 +708,9 @@ define <4 x i16> @test_pdif_h(<4 x i16> %a, <4 x i16> %b) {
 define <4 x i16> @test_pdifu_h(<4 x i16> %a, <4 x i16> %b) {
 ; RV32-LABEL: test_pdifu_h:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    pabdu.h a0, a0, a2
-; RV32-NEXT:    pabdu.h a1, a1, a3
+; RV32-NEXT:    pminu.dh a4, a0, a2
+; RV32-NEXT:    pmaxu.dh a0, a0, a2
+; RV32-NEXT:    psub.dh a0, a0, a4
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_pdifu_h:
@@ -737,8 +727,9 @@ define <4 x i16> @test_pdifu_h(<4 x i16> %a, <4 x i16> %b) {
 define <8 x i8> @test_pdif_b(<8 x i8> %a, <8 x i8> %b) {
 ; RV32-LABEL: test_pdif_b:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    pabd.b a0, a0, a2
-; RV32-NEXT:    pabd.b a1, a1, a3
+; RV32-NEXT:    pmin.db a4, a0, a2
+; RV32-NEXT:    pmax.db a0, a0, a2
+; RV32-NEXT:    psub.db a0, a0, a4
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_pdif_b:
@@ -755,8 +746,9 @@ define <8 x i8> @test_pdif_b(<8 x i8> %a, <8 x i8> %b) {
 define <8 x i8> @test_pdifu_b(<8 x i8> %a, <8 x i8> %b) {
 ; RV32-LABEL: test_pdifu_b:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    pabdu.b a0, a0, a2
-; RV32-NEXT:    pabdu.b a1, a1, a3
+; RV32-NEXT:    pminu.db a4, a0, a2
+; RV32-NEXT:    pmaxu.db a0, a0, a2
+; RV32-NEXT:    psub.db a0, a0, a4
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_pdifu_b:
@@ -774,24 +766,7 @@ define <8 x i8> @test_pdifu_b(<8 x i8> %a, <8 x i8> %b) {
 define <4 x i16> @test_pasub_h(<4 x i16> %a, <4 x i16> %b) {
 ; RV32-LABEL: test_pasub_h:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    srai a4, a1, 16
-; RV32-NEXT:    sext.h a1, a1
-; RV32-NEXT:    srai a5, a0, 16
-; RV32-NEXT:    sext.h a0, a0
-; RV32-NEXT:    srai a6, a3, 16
-; RV32-NEXT:    sext.h a3, a3
-; RV32-NEXT:    srai a7, a2, 16
-; RV32-NEXT:    sext.h a2, a2
-; RV32-NEXT:    sub a0, a0, a2
-; RV32-NEXT:    sub a2, a5, a7
-; RV32-NEXT:    sub a1, a1, a3
-; RV32-NEXT:    sub a3, a4, a6
-; RV32-NEXT:    srli a3, a3, 1
-; RV32-NEXT:    srli a1, a1, 1
-; RV32-NEXT:    srli a2, a2, 1
-; RV32-NEXT:    srli a0, a0, 1
-; RV32-NEXT:    pack a0, a0, a2
-; RV32-NEXT:    pack a1, a1, a3
+; RV32-NEXT:    pasub.dh a0, a0, a2
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_pasub_h:
@@ -811,24 +786,7 @@ define <4 x i16> @test_pasub_h(<4 x i16> %a, <4 x i16> %b) {
 define <4 x i16> @test_pasubu_h(<4 x i16> %a, <4 x i16> %b) {
 ; RV32-LABEL: test_pasubu_h:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    srli a4, a1, 16
-; RV32-NEXT:    zext.h a1, a1
-; RV32-NEXT:    srli a5, a0, 16
-; RV32-NEXT:    zext.h a0, a0
-; RV32-NEXT:    srli a6, a3, 16
-; RV32-NEXT:    zext.h a3, a3
-; RV32-NEXT:    srli a7, a2, 16
-; RV32-NEXT:    zext.h a2, a2
-; RV32-NEXT:    sub a0, a0, a2
-; RV32-NEXT:    sub a2, a5, a7
-; RV32-NEXT:    sub a1, a1, a3
-; RV32-NEXT:    sub a3, a4, a6
-; RV32-NEXT:    srli a3, a3, 1
-; RV32-NEXT:    srli a1, a1, 1
-; RV32-NEXT:    srli a2, a2, 1
-; RV32-NEXT:    srli a0, a0, 1
-; RV32-NEXT:    pack a0, a0, a2
-; RV32-NEXT:    pack a1, a1, a3
+; RV32-NEXT:    pasubu.dh a0, a0, a2
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_pasubu_h:
@@ -847,58 +805,7 @@ define <4 x i16> @test_pasubu_h(<4 x i16> %a, <4 x i16> %b) {
 define <8 x i8> @test_pasub_b(<8 x i8> %a, <8 x i8> %b) {
 ; RV32-LABEL: test_pasub_b:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    srli a4, a1, 24
-; RV32-NEXT:    srli a5, a1, 16
-; RV32-NEXT:    srli a6, a1, 8
-; RV32-NEXT:    srli a7, a0, 24
-; RV32-NEXT:    srli t0, a0, 16
-; RV32-NEXT:    pack a4, a5, a4
-; RV32-NEXT:    srli a5, a0, 8
-; RV32-NEXT:    pack a1, a1, a6
-; RV32-NEXT:    srli a6, a3, 24
-; RV32-NEXT:    pack a7, t0, a7
-; RV32-NEXT:    srli t0, a3, 16
-; RV32-NEXT:    pack a0, a0, a5
-; RV32-NEXT:    srli a5, a3, 8
-; RV32-NEXT:    pack a6, t0, a6
-; RV32-NEXT:    srli t0, a2, 24
-; RV32-NEXT:    pack a3, a3, a5
-; RV32-NEXT:    srli a5, a2, 16
-; RV32-NEXT:    pack a5, a5, t0
-; RV32-NEXT:    srli t0, a2, 8
-; RV32-NEXT:    pack a2, a2, t0
-; RV32-NEXT:    pslli.h a4, a4, 8
-; RV32-NEXT:    pslli.h a1, a1, 8
-; RV32-NEXT:    pslli.h a7, a7, 8
-; RV32-NEXT:    pslli.h a0, a0, 8
-; RV32-NEXT:    pslli.h a6, a6, 8
-; RV32-NEXT:    pslli.h a3, a3, 8
-; RV32-NEXT:    pslli.h a5, a5, 8
-; RV32-NEXT:    pslli.h a2, a2, 8
-; RV32-NEXT:    psrai.h a4, a4, 8
-; RV32-NEXT:    psrai.h a1, a1, 8
-; RV32-NEXT:    psrai.h a7, a7, 8
-; RV32-NEXT:    psrai.h a0, a0, 8
-; RV32-NEXT:    psrai.h a6, a6, 8
-; RV32-NEXT:    psrai.h a3, a3, 8
-; RV32-NEXT:    psrai.h a5, a5, 8
-; RV32-NEXT:    psrai.h a2, a2, 8
-; RV32-NEXT:    psub.h a0, a0, a2
-; RV32-NEXT:    psub.h a2, a7, a5
-; RV32-NEXT:    psub.h a1, a1, a3
-; RV32-NEXT:    psub.h a3, a4, a6
-; RV32-NEXT:    psrli.h a3, a3, 1
-; RV32-NEXT:    psrli.h a5, a2, 1
-; RV32-NEXT:    psrli.h a2, a1, 1
-; RV32-NEXT:    psrli.h a4, a0, 1
-; RV32-NEXT:    srli a1, a5, 16
-; RV32-NEXT:    srli a7, a3, 16
-; RV32-NEXT:    srli a0, a4, 16
-; RV32-NEXT:    srli a6, a2, 16
-; RV32-NEXT:    ppaire.db a0, a4, a0
-; RV32-NEXT:    ppaire.db a2, a2, a6
-; RV32-NEXT:    pack a0, a0, a1
-; RV32-NEXT:    pack a1, a2, a3
+; RV32-NEXT:    pasub.db a0, a0, a2
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_pasub_b:
@@ -917,51 +824,7 @@ define <8 x i8> @test_pasub_b(<8 x i8> %a, <8 x i8> %b) {
 define <8 x i8> @test_pasubu_b(<8 x i8> %a, <8 x i8> %b) {
 ; RV32-LABEL: test_pasubu_b:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    srli a4, a1, 24
-; RV32-NEXT:    srli a5, a1, 16
-; RV32-NEXT:    pli.h a6, 255
-; RV32-NEXT:    srli a7, a1, 8
-; RV32-NEXT:    srli t0, a0, 24
-; RV32-NEXT:    srli t1, a0, 16
-; RV32-NEXT:    pack a4, a5, a4
-; RV32-NEXT:    srli a5, a0, 8
-; RV32-NEXT:    pack a1, a1, a7
-; RV32-NEXT:    srli a7, a3, 24
-; RV32-NEXT:    pack t0, t1, t0
-; RV32-NEXT:    srli t1, a3, 16
-; RV32-NEXT:    pack a0, a0, a5
-; RV32-NEXT:    srli a5, a3, 8
-; RV32-NEXT:    pack a7, t1, a7
-; RV32-NEXT:    srli t1, a2, 24
-; RV32-NEXT:    pack a3, a3, a5
-; RV32-NEXT:    srli a5, a2, 16
-; RV32-NEXT:    pack a5, a5, t1
-; RV32-NEXT:    srli t1, a2, 8
-; RV32-NEXT:    pack a2, a2, t1
-; RV32-NEXT:    and a4, a4, a6
-; RV32-NEXT:    and a1, a1, a6
-; RV32-NEXT:    and t0, t0, a6
-; RV32-NEXT:    and a0, a0, a6
-; RV32-NEXT:    and a7, a7, a6
-; RV32-NEXT:    and a3, a3, a6
-; RV32-NEXT:    and a5, a5, a6
-; RV32-NEXT:    and a2, a2, a6
-; RV32-NEXT:    psub.h a0, a0, a2
-; RV32-NEXT:    psub.h a2, t0, a5
-; RV32-NEXT:    psub.h a1, a1, a3
-; RV32-NEXT:    psub.h a3, a4, a7
-; RV32-NEXT:    psrli.h a3, a3, 1
-; RV32-NEXT:    psrli.h a5, a2, 1
-; RV32-NEXT:    psrli.h a2, a1, 1
-; RV32-NEXT:    psrli.h a4, a0, 1
-; RV32-NEXT:    srli a1, a5, 16
-; RV32-NEXT:    srli a7, a3, 16
-; RV32-NEXT:    srli a0, a4, 16
-; RV32-NEXT:    srli a6, a2, 16
-; RV32-NEXT:    ppaire.db a0, a4, a0
-; RV32-NEXT:    ppaire.db a2, a2, a6
-; RV32-NEXT:    pack a0, a0, a1
-; RV32-NEXT:    pack a1, a2, a3
+; RV32-NEXT:    pasubu.db a0, a0, a2
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_pasubu_b:
@@ -980,8 +843,10 @@ define <8 x i8> @test_pasubu_b(<8 x i8> %a, <8 x i8> %b) {
 define <4 x i16> @test_pli_h() {
 ; RV32-LABEL: test_pli_h:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    pli.h a0, 100
-; RV32-NEXT:    pli.h a1, 100
+; RV32-NEXT:    lui a1, %hi(.LCPI50_0)
+; RV32-NEXT:    lw a0, %lo(.LCPI50_0)(a1)
+; RV32-NEXT:    addi a1, a1, %lo(.LCPI50_0)
+; RV32-NEXT:    lw a1, 4(a1)
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_pli_h:
@@ -1009,8 +874,10 @@ define <2 x i32> @test_pli_h_v2i32() {
 define <8 x i8> @test_pli_b() {
 ; RV32-LABEL: test_pli_b:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    pli.b a0, 64
-; RV32-NEXT:    pli.b a1, 64
+; RV32-NEXT:    lui a1, %hi(.LCPI52_0)
+; RV32-NEXT:    lw a0, %lo(.LCPI52_0)(a1)
+; RV32-NEXT:    addi a1, a1, %lo(.LCPI52_0)
+; RV32-NEXT:    lw a1, 4(a1)
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_pli_b:
@@ -1023,8 +890,10 @@ define <8 x i8> @test_pli_b() {
 define <4 x i16> @test_pli_b_v4i16() {
 ; RV32-LABEL: test_pli_b_v4i16:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    pli.b a0, 64
-; RV32-NEXT:    pli.b a1, 64
+; RV32-NEXT:    lui a1, %hi(.LCPI53_0)
+; RV32-NEXT:    lw a0, %lo(.LCPI53_0)(a1)
+; RV32-NEXT:    addi a1, a1, %lo(.LCPI53_0)
+; RV32-NEXT:    lw a1, 4(a1)
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_pli_b_v4i16:
@@ -1066,8 +935,10 @@ define <2 x i32> @test_pli_w() {
 define <4 x i16> @test_plui_h() {
 ; RV32-LABEL: test_plui_h:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    plui.h a0, 100
-; RV32-NEXT:    plui.h a1, 100
+; RV32-NEXT:    lui a1, %hi(.LCPI56_0)
+; RV32-NEXT:    lw a0, %lo(.LCPI56_0)(a1)
+; RV32-NEXT:    addi a1, a1, %lo(.LCPI56_0)
+; RV32-NEXT:    lw a1, 4(a1)
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_plui_h:
@@ -1080,8 +951,10 @@ define <4 x i16> @test_plui_h() {
 define <4 x i16> @test_plui_h_negative() {
 ; RV32-LABEL: test_plui_h_negative:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    plui.h a0, -412
-; RV32-NEXT:    plui.h a1, -412
+; RV32-NEXT:    lui a1, %hi(.LCPI57_0)
+; RV32-NEXT:    lw a0, %lo(.LCPI57_0)(a1)
+; RV32-NEXT:    addi a1, a1, %lo(.LCPI57_0)
+; RV32-NEXT:    lw a1, 4(a1)
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_plui_h_negative:
@@ -1150,8 +1023,10 @@ define <2 x i32> @test_plui_w_negative() {
 define <8 x i8> @test_allones_v8i8() {
 ; RV32-LABEL: test_allones_v8i8:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    li a0, -1
-; RV32-NEXT:    li a1, -1
+; RV32-NEXT:    lui a1, %hi(.LCPI62_0)
+; RV32-NEXT:    lw a0, %lo(.LCPI62_0)(a1)
+; RV32-NEXT:    addi a1, a1, %lo(.LCPI62_0)
+; RV32-NEXT:    lw a1, 4(a1)
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_allones_v8i8:
@@ -1164,8 +1039,10 @@ define <8 x i8> @test_allones_v8i8() {
 define <4 x i16> @test_allones_v4i16() {
 ; RV32-LABEL: test_allones_v4i16:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    li a0, -1
-; RV32-NEXT:    li a1, -1
+; RV32-NEXT:    lui a1, %hi(.LCPI63_0)
+; RV32-NEXT:    lw a0, %lo(.LCPI63_0)(a1)
+; RV32-NEXT:    addi a1, a1, %lo(.LCPI63_0)
+; RV32-NEXT:    lw a1, 4(a1)
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_allones_v4i16:
@@ -1190,17 +1067,37 @@ define <2 x i32> @test_allones_v2i32() {
 }
 
 define i16 @test_extract_vector_16(<4 x i16> %a) {
-; CHECK-LABEL: test_extract_vector_16:
-; CHECK:       # %bb.0:
-; CHECK-NEXT:    ret
+; RV32-LABEL: test_extract_vector_16:
+; RV32:       # %bb.0:
+; RV32-NEXT:    addi sp, sp, -16
+; RV32-NEXT:    .cfi_def_cfa_offset 16
+; RV32-NEXT:    sw a0, 8(sp)
+; RV32-NEXT:    lh a0, 8(sp)
+; RV32-NEXT:    addi sp, sp, 16
+; RV32-NEXT:    .cfi_def_cfa_offset 0
+; RV32-NEXT:    ret
+;
+; RV64-LABEL: test_extract_vector_16:
+; RV64:       # %bb.0:
+; RV64-NEXT:    ret
   %extracted = extractelement <4 x i16> %a, i32 0
   ret i16 %extracted
 }
 
 define i8 @test_extract_vector_8(<8 x i8> %a) {
-; CHECK-LABEL: test_extract_vector_8:
-; CHECK:       # %bb.0:
-; CHECK-NEXT:    ret
+; RV32-LABEL: test_extract_vector_8:
+; RV32:       # %bb.0:
+; RV32-NEXT:    addi sp, sp, -16
+; RV32-NEXT:    .cfi_def_cfa_offset 16
+; RV32-NEXT:    sw a0, 8(sp)
+; RV32-NEXT:    lbu a0, 8(sp)
+; RV32-NEXT:    addi sp, sp, 16
+; RV32-NEXT:    .cfi_def_cfa_offset 0
+; RV32-NEXT:    ret
+;
+; RV64-LABEL: test_extract_vector_8:
+; RV64:       # %bb.0:
+; RV64-NEXT:    ret
   %extracted = extractelement <8 x i8> %a, i32 0
   ret i8 %extracted
 }
@@ -1230,8 +1127,23 @@ define i32 @test_extract_vector_32_elem1(<2 x i32> %a) {
 define <4 x i16> @test_insert_vector_16(<4 x i16> %a, i16 %val) {
 ; RV32-LABEL: test_insert_vector_16:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    srli a0, a0, 16
-; RV32-NEXT:    pack a0, a2, a0
+; RV32-NEXT:    addi sp, sp, -32
+; RV32-NEXT:    .cfi_def_cfa_offset 32
+; RV32-NEXT:    sh a2, 24(sp)
+; RV32-NEXT:    sw a0, 8(sp)
+; RV32-NEXT:    sw a1, 12(sp)
+; RV32-NEXT:    lw a0, 24(sp)
+; RV32-NEXT:    sw a0, 0(sp)
+; RV32-NEXT:    lw a0, 12(sp)
+; RV32-NEXT:    sw a0, 20(sp)
+; RV32-NEXT:    lh a0, 10(sp)
+; RV32-NEXT:    sh a0, 18(sp)
+; RV32-NEXT:    lh a0, 0(sp)
+; RV32-NEXT:    sh a0, 16(sp)
+; RV32-NEXT:    lw a0, 16(sp)
+; RV32-NEXT:    lw a1, 20(sp)
+; RV32-NEXT:    addi sp, sp, 32
+; RV32-NEXT:    .cfi_def_cfa_offset 0
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_insert_vector_16:
@@ -1247,8 +1159,25 @@ define <4 x i16> @test_insert_vector_16(<4 x i16> %a, i16 %val) {
 define <4 x i16> @test_insert_vector_16_elem2(<4 x i16> %a, i16 %val) {
 ; RV32-LABEL: test_insert_vector_16_elem2:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    srli a1, a1, 16
-; RV32-NEXT:    pack a1, a2, a1
+; RV32-NEXT:    addi sp, sp, -32
+; RV32-NEXT:    .cfi_def_cfa_offset 32
+; RV32-NEXT:    sh a2, 24(sp)
+; RV32-NEXT:    sw a1, 12(sp)
+; RV32-NEXT:    lw a1, 24(sp)
+; RV32-NEXT:    sw a1, 0(sp)
+; RV32-NEXT:    lh a1, 14(sp)
+; RV32-NEXT:    sw a0, 8(sp)
+; RV32-NEXT:    sh a1, 22(sp)
+; RV32-NEXT:    lh a0, 0(sp)
+; RV32-NEXT:    sh a0, 20(sp)
+; RV32-NEXT:    lh a0, 10(sp)
+; RV32-NEXT:    sh a0, 18(sp)
+; RV32-NEXT:    lh a0, 8(sp)
+; RV32-NEXT:    sh a0, 16(sp)
+; RV32-NEXT:    lw a0, 16(sp)
+; RV32-NEXT:    lw a1, 20(sp)
+; RV32-NEXT:    addi sp, sp, 32
+; RV32-NEXT:    .cfi_def_cfa_offset 0
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_insert_vector_16_elem2:
@@ -1265,8 +1194,25 @@ define <4 x i16> @test_insert_vector_16_elem2(<4 x i16> %a, i16 %val) {
 define <8 x i8> @test_insert_vector_8(<8 x i8> %a, i8 %val) {
 ; RV32-LABEL: test_insert_vector_8:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    li a3, 255
-; RV32-NEXT:    mvm a0, a2, a3
+; RV32-NEXT:    addi sp, sp, -32
+; RV32-NEXT:    .cfi_def_cfa_offset 32
+; RV32-NEXT:    sb a2, 24(sp)
+; RV32-NEXT:    sw a0, 8(sp)
+; RV32-NEXT:    sw a1, 12(sp)
+; RV32-NEXT:    lw a0, 24(sp)
+; RV32-NEXT:    sw a0, 0(sp)
+; RV32-NEXT:    lw a0, 12(sp)
+; RV32-NEXT:    sw a0, 20(sp)
+; RV32-NEXT:    lh a0, 10(sp)
+; RV32-NEXT:    sh a0, 18(sp)
+; RV32-NEXT:    lbu a0, 9(sp)
+; RV32-NEXT:    sb a0, 17(sp)
+; RV32-NEXT:    lbu a0, 0(sp)
+; RV32-NEXT:    sb a0, 16(sp)
+; RV32-NEXT:    lw a0, 16(sp)
+; RV32-NEXT:    lw a1, 20(sp)
+; RV32-NEXT:    addi sp, sp, 32
+; RV32-NEXT:    .cfi_def_cfa_offset 0
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_insert_vector_8:
@@ -1281,9 +1227,27 @@ define <8 x i8> @test_insert_vector_8(<8 x i8> %a, i8 %val) {
 define <8 x i8> @test_insert_vector_8_elem3(<8 x i8> %a, i8 %val) {
 ; RV32-LABEL: test_insert_vector_8_elem3:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    slli a2, a2, 24
-; RV32-NEXT:    lui a3, 1044480
-; RV32-NEXT:    mvm a0, a2, a3
+; RV32-NEXT:    addi sp, sp, -32
+; RV32-NEXT:    .cfi_def_cfa_offset 32
+; RV32-NEXT:    sb a2, 24(sp)
+; RV32-NEXT:    sw a1, 12(sp)
+; RV32-NEXT:    lw a1, 24(sp)
+; RV32-NEXT:    sw a1, 0(sp)
+; RV32-NEXT:    lw a1, 12(sp)
+; RV32-NEXT:    sw a0, 8(sp)
+; RV32-NEXT:    sw a1, 20(sp)
+; RV32-NEXT:    lbu a0, 0(sp)
+; RV32-NEXT:    sb a0, 19(sp)
+; RV32-NEXT:    lbu a0, 10(sp)
+; RV32-NEXT:    sb a0, 18(sp)
+; RV32-NEXT:    lbu a0, 9(sp)
+; RV32-NEXT:    sb a0, 17(sp)
+; RV32-NEXT:    lbu a0, 8(sp)
+; RV32-NEXT:    sb a0, 16(sp)
+; RV32-NEXT:    lw a0, 16(sp)
+; RV32-NEXT:    lw a1, 20(sp)
+; RV32-NEXT:    addi sp, sp, 32
+; RV32-NEXT:    .cfi_def_cfa_offset 0
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_insert_vector_8_elem3:
@@ -1300,7 +1264,11 @@ define <8 x i8> @test_insert_vector_8_elem3(<8 x i8> %a, i8 %val) {
 define <2 x i32> @test_insert_vector_32(<2 x i32> %a, i32 %val) {
 ; RV32-LABEL: test_insert_vector_32:
 ; RV32:       # %bb.0:
+; RV32-NEXT:    addi sp, sp, -16
+; RV32-NEXT:    .cfi_def_cfa_offset 16
 ; RV32-NEXT:    mv a0, a2
+; RV32-NEXT:    addi sp, sp, 16
+; RV32-NEXT:    .cfi_def_cfa_offset 0
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_insert_vector_32:
@@ -1315,7 +1283,11 @@ define <2 x i32> @test_insert_vector_32(<2 x i32> %a, i32 %val) {
 define <2 x i32> @test_insert_vector_32_elem1(<2 x i32> %a, i32 %val) {
 ; RV32-LABEL: test_insert_vector_32_elem1:
 ; RV32:       # %bb.0:
+; RV32-NEXT:    addi sp, sp, -16
+; RV32-NEXT:    .cfi_def_cfa_offset 16
 ; RV32-NEXT:    mv a1, a2
+; RV32-NEXT:    addi sp, sp, 16
+; RV32-NEXT:    .cfi_def_cfa_offset 0
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_insert_vector_32_elem1:
@@ -1330,8 +1302,7 @@ define <2 x i32> @test_insert_vector_32_elem1(<2 x i32> %a, i32 %val) {
 define <2 x i32> @test_padd_w(<2 x i32> %a, <2 x i32> %b) {
 ; RV32-LABEL: test_padd_w:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    add a0, a0, a2
-; RV32-NEXT:    add a1, a1, a3
+; RV32-NEXT:    padd.dw a0, a0, a2
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_padd_w:
@@ -1345,8 +1316,7 @@ define <2 x i32> @test_padd_w(<2 x i32> %a, <2 x i32> %b) {
 define <2 x i32> @test_psub_w(<2 x i32> %a, <2 x i32> %b) {
 ; RV32-LABEL: test_psub_w:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    sub a0, a0, a2
-; RV32-NEXT:    sub a1, a1, a3
+; RV32-NEXT:    psub.dw a0, a0, a2
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_psub_w:
@@ -1361,8 +1331,7 @@ define <2 x i32> @test_psub_w(<2 x i32> %a, <2 x i32> %b) {
 define <2 x i32> @test_psadd_w(<2 x i32> %a, <2 x i32> %b) {
 ; RV32-LABEL: test_psadd_w:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    sadd a0, a0, a2
-; RV32-NEXT:    sadd a1, a1, a3
+; RV32-NEXT:    psadd.dw a0, a0, a2
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_psadd_w:
@@ -1376,8 +1345,7 @@ define <2 x i32> @test_psadd_w(<2 x i32> %a, <2 x i32> %b) {
 define <2 x i32> @test_psaddu_w(<2 x i32> %a, <2 x i32> %b) {
 ; RV32-LABEL: test_psaddu_w:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    saddu a0, a0, a2
-; RV32-NEXT:    saddu a1, a1, a3
+; RV32-NEXT:    psaddu.dw a0, a0, a2
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_psaddu_w:
@@ -1392,8 +1360,7 @@ define <2 x i32> @test_psaddu_w(<2 x i32> %a, <2 x i32> %b) {
 define <2 x i32> @test_pssub_w(<2 x i32> %a, <2 x i32> %b) {
 ; RV32-LABEL: test_pssub_w:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    ssub a0, a0, a2
-; RV32-NEXT:    ssub a1, a1, a3
+; RV32-NEXT:    pssub.dw a0, a0, a2
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_pssub_w:
@@ -1407,8 +1374,7 @@ define <2 x i32> @test_pssub_w(<2 x i32> %a, <2 x i32> %b) {
 define <2 x i32> @test_pssubu_w(<2 x i32> %a, <2 x i32> %b) {
 ; RV32-LABEL: test_pssubu_w:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    ssubu a0, a0, a2
-; RV32-NEXT:    ssubu a1, a1, a3
+; RV32-NEXT:    pssubu.dw a0, a0, a2
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_pssubu_w:
@@ -1424,8 +1390,7 @@ define <2 x i32> @test_pssubu_w(<2 x i32> %a, <2 x i32> %b) {
 define <2 x i32> @test_paadd_w(<2 x i32> %a, <2 x i32> %b) {
 ; RV32-LABEL: test_paadd_w:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    aadd a0, a0, a2
-; RV32-NEXT:    aadd a1, a1, a3
+; RV32-NEXT:    paadd.dw a0, a0, a2
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_paadd_w:
@@ -1445,8 +1410,7 @@ define <2 x i32> @test_paadd_w(<2 x i32> %a, <2 x i32> %b) {
 define <2 x i32> @test_paaddu_w(<2 x i32> %a, <2 x i32> %b) {
 ; RV32-LABEL: test_paaddu_w:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    aaddu a0, a0, a2
-; RV32-NEXT:    aaddu a1, a1, a3
+; RV32-NEXT:    paaddu.dw a0, a0, a2
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_paaddu_w:
@@ -1465,16 +1429,7 @@ define <2 x i32> @test_paaddu_w(<2 x i32> %a, <2 x i32> %b) {
 define <2 x i32> @test_pasub_w(<2 x i32> %a, <2 x i32> %b) {
 ; RV32-LABEL: test_pasub_w:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    mv a4, a3
-; RV32-NEXT:    mv a6, a1
-; RV32-NEXT:    srai a1, a0, 31
-; RV32-NEXT:    srai a7, a6, 31
-; RV32-NEXT:    srai a3, a2, 31
-; RV32-NEXT:    srai a5, a4, 31
-; RV32-NEXT:    subd a4, a6, a4
-; RV32-NEXT:    subd a0, a0, a2
-; RV32-NEXT:    nsrli a0, a0, 1
-; RV32-NEXT:    nsrli a1, a4, 1
+; RV32-NEXT:    pasub.dw a0, a0, a2
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_pasub_w:
@@ -1494,10 +1449,7 @@ define <2 x i32> @test_pasub_w(<2 x i32> %a, <2 x i32> %b) {
 define <2 x i32> @test_pasubu_w(<2 x i32> %a, <2 x i32> %b) {
 ; RV32-LABEL: test_pasubu_w:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    wsubu a4, a1, a3
-; RV32-NEXT:    wsubu a0, a0, a2
-; RV32-NEXT:    nsrli a0, a0, 1
-; RV32-NEXT:    nsrli a1, a4, 1
+; RV32-NEXT:    pasubu.dw a0, a0, a2
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_pasubu_w:
@@ -1532,8 +1484,21 @@ define <2 x i32> @test_non_const_splat_i32(i32 %elt) {
 define <8 x i8> @test_padd_bs_splat_lhs(<8 x i8> %a, i8 %b) {
 ; RV32-LABEL: test_padd_bs_splat_lhs:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    padd.bs a0, a0, a2
-; RV32-NEXT:    padd.bs a1, a1, a2
+; RV32-NEXT:    addi sp, sp, -16
+; RV32-NEXT:    .cfi_def_cfa_offset 16
+; RV32-NEXT:    sb a2, 12(sp)
+; RV32-NEXT:    sb a2, 13(sp)
+; RV32-NEXT:    sb a2, 14(sp)
+; RV32-NEXT:    sb a2, 15(sp)
+; RV32-NEXT:    sb a2, 8(sp)
+; RV32-NEXT:    sb a2, 9(sp)
+; RV32-NEXT:    sb a2, 10(sp)
+; RV32-NEXT:    sb a2, 11(sp)
+; RV32-NEXT:    lw a3, 12(sp)
+; RV32-NEXT:    lw a2, 8(sp)
+; RV32-NEXT:    padd.db a0, a2, a0
+; RV32-NEXT:    addi sp, sp, 16
+; RV32-NEXT:    .cfi_def_cfa_offset 0
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_padd_bs_splat_lhs:
@@ -1549,8 +1514,21 @@ define <8 x i8> @test_padd_bs_splat_lhs(<8 x i8> %a, i8 %b) {
 define <8 x i8> @test_padd_bs_splat_rhs(<8 x i8> %a, i8 %b) {
 ; RV32-LABEL: test_padd_bs_splat_rhs:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    padd.bs a0, a0, a2
-; RV32-NEXT:    padd.bs a1, a1, a2
+; RV32-NEXT:    addi sp, sp, -16
+; RV32-NEXT:    .cfi_def_cfa_offset 16
+; RV32-NEXT:    sb a2, 12(sp)
+; RV32-NEXT:    sb a2, 13(sp)
+; RV32-NEXT:    sb a2, 14(sp)
+; RV32-NEXT:    sb a2, 15(sp)
+; RV32-NEXT:    sb a2, 8(sp)
+; RV32-NEXT:    sb a2, 9(sp)
+; RV32-NEXT:    sb a2, 10(sp)
+; RV32-NEXT:    sb a2, 11(sp)
+; RV32-NEXT:    lw a3, 12(sp)
+; RV32-NEXT:    lw a2, 8(sp)
+; RV32-NEXT:    padd.db a0, a0, a2
+; RV32-NEXT:    addi sp, sp, 16
+; RV32-NEXT:    .cfi_def_cfa_offset 0
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_padd_bs_splat_rhs:
@@ -1566,8 +1544,17 @@ define <8 x i8> @test_padd_bs_splat_rhs(<8 x i8> %a, i8 %b) {
 define <4 x i16> @test_padd_hs_splat_lhs(<4 x i16> %a, i16 %b) {
 ; RV32-LABEL: test_padd_hs_splat_lhs:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    padd.hs a0, a0, a2
-; RV32-NEXT:    padd.hs a1, a1, a2
+; RV32-NEXT:    addi sp, sp, -16
+; RV32-NEXT:    .cfi_def_cfa_offset 16
+; RV32-NEXT:    sh a2, 8(sp)
+; RV32-NEXT:    sh a2, 10(sp)
+; RV32-NEXT:    sh a2, 12(sp)
+; RV32-NEXT:    sh a2, 14(sp)
+; RV32-NEXT:    lw a3, 12(sp)
+; RV32-NEXT:    lw a2, 8(sp)
+; RV32-NEXT:    padd.dh a0, a2, a0
+; RV32-NEXT:    addi sp, sp, 16
+; RV32-NEXT:    .cfi_def_cfa_offset 0
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_padd_hs_splat_lhs:
@@ -1583,8 +1570,17 @@ define <4 x i16> @test_padd_hs_splat_lhs(<4 x i16> %a, i16 %b) {
 define <4 x i16> @test_padd_hs_splat_rhs(<4 x i16> %a, i16 %b) {
 ; RV32-LABEL: test_padd_hs_splat_rhs:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    padd.hs a0, a0, a2
-; RV32-NEXT:    padd.hs a1, a1, a2
+; RV32-NEXT:    addi sp, sp, -16
+; RV32-NEXT:    .cfi_def_cfa_offset 16
+; RV32-NEXT:    sh a2, 8(sp)
+; RV32-NEXT:    sh a2, 10(sp)
+; RV32-NEXT:    sh a2, 12(sp)
+; RV32-NEXT:    sh a2, 14(sp)
+; RV32-NEXT:    lw a3, 12(sp)
+; RV32-NEXT:    lw a2, 8(sp)
+; RV32-NEXT:    padd.dh a0, a0, a2
+; RV32-NEXT:    addi sp, sp, 16
+; RV32-NEXT:    .cfi_def_cfa_offset 0
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_padd_hs_splat_rhs:
@@ -1600,8 +1596,8 @@ define <4 x i16> @test_padd_hs_splat_rhs(<4 x i16> %a, i16 %b) {
 define <2 x i32> @test_padd_ws_splat_lhs(<2 x i32> %a, i32 %b) {
 ; RV32-LABEL: test_padd_ws_splat_lhs:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    add a0, a2, a0
-; RV32-NEXT:    add a1, a2, a1
+; RV32-NEXT:    mv a3, a2
+; RV32-NEXT:    padd.dw a0, a2, a0
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_padd_ws_splat_lhs:
@@ -1617,8 +1613,8 @@ define <2 x i32> @test_padd_ws_splat_lhs(<2 x i32> %a, i32 %b) {
 define <2 x i32> @test_padd_ws_splat_rhs(<2 x i32> %a, i32 %b) {
 ; RV32-LABEL: test_padd_ws_splat_rhs:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    add a0, a0, a2
-; RV32-NEXT:    add a1, a1, a2
+; RV32-NEXT:    mv a3, a2
+; RV32-NEXT:    padd.dw a0, a0, a2
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_padd_ws_splat_rhs:
@@ -1634,16 +1630,20 @@ define <2 x i32> @test_padd_ws_splat_rhs(<2 x i32> %a, i32 %b) {
 define <8 x i8> @test_build_vector_i8(i8 %a, i8 %b, i8 %c, i8 %d, i8 %e, i8 %f, i8 %g, i8 %h) {
 ; RV32-LABEL: test_build_vector_i8:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    mv t2, a6
-; RV32-NEXT:    mv t4, a2
-; RV32-NEXT:    mv a6, a5
-; RV32-NEXT:    mv t1, a4
-; RV32-NEXT:    mv a2, a1
-; RV32-NEXT:    mv t3, a0
-; RV32-NEXT:    ppaire.db a0, t3, a2
-; RV32-NEXT:    ppaire.db a2, t1, a6
-; RV32-NEXT:    pack a0, a0, a1
-; RV32-NEXT:    pack a1, a2, a3
+; RV32-NEXT:    addi sp, sp, -16
+; RV32-NEXT:    .cfi_def_cfa_offset 16
+; RV32-NEXT:    sb a4, 12(sp)
+; RV32-NEXT:    sb a5, 13(sp)
+; RV32-NEXT:    sb a6, 14(sp)
+; RV32-NEXT:    sb a7, 15(sp)
+; RV32-NEXT:    sb a0, 8(sp)
+; RV32-NEXT:    sb a1, 9(sp)
+; RV32-NEXT:    sb a2, 10(sp)
+; RV32-NEXT:    sb a3, 11(sp)
+; RV32-NEXT:    lw a0, 8(sp)
+; RV32-NEXT:    lw a1, 12(sp)
+; RV32-NEXT:    addi sp, sp, 16
+; RV32-NEXT:    .cfi_def_cfa_offset 0
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_build_vector_i8:
@@ -1670,8 +1670,16 @@ define <8 x i8> @test_build_vector_i8(i8 %a, i8 %b, i8 %c, i8 %d, i8 %e, i8 %f,
 define <4 x i16> @test_build_vector_i16(i16 %a, i16 %b, i16 %c, i16 %d) {
 ; RV32-LABEL: test_build_vector_i16:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    pack a0, a0, a1
-; RV32-NEXT:    pack a1, a2, a3
+; RV32-NEXT:    addi sp, sp, -16
+; RV32-NEXT:    .cfi_def_cfa_offset 16
+; RV32-NEXT:    sh a0, 8(sp)
+; RV32-NEXT:    sh a1, 10(sp)
+; RV32-NEXT:    sh a2, 12(sp)
+; RV32-NEXT:    sh a3, 14(sp)
+; RV32-NEXT:    lw a0, 8(sp)
+; RV32-NEXT:    lw a1, 12(sp)
+; RV32-NEXT:    addi sp, sp, 16
+; RV32-NEXT:    .cfi_def_cfa_offset 0
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_build_vector_i16:
@@ -1705,8 +1713,26 @@ define <2 x i32> @test_build_vector_i32(i32 %a, i32 %b) {
 define <4 x i16> @test_pslli_h(<4 x i16> %a) {
 ; RV32-LABEL: test_pslli_h:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    pslli.h a0, a0, 2
-; RV32-NEXT:    pslli.h a1, a1, 2
+; RV32-NEXT:    addi sp, sp, -16
+; RV32-NEXT:    .cfi_def_cfa_offset 16
+; RV32-NEXT:    sw a1, 4(sp)
+; RV32-NEXT:    lh a1, 6(sp)
+; RV32-NEXT:    sw a0, 0(sp)
+; RV32-NEXT:    slli a1, a1, 2
+; RV32-NEXT:    sh a1, 14(sp)
+; RV32-NEXT:    lh a0, 4(sp)
+; RV32-NEXT:    slli a0, a0, 2
+; RV32-NEXT:    sh a0, 12(sp)
+; RV32-NEXT:    lh a0, 2(sp)
+; RV32-NEXT:    slli a0, a0, 2
+; RV32-NEXT:    sh a0, 10(sp)
+; RV32-NEXT:    lh a0, 0(sp)
+; RV32-NEXT:    slli a0, a0, 2
+; RV32-NEXT:    sh a0, 8(sp)
+; RV32-NEXT:    lw a0, 8(sp)
+; RV32-NEXT:    lw a1, 12(sp)
+; RV32-NEXT:    addi sp, sp, 16
+; RV32-NEXT:    .cfi_def_cfa_offset 0
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_pslli_h:
@@ -1721,8 +1747,38 @@ define <4 x i16> @test_pslli_h(<4 x i16> %a) {
 define <8 x i8> @test_pslli_b(<8 x i8> %a) {
 ; RV32-LABEL: test_pslli_b:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    pslli.b a0, a0, 2
-; RV32-NEXT:    pslli.b a1, a1, 2
+; RV32-NEXT:    addi sp, sp, -16
+; RV32-NEXT:    .cfi_def_cfa_offset 16
+; RV32-NEXT:    sw a1, 4(sp)
+; RV32-NEXT:    lbu a1, 7(sp)
+; RV32-NEXT:    sw a0, 0(sp)
+; RV32-NEXT:    slli a1, a1, 2
+; RV32-NEXT:    sb a1, 15(sp)
+; RV32-NEXT:    lbu a0, 6(sp)
+; RV32-NEXT:    slli a0, a0, 2
+; RV32-NEXT:    sb a0, 14(sp)
+; RV32-NEXT:    lbu a0, 5(sp)
+; RV32-NEXT:    slli a0, a0, 2
+; RV32-NEXT:    sb a0, 13(sp)
+; RV32-NEXT:    lbu a0, 4(sp)
+; RV32-NEXT:    slli a0, a0, 2
+; RV32-NEXT:    sb a0, 12(sp)
+; RV32-NEXT:    lbu a0, 3(sp)
+; RV32-NEXT:    slli a0, a0, 2
+; RV32-NEXT:    sb a0, 11(sp)
+; RV32-NEXT:    lbu a0, 2(sp)
+; RV32-NEXT:    slli a0, a0, 2
+; RV32-NEXT:    sb a0, 10(sp)
+; RV32-NEXT:    lbu a0, 1(sp)
+; RV32-NEXT:    slli a0, a0, 2
+; RV32-NEXT:    sb a0, 9(sp)
+; RV32-NEXT:    lbu a0, 0(sp)
+; RV32-NEXT:    slli a0, a0, 2
+; RV32-NEXT:    sb a0, 8(sp)
+; RV32-NEXT:    lw a0, 8(sp)
+; RV32-NEXT:    lw a1, 12(sp)
+; RV32-NEXT:    addi sp, sp, 16
+; RV32-NEXT:    .cfi_def_cfa_offset 0
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_pslli_b:
@@ -1737,8 +1793,8 @@ define <8 x i8> @test_pslli_b(<8 x i8> %a) {
 define <2 x i32> @test_pslli_w(<2 x i32> %a) {
 ; RV32-LABEL: test_pslli_w:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    slli a0, a0, 2
 ; RV32-NEXT:    slli a1, a1, 2
+; RV32-NEXT:    slli a0, a0, 2
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_pslli_w:
@@ -1753,8 +1809,8 @@ define <2 x i32> @test_pslli_w(<2 x i32> %a) {
 define <2 x i32> @test_psrli_w(<2 x i32> %a) {
 ; RV32-LABEL: test_psrli_w:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    srli a0, a0, 2
 ; RV32-NEXT:    srli a1, a1, 2
+; RV32-NEXT:    srli a0, a0, 2
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_psrli_w:
@@ -1768,8 +1824,26 @@ define <2 x i32> @test_psrli_w(<2 x i32> %a) {
 define <4 x i16> @test_psrli_h(<4 x i16> %a) {
 ; RV32-LABEL: test_psrli_h:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    psrli.h a0, a0, 2
-; RV32-NEXT:    psrli.h a1, a1, 2
+; RV32-NEXT:    addi sp, sp, -16
+; RV32-NEXT:    .cfi_def_cfa_offset 16
+; RV32-NEXT:    sw a1, 4(sp)
+; RV32-NEXT:    lhu a1, 6(sp)
+; RV32-NEXT:    sw a0, 0(sp)
+; RV32-NEXT:    srli a1, a1, 2
+; RV32-NEXT:    sh a1, 14(sp)
+; RV32-NEXT:    lhu a0, 4(sp)
+; RV32-NEXT:    srli a0, a0, 2
+; RV32-NEXT:    sh a0, 12(sp)
+; RV32-NEXT:    lhu a0, 2(sp)
+; RV32-NEXT:    srli a0, a0, 2
+; RV32-NEXT:    sh a0, 10(sp)
+; RV32-NEXT:    lhu a0, 0(sp)
+; RV32-NEXT:    srli a0, a0, 2
+; RV32-NEXT:    sh a0, 8(sp)
+; RV32-NEXT:    lw a0, 8(sp)
+; RV32-NEXT:    lw a1, 12(sp)
+; RV32-NEXT:    addi sp, sp, 16
+; RV32-NEXT:    .cfi_def_cfa_offset 0
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_psrli_h:
@@ -1783,8 +1857,46 @@ define <4 x i16> @test_psrli_h(<4 x i16> %a) {
 define <8 x i8> @test_psrli_b(<8 x i8> %a) {
 ; RV32-LABEL: test_psrli_b:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    psrli.b a0, a0, 2
-; RV32-NEXT:    psrli.b a1, a1, 2
+; RV32-NEXT:    addi sp, sp, -16
+; RV32-NEXT:    .cfi_def_cfa_offset 16
+; RV32-NEXT:    sw a1, 4(sp)
+; RV32-NEXT:    lbu a1, 7(sp)
+; RV32-NEXT:    sw a0, 0(sp)
+; RV32-NEXT:    slli a1, a1, 24
+; RV32-NEXT:    srli a1, a1, 26
+; RV32-NEXT:    sb a1, 15(sp)
+; RV32-NEXT:    lbu a0, 6(sp)
+; RV32-NEXT:    slli a0, a0, 24
+; RV32-NEXT:    srli a0, a0, 26
+; RV32-NEXT:    sb a0, 14(sp)
+; RV32-NEXT:    lbu a0, 5(sp)
+; RV32-NEXT:    slli a0, a0, 24
+; RV32-NEXT:    srli a0, a0, 26
+; RV32-NEXT:    sb a0, 13(sp)
+; RV32-NEXT:    lbu a0, 4(sp)
+; RV32-NEXT:    slli a0, a0, 24
+; RV32-NEXT:    srli a0, a0, 26
+; RV32-NEXT:    sb a0, 12(sp)
+; RV32-NEXT:    lbu a0, 3(sp)
+; RV32-NEXT:    slli a0, a0, 24
+; RV32-NEXT:    srli a0, a0, 26
+; RV32-NEXT:    sb a0, 11(sp)
+; RV32-NEXT:    lbu a0, 2(sp)
+; RV32-NEXT:    slli a0, a0, 24
+; RV32-NEXT:    srli a0, a0, 26
+; RV32-NEXT:    sb a0, 10(sp)
+; RV32-NEXT:    lbu a0, 1(sp)
+; RV32-NEXT:    slli a0, a0, 24
+; RV32-NEXT:    srli a0, a0, 26
+; RV32-NEXT:    sb a0, 9(sp)
+; RV32-NEXT:    lbu a0, 0(sp)
+; RV32-NEXT:    slli a0, a0, 24
+; RV32-NEXT:    srli a0, a0, 26
+; RV32-NEXT:    sb a0, 8(sp)
+; RV32-NEXT:    lw a0, 8(sp)
+; RV32-NEXT:    lw a1, 12(sp)
+; RV32-NEXT:    addi sp, sp, 16
+; RV32-NEXT:    .cfi_def_cfa_offset 0
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_psrli_b:
@@ -1799,8 +1911,8 @@ define <8 x i8> @test_psrli_b(<8 x i8> %a) {
 define <2 x i32> @test_psrai_w(<2 x i32> %a) {
 ; RV32-LABEL: test_psrai_w:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    srai a0, a0, 2
 ; RV32-NEXT:    srai a1, a1, 2
+; RV32-NEXT:    srai a0, a0, 2
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_psrai_w:
@@ -1814,8 +1926,26 @@ define <2 x i32> @test_psrai_w(<2 x i32> %a) {
 define <4 x i16> @test_psrai_h(<4 x i16> %a) {
 ; RV32-LABEL: test_psrai_h:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    psrai.h a0, a0, 2
-; RV32-NEXT:    psrai.h a1, a1, 2
+; RV32-NEXT:    addi sp, sp, -16
+; RV32-NEXT:    .cfi_def_cfa_offset 16
+; RV32-NEXT:    sw a1, 4(sp)
+; RV32-NEXT:    lh a1, 6(sp)
+; RV32-NEXT:    sw a0, 0(sp)
+; RV32-NEXT:    srli a1, a1, 2
+; RV32-NEXT:    sh a1, 14(sp)
+; RV32-NEXT:    lh a0, 4(sp)
+; RV32-NEXT:    srli a0, a0, 2
+; RV32-NEXT:    sh a0, 12(sp)
+; RV32-NEXT:    lh a0, 2(sp)
+; RV32-NEXT:    srli a0, a0, 2
+; RV32-NEXT:    sh a0, 10(sp)
+; RV32-NEXT:    lh a0, 0(sp)
+; RV32-NEXT:    srli a0, a0, 2
+; RV32-NEXT:    sh a0, 8(sp)
+; RV32-NEXT:    lw a0, 8(sp)
+; RV32-NEXT:    lw a1, 12(sp)
+; RV32-NEXT:    addi sp, sp, 16
+; RV32-NEXT:    .cfi_def_cfa_offset 0
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_psrai_h:
@@ -1829,8 +1959,38 @@ define <4 x i16> @test_psrai_h(<4 x i16> %a) {
 define <8 x i8> @test_psrai_b(<8 x i8> %a) {
 ; RV32-LABEL: test_psrai_b:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    psrai.b a0, a0, 2
-; RV32-NEXT:    psrai.b a1, a1, 2
+; RV32-NEXT:    addi sp, sp, -16
+; RV32-NEXT:    .cfi_def_cfa_offset 16
+; RV32-NEXT:    sw a1, 4(sp)
+; RV32-NEXT:    lb a1, 7(sp)
+; RV32-NEXT:    sw a0, 0(sp)
+; RV32-NEXT:    srli a1, a1, 2
+; RV32-NEXT:    sb a1, 15(sp)
+; RV32-NEXT:    lb a0, 6(sp)
+; RV32-NEXT:    srli a0, a0, 2
+; RV32-NEXT:    sb a0, 14(sp)
+; RV32-NEXT:    lb a0, 5(sp)
+; RV32-NEXT:    srli a0, a0, 2
+; RV32-NEXT:    sb a0, 13(sp)
+; RV32-NEXT:    lb a0, 4(sp)
+; RV32-NEXT:    srli a0, a0, 2
+; RV32-NEXT:    sb a0, 12(sp)
+; RV32-NEXT:    lb a0, 3(sp)
+; RV32-NEXT:    srli a0, a0, 2
+; RV32-NEXT:    sb a0, 11(sp)
+; RV32-NEXT:    lb a0, 2(sp)
+; RV32-NEXT:    srli a0, a0, 2
+; RV32-NEXT:    sb a0, 10(sp)
+; RV32-NEXT:    lb a0, 1(sp)
+; RV32-NEXT:    srli a0, a0, 2
+; RV32-NEXT:    sb a0, 9(sp)
+; RV32-NEXT:    lb a0, 0(sp)
+; RV32-NEXT:    srli a0, a0, 2
+; RV32-NEXT:    sb a0, 8(sp)
+; RV32-NEXT:    lw a0, 8(sp)
+; RV32-NEXT:    lw a1, 12(sp)
+; RV32-NEXT:    addi sp, sp, 16
+; RV32-NEXT:    .cfi_def_cfa_offset 0
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_psrai_b:
@@ -1845,8 +2005,8 @@ define <8 x i8> @test_psrai_b(<8 x i8> %a) {
 define <2 x i32> @test_psslai_w(<2 x i32> %a) {
 ; RV32-LABEL: test_psslai_w:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    sslai a0, a0, 2
 ; RV32-NEXT:    sslai a1, a1, 2
+; RV32-NEXT:    sslai a0, a0, 2
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_psslai_w:
@@ -1861,8 +2021,34 @@ define <2 x i32> @test_psslai_w(<2 x i32> %a) {
 define <4 x i16> @test_psslai_h(<4 x i16> %a) {
 ; RV32-LABEL: test_psslai_h:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    psslai.h a0, a0, 2
-; RV32-NEXT:    psslai.h a1, a1, 2
+; RV32-NEXT:    addi sp, sp, -16
+; RV32-NEXT:    .cfi_def_cfa_offset 16
+; RV32-NEXT:    sw a1, 4(sp)
+; RV32-NEXT:    lh a1, 6(sp)
+; RV32-NEXT:    sw a0, 0(sp)
+; RV32-NEXT:    slli a1, a1, 16
+; RV32-NEXT:    sslai a0, a1, 2
+; RV32-NEXT:    srli a0, a0, 16
+; RV32-NEXT:    sh a0, 14(sp)
+; RV32-NEXT:    lh a0, 4(sp)
+; RV32-NEXT:    slli a0, a0, 16
+; RV32-NEXT:    sslai a0, a0, 2
+; RV32-NEXT:    srli a0, a0, 16
+; RV32-NEXT:    sh a0, 12(sp)
+; RV32-NEXT:    lh a0, 2(sp)
+; RV32-NEXT:    slli a0, a0, 16
+; RV32-NEXT:    sslai a0, a0, 2
+; RV32-NEXT:    srli a0, a0, 16
+; RV32-NEXT:    sh a0, 10(sp)
+; RV32-NEXT:    lh a0, 0(sp)
+; RV32-NEXT:    slli a0, a0, 16
+; RV32-NEXT:    sslai a0, a0, 2
+; RV32-NEXT:    srli a0, a0, 16
+; RV32-NEXT:    sh a0, 8(sp)
+; RV32-NEXT:    lw a0, 8(sp)
+; RV32-NEXT:    lw a1, 12(sp)
+; RV32-NEXT:    addi sp, sp, 16
+; RV32-NEXT:    .cfi_def_cfa_offset 0
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_psslai_h:
@@ -1877,20 +2063,54 @@ define <4 x i16> @test_psslai_h(<4 x i16> %a) {
 define <8 x i8> @test_psslai_b(<8 x i8> %a) {
 ; RV32-LABEL: test_psslai_b:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    pmsltz.b a2, a0
-; RV32-NEXT:    pli.b a3, -128
-; RV32-NEXT:    pli.b a4, 127
-; RV32-NEXT:    pslli.b a5, a0, 2
-; RV32-NEXT:    pmsltz.b a6, a1
-; RV32-NEXT:    merge a2, a4, a3
-; RV32-NEXT:    merge a6, a4, a3
-; RV32-NEXT:    pslli.b a3, a1, 2
-; RV32-NEXT:    psrai.b a4, a5, 2
-; RV32-NEXT:    pmseq.b a0, a0, a4
-; RV32-NEXT:    psrai.b a4, a3, 2
-; RV32-NEXT:    pmseq.b a1, a1, a4
-; RV32-NEXT:    merge a0, a2, a5
-; RV32-NEXT:    merge a1, a6, a3
+; RV32-NEXT:    addi sp, sp, -16
+; RV32-NEXT:    .cfi_def_cfa_offset 16
+; RV32-NEXT:    sw a1, 4(sp)
+; RV32-NEXT:    lbu a1, 7(sp)
+; RV32-NEXT:    sw a0, 0(sp)
+; RV32-NEXT:    slli a1, a1, 24
+; RV32-NEXT:    sslai a0, a1, 2
+; RV32-NEXT:    srli a0, a0, 24
+; RV32-NEXT:    sb a0, 15(sp)
+; RV32-NEXT:    lbu a0, 6(sp)
+; RV32-NEXT:    slli a0, a0, 24
+; RV32-NEXT:    sslai a0, a0, 2
+; RV32-NEXT:    srli a0, a0, 24
+; RV32-NEXT:    sb a0, 14(sp)
+; RV32-NEXT:    lbu a0, 5(sp)
+; RV32-NEXT:    slli a0, a0, 24
+; RV32-NEXT:    sslai a0, a0, 2
+; RV32-NEXT:    srli a0, a0, 24
+; RV32-NEXT:    sb a0, 13(sp)
+; RV32-NEXT:    lbu a0, 4(sp)
+; RV32-NEXT:    slli a0, a0, 24
+; RV32-NEXT:    sslai a0, a0, 2
+; RV32-NEXT:    srli a0, a0, 24
+; RV32-NEXT:    sb a0, 12(sp)
+; RV32-NEXT:    lbu a0, 3(sp)
+; RV32-NEXT:    slli a0, a0, 24
+; RV32-NEXT:    sslai a0, a0, 2
+; RV32-NEXT:    srli a0, a0, 24
+; RV32-NEXT:    sb a0, 11(sp)
+; RV32-NEXT:    lbu a0, 2(sp)
+; RV32-NEXT:    slli a0, a0, 24
+; RV32-NEXT:    sslai a0, a0, 2
+; RV32-NEXT:    srli a0, a0, 24
+; RV32-NEXT:    sb a0, 10(sp)
+; RV32-NEXT:    lbu a0, 1(sp)
+; RV32-NEXT:    slli a0, a0, 24
+; RV32-NEXT:    sslai a0, a0, 2
+; RV32-NEXT:    srli a0, a0, 24
+; RV32-NEXT:    sb a0, 9(sp)
+; RV32-NEXT:    lbu a0, 0(sp)
+; RV32-NEXT:    slli a0, a0, 24
+; RV32-NEXT:    sslai a0, a0, 2
+; RV32-NEXT:    srli a0, a0, 24
+; RV32-NEXT:    sb a0, 8(sp)
+; RV32-NEXT:    lw a0, 8(sp)
+; RV32-NEXT:    lw a1, 12(sp)
+; RV32-NEXT:    addi sp, sp, 16
+; RV32-NEXT:    .cfi_def_cfa_offset 0
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_psslai_b:
@@ -1912,23 +2132,35 @@ define <8 x i8> @test_psslai_b(<8 x i8> %a) {
 define <4 x i16> @test_pssla_hs(<4 x i16> %a, i16 %shamt) {
 ; RV32-LABEL: test_pssla_hs:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    pmsltz.h a3, a0
-; RV32-NEXT:    lui a4, 8
-; RV32-NEXT:    plui.h a5, -512
-; RV32-NEXT:    psll.hs a6, a0, a2
-; RV32-NEXT:    psra.hs a7, a6, a2
-; RV32-NEXT:    pmseq.h a0, a0, a7
-; RV32-NEXT:    psll.hs a7, a1, a2
-; RV32-NEXT:    psra.hs a2, a7, a2
-; RV32-NEXT:    pmseq.h a2, a1, a2
-; RV32-NEXT:    pmsltz.h a1, a1
-; RV32-NEXT:    addi a4, a4, -1
-; RV32-NEXT:    pmv.hs a4, a4
-; RV32-NEXT:    merge a3, a4, a5
-; RV32-NEXT:    merge a1, a4, a5
-; RV32-NEXT:    merge a0, a3, a6
-; RV32-NEXT:    merge a2, a1, a7
-; RV32-NEXT:    mv a1, a2
+; RV32-NEXT:    addi sp, sp, -16
+; RV32-NEXT:    .cfi_def_cfa_offset 16
+; RV32-NEXT:    sw a1, 4(sp)
+; RV32-NEXT:    lh a1, 6(sp)
+; RV32-NEXT:    sw a0, 0(sp)
+; RV32-NEXT:    zext.h a0, a2
+; RV32-NEXT:    slli a1, a1, 16
+; RV32-NEXT:    ssha a1, a1, a0
+; RV32-NEXT:    srli a1, a1, 16
+; RV32-NEXT:    sh a1, 14(sp)
+; RV32-NEXT:    lh a1, 4(sp)
+; RV32-NEXT:    slli a1, a1, 16
+; RV32-NEXT:    ssha a1, a1, a0
+; RV32-NEXT:    srli a1, a1, 16
+; RV32-NEXT:    sh a1, 12(sp)
+; RV32-NEXT:    lh a1, 2(sp)
+; RV32-NEXT:    slli a1, a1, 16
+; RV32-NEXT:    ssha a1, a1, a0
+; RV32-NEXT:    srli a1, a1, 16
+; RV32-NEXT:    sh a1, 10(sp)
+; RV32-NEXT:    lh a1, 0(sp)
+; RV32-NEXT:    slli a1, a1, 16
+; RV32-NEXT:    ssha a0, a1, a0
+; RV32-NEXT:    srli a0, a0, 16
+; RV32-NEXT:    sh a0, 8(sp)
+; RV32-NEXT:    lw a0, 8(sp)
+; RV32-NEXT:    lw a1, 12(sp)
+; RV32-NEXT:    addi sp, sp, 16
+; RV32-NEXT:    .cfi_def_cfa_offset 0
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_pssla_hs:
@@ -1954,8 +2186,8 @@ define <4 x i16> @test_pssla_hs(<4 x i16> %a, i16 %shamt) {
 define <2 x i32> @test_pssla_ws(<2 x i32> %a, i32 %shamt) {
 ; RV32-LABEL: test_pssla_ws:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    ssha a0, a0, a2
 ; RV32-NEXT:    ssha a1, a1, a2
+; RV32-NEXT:    ssha a0, a0, a2
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_pssla_ws:
@@ -1981,38 +2213,40 @@ define <2 x i32> @test_pssla_ws(<2 x i32> %a, i32 %shamt) {
 define <4 x i16> @test_pssla_h(<4 x i16> %a, <4 x i16> %b) {
 ; RV32-LABEL: test_pssla_h:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    sll a4, a0, a2
-; RV32-NEXT:    srli a5, a2, 16
-; RV32-NEXT:    srli a6, a0, 16
-; RV32-NEXT:    pmsltz.h a7, a0
-; RV32-NEXT:    lui t0, 8
-; RV32-NEXT:    plui.h t1, -512
-; RV32-NEXT:    pmsltz.h t2, a1
-; RV32-NEXT:    addi t0, t0, -1
-; RV32-NEXT:    pmv.hs t0, t0
-; RV32-NEXT:    merge a7, t0, t1
-; RV32-NEXT:    merge t2, t0, t1
-; RV32-NEXT:    sll t0, a1, a3
-; RV32-NEXT:    sext.h t1, a4
-; RV32-NEXT:    sra a2, t1, a2
-; RV32-NEXT:    sext.h t1, t0
-; RV32-NEXT:    sra t1, t1, a3
-; RV32-NEXT:    srli a3, a3, 16
-; RV32-NEXT:    sll a6, a6, a5
-; RV32-NEXT:    pack a4, a4, a6
-; RV32-NEXT:    sext.h a6, a6
-; RV32-NEXT:    sra a5, a6, a5
-; RV32-NEXT:    srli a6, a1, 16
-; RV32-NEXT:    sll a6, a6, a3
-; RV32-NEXT:    pack t0, t0, a6
-; RV32-NEXT:    sext.h a6, a6
-; RV32-NEXT:    sra a3, a6, a3
-; RV32-NEXT:    pack a2, a2, a5
-; RV32-NEXT:    pack a3, t1, a3
-; RV32-NEXT:    pmseq.h a0, a0, a2
-; RV32-NEXT:    pmseq.h a1, a1, a3
-; RV32-NEXT:    merge a0, a7, a4
-; RV32-NEXT:    merge a1, t2, t0
+; RV32-NEXT:    addi sp, sp, -32
+; RV32-NEXT:    .cfi_def_cfa_offset 32
+; RV32-NEXT:    sw a1, 12(sp)
+; RV32-NEXT:    sw a3, 20(sp)
+; RV32-NEXT:    sw a0, 8(sp)
+; RV32-NEXT:    sw a2, 16(sp)
+; RV32-NEXT:    lh a0, 14(sp)
+; RV32-NEXT:    lhu a1, 22(sp)
+; RV32-NEXT:    slli a0, a0, 16
+; RV32-NEXT:    ssha a0, a0, a1
+; RV32-NEXT:    srli a0, a0, 16
+; RV32-NEXT:    sh a0, 30(sp)
+; RV32-NEXT:    lh a0, 12(sp)
+; RV32-NEXT:    lhu a1, 20(sp)
+; RV32-NEXT:    slli a0, a0, 16
+; RV32-NEXT:    ssha a0, a0, a1
+; RV32-NEXT:    srli a0, a0, 16
+; RV32-NEXT:    sh a0, 28(sp)
+; RV32-NEXT:    lh a0, 10(sp)
+; RV32-NEXT:    lhu a1, 18(sp)
+; RV32-NEXT:    slli a0, a0, 16
+; RV32-NEXT:    ssha a0, a0, a1
+; RV32-NEXT:    srli a0, a0, 16
+; RV32-NEXT:    sh a0, 26(sp)
+; RV32-NEXT:    lh a0, 8(sp)
+; RV32-NEXT:    lhu a1, 16(sp)
+; RV32-NEXT:    slli a0, a0, 16
+; RV32-NEXT:    ssha a0, a0, a1
+; RV32-NEXT:    srli a0, a0, 16
+; RV32-NEXT:    sh a0, 24(sp)
+; RV32-NEXT:    lw a0, 24(sp)
+; RV32-NEXT:    lw a1, 28(sp)
+; RV32-NEXT:    addi sp, sp, 32
+; RV32-NEXT:    .cfi_def_cfa_offset 0
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_pssla_h:
@@ -2058,8 +2292,8 @@ define <4 x i16> @test_pssla_h(<4 x i16> %a, <4 x i16> %b) {
 define <2 x i32> @test_pssla_w(<2 x i32> %a, <2 x i32> %b) {
 ; RV32-LABEL: test_pssla_w:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    ssha a0, a0, a2
 ; RV32-NEXT:    ssha a1, a1, a3
+; RV32-NEXT:    ssha a0, a0, a2
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_pssla_w:
@@ -2089,8 +2323,26 @@ define <2 x i32> @test_pssla_w(<2 x i32> %a, <2 x i32> %b) {
 define <4 x i16> @test_psll_hs(<4 x i16> %a, i16 %shamt) {
 ; RV32-LABEL: test_psll_hs:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    psll.hs a0, a0, a2
-; RV32-NEXT:    psll.hs a1, a1, a2
+; RV32-NEXT:    addi sp, sp, -16
+; RV32-NEXT:    .cfi_def_cfa_offset 16
+; RV32-NEXT:    sw a1, 4(sp)
+; RV32-NEXT:    lh a1, 6(sp)
+; RV32-NEXT:    sw a0, 0(sp)
+; RV32-NEXT:    sll a0, a1, a2
+; RV32-NEXT:    sh a0, 14(sp)
+; RV32-NEXT:    lh a0, 4(sp)
+; RV32-NEXT:    sll a0, a0, a2
+; RV32-NEXT:    sh a0, 12(sp)
+; RV32-NEXT:    lh a0, 2(sp)
+; RV32-NEXT:    sll a0, a0, a2
+; RV32-NEXT:    sh a0, 10(sp)
+; RV32-NEXT:    lh a0, 0(sp)
+; RV32-NEXT:    sll a0, a0, a2
+; RV32-NEXT:    sh a0, 8(sp)
+; RV32-NEXT:    lw a0, 8(sp)
+; RV32-NEXT:    lw a1, 12(sp)
+; RV32-NEXT:    addi sp, sp, 16
+; RV32-NEXT:    .cfi_def_cfa_offset 0
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_psll_hs:
@@ -2106,8 +2358,27 @@ define <4 x i16> @test_psll_hs(<4 x i16> %a, i16 %shamt) {
 define <4 x i16> @test_psll_hs_mask(<4 x i16> %a, i16 %shamt) {
 ; RV32-LABEL: test_psll_hs_mask:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    psll.hs a0, a0, a2
-; RV32-NEXT:    psll.hs a1, a1, a2
+; RV32-NEXT:    addi sp, sp, -16
+; RV32-NEXT:    .cfi_def_cfa_offset 16
+; RV32-NEXT:    sw a1, 4(sp)
+; RV32-NEXT:    lh a1, 6(sp)
+; RV32-NEXT:    sw a0, 0(sp)
+; RV32-NEXT:    andi a2, a2, 15
+; RV32-NEXT:    sll a0, a1, a2
+; RV32-NEXT:    sh a0, 14(sp)
+; RV32-NEXT:    lh a0, 4(sp)
+; RV32-NEXT:    sll a0, a0, a2
+; RV32-NEXT:    sh a0, 12(sp)
+; RV32-NEXT:    lh a0, 2(sp)
+; RV32-NEXT:    sll a0, a0, a2
+; RV32-NEXT:    sh a0, 10(sp)
+; RV32-NEXT:    lh a0, 0(sp)
+; RV32-NEXT:    sll a0, a0, a2
+; RV32-NEXT:    sh a0, 8(sp)
+; RV32-NEXT:    lw a0, 8(sp)
+; RV32-NEXT:    lw a1, 12(sp)
+; RV32-NEXT:    addi sp, sp, 16
+; RV32-NEXT:    .cfi_def_cfa_offset 0
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_psll_hs_mask:
@@ -2124,8 +2395,38 @@ define <4 x i16> @test_psll_hs_mask(<4 x i16> %a, i16 %shamt) {
 define <8 x i8> @test_psll_bs(<8 x i8> %a, i8 %shamt) {
 ; RV32-LABEL: test_psll_bs:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    psll.bs a0, a0, a2
-; RV32-NEXT:    psll.bs a1, a1, a2
+; RV32-NEXT:    addi sp, sp, -16
+; RV32-NEXT:    .cfi_def_cfa_offset 16
+; RV32-NEXT:    sw a1, 4(sp)
+; RV32-NEXT:    lbu a1, 7(sp)
+; RV32-NEXT:    sw a0, 0(sp)
+; RV32-NEXT:    sll a0, a1, a2
+; RV32-NEXT:    sb a0, 15(sp)
+; RV32-NEXT:    lbu a0, 6(sp)
+; RV32-NEXT:    sll a0, a0, a2
+; RV32-NEXT:    sb a0, 14(sp)
+; RV32-NEXT:    lbu a0, 5(sp)
+; RV32-NEXT:    sll a0, a0, a2
+; RV32-NEXT:    sb a0, 13(sp)
+; RV32-NEXT:    lbu a0, 4(sp)
+; RV32-NEXT:    sll a0, a0, a2
+; RV32-NEXT:    sb a0, 12(sp)
+; RV32-NEXT:    lbu a0, 3(sp)
+; RV32-NEXT:    sll a0, a0, a2
+; RV32-NEXT:    sb a0, 11(sp)
+; RV32-NEXT:    lbu a0, 2(sp)
+; RV32-NEXT:    sll a0, a0, a2
+; RV32-NEXT:    sb a0, 10(sp)
+; RV32-NEXT:    lbu a0, 1(sp)
+; RV32-NEXT:    sll a0, a0, a2
+; RV32-NEXT:    sb a0, 9(sp)
+; RV32-NEXT:    lbu a0, 0(sp)
+; RV32-NEXT:    sll a0, a0, a2
+; RV32-NEXT:    sb a0, 8(sp)
+; RV32-NEXT:    lw a0, 8(sp)
+; RV32-NEXT:    lw a1, 12(sp)
+; RV32-NEXT:    addi sp, sp, 16
+; RV32-NEXT:    .cfi_def_cfa_offset 0
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_psll_bs:
@@ -2141,8 +2442,39 @@ define <8 x i8> @test_psll_bs(<8 x i8> %a, i8 %shamt) {
 define <8 x i8> @test_psll_bs_mask(<8 x i8> %a, i8 %shamt) {
 ; RV32-LABEL: test_psll_bs_mask:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    psll.bs a0, a0, a2
-; RV32-NEXT:    psll.bs a1, a1, a2
+; RV32-NEXT:    addi sp, sp, -16
+; RV32-NEXT:    .cfi_def_cfa_offset 16
+; RV32-NEXT:    sw a1, 4(sp)
+; RV32-NEXT:    lbu a1, 7(sp)
+; RV32-NEXT:    sw a0, 0(sp)
+; RV32-NEXT:    andi a2, a2, 7
+; RV32-NEXT:    sll a0, a1, a2
+; RV32-NEXT:    sb a0, 15(sp)
+; RV32-NEXT:    lbu a0, 6(sp)
+; RV32-NEXT:    sll a0, a0, a2
+; RV32-NEXT:    sb a0, 14(sp)
+; RV32-NEXT:    lbu a0, 5(sp)
+; RV32-NEXT:    sll a0, a0, a2
+; RV32-NEXT:    sb a0, 13(sp)
+; RV32-NEXT:    lbu a0, 4(sp)
+; RV32-NEXT:    sll a0, a0, a2
+; RV32-NEXT:    sb a0, 12(sp)
+; RV32-NEXT:    lbu a0, 3(sp)
+; RV32-NEXT:    sll a0, a0, a2
+; RV32-NEXT:    sb a0, 11(sp)
+; RV32-NEXT:    lbu a0, 2(sp)
+; RV32-NEXT:    sll a0, a0, a2
+; RV32-NEXT:    sb a0, 10(sp)
+; RV32-NEXT:    lbu a0, 1(sp)
+; RV32-NEXT:    sll a0, a0, a2
+; RV32-NEXT:    sb a0, 9(sp)
+; RV32-NEXT:    lbu a0, 0(sp)
+; RV32-NEXT:    sll a0, a0, a2
+; RV32-NEXT:    sb a0, 8(sp)
+; RV32-NEXT:    lw a0, 8(sp)
+; RV32-NEXT:    lw a1, 12(sp)
+; RV32-NEXT:    addi sp, sp, 16
+; RV32-NEXT:    .cfi_def_cfa_offset 0
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_psll_bs_mask:
@@ -2159,8 +2491,8 @@ define <8 x i8> @test_psll_bs_mask(<8 x i8> %a, i8 %shamt) {
 define <2 x i32> @test_psll_ws(<2 x i32> %a, i32 %shamt) {
 ; RV32-LABEL: test_psll_ws:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    sll a0, a0, a2
 ; RV32-NEXT:    sll a1, a1, a2
+; RV32-NEXT:    sll a0, a0, a2
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_psll_ws:
@@ -2176,8 +2508,8 @@ define <2 x i32> @test_psll_ws(<2 x i32> %a, i32 %shamt) {
 define <2 x i32> @test_psll_ws_mask(<2 x i32> %a, i32 %shamt) {
 ; RV32-LABEL: test_psll_ws_mask:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    sll a0, a0, a2
 ; RV32-NEXT:    sll a1, a1, a2
+; RV32-NEXT:    sll a0, a0, a2
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_psll_ws_mask:
@@ -2195,8 +2527,8 @@ define <2 x i32> @test_psll_ws_mask(<2 x i32> %a, i32 %shamt) {
 define <2 x i32> @test_psll_ws_vec_shamt(<2 x i32> %a, <2 x i32> %b) {
 ; RV32-LABEL: test_psll_ws_vec_shamt:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    sll a0, a0, a2
 ; RV32-NEXT:    sll a1, a1, a3
+; RV32-NEXT:    sll a0, a0, a2
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_psll_ws_vec_shamt:
@@ -2215,8 +2547,26 @@ define <2 x i32> @test_psll_ws_vec_shamt(<2 x i32> %a, <2 x i32> %b) {
 define <4 x i16> @test_psrl_hs(<4 x i16> %a, i16 %shamt) {
 ; RV32-LABEL: test_psrl_hs:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    psrl.hs a0, a0, a2
-; RV32-NEXT:    psrl.hs a1, a1, a2
+; RV32-NEXT:    addi sp, sp, -16
+; RV32-NEXT:    .cfi_def_cfa_offset 16
+; RV32-NEXT:    sw a1, 4(sp)
+; RV32-NEXT:    lhu a1, 6(sp)
+; RV32-NEXT:    sw a0, 0(sp)
+; RV32-NEXT:    srl a0, a1, a2
+; RV32-NEXT:    sh a0, 14(sp)
+; RV32-NEXT:    lhu a0, 4(sp)
+; RV32-NEXT:    srl a0, a0, a2
+; RV32-NEXT:    sh a0, 12(sp)
+; RV32-NEXT:    lhu a0, 2(sp)
+; RV32-NEXT:    srl a0, a0, a2
+; RV32-NEXT:    sh a0, 10(sp)
+; RV32-NEXT:    lhu a0, 0(sp)
+; RV32-NEXT:    srl a0, a0, a2
+; RV32-NEXT:    sh a0, 8(sp)
+; RV32-NEXT:    lw a0, 8(sp)
+; RV32-NEXT:    lw a1, 12(sp)
+; RV32-NEXT:    addi sp, sp, 16
+; RV32-NEXT:    .cfi_def_cfa_offset 0
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_psrl_hs:
@@ -2232,8 +2582,27 @@ define <4 x i16> @test_psrl_hs(<4 x i16> %a, i16 %shamt) {
 define <4 x i16> @test_psrl_hs_mask(<4 x i16> %a, i16 %shamt) {
 ; RV32-LABEL: test_psrl_hs_mask:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    psrl.hs a0, a0, a2
-; RV32-NEXT:    psrl.hs a1, a1, a2
+; RV32-NEXT:    addi sp, sp, -16
+; RV32-NEXT:    .cfi_def_cfa_offset 16
+; RV32-NEXT:    sw a1, 4(sp)
+; RV32-NEXT:    lhu a1, 6(sp)
+; RV32-NEXT:    sw a0, 0(sp)
+; RV32-NEXT:    andi a2, a2, 15
+; RV32-NEXT:    srl a0, a1, a2
+; RV32-NEXT:    sh a0, 14(sp)
+; RV32-NEXT:    lhu a0, 4(sp)
+; RV32-NEXT:    srl a0, a0, a2
+; RV32-NEXT:    sh a0, 12(sp)
+; RV32-NEXT:    lhu a0, 2(sp)
+; RV32-NEXT:    srl a0, a0, a2
+; RV32-NEXT:    sh a0, 10(sp)
+; RV32-NEXT:    lhu a0, 0(sp)
+; RV32-NEXT:    srl a0, a0, a2
+; RV32-NEXT:    sh a0, 8(sp)
+; RV32-NEXT:    lw a0, 8(sp)
+; RV32-NEXT:    lw a1, 12(sp)
+; RV32-NEXT:    addi sp, sp, 16
+; RV32-NEXT:    .cfi_def_cfa_offset 0
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_psrl_hs_mask:
@@ -2250,8 +2619,38 @@ define <4 x i16> @test_psrl_hs_mask(<4 x i16> %a, i16 %shamt) {
 define <8 x i8> @test_psrl_bs(<8 x i8> %a, i8 %shamt) {
 ; RV32-LABEL: test_psrl_bs:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    psrl.bs a0, a0, a2
-; RV32-NEXT:    psrl.bs a1, a1, a2
+; RV32-NEXT:    addi sp, sp, -16
+; RV32-NEXT:    .cfi_def_cfa_offset 16
+; RV32-NEXT:    sw a1, 4(sp)
+; RV32-NEXT:    lbu a1, 7(sp)
+; RV32-NEXT:    sw a0, 0(sp)
+; RV32-NEXT:    srl a0, a1, a2
+; RV32-NEXT:    sb a0, 15(sp)
+; RV32-NEXT:    lbu a0, 6(sp)
+; RV32-NEXT:    srl a0, a0, a2
+; RV32-NEXT:    sb a0, 14(sp)
+; RV32-NEXT:    lbu a0, 5(sp)
+; RV32-NEXT:    srl a0, a0, a2
+; RV32-NEXT:    sb a0, 13(sp)
+; RV32-NEXT:    lbu a0, 4(sp)
+; RV32-NEXT:    srl a0, a0, a2
+; RV32-NEXT:    sb a0, 12(sp)
+; RV32-NEXT:    lbu a0, 3(sp)
+; RV32-NEXT:    srl a0, a0, a2
+; RV32-NEXT:    sb a0, 11(sp)
+; RV32-NEXT:    lbu a0, 2(sp)
+; RV32-NEXT:    srl a0, a0, a2
+; RV32-NEXT:    sb a0, 10(sp)
+; RV32-NEXT:    lbu a0, 1(sp)
+; RV32-NEXT:    srl a0, a0, a2
+; RV32-NEXT:    sb a0, 9(sp)
+; RV32-NEXT:    lbu a0, 0(sp)
+; RV32-NEXT:    srl a0, a0, a2
+; RV32-NEXT:    sb a0, 8(sp)
+; RV32-NEXT:    lw a0, 8(sp)
+; RV32-NEXT:    lw a1, 12(sp)
+; RV32-NEXT:    addi sp, sp, 16
+; RV32-NEXT:    .cfi_def_cfa_offset 0
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_psrl_bs:
@@ -2267,8 +2666,39 @@ define <8 x i8> @test_psrl_bs(<8 x i8> %a, i8 %shamt) {
 define <8 x i8> @test_psrl_bs_mask(<8 x i8> %a, i8 %shamt) {
 ; RV32-LABEL: test_psrl_bs_mask:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    psrl.bs a0, a0, a2
-; RV32-NEXT:    psrl.bs a1, a1, a2
+; RV32-NEXT:    addi sp, sp, -16
+; RV32-NEXT:    .cfi_def_cfa_offset 16
+; RV32-NEXT:    sw a1, 4(sp)
+; RV32-NEXT:    lbu a1, 7(sp)
+; RV32-NEXT:    sw a0, 0(sp)
+; RV32-NEXT:    andi a2, a2, 7
+; RV32-NEXT:    srl a0, a1, a2
+; RV32-NEXT:    sb a0, 15(sp)
+; RV32-NEXT:    lbu a0, 6(sp)
+; RV32-NEXT:    srl a0, a0, a2
+; RV32-NEXT:    sb a0, 14(sp)
+; RV32-NEXT:    lbu a0, 5(sp)
+; RV32-NEXT:    srl a0, a0, a2
+; RV32-NEXT:    sb a0, 13(sp)
+; RV32-NEXT:    lbu a0, 4(sp)
+; RV32-NEXT:    srl a0, a0, a2
+; RV32-NEXT:    sb a0, 12(sp)
+; RV32-NEXT:    lbu a0, 3(sp)
+; RV32-NEXT:    srl a0, a0, a2
+; RV32-NEXT:    sb a0, 11(sp)
+; RV32-NEXT:    lbu a0, 2(sp)
+; RV32-NEXT:    srl a0, a0, a2
+; RV32-NEXT:    sb a0, 10(sp)
+; RV32-NEXT:    lbu a0, 1(sp)
+; RV32-NEXT:    srl a0, a0, a2
+; RV32-NEXT:    sb a0, 9(sp)
+; RV32-NEXT:    lbu a0, 0(sp)
+; RV32-NEXT:    srl a0, a0, a2
+; RV32-NEXT:    sb a0, 8(sp)
+; RV32-NEXT:    lw a0, 8(sp)
+; RV32-NEXT:    lw a1, 12(sp)
+; RV32-NEXT:    addi sp, sp, 16
+; RV32-NEXT:    .cfi_def_cfa_offset 0
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_psrl_bs_mask:
@@ -2285,8 +2715,8 @@ define <8 x i8> @test_psrl_bs_mask(<8 x i8> %a, i8 %shamt) {
 define <2 x i32> @test_psrl_ws(<2 x i32> %a, i32 %shamt) {
 ; RV32-LABEL: test_psrl_ws:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    srl a0, a0, a2
 ; RV32-NEXT:    srl a1, a1, a2
+; RV32-NEXT:    srl a0, a0, a2
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_psrl_ws:
@@ -2302,8 +2732,8 @@ define <2 x i32> @test_psrl_ws(<2 x i32> %a, i32 %shamt) {
 define <2 x i32> @test_psrl_ws_mask(<2 x i32> %a, i32 %shamt) {
 ; RV32-LABEL: test_psrl_ws_mask:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    srl a0, a0, a2
 ; RV32-NEXT:    srl a1, a1, a2
+; RV32-NEXT:    srl a0, a0, a2
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_psrl_ws_mask:
@@ -2321,8 +2751,26 @@ define <2 x i32> @test_psrl_ws_mask(<2 x i32> %a, i32 %shamt) {
 define <4 x i16> @test_psra_hs(<4 x i16> %a, i16 %shamt) {
 ; RV32-LABEL: test_psra_hs:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    psra.hs a0, a0, a2
-; RV32-NEXT:    psra.hs a1, a1, a2
+; RV32-NEXT:    addi sp, sp, -16
+; RV32-NEXT:    .cfi_def_cfa_offset 16
+; RV32-NEXT:    sw a1, 4(sp)
+; RV32-NEXT:    lh a1, 6(sp)
+; RV32-NEXT:    sw a0, 0(sp)
+; RV32-NEXT:    sra a0, a1, a2
+; RV32-NEXT:    sh a0, 14(sp)
+; RV32-NEXT:    lh a0, 4(sp)
+; RV32-NEXT:    sra a0, a0, a2
+; RV32-NEXT:    sh a0, 12(sp)
+; RV32-NEXT:    lh a0, 2(sp)
+; RV32-NEXT:    sra a0, a0, a2
+; RV32-NEXT:    sh a0, 10(sp)
+; RV32-NEXT:    lh a0, 0(sp)
+; RV32-NEXT:    sra a0, a0, a2
+; RV32-NEXT:    sh a0, 8(sp)
+; RV32-NEXT:    lw a0, 8(sp)
+; RV32-NEXT:    lw a1, 12(sp)
+; RV32-NEXT:    addi sp, sp, 16
+; RV32-NEXT:    .cfi_def_cfa_offset 0
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_psra_hs:
@@ -2338,8 +2786,27 @@ define <4 x i16> @test_psra_hs(<4 x i16> %a, i16 %shamt) {
 define <4 x i16> @test_psra_hs_mask(<4 x i16> %a, i16 %shamt) {
 ; RV32-LABEL: test_psra_hs_mask:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    psra.hs a0, a0, a2
-; RV32-NEXT:    psra.hs a1, a1, a2
+; RV32-NEXT:    addi sp, sp, -16
+; RV32-NEXT:    .cfi_def_cfa_offset 16
+; RV32-NEXT:    sw a1, 4(sp)
+; RV32-NEXT:    lh a1, 6(sp)
+; RV32-NEXT:    sw a0, 0(sp)
+; RV32-NEXT:    andi a2, a2, 15
+; RV32-NEXT:    sra a0, a1, a2
+; RV32-NEXT:    sh a0, 14(sp)
+; RV32-NEXT:    lh a0, 4(sp)
+; RV32-NEXT:    sra a0, a0, a2
+; RV32-NEXT:    sh a0, 12(sp)
+; RV32-NEXT:    lh a0, 2(sp)
+; RV32-NEXT:    sra a0, a0, a2
+; RV32-NEXT:    sh a0, 10(sp)
+; RV32-NEXT:    lh a0, 0(sp)
+; RV32-NEXT:    sra a0, a0, a2
+; RV32-NEXT:    sh a0, 8(sp)
+; RV32-NEXT:    lw a0, 8(sp)
+; RV32-NEXT:    lw a1, 12(sp)
+; RV32-NEXT:    addi sp, sp, 16
+; RV32-NEXT:    .cfi_def_cfa_offset 0
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_psra_hs_mask:
@@ -2356,8 +2823,38 @@ define <4 x i16> @test_psra_hs_mask(<4 x i16> %a, i16 %shamt) {
 define <8 x i8> @test_psra_bs(<8 x i8> %a, i8 %shamt) {
 ; RV32-LABEL: test_psra_bs:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    psra.bs a0, a0, a2
-; RV32-NEXT:    psra.bs a1, a1, a2
+; RV32-NEXT:    addi sp, sp, -16
+; RV32-NEXT:    .cfi_def_cfa_offset 16
+; RV32-NEXT:    sw a1, 4(sp)
+; RV32-NEXT:    lb a1, 7(sp)
+; RV32-NEXT:    sw a0, 0(sp)
+; RV32-NEXT:    sra a0, a1, a2
+; RV32-NEXT:    sb a0, 15(sp)
+; RV32-NEXT:    lb a0, 6(sp)
+; RV32-NEXT:    sra a0, a0, a2
+; RV32-NEXT:    sb a0, 14(sp)
+; RV32-NEXT:    lb a0, 5(sp)
+; RV32-NEXT:    sra a0, a0, a2
+; RV32-NEXT:    sb a0, 13(sp)
+; RV32-NEXT:    lb a0, 4(sp)
+; RV32-NEXT:    sra a0, a0, a2
+; RV32-NEXT:    sb a0, 12(sp)
+; RV32-NEXT:    lb a0, 3(sp)
+; RV32-NEXT:    sra a0, a0, a2
+; RV32-NEXT:    sb a0, 11(sp)
+; RV32-NEXT:    lb a0, 2(sp)
+; RV32-NEXT:    sra a0, a0, a2
+; RV32-NEXT:    sb a0, 10(sp)
+; RV32-NEXT:    lb a0, 1(sp)
+; RV32-NEXT:    sra a0, a0, a2
+; RV32-NEXT:    sb a0, 9(sp)
+; RV32-NEXT:    lb a0, 0(sp)
+; RV32-NEXT:    sra a0, a0, a2
+; RV32-NEXT:    sb a0, 8(sp)
+; RV32-NEXT:    lw a0, 8(sp)
+; RV32-NEXT:    lw a1, 12(sp)
+; RV32-NEXT:    addi sp, sp, 16
+; RV32-NEXT:    .cfi_def_cfa_offset 0
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_psra_bs:
@@ -2373,8 +2870,39 @@ define <8 x i8> @test_psra_bs(<8 x i8> %a, i8 %shamt) {
 define <8 x i8> @test_psra_bs_mask(<8 x i8> %a, i8 %shamt) {
 ; RV32-LABEL: test_psra_bs_mask:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    psra.bs a0, a0, a2
-; RV32-NEXT:    psra.bs a1, a1, a2
+; RV32-NEXT:    addi sp, sp, -16
+; RV32-NEXT:    .cfi_def_cfa_offset 16
+; RV32-NEXT:    sw a1, 4(sp)
+; RV32-NEXT:    lb a1, 7(sp)
+; RV32-NEXT:    sw a0, 0(sp)
+; RV32-NEXT:    andi a2, a2, 7
+; RV32-NEXT:    sra a0, a1, a2
+; RV32-NEXT:    sb a0, 15(sp)
+; RV32-NEXT:    lb a0, 6(sp)
+; RV32-NEXT:    sra a0, a0, a2
+; RV32-NEXT:    sb a0, 14(sp)
+; RV32-NEXT:    lb a0, 5(sp)
+; RV32-NEXT:    sra a0, a0, a2
+; RV32-NEXT:    sb a0, 13(sp)
+; RV32-NEXT:    lb a0, 4(sp)
+; RV32-NEXT:    sra a0, a0, a2
+; RV32-NEXT:    sb a0, 12(sp)
+; RV32-NEXT:    lb a0, 3(sp)
+; RV32-NEXT:    sra a0, a0, a2
+; RV32-NEXT:    sb a0, 11(sp)
+; RV32-NEXT:    lb a0, 2(sp)
+; RV32-NEXT:    sra a0, a0, a2
+; RV32-NEXT:    sb a0, 10(sp)
+; RV32-NEXT:    lb a0, 1(sp)
+; RV32-NEXT:    sra a0, a0, a2
+; RV32-NEXT:    sb a0, 9(sp)
+; RV32-NEXT:    lb a0, 0(sp)
+; RV32-NEXT:    sra a0, a0, a2
+; RV32-NEXT:    sb a0, 8(sp)
+; RV32-NEXT:    lw a0, 8(sp)
+; RV32-NEXT:    lw a1, 12(sp)
+; RV32-NEXT:    addi sp, sp, 16
+; RV32-NEXT:    .cfi_def_cfa_offset 0
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_psra_bs_mask:
@@ -2391,8 +2919,8 @@ define <8 x i8> @test_psra_bs_mask(<8 x i8> %a, i8 %shamt) {
 define <2 x i32> @test_psra_ws(<2 x i32> %a, i32 %shamt) {
 ; RV32-LABEL: test_psra_ws:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    sra a0, a0, a2
 ; RV32-NEXT:    sra a1, a1, a2
+; RV32-NEXT:    sra a0, a0, a2
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_psra_ws:
@@ -2408,8 +2936,8 @@ define <2 x i32> @test_psra_ws(<2 x i32> %a, i32 %shamt) {
 define <2 x i32> @test_psra_ws_mask(<2 x i32> %a, i32 %shamt) {
 ; RV32-LABEL: test_psra_ws_mask:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    sra a0, a0, a2
 ; RV32-NEXT:    sra a1, a1, a2
+; RV32-NEXT:    sra a0, a0, a2
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_psra_ws_mask:
@@ -2427,8 +2955,8 @@ define <2 x i32> @test_psra_ws_mask(<2 x i32> %a, i32 %shamt) {
 define <2 x i32> @test_psrl_ws_vec_shamt(<2 x i32> %a, <2 x i32> %b) {
 ; RV32-LABEL: test_psrl_ws_vec_shamt:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    srl a0, a0, a2
 ; RV32-NEXT:    srl a1, a1, a3
+; RV32-NEXT:    srl a0, a0, a2
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_psrl_ws_vec_shamt:
@@ -2447,8 +2975,8 @@ define <2 x i32> @test_psrl_ws_vec_shamt(<2 x i32> %a, <2 x i32> %b) {
 define <2 x i32> @test_psra_ws_vec_shamt(<2 x i32> %a, <2 x i32> %b) {
 ; RV32-LABEL: test_psra_ws_vec_shamt:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    sra a0, a0, a2
 ; RV32-NEXT:    sra a1, a1, a3
+; RV32-NEXT:    sra a0, a0, a2
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_psra_ws_vec_shamt:
@@ -2467,8 +2995,8 @@ define <2 x i32> @test_psra_ws_vec_shamt(<2 x i32> %a, <2 x i32> %b) {
 define <4 x i16> @test_pmulh_h(<4 x i16> %a, <4 x i16> %b) {
 ; RV32-LABEL: test_pmulh_h:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    pmulh.h a0, a0, a2
 ; RV32-NEXT:    pmulh.h a1, a1, a3
+; RV32-NEXT:    pmulh.h a0, a0, a2
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_pmulh_h:
@@ -2486,8 +3014,8 @@ define <4 x i16> @test_pmulh_h(<4 x i16> %a, <4 x i16> %b) {
 define <2 x i32> @test_pmulh_w(<2 x i32> %a, <2 x i32> %b) {
 ; RV32-LABEL: test_pmulh_w:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    mulh a0, a0, a2
 ; RV32-NEXT:    mulh a1, a1, a3
+; RV32-NEXT:    mulh a0, a0, a2
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_pmulh_w:
@@ -2506,8 +3034,8 @@ define <2 x i32> @test_pmulh_w(<2 x i32> %a, <2 x i32> %b) {
 define <4 x i16> @test_pmulhu_h(<4 x i16> %a, <4 x i16> %b) {
 ; RV32-LABEL: test_pmulhu_h:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    pmulhu.h a0, a0, a2
 ; RV32-NEXT:    pmulhu.h a1, a1, a3
+; RV32-NEXT:    pmulhu.h a0, a0, a2
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_pmulhu_h:
@@ -2525,8 +3053,8 @@ define <4 x i16> @test_pmulhu_h(<4 x i16> %a, <4 x i16> %b) {
 define <2 x i32> @test_pmulhu_w(<2 x i32> %a, <2 x i32> %b) {
 ; RV32-LABEL: test_pmulhu_w:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    mulhu a0, a0, a2
 ; RV32-NEXT:    mulhu a1, a1, a3
+; RV32-NEXT:    mulhu a0, a0, a2
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_pmulhu_w:
@@ -2545,20 +3073,8 @@ define <2 x i32> @test_pmulhu_w(<2 x i32> %a, <2 x i32> %b) {
 define <4 x i16> @test_pmulhsu_h(<4 x i16> %a, <4 x i16> %b) {
 ; RV32-LABEL: test_pmulhsu_h:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    srai a4, a1, 16
-; RV32-NEXT:    srai a5, a0, 16
-; RV32-NEXT:    srli a6, a3, 16
-; RV32-NEXT:    srli a7, a2, 16
-; RV32-NEXT:    mulsu.h00 a0, a0, a2
-; RV32-NEXT:    mulsu.h00 a1, a1, a3
-; RV32-NEXT:    mul a2, a5, a7
-; RV32-NEXT:    mul a3, a4, a6
-; RV32-NEXT:    srli a1, a1, 16
-; RV32-NEXT:    srli a0, a0, 16
-; RV32-NEXT:    srli a3, a3, 16
-; RV32-NEXT:    srli a2, a2, 16
-; RV32-NEXT:    pack a0, a0, a2
-; RV32-NEXT:    pack a1, a1, a3
+; RV32-NEXT:    pmulhsu.h a1, a1, a3
+; RV32-NEXT:    pmulhsu.h a0, a0, a2
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_pmulhsu_h:
@@ -2576,20 +3092,8 @@ define <4 x i16> @test_pmulhsu_h(<4 x i16> %a, <4 x i16> %b) {
 define <4 x i16> @test_pmulhsu_h_commuted(<4 x i16> %a, <4 x i16> %b) {
 ; RV32-LABEL: test_pmulhsu_h_commuted:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    srli a4, a1, 16
-; RV32-NEXT:    srli a5, a0, 16
-; RV32-NEXT:    srai a6, a3, 16
-; RV32-NEXT:    srai a7, a2, 16
-; RV32-NEXT:    mulsu.h00 a0, a2, a0
-; RV32-NEXT:    mulsu.h00 a1, a3, a1
-; RV32-NEXT:    mul a2, a5, a7
-; RV32-NEXT:    mul a3, a4, a6
-; RV32-NEXT:    srli a1, a1, 16
-; RV32-NEXT:    srli a0, a0, 16
-; RV32-NEXT:    srli a3, a3, 16
-; RV32-NEXT:    srli a2, a2, 16
-; RV32-NEXT:    pack a0, a0, a2
-; RV32-NEXT:    pack a1, a1, a3
+; RV32-NEXT:    pmulhsu.h a1, a3, a1
+; RV32-NEXT:    pmulhsu.h a0, a2, a0
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_pmulhsu_h_commuted:
@@ -2607,8 +3111,8 @@ define <4 x i16> @test_pmulhsu_h_commuted(<4 x i16> %a, <4 x i16> %b) {
 define <2 x i32> @test_pmulhsu_w(<2 x i32> %a, <2 x i32> %b) {
 ; RV32-LABEL: test_pmulhsu_w:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    mulhsu a0, a0, a2
 ; RV32-NEXT:    mulhsu a1, a1, a3
+; RV32-NEXT:    mulhsu a0, a0, a2
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_pmulhsu_w:
@@ -2626,8 +3130,8 @@ define <2 x i32> @test_pmulhsu_w(<2 x i32> %a, <2 x i32> %b) {
 define <2 x i32> @test_pmulhsu_w_commuted(<2 x i32> %a, <2 x i32> %b) {
 ; RV32-LABEL: test_pmulhsu_w_commuted:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    mulhsu a0, a2, a0
 ; RV32-NEXT:    mulhsu a1, a3, a1
+; RV32-NEXT:    mulhsu a0, a2, a0
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_pmulhsu_w_commuted:
@@ -2646,24 +3150,8 @@ define <2 x i32> @test_pmulhsu_w_commuted(<2 x i32> %a, <2 x i32> %b) {
 define <4 x i16> @test_pmulhr_h(<4 x i16> %a, <4 x i16> %b) {
 ; RV32-LABEL: test_pmulhr_h:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    srai a4, a1, 16
-; RV32-NEXT:    srai a5, a0, 16
-; RV32-NEXT:    srai a6, a3, 16
-; RV32-NEXT:    srai a7, a2, 16
-; RV32-NEXT:    lui t0, 8
-; RV32-NEXT:    lui t1, 8
-; RV32-NEXT:    macc.h00 t1, a5, a7
-; RV32-NEXT:    lui a5, 8
-; RV32-NEXT:    lui a7, 8
-; RV32-NEXT:    macc.h00 a5, a0, a2
-; RV32-NEXT:    macc.h00 a7, a4, a6
-; RV32-NEXT:    macc.h00 t0, a1, a3
-; RV32-NEXT:    srli a1, t0, 16
-; RV32-NEXT:    srli a2, a7, 16
-; RV32-NEXT:    srli a5, a5, 16
-; RV32-NEXT:    srli a0, t1, 16
-; RV32-NEXT:    pack a0, a5, a0
-; RV32-NEXT:    pack a1, a1, a2
+; RV32-NEXT:    pmulhr.h a1, a1, a3
+; RV32-NEXT:    pmulhr.h a0, a0, a2
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_pmulhr_h:
@@ -2682,13 +3170,12 @@ define <4 x i16> @test_pmulhr_h(<4 x i16> %a, <4 x i16> %b) {
 define <2 x i32> @test_pmulhr_w(<2 x i32> %a, <2 x i32> %b) {
 ; RV32-LABEL: test_pmulhr_w:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    mv a4, a0
+; RV32-NEXT:    wmul a4, a0, a2
 ; RV32-NEXT:    wmul a0, a1, a3
-; RV32-NEXT:    wmul a2, a4, a2
-; RV32-NEXT:    lui a4, 524288
-; RV32-NEXT:    waddau a2, a4, zero
-; RV32-NEXT:    waddau a0, a4, zero
-; RV32-NEXT:    mv a0, a3
+; RV32-NEXT:    lui a2, 524288
+; RV32-NEXT:    waddau a0, a2, zero
+; RV32-NEXT:    waddau a4, a2, zero
+; RV32-NEXT:    mv a0, a5
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_pmulhr_w:
@@ -2708,24 +3195,8 @@ define <2 x i32> @test_pmulhr_w(<2 x i32> %a, <2 x i32> %b) {
 define <4 x i16> @test_pmulhru_h(<4 x i16> %a, <4 x i16> %b) {
 ; RV32-LABEL: test_pmulhru_h:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    srli a4, a1, 16
-; RV32-NEXT:    srli a5, a0, 16
-; RV32-NEXT:    srli a6, a3, 16
-; RV32-NEXT:    srli a7, a2, 16
-; RV32-NEXT:    lui t0, 8
-; RV32-NEXT:    lui t1, 8
-; RV32-NEXT:    maccu.h00 t1, a5, a7
-; RV32-NEXT:    lui a5, 8
-; RV32-NEXT:    lui a7, 8
-; RV32-NEXT:    maccu.h00 a5, a0, a2
-; RV32-NEXT:    maccu.h00 a7, a4, a6
-; RV32-NEXT:    maccu.h00 t0, a1, a3
-; RV32-NEXT:    srli a1, t0, 16
-; RV32-NEXT:    srli a2, a7, 16
-; RV32-NEXT:    srli a5, a5, 16
-; RV32-NEXT:    srli a0, t1, 16
-; RV32-NEXT:    pack a0, a5, a0
-; RV32-NEXT:    pack a1, a1, a2
+; RV32-NEXT:    pmulhru.h a1, a1, a3
+; RV32-NEXT:    pmulhru.h a0, a0, a2
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_pmulhru_h:
@@ -2744,13 +3215,12 @@ define <4 x i16> @test_pmulhru_h(<4 x i16> %a, <4 x i16> %b) {
 define <2 x i32> @test_pmulhru_w(<2 x i32> %a, <2 x i32> %b) {
 ; RV32-LABEL: test_pmulhru_w:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    mv a4, a0
+; RV32-NEXT:    wmulu a4, a0, a2
 ; RV32-NEXT:    wmulu a0, a1, a3
-; RV32-NEXT:    wmulu a2, a4, a2
-; RV32-NEXT:    lui a4, 524288
-; RV32-NEXT:    waddau a2, a4, zero
-; RV32-NEXT:    waddau a0, a4, zero
-; RV32-NEXT:    mv a0, a3
+; RV32-NEXT:    lui a2, 524288
+; RV32-NEXT:    waddau a0, a2, zero
+; RV32-NEXT:    waddau a4, a2, zero
+; RV32-NEXT:    mv a0, a5
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_pmulhru_w:
@@ -2770,24 +3240,8 @@ define <2 x i32> @test_pmulhru_w(<2 x i32> %a, <2 x i32> %b) {
 define <4 x i16> @test_pmulhrsu_h(<4 x i16> %a, <4 x i16> %b) {
 ; RV32-LABEL: test_pmulhrsu_h:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    srai a4, a1, 16
-; RV32-NEXT:    srai a5, a0, 16
-; RV32-NEXT:    srli a6, a3, 16
-; RV32-NEXT:    srli a7, a2, 16
-; RV32-NEXT:    lui t0, 8
-; RV32-NEXT:    lui t1, 8
-; RV32-NEXT:    maccsu.h00 t1, a5, a7
-; RV32-NEXT:    lui a5, 8
-; RV32-NEXT:    lui a7, 8
-; RV32-NEXT:    maccsu.h00 a5, a0, a2
-; RV32-NEXT:    maccsu.h00 a7, a4, a6
-; RV32-NEXT:    maccsu.h00 t0, a1, a3
-; RV32-NEXT:    srli a1, t0, 16
-; RV32-NEXT:    srli a2, a7, 16
-; RV32-NEXT:    srli a5, a5, 16
-; RV32-NEXT:    srli a0, t1, 16
-; RV32-NEXT:    pack a0, a5, a0
-; RV32-NEXT:    pack a1, a1, a2
+; RV32-NEXT:    pmulhrsu.h a1, a1, a3
+; RV32-NEXT:    pmulhrsu.h a0, a0, a2
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_pmulhrsu_h:
@@ -2806,24 +3260,8 @@ define <4 x i16> @test_pmulhrsu_h(<4 x i16> %a, <4 x i16> %b) {
 define <4 x i16> @test_pmulhrsu_h_commuted(<4 x i16> %a, <4 x i16> %b) {
 ; RV32-LABEL: test_pmulhrsu_h_commuted:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    srli a4, a1, 16
-; RV32-NEXT:    srli a5, a0, 16
-; RV32-NEXT:    srai a6, a3, 16
-; RV32-NEXT:    srai a7, a2, 16
-; RV32-NEXT:    lui t0, 8
-; RV32-NEXT:    lui t1, 8
-; RV32-NEXT:    maccsu.h00 t1, a7, a5
-; RV32-NEXT:    lui a5, 8
-; RV32-NEXT:    lui a7, 8
-; RV32-NEXT:    maccsu.h00 a5, a2, a0
-; RV32-NEXT:    maccsu.h00 a7, a6, a4
-; RV32-NEXT:    maccsu.h00 t0, a3, a1
-; RV32-NEXT:    srli a1, t0, 16
-; RV32-NEXT:    srli a2, a7, 16
-; RV32-NEXT:    srli a5, a5, 16
-; RV32-NEXT:    srli a0, t1, 16
-; RV32-NEXT:    pack a0, a5, a0
-; RV32-NEXT:    pack a1, a1, a2
+; RV32-NEXT:    pmulhrsu.h a1, a3, a1
+; RV32-NEXT:    pmulhrsu.h a0, a2, a0
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_pmulhrsu_h_commuted:
@@ -2842,13 +3280,12 @@ define <4 x i16> @test_pmulhrsu_h_commuted(<4 x i16> %a, <4 x i16> %b) {
 define <2 x i32> @test_pmulhrsu_w(<2 x i32> %a, <2 x i32> %b) {
 ; RV32-LABEL: test_pmulhrsu_w:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    mv a4, a0
+; RV32-NEXT:    wmulsu a4, a0, a2
 ; RV32-NEXT:    wmulsu a0, a1, a3
-; RV32-NEXT:    wmulsu a2, a4, a2
-; RV32-NEXT:    lui a4, 524288
-; RV32-NEXT:    waddau a2, a4, zero
-; RV32-NEXT:    waddau a0, a4, zero
-; RV32-NEXT:    mv a0, a3
+; RV32-NEXT:    lui a2, 524288
+; RV32-NEXT:    waddau a0, a2, zero
+; RV32-NEXT:    waddau a4, a2, zero
+; RV32-NEXT:    mv a0, a5
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_pmulhrsu_w:
@@ -2867,13 +3304,12 @@ define <2 x i32> @test_pmulhrsu_w(<2 x i32> %a, <2 x i32> %b) {
 define <2 x i32> @test_pmulhrsu_w_commuted(<2 x i32> %a, <2 x i32> %b) {
 ; RV32-LABEL: test_pmulhrsu_w_commuted:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    mv a4, a0
+; RV32-NEXT:    wmulsu a4, a2, a0
 ; RV32-NEXT:    wmulsu a0, a3, a1
-; RV32-NEXT:    wmulsu a2, a2, a4
-; RV32-NEXT:    lui a4, 524288
-; RV32-NEXT:    waddau a2, a4, zero
-; RV32-NEXT:    waddau a0, a4, zero
-; RV32-NEXT:    mv a0, a3
+; RV32-NEXT:    lui a2, 524288
+; RV32-NEXT:    waddau a0, a2, zero
+; RV32-NEXT:    waddau a4, a2, zero
+; RV32-NEXT:    mv a0, a5
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_pmulhrsu_w_commuted:
@@ -2893,10 +3329,32 @@ define <2 x i32> @test_pmulhrsu_w_commuted(<2 x i32> %a, <2 x i32> %b) {
 define <4 x i16> @test_pmul_h(<4 x i16> %a, <4 x i16> %b) {
 ; RV32-LABEL: test_pmul_h:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    pwmul.h a4, a0, a2
-; RV32-NEXT:    pwmul.h a2, a1, a3
-; RV32-NEXT:    pncvt.h a0, a4
-; RV32-NEXT:    pncvt.h a1, a2
+; RV32-NEXT:    addi sp, sp, -32
+; RV32-NEXT:    .cfi_def_cfa_offset 32
+; RV32-NEXT:    sw a3, 20(sp)
+; RV32-NEXT:    sw a1, 12(sp)
+; RV32-NEXT:    sw a2, 16(sp)
+; RV32-NEXT:    sw a0, 8(sp)
+; RV32-NEXT:    lh a0, 22(sp)
+; RV32-NEXT:    lh a1, 14(sp)
+; RV32-NEXT:    mul a0, a1, a0
+; RV32-NEXT:    sh a0, 30(sp)
+; RV32-NEXT:    lh a0, 20(sp)
+; RV32-NEXT:    lh a1, 12(sp)
+; RV32-NEXT:    mul a0, a1, a0
+; RV32-NEXT:    sh a0, 28(sp)
+; RV32-NEXT:    lh a0, 18(sp)
+; RV32-NEXT:    lh a1, 10(sp)
+; RV32-NEXT:    mul a0, a1, a0
+; RV32-NEXT:    sh a0, 26(sp)
+; RV32-NEXT:    lh a0, 16(sp)
+; RV32-NEXT:    lh a1, 8(sp)
+; RV32-NEXT:    mul a0, a1, a0
+; RV32-NEXT:    sh a0, 24(sp)
+; RV32-NEXT:    lw a0, 24(sp)
+; RV32-NEXT:    lw a1, 28(sp)
+; RV32-NEXT:    addi sp, sp, 32
+; RV32-NEXT:    .cfi_def_cfa_offset 0
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_pmul_h:
@@ -2913,10 +3371,48 @@ define <4 x i16> @test_pmul_h(<4 x i16> %a, <4 x i16> %b) {
 define <8 x i8> @test_pmul_b(<8 x i8> %a, <8 x i8> %b) {
 ; RV32-LABEL: test_pmul_b:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    pwmul.b a4, a0, a2
-; RV32-NEXT:    pwmul.b a2, a1, a3
-; RV32-NEXT:    pncvt.b a0, a4
-; RV32-NEXT:    pncvt.b a1, a2
+; RV32-NEXT:    addi sp, sp, -32
+; RV32-NEXT:    .cfi_def_cfa_offset 32
+; RV32-NEXT:    sw a3, 20(sp)
+; RV32-NEXT:    sw a1, 12(sp)
+; RV32-NEXT:    sw a2, 16(sp)
+; RV32-NEXT:    sw a0, 8(sp)
+; RV32-NEXT:    lbu a0, 23(sp)
+; RV32-NEXT:    lbu a1, 15(sp)
+; RV32-NEXT:    mul a0, a1, a0
+; RV32-NEXT:    sb a0, 31(sp)
+; RV32-NEXT:    lbu a0, 22(sp)
+; RV32-NEXT:    lbu a1, 14(sp)
+; RV32-NEXT:    mul a0, a1, a0
+; RV32-NEXT:    sb a0, 30(sp)
+; RV32-NEXT:    lbu a0, 21(sp)
+; RV32-NEXT:    lbu a1, 13(sp)
+; RV32-NEXT:    mul a0, a1, a0
+; RV32-NEXT:    sb a0, 29(sp)
+; RV32-NEXT:    lbu a0, 20(sp)
+; RV32-NEXT:    lbu a1, 12(sp)
+; RV32-NEXT:    mul a0, a1, a0
+; RV32-NEXT:    sb a0, 28(sp)
+; RV32-NEXT:    lbu a0, 19(sp)
+; RV32-NEXT:    lbu a1, 11(sp)
+; RV32-NEXT:    mul a0, a1, a0
+; RV32-NEXT:    sb a0, 27(sp)
+; RV32-NEXT:    lbu a0, 18(sp)
+; RV32-NEXT:    lbu a1, 10(sp)
+; RV32-NEXT:    mul a0, a1, a0
+; RV32-NEXT:    sb a0, 26(sp)
+; RV32-NEXT:    lbu a0, 17(sp)
+; RV32-NEXT:    lbu a1, 9(sp)
+; RV32-NEXT:    mul a0, a1, a0
+; RV32-NEXT:    sb a0, 25(sp)
+; RV32-NEXT:    lbu a0, 16(sp)
+; RV32-NEXT:    lbu a1, 8(sp)
+; RV32-NEXT:    mul a0, a1, a0
+; RV32-NEXT:    sb a0, 24(sp)
+; RV32-NEXT:    lw a0, 24(sp)
+; RV32-NEXT:    lw a1, 28(sp)
+; RV32-NEXT:    addi sp, sp, 32
+; RV32-NEXT:    .cfi_def_cfa_offset 0
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_pmul_b:
@@ -2933,8 +3429,8 @@ define <8 x i8> @test_pmul_b(<8 x i8> %a, <8 x i8> %b) {
 define <2 x i32> @test_pmul_w(<2 x i32> %a, <2 x i32> %b) {
 ; RV32-LABEL: test_pmul_w:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    mul a0, a0, a2
 ; RV32-NEXT:    mul a1, a1, a3
+; RV32-NEXT:    mul a0, a0, a2
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_pmul_w:
@@ -2951,20 +3447,32 @@ define <2 x i32> @test_pmul_w(<2 x i32> %a, <2 x i32> %b) {
 define <4 x i16> @test_psdiv_h(<4 x i16> %a, <4 x i16> %b) {
 ; RV32-LABEL: test_psdiv_h:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    srai a4, a2, 16
-; RV32-NEXT:    srai a5, a0, 16
-; RV32-NEXT:    sext.h a2, a2
-; RV32-NEXT:    sext.h a0, a0
-; RV32-NEXT:    div a4, a5, a4
-; RV32-NEXT:    srai a5, a3, 16
-; RV32-NEXT:    div a0, a0, a2
-; RV32-NEXT:    srai a2, a1, 16
-; RV32-NEXT:    sext.h a3, a3
-; RV32-NEXT:    sext.h a1, a1
-; RV32-NEXT:    div a2, a2, a5
-; RV32-NEXT:    div a1, a1, a3
-; RV32-NEXT:    pack a0, a0, a4
-; RV32-NEXT:    pack a1, a1, a2
+; RV32-NEXT:    addi sp, sp, -32
+; RV32-NEXT:    .cfi_def_cfa_offset 32
+; RV32-NEXT:    sw a3, 20(sp)
+; RV32-NEXT:    sw a1, 12(sp)
+; RV32-NEXT:    sw a2, 16(sp)
+; RV32-NEXT:    sw a0, 8(sp)
+; RV32-NEXT:    lh a0, 22(sp)
+; RV32-NEXT:    lh a1, 14(sp)
+; RV32-NEXT:    div a0, a1, a0
+; RV32-NEXT:    sh a0, 30(sp)
+; RV32-NEXT:    lh a0, 20(sp)
+; RV32-NEXT:    lh a1, 12(sp)
+; RV32-NEXT:    div a0, a1, a0
+; RV32-NEXT:    sh a0, 28(sp)
+; RV32-NEXT:    lh a0, 18(sp)
+; RV32-NEXT:    lh a1, 10(sp)
+; RV32-NEXT:    div a0, a1, a0
+; RV32-NEXT:    sh a0, 26(sp)
+; RV32-NEXT:    lh a0, 16(sp)
+; RV32-NEXT:    lh a1, 8(sp)
+; RV32-NEXT:    div a0, a1, a0
+; RV32-NEXT:    sh a0, 24(sp)
+; RV32-NEXT:    lw a0, 24(sp)
+; RV32-NEXT:    lw a1, 28(sp)
+; RV32-NEXT:    addi sp, sp, 32
+; RV32-NEXT:    .cfi_def_cfa_offset 0
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_psdiv_h:
@@ -2996,42 +3504,48 @@ define <4 x i16> @test_psdiv_h(<4 x i16> %a, <4 x i16> %b) {
 define <8 x i8> @test_psdiv_b(<8 x i8> %a, <8 x i8> %b) {
 ; RV32-LABEL: test_psdiv_b:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    srai a4, a2, 24
-; RV32-NEXT:    srai a5, a0, 24
-; RV32-NEXT:    slli a6, a2, 16
-; RV32-NEXT:    slli a7, a0, 16
-; RV32-NEXT:    sext.b t0, a2
-; RV32-NEXT:    sext.b t1, a0
-; RV32-NEXT:    slli a2, a2, 8
-; RV32-NEXT:    slli a0, a0, 8
-; RV32-NEXT:    div a5, a5, a4
-; RV32-NEXT:    srai a4, a6, 24
-; RV32-NEXT:    srai a6, a7, 24
-; RV32-NEXT:    div a4, a6, a4
-; RV32-NEXT:    srai a6, a3, 24
-; RV32-NEXT:    srai a7, a1, 24
-; RV32-NEXT:    div t1, t1, t0
-; RV32-NEXT:    srai a2, a2, 24
-; RV32-NEXT:    srai a0, a0, 24
-; RV32-NEXT:    div t2, a0, a2
-; RV32-NEXT:    slli a0, a3, 16
-; RV32-NEXT:    slli a2, a1, 16
-; RV32-NEXT:    div a7, a7, a6
-; RV32-NEXT:    srai a0, a0, 24
-; RV32-NEXT:    srai a2, a2, 24
-; RV32-NEXT:    div a6, a2, a0
-; RV32-NEXT:    sext.b a0, a3
-; RV32-NEXT:    sext.b a2, a1
-; RV32-NEXT:    slli a3, a3, 8
-; RV32-NEXT:    slli a1, a1, 8
-; RV32-NEXT:    div a0, a2, a0
-; RV32-NEXT:    srai a3, a3, 24
-; RV32-NEXT:    srai a1, a1, 24
-; RV32-NEXT:    div a1, a1, a3
-; RV32-NEXT:    ppaire.db a2, t1, a4
-; RV32-NEXT:    ppaire.db a4, a0, a6
-; RV32-NEXT:    pack a0, a2, a3
-; RV32-NEXT:    pack a1, a4, a5
+; RV32-NEXT:    addi sp, sp, -32
+; RV32-NEXT:    .cfi_def_cfa_offset 32
+; RV32-NEXT:    sw a3, 20(sp)
+; RV32-NEXT:    sw a1, 12(sp)
+; RV32-NEXT:    sw a2, 16(sp)
+; RV32-NEXT:    sw a0, 8(sp)
+; RV32-NEXT:    lb a0, 23(sp)
+; RV32-NEXT:    lb a1, 15(sp)
+; RV32-NEXT:    div a0, a1, a0
+; RV32-NEXT:    sb a0, 31(sp)
+; RV32-NEXT:    lb a0, 22(sp)
+; RV32-NEXT:    lb a1, 14(sp)
+; RV32-NEXT:    div a0, a1, a0
+; RV32-NEXT:    sb a0, 30(sp)
+; RV32-NEXT:    lb a0, 21(sp)
+; RV32-NEXT:    lb a1, 13(sp)
+; RV32-NEXT:    div a0, a1, a0
+; RV32-NEXT:    sb a0, 29(sp)
+; RV32-NEXT:    lb a0, 20(sp)
+; RV32-NEXT:    lb a1, 12(sp)
+; RV32-NEXT:    div a0, a1, a0
+; RV32-NEXT:    sb a0, 28(sp)
+; RV32-NEXT:    lb a0, 19(sp)
+; RV32-NEXT:    lb a1, 11(sp)
+; RV32-NEXT:    div a0, a1, a0
+; RV32-NEXT:    sb a0, 27(sp)
+; RV32-NEXT:    lb a0, 18(sp)
+; RV32-NEXT:    lb a1, 10(sp)
+; RV32-NEXT:    div a0, a1, a0
+; RV32-NEXT:    sb a0, 26(sp)
+; RV32-NEXT:    lb a0, 17(sp)
+; RV32-NEXT:    lb a1, 9(sp)
+; RV32-NEXT:    div a0, a1, a0
+; RV32-NEXT:    sb a0, 25(sp)
+; RV32-NEXT:    lb a0, 16(sp)
+; RV32-NEXT:    lb a1, 8(sp)
+; RV32-NEXT:    div a0, a1, a0
+; RV32-NEXT:    sb a0, 24(sp)
+; RV32-NEXT:    lw a0, 24(sp)
+; RV32-NEXT:    lw a1, 28(sp)
+; RV32-NEXT:    addi sp, sp, 32
+; RV32-NEXT:    .cfi_def_cfa_offset 0
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_psdiv_b:
@@ -3087,8 +3601,8 @@ define <8 x i8> @test_psdiv_b(<8 x i8> %a, <8 x i8> %b) {
 define <2 x i32> @test_psdiv_w(<2 x i32> %a, <2 x i32> %b) {
 ; RV32-LABEL: test_psdiv_w:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    div a0, a0, a2
 ; RV32-NEXT:    div a1, a1, a3
+; RV32-NEXT:    div a0, a0, a2
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_psdiv_w:
@@ -3106,20 +3620,32 @@ define <2 x i32> @test_psdiv_w(<2 x i32> %a, <2 x i32> %b) {
 define <4 x i16> @test_pudiv_h(<4 x i16> %a, <4 x i16> %b) {
 ; RV32-LABEL: test_pudiv_h:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    srli a4, a2, 16
-; RV32-NEXT:    srli a5, a0, 16
-; RV32-NEXT:    zext.h a2, a2
-; RV32-NEXT:    zext.h a0, a0
-; RV32-NEXT:    divu a4, a5, a4
-; RV32-NEXT:    srli a5, a3, 16
-; RV32-NEXT:    divu a0, a0, a2
-; RV32-NEXT:    srli a2, a1, 16
-; RV32-NEXT:    zext.h a3, a3
-; RV32-NEXT:    zext.h a1, a1
-; RV32-NEXT:    divu a2, a2, a5
-; RV32-NEXT:    divu a1, a1, a3
-; RV32-NEXT:    pack a0, a0, a4
-; RV32-NEXT:    pack a1, a1, a2
+; RV32-NEXT:    addi sp, sp, -32
+; RV32-NEXT:    .cfi_def_cfa_offset 32
+; RV32-NEXT:    sw a3, 20(sp)
+; RV32-NEXT:    sw a1, 12(sp)
+; RV32-NEXT:    sw a2, 16(sp)
+; RV32-NEXT:    sw a0, 8(sp)
+; RV32-NEXT:    lhu a0, 22(sp)
+; RV32-NEXT:    lhu a1, 14(sp)
+; RV32-NEXT:    divu a0, a1, a0
+; RV32-NEXT:    sh a0, 30(sp)
+; RV32-NEXT:    lhu a0, 20(sp)
+; RV32-NEXT:    lhu a1, 12(sp)
+; RV32-NEXT:    divu a0, a1, a0
+; RV32-NEXT:    sh a0, 28(sp)
+; RV32-NEXT:    lhu a0, 18(sp)
+; RV32-NEXT:    lhu a1, 10(sp)
+; RV32-NEXT:    divu a0, a1, a0
+; RV32-NEXT:    sh a0, 26(sp)
+; RV32-NEXT:    lhu a0, 16(sp)
+; RV32-NEXT:    lhu a1, 8(sp)
+; RV32-NEXT:    divu a0, a1, a0
+; RV32-NEXT:    sh a0, 24(sp)
+; RV32-NEXT:    lw a0, 24(sp)
+; RV32-NEXT:    lw a1, 28(sp)
+; RV32-NEXT:    addi sp, sp, 32
+; RV32-NEXT:    .cfi_def_cfa_offset 0
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_pudiv_h:
@@ -3149,42 +3675,48 @@ define <4 x i16> @test_pudiv_h(<4 x i16> %a, <4 x i16> %b) {
 define <8 x i8> @test_pudiv_b(<8 x i8> %a, <8 x i8> %b) {
 ; RV32-LABEL: test_pudiv_b:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    srli a4, a2, 24
-; RV32-NEXT:    srli a5, a0, 24
-; RV32-NEXT:    slli a6, a2, 16
-; RV32-NEXT:    slli a7, a0, 16
-; RV32-NEXT:    zext.b t0, a2
-; RV32-NEXT:    zext.b t1, a0
-; RV32-NEXT:    slli a2, a2, 8
-; RV32-NEXT:    slli a0, a0, 8
-; RV32-NEXT:    divu a5, a5, a4
-; RV32-NEXT:    srli a4, a6, 24
-; RV32-NEXT:    srli a6, a7, 24
-; RV32-NEXT:    divu a4, a6, a4
-; RV32-NEXT:    srli a6, a3, 24
-; RV32-NEXT:    srli a7, a1, 24
-; RV32-NEXT:    divu t1, t1, t0
-; RV32-NEXT:    srli a2, a2, 24
-; RV32-NEXT:    srli a0, a0, 24
-; RV32-NEXT:    divu t2, a0, a2
-; RV32-NEXT:    slli a0, a3, 16
-; RV32-NEXT:    slli a2, a1, 16
-; RV32-NEXT:    divu a7, a7, a6
-; RV32-NEXT:    srli a0, a0, 24
-; RV32-NEXT:    srli a2, a2, 24
-; RV32-NEXT:    divu a6, a2, a0
-; RV32-NEXT:    zext.b a0, a3
-; RV32-NEXT:    zext.b a2, a1
-; RV32-NEXT:    slli a3, a3, 8
-; RV32-NEXT:    slli a1, a1, 8
-; RV32-NEXT:    divu a0, a2, a0
-; RV32-NEXT:    srli a3, a3, 24
-; RV32-NEXT:    srli a1, a1, 24
-; RV32-NEXT:    divu a1, a1, a3
-; RV32-NEXT:    ppaire.db a2, t1, a4
-; RV32-NEXT:    ppaire.db a4, a0, a6
-; RV32-NEXT:    pack a0, a2, a3
-; RV32-NEXT:    pack a1, a4, a5
+; RV32-NEXT:    addi sp, sp, -32
+; RV32-NEXT:    .cfi_def_cfa_offset 32
+; RV32-NEXT:    sw a3, 20(sp)
+; RV32-NEXT:    sw a1, 12(sp)
+; RV32-NEXT:    sw a2, 16(sp)
+; RV32-NEXT:    sw a0, 8(sp)
+; RV32-NEXT:    lbu a0, 23(sp)
+; RV32-NEXT:    lbu a1, 15(sp)
+; RV32-NEXT:    divu a0, a1, a0
+; RV32-NEXT:    sb a0, 31(sp)
+; RV32-NEXT:    lbu a0, 22(sp)
+; RV32-NEXT:    lbu a1, 14(sp)
+; RV32-NEXT:    divu a0, a1, a0
+; RV32-NEXT:    sb a0, 30(sp)
+; RV32-NEXT:    lbu a0, 21(sp)
+; RV32-NEXT:    lbu a1, 13(sp)
+; RV32-NEXT:    divu a0, a1, a0
+; RV32-NEXT:    sb a0, 29(sp)
+; RV32-NEXT:    lbu a0, 20(sp)
+; RV32-NEXT:    lbu a1, 12(sp)
+; RV32-NEXT:    divu a0, a1, a0
+; RV32-NEXT:    sb a0, 28(sp)
+; RV32-NEXT:    lbu a0, 19(sp)
+; RV32-NEXT:    lbu a1, 11(sp)
+; RV32-NEXT:    divu a0, a1, a0
+; RV32-NEXT:    sb a0, 27(sp)
+; RV32-NEXT:    lbu a0, 18(sp)
+; RV32-NEXT:    lbu a1, 10(sp)
+; RV32-NEXT:    divu a0, a1, a0
+; RV32-NEXT:    sb a0, 26(sp)
+; RV32-NEXT:    lbu a0, 17(sp)
+; RV32-NEXT:    lbu a1, 9(sp)
+; RV32-NEXT:    divu a0, a1, a0
+; RV32-NEXT:    sb a0, 25(sp)
+; RV32-NEXT:    lbu a0, 16(sp)
+; RV32-NEXT:    lbu a1, 8(sp)
+; RV32-NEXT:    divu a0, a1, a0
+; RV32-NEXT:    sb a0, 24(sp)
+; RV32-NEXT:    lw a0, 24(sp)
+; RV32-NEXT:    lw a1, 28(sp)
+; RV32-NEXT:    addi sp, sp, 32
+; RV32-NEXT:    .cfi_def_cfa_offset 0
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_pudiv_b:
@@ -3238,8 +3770,8 @@ define <8 x i8> @test_pudiv_b(<8 x i8> %a, <8 x i8> %b) {
 define <2 x i32> @test_pudiv_w(<2 x i32> %a, <2 x i32> %b) {
 ; RV32-LABEL: test_pudiv_w:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    divu a0, a0, a2
 ; RV32-NEXT:    divu a1, a1, a3
+; RV32-NEXT:    divu a0, a0, a2
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_pudiv_w:
@@ -3257,20 +3789,32 @@ define <2 x i32> @test_pudiv_w(<2 x i32> %a, <2 x i32> %b) {
 define <4 x i16> @test_psrem_h(<4 x i16> %a, <4 x i16> %b) {
 ; RV32-LABEL: test_psrem_h:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    srai a4, a2, 16
-; RV32-NEXT:    srai a5, a0, 16
-; RV32-NEXT:    sext.h a2, a2
-; RV32-NEXT:    sext.h a0, a0
-; RV32-NEXT:    rem a4, a5, a4
-; RV32-NEXT:    srai a5, a3, 16
-; RV32-NEXT:    rem a0, a0, a2
-; RV32-NEXT:    srai a2, a1, 16
-; RV32-NEXT:    sext.h a3, a3
-; RV32-NEXT:    sext.h a1, a1
-; RV32-NEXT:    rem a2, a2, a5
-; RV32-NEXT:    rem a1, a1, a3
-; RV32-NEXT:    pack a0, a0, a4
-; RV32-NEXT:    pack a1, a1, a2
+; RV32-NEXT:    addi sp, sp, -32
+; RV32-NEXT:    .cfi_def_cfa_offset 32
+; RV32-NEXT:    sw a3, 20(sp)
+; RV32-NEXT:    sw a1, 12(sp)
+; RV32-NEXT:    sw a2, 16(sp)
+; RV32-NEXT:    sw a0, 8(sp)
+; RV32-NEXT:    lh a0, 22(sp)
+; RV32-NEXT:    lh a1, 14(sp)
+; RV32-NEXT:    rem a0, a1, a0
+; RV32-NEXT:    sh a0, 30(sp)
+; RV32-NEXT:    lh a0, 20(sp)
+; RV32-NEXT:    lh a1, 12(sp)
+; RV32-NEXT:    rem a0, a1, a0
+; RV32-NEXT:    sh a0, 28(sp)
+; RV32-NEXT:    lh a0, 18(sp)
+; RV32-NEXT:    lh a1, 10(sp)
+; RV32-NEXT:    rem a0, a1, a0
+; RV32-NEXT:    sh a0, 26(sp)
+; RV32-NEXT:    lh a0, 16(sp)
+; RV32-NEXT:    lh a1, 8(sp)
+; RV32-NEXT:    rem a0, a1, a0
+; RV32-NEXT:    sh a0, 24(sp)
+; RV32-NEXT:    lw a0, 24(sp)
+; RV32-NEXT:    lw a1, 28(sp)
+; RV32-NEXT:    addi sp, sp, 32
+; RV32-NEXT:    .cfi_def_cfa_offset 0
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_psrem_h:
@@ -3302,42 +3846,48 @@ define <4 x i16> @test_psrem_h(<4 x i16> %a, <4 x i16> %b) {
 define <8 x i8> @test_psrem_b(<8 x i8> %a, <8 x i8> %b) {
 ; RV32-LABEL: test_psrem_b:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    srai a4, a2, 24
-; RV32-NEXT:    srai a5, a0, 24
-; RV32-NEXT:    slli a6, a2, 16
-; RV32-NEXT:    slli a7, a0, 16
-; RV32-NEXT:    sext.b t0, a2
-; RV32-NEXT:    sext.b t1, a0
-; RV32-NEXT:    slli a2, a2, 8
-; RV32-NEXT:    slli a0, a0, 8
-; RV32-NEXT:    rem a5, a5, a4
-; RV32-NEXT:    srai a4, a6, 24
-; RV32-NEXT:    srai a6, a7, 24
-; RV32-NEXT:    rem a4, a6, a4
-; RV32-NEXT:    srai a6, a3, 24
-; RV32-NEXT:    srai a7, a1, 24
-; RV32-NEXT:    rem t1, t1, t0
-; RV32-NEXT:    srai a2, a2, 24
-; RV32-NEXT:    srai a0, a0, 24
-; RV32-NEXT:    rem t2, a0, a2
-; RV32-NEXT:    slli a0, a3, 16
-; RV32-NEXT:    slli a2, a1, 16
-; RV32-NEXT:    rem a7, a7, a6
-; RV32-NEXT:    srai a0, a0, 24
-; RV32-NEXT:    srai a2, a2, 24
-; RV32-NEXT:    rem a6, a2, a0
-; RV32-NEXT:    sext.b a0, a3
-; RV32-NEXT:    sext.b a2, a1
-; RV32-NEXT:    slli a3, a3, 8
-; RV32-NEXT:    slli a1, a1, 8
-; RV32-NEXT:    rem a0, a2, a0
-; RV32-NEXT:    srai a3, a3, 24
-; RV32-NEXT:    srai a1, a1, 24
-; RV32-NEXT:    rem a1, a1, a3
-; RV32-NEXT:    ppaire.db a2, t1, a4
-; RV32-NEXT:    ppaire.db a4, a0, a6
-; RV32-NEXT:    pack a0, a2, a3
-; RV32-NEXT:    pack a1, a4, a5
+; RV32-NEXT:    addi sp, sp, -32
+; RV32-NEXT:    .cfi_def_cfa_offset 32
+; RV32-NEXT:    sw a3, 20(sp)
+; RV32-NEXT:    sw a1, 12(sp)
+; RV32-NEXT:    sw a2, 16(sp)
+; RV32-NEXT:    sw a0, 8(sp)
+; RV32-NEXT:    lb a0, 23(sp)
+; RV32-NEXT:    lb a1, 15(sp)
+; RV32-NEXT:    rem a0, a1, a0
+; RV32-NEXT:    sb a0, 31(sp)
+; RV32-NEXT:    lb a0, 22(sp)
+; RV32-NEXT:    lb a1, 14(sp)
+; RV32-NEXT:    rem a0, a1, a0
+; RV32-NEXT:    sb a0, 30(sp)
+; RV32-NEXT:    lb a0, 21(sp)
+; RV32-NEXT:    lb a1, 13(sp)
+; RV32-NEXT:    rem a0, a1, a0
+; RV32-NEXT:    sb a0, 29(sp)
+; RV32-NEXT:    lb a0, 20(sp)
+; RV32-NEXT:    lb a1, 12(sp)
+; RV32-NEXT:    rem a0, a1, a0
+; RV32-NEXT:    sb a0, 28(sp)
+; RV32-NEXT:    lb a0, 19(sp)
+; RV32-NEXT:    lb a1, 11(sp)
+; RV32-NEXT:    rem a0, a1, a0
+; RV32-NEXT:    sb a0, 27(sp)
+; RV32-NEXT:    lb a0, 18(sp)
+; RV32-NEXT:    lb a1, 10(sp)
+; RV32-NEXT:    rem a0, a1, a0
+; RV32-NEXT:    sb a0, 26(sp)
+; RV32-NEXT:    lb a0, 17(sp)
+; RV32-NEXT:    lb a1, 9(sp)
+; RV32-NEXT:    rem a0, a1, a0
+; RV32-NEXT:    sb a0, 25(sp)
+; RV32-NEXT:    lb a0, 16(sp)
+; RV32-NEXT:    lb a1, 8(sp)
+; RV32-NEXT:    rem a0, a1, a0
+; RV32-NEXT:    sb a0, 24(sp)
+; RV32-NEXT:    lw a0, 24(sp)
+; RV32-NEXT:    lw a1, 28(sp)
+; RV32-NEXT:    addi sp, sp, 32
+; RV32-NEXT:    .cfi_def_cfa_offset 0
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_psrem_b:
@@ -3393,8 +3943,8 @@ define <8 x i8> @test_psrem_b(<8 x i8> %a, <8 x i8> %b) {
 define <2 x i32> @test_psrem_w(<2 x i32> %a, <2 x i32> %b) {
 ; RV32-LABEL: test_psrem_w:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    rem a0, a0, a2
 ; RV32-NEXT:    rem a1, a1, a3
+; RV32-NEXT:    rem a0, a0, a2
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_psrem_w:
@@ -3412,20 +3962,32 @@ define <2 x i32> @test_psrem_w(<2 x i32> %a, <2 x i32> %b) {
 define <4 x i16> @test_purem_h(<4 x i16> %a, <4 x i16> %b) {
 ; RV32-LABEL: test_purem_h:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    srli a4, a2, 16
-; RV32-NEXT:    srli a5, a0, 16
-; RV32-NEXT:    zext.h a2, a2
-; RV32-NEXT:    zext.h a0, a0
-; RV32-NEXT:    remu a4, a5, a4
-; RV32-NEXT:    srli a5, a3, 16
-; RV32-NEXT:    remu a0, a0, a2
-; RV32-NEXT:    srli a2, a1, 16
-; RV32-NEXT:    zext.h a3, a3
-; RV32-NEXT:    zext.h a1, a1
-; RV32-NEXT:    remu a2, a2, a5
-; RV32-NEXT:    remu a1, a1, a3
-; RV32-NEXT:    pack a0, a0, a4
-; RV32-NEXT:    pack a1, a1, a2
+; RV32-NEXT:    addi sp, sp, -32
+; RV32-NEXT:    .cfi_def_cfa_offset 32
+; RV32-NEXT:    sw a3, 20(sp)
+; RV32-NEXT:    sw a1, 12(sp)
+; RV32-NEXT:    sw a2, 16(sp)
+; RV32-NEXT:    sw a0, 8(sp)
+; RV32-NEXT:    lhu a0, 22(sp)
+; RV32-NEXT:    lhu a1, 14(sp)
+; RV32-NEXT:    remu a0, a1, a0
+; RV32-NEXT:    sh a0, 30(sp)
+; RV32-NEXT:    lhu a0, 20(sp)
+; RV32-NEXT:    lhu a1, 12(sp)
+; RV32-NEXT:    remu a0, a1, a0
+; RV32-NEXT:    sh a0, 28(sp)
+; RV32-NEXT:    lhu a0, 18(sp)
+; RV32-NEXT:    lhu a1, 10(sp)
+; RV32-NEXT:    remu a0, a1, a0
+; RV32-NEXT:    sh a0, 26(sp)
+; RV32-NEXT:    lhu a0, 16(sp)
+; RV32-NEXT:    lhu a1, 8(sp)
+; RV32-NEXT:    remu a0, a1, a0
+; RV32-NEXT:    sh a0, 24(sp)
+; RV32-NEXT:    lw a0, 24(sp)
+; RV32-NEXT:    lw a1, 28(sp)
+; RV32-NEXT:    addi sp, sp, 32
+; RV32-NEXT:    .cfi_def_cfa_offset 0
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_purem_h:
@@ -3455,42 +4017,48 @@ define <4 x i16> @test_purem_h(<4 x i16> %a, <4 x i16> %b) {
 define <8 x i8> @test_purem_b(<8 x i8> %a, <8 x i8> %b) {
 ; RV32-LABEL: test_purem_b:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    srli a4, a2, 24
-; RV32-NEXT:    srli a5, a0, 24
-; RV32-NEXT:    slli a6, a2, 16
-; RV32-NEXT:    slli a7, a0, 16
-; RV32-NEXT:    zext.b t0, a2
-; RV32-NEXT:    zext.b t1, a0
-; RV32-NEXT:    slli a2, a2, 8
-; RV32-NEXT:    slli a0, a0, 8
-; RV32-NEXT:    remu a5, a5, a4
-; RV32-NEXT:    srli a4, a6, 24
-; RV32-NEXT:    srli a6, a7, 24
-; RV32-NEXT:    remu a4, a6, a4
-; RV32-NEXT:    srli a6, a3, 24
-; RV32-NEXT:    srli a7, a1, 24
-; RV32-NEXT:    remu t1, t1, t0
-; RV32-NEXT:    srli a2, a2, 24
-; RV32-NEXT:    srli a0, a0, 24
-; RV32-NEXT:    remu t2, a0, a2
-; RV32-NEXT:    slli a0, a3, 16
-; RV32-NEXT:    slli a2, a1, 16
-; RV32-NEXT:    remu a7, a7, a6
-; RV32-NEXT:    srli a0, a0, 24
-; RV32-NEXT:    srli a2, a2, 24
-; RV32-NEXT:    remu a6, a2, a0
-; RV32-NEXT:    zext.b a0, a3
-; RV32-NEXT:    zext.b a2, a1
-; RV32-NEXT:    slli a3, a3, 8
-; RV32-NEXT:    slli a1, a1, 8
-; RV32-NEXT:    remu a0, a2, a0
-; RV32-NEXT:    srli a3, a3, 24
-; RV32-NEXT:    srli a1, a1, 24
-; RV32-NEXT:    remu a1, a1, a3
-; RV32-NEXT:    ppaire.db a2, t1, a4
-; RV32-NEXT:    ppaire.db a4, a0, a6
-; RV32-NEXT:    pack a0, a2, a3
-; RV32-NEXT:    pack a1, a4, a5
+; RV32-NEXT:    addi sp, sp, -32
+; RV32-NEXT:    .cfi_def_cfa_offset 32
+; RV32-NEXT:    sw a3, 20(sp)
+; RV32-NEXT:    sw a1, 12(sp)
+; RV32-NEXT:    sw a2, 16(sp)
+; RV32-NEXT:    sw a0, 8(sp)
+; RV32-NEXT:    lbu a0, 23(sp)
+; RV32-NEXT:    lbu a1, 15(sp)
+; RV32-NEXT:    remu a0, a1, a0
+; RV32-NEXT:    sb a0, 31(sp)
+; RV32-NEXT:    lbu a0, 22(sp)
+; RV32-NEXT:    lbu a1, 14(sp)
+; RV32-NEXT:    remu a0, a1, a0
+; RV32-NEXT:    sb a0, 30(sp)
+; RV32-NEXT:    lbu a0, 21(sp)
+; RV32-NEXT:    lbu a1, 13(sp)
+; RV32-NEXT:    remu a0, a1, a0
+; RV32-NEXT:    sb a0, 29(sp)
+; RV32-NEXT:    lbu a0, 20(sp)
+; RV32-NEXT:    lbu a1, 12(sp)
+; RV32-NEXT:    remu a0, a1, a0
+; RV32-NEXT:    sb a0, 28(sp)
+; RV32-NEXT:    lbu a0, 19(sp)
+; RV32-NEXT:    lbu a1, 11(sp)
+; RV32-NEXT:    remu a0, a1, a0
+; RV32-NEXT:    sb a0, 27(sp)
+; RV32-NEXT:    lbu a0, 18(sp)
+; RV32-NEXT:    lbu a1, 10(sp)
+; RV32-NEXT:    remu a0, a1, a0
+; RV32-NEXT:    sb a0, 26(sp)
+; RV32-NEXT:    lbu a0, 17(sp)
+; RV32-NEXT:    lbu a1, 9(sp)
+; RV32-NEXT:    remu a0, a1, a0
+; RV32-NEXT:    sb a0, 25(sp)
+; RV32-NEXT:    lbu a0, 16(sp)
+; RV32-NEXT:    lbu a1, 8(sp)
+; RV32-NEXT:    remu a0, a1, a0
+; RV32-NEXT:    sb a0, 24(sp)
+; RV32-NEXT:    lw a0, 24(sp)
+; RV32-NEXT:    lw a1, 28(sp)
+; RV32-NEXT:    addi sp, sp, 32
+; RV32-NEXT:    .cfi_def_cfa_offset 0
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_purem_b:
@@ -3544,8 +4112,8 @@ define <8 x i8> @test_purem_b(<8 x i8> %a, <8 x i8> %b) {
 define <2 x i32> @test_purem_w(<2 x i32> %a, <2 x i32> %b) {
 ; RV32-LABEL: test_purem_w:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    remu a0, a0, a2
 ; RV32-NEXT:    remu a1, a1, a3
+; RV32-NEXT:    remu a0, a0, a2
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_purem_w:
@@ -3564,8 +4132,40 @@ define <2 x i32> @test_purem_w(<2 x i32> %a, <2 x i32> %b) {
 define <4 x i16> @test_eq_h(<4 x i16> %a, <4 x i16> %b) {
 ; RV32-LABEL: test_eq_h:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    pmseq.h a0, a0, a2
-; RV32-NEXT:    pmseq.h a1, a1, a3
+; RV32-NEXT:    addi sp, sp, -32
+; RV32-NEXT:    .cfi_def_cfa_offset 32
+; RV32-NEXT:    sw a3, 20(sp)
+; RV32-NEXT:    sw a1, 12(sp)
+; RV32-NEXT:    sw a2, 16(sp)
+; RV32-NEXT:    sw a0, 8(sp)
+; RV32-NEXT:    lhu a0, 22(sp)
+; RV32-NEXT:    lhu a1, 14(sp)
+; RV32-NEXT:    xor a0, a1, a0
+; RV32-NEXT:    snez a0, a0
+; RV32-NEXT:    addi a0, a0, -1
+; RV32-NEXT:    sh a0, 30(sp)
+; RV32-NEXT:    lhu a0, 20(sp)
+; RV32-NEXT:    lhu a1, 12(sp)
+; RV32-NEXT:    xor a0, a1, a0
+; RV32-NEXT:    snez a0, a0
+; RV32-NEXT:    addi a0, a0, -1
+; RV32-NEXT:    sh a0, 28(sp)
+; RV32-NEXT:    lhu a0, 18(sp)
+; RV32-NEXT:    lhu a1, 10(sp)
+; RV32-NEXT:    xor a0, a1, a0
+; RV32-NEXT:    snez a0, a0
+; RV32-NEXT:    addi a0, a0, -1
+; RV32-NEXT:    sh a0, 26(sp)
+; RV32-NEXT:    lhu a0, 16(sp)
+; RV32-NEXT:    lhu a1, 8(sp)
+; RV32-NEXT:    xor a0, a1, a0
+; RV32-NEXT:    snez a0, a0
+; RV32-NEXT:    addi a0, a0, -1
+; RV32-NEXT:    sh a0, 24(sp)
+; RV32-NEXT:    lw a0, 24(sp)
+; RV32-NEXT:    lw a1, 28(sp)
+; RV32-NEXT:    addi sp, sp, 32
+; RV32-NEXT:    .cfi_def_cfa_offset 0
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_eq_h:
@@ -3580,10 +4180,40 @@ define <4 x i16> @test_eq_h(<4 x i16> %a, <4 x i16> %b) {
 define <4 x i16> @test_ne_h(<4 x i16> %a, <4 x i16> %b) {
 ; RV32-LABEL: test_ne_h:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    pmseq.h a0, a0, a2
-; RV32-NEXT:    pmseq.h a1, a1, a3
-; RV32-NEXT:    not a0, a0
-; RV32-NEXT:    not a1, a1
+; RV32-NEXT:    addi sp, sp, -32
+; RV32-NEXT:    .cfi_def_cfa_offset 32
+; RV32-NEXT:    sw a3, 20(sp)
+; RV32-NEXT:    sw a1, 12(sp)
+; RV32-NEXT:    sw a2, 16(sp)
+; RV32-NEXT:    sw a0, 8(sp)
+; RV32-NEXT:    lhu a0, 22(sp)
+; RV32-NEXT:    lhu a1, 14(sp)
+; RV32-NEXT:    xor a0, a1, a0
+; RV32-NEXT:    seqz a0, a0
+; RV32-NEXT:    addi a0, a0, -1
+; RV32-NEXT:    sh a0, 30(sp)
+; RV32-NEXT:    lhu a0, 20(sp)
+; RV32-NEXT:    lhu a1, 12(sp)
+; RV32-NEXT:    xor a0, a1, a0
+; RV32-NEXT:    seqz a0, a0
+; RV32-NEXT:    addi a0, a0, -1
+; RV32-NEXT:    sh a0, 28(sp)
+; RV32-NEXT:    lhu a0, 18(sp)
+; RV32-NEXT:    lhu a1, 10(sp)
+; RV32-NEXT:    xor a0, a1, a0
+; RV32-NEXT:    seqz a0, a0
+; RV32-NEXT:    addi a0, a0, -1
+; RV32-NEXT:    sh a0, 26(sp)
+; RV32-NEXT:    lhu a0, 16(sp)
+; RV32-NEXT:    lhu a1, 8(sp)
+; RV32-NEXT:    xor a0, a1, a0
+; RV32-NEXT:    seqz a0, a0
+; RV32-NEXT:    addi a0, a0, -1
+; RV32-NEXT:    sh a0, 24(sp)
+; RV32-NEXT:    lw a0, 24(sp)
+; RV32-NEXT:    lw a1, 28(sp)
+; RV32-NEXT:    addi sp, sp, 32
+; RV32-NEXT:    .cfi_def_cfa_offset 0
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_ne_h:
@@ -3599,8 +4229,36 @@ define <4 x i16> @test_ne_h(<4 x i16> %a, <4 x i16> %b) {
 define <4 x i16> @test_slt_h(<4 x i16> %a, <4 x i16> %b) {
 ; RV32-LABEL: test_slt_h:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    pmslt.h a0, a0, a2
-; RV32-NEXT:    pmslt.h a1, a1, a3
+; RV32-NEXT:    addi sp, sp, -32
+; RV32-NEXT:    .cfi_def_cfa_offset 32
+; RV32-NEXT:    sw a3, 20(sp)
+; RV32-NEXT:    sw a1, 12(sp)
+; RV32-NEXT:    sw a2, 16(sp)
+; RV32-NEXT:    sw a0, 8(sp)
+; RV32-NEXT:    lh a0, 22(sp)
+; RV32-NEXT:    lh a1, 14(sp)
+; RV32-NEXT:    slt a0, a1, a0
+; RV32-NEXT:    neg a0, a0
+; RV32-NEXT:    sh a0, 30(sp)
+; RV32-NEXT:    lh a0, 20(sp)
+; RV32-NEXT:    lh a1, 12(sp)
+; RV32-NEXT:    slt a0, a1, a0
+; RV32-NEXT:    neg a0, a0
+; RV32-NEXT:    sh a0, 28(sp)
+; RV32-NEXT:    lh a0, 18(sp)
+; RV32-NEXT:    lh a1, 10(sp)
+; RV32-NEXT:    slt a0, a1, a0
+; RV32-NEXT:    neg a0, a0
+; RV32-NEXT:    sh a0, 26(sp)
+; RV32-NEXT:    lh a0, 16(sp)
+; RV32-NEXT:    lh a1, 8(sp)
+; RV32-NEXT:    slt a0, a1, a0
+; RV32-NEXT:    neg a0, a0
+; RV32-NEXT:    sh a0, 24(sp)
+; RV32-NEXT:    lw a0, 24(sp)
+; RV32-NEXT:    lw a1, 28(sp)
+; RV32-NEXT:    addi sp, sp, 32
+; RV32-NEXT:    .cfi_def_cfa_offset 0
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_slt_h:
@@ -3615,10 +4273,36 @@ define <4 x i16> @test_slt_h(<4 x i16> %a, <4 x i16> %b) {
 define <4 x i16> @test_sle_h(<4 x i16> %a, <4 x i16> %b) {
 ; RV32-LABEL: test_sle_h:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    pmslt.h a0, a2, a0
-; RV32-NEXT:    pmslt.h a1, a3, a1
-; RV32-NEXT:    not a0, a0
-; RV32-NEXT:    not a1, a1
+; RV32-NEXT:    addi sp, sp, -32
+; RV32-NEXT:    .cfi_def_cfa_offset 32
+; RV32-NEXT:    sw a1, 12(sp)
+; RV32-NEXT:    sw a3, 20(sp)
+; RV32-NEXT:    sw a0, 8(sp)
+; RV32-NEXT:    sw a2, 16(sp)
+; RV32-NEXT:    lh a0, 14(sp)
+; RV32-NEXT:    lh a1, 22(sp)
+; RV32-NEXT:    slt a0, a1, a0
+; RV32-NEXT:    addi a0, a0, -1
+; RV32-NEXT:    sh a0, 30(sp)
+; RV32-NEXT:    lh a0, 12(sp)
+; RV32-NEXT:    lh a1, 20(sp)
+; RV32-NEXT:    slt a0, a1, a0
+; RV32-NEXT:    addi a0, a0, -1
+; RV32-NEXT:    sh a0, 28(sp)
+; RV32-NEXT:    lh a0, 10(sp)
+; RV32-NEXT:    lh a1, 18(sp)
+; RV32-NEXT:    slt a0, a1, a0
+; RV32-NEXT:    addi a0, a0, -1
+; RV32-NEXT:    sh a0, 26(sp)
+; RV32-NEXT:    lh a0, 8(sp)
+; RV32-NEXT:    lh a1, 16(sp)
+; RV32-NEXT:    slt a0, a1, a0
+; RV32-NEXT:    addi a0, a0, -1
+; RV32-NEXT:    sh a0, 24(sp)
+; RV32-NEXT:    lw a0, 24(sp)
+; RV32-NEXT:    lw a1, 28(sp)
+; RV32-NEXT:    addi sp, sp, 32
+; RV32-NEXT:    .cfi_def_cfa_offset 0
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_sle_h:
@@ -3634,8 +4318,36 @@ define <4 x i16> @test_sle_h(<4 x i16> %a, <4 x i16> %b) {
 define <4 x i16> @test_sgt_h(<4 x i16> %a, <4 x i16> %b) {
 ; RV32-LABEL: test_sgt_h:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    pmslt.h a0, a2, a0
-; RV32-NEXT:    pmslt.h a1, a3, a1
+; RV32-NEXT:    addi sp, sp, -32
+; RV32-NEXT:    .cfi_def_cfa_offset 32
+; RV32-NEXT:    sw a1, 12(sp)
+; RV32-NEXT:    sw a3, 20(sp)
+; RV32-NEXT:    sw a0, 8(sp)
+; RV32-NEXT:    sw a2, 16(sp)
+; RV32-NEXT:    lh a0, 14(sp)
+; RV32-NEXT:    lh a1, 22(sp)
+; RV32-NEXT:    slt a0, a1, a0
+; RV32-NEXT:    neg a0, a0
+; RV32-NEXT:    sh a0, 30(sp)
+; RV32-NEXT:    lh a0, 12(sp)
+; RV32-NEXT:    lh a1, 20(sp)
+; RV32-NEXT:    slt a0, a1, a0
+; RV32-NEXT:    neg a0, a0
+; RV32-NEXT:    sh a0, 28(sp)
+; RV32-NEXT:    lh a0, 10(sp)
+; RV32-NEXT:    lh a1, 18(sp)
+; RV32-NEXT:    slt a0, a1, a0
+; RV32-NEXT:    neg a0, a0
+; RV32-NEXT:    sh a0, 26(sp)
+; RV32-NEXT:    lh a0, 8(sp)
+; RV32-NEXT:    lh a1, 16(sp)
+; RV32-NEXT:    slt a0, a1, a0
+; RV32-NEXT:    neg a0, a0
+; RV32-NEXT:    sh a0, 24(sp)
+; RV32-NEXT:    lw a0, 24(sp)
+; RV32-NEXT:    lw a1, 28(sp)
+; RV32-NEXT:    addi sp, sp, 32
+; RV32-NEXT:    .cfi_def_cfa_offset 0
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_sgt_h:
@@ -3650,10 +4362,36 @@ define <4 x i16> @test_sgt_h(<4 x i16> %a, <4 x i16> %b) {
 define <4 x i16> @test_sge_h(<4 x i16> %a, <4 x i16> %b) {
 ; RV32-LABEL: test_sge_h:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    pmslt.h a0, a0, a2
-; RV32-NEXT:    pmslt.h a1, a1, a3
-; RV32-NEXT:    not a0, a0
-; RV32-NEXT:    not a1, a1
+; RV32-NEXT:    addi sp, sp, -32
+; RV32-NEXT:    .cfi_def_cfa_offset 32
+; RV32-NEXT:    sw a3, 20(sp)
+; RV32-NEXT:    sw a1, 12(sp)
+; RV32-NEXT:    sw a2, 16(sp)
+; RV32-NEXT:    sw a0, 8(sp)
+; RV32-NEXT:    lh a0, 22(sp)
+; RV32-NEXT:    lh a1, 14(sp)
+; RV32-NEXT:    slt a0, a1, a0
+; RV32-NEXT:    addi a0, a0, -1
+; RV32-NEXT:    sh a0, 30(sp)
+; RV32-NEXT:    lh a0, 20(sp)
+; RV32-NEXT:    lh a1, 12(sp)
+; RV32-NEXT:    slt a0, a1, a0
+; RV32-NEXT:    addi a0, a0, -1
+; RV32-NEXT:    sh a0, 28(sp)
+; RV32-NEXT:    lh a0, 18(sp)
+; RV32-NEXT:    lh a1, 10(sp)
+; RV32-NEXT:    slt a0, a1, a0
+; RV32-NEXT:    addi a0, a0, -1
+; RV32-NEXT:    sh a0, 26(sp)
+; RV32-NEXT:    lh a0, 16(sp)
+; RV32-NEXT:    lh a1, 8(sp)
+; RV32-NEXT:    slt a0, a1, a0
+; RV32-NEXT:    addi a0, a0, -1
+; RV32-NEXT:    sh a0, 24(sp)
+; RV32-NEXT:    lw a0, 24(sp)
+; RV32-NEXT:    lw a1, 28(sp)
+; RV32-NEXT:    addi sp, sp, 32
+; RV32-NEXT:    .cfi_def_cfa_offset 0
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_sge_h:
@@ -3669,8 +4407,36 @@ define <4 x i16> @test_sge_h(<4 x i16> %a, <4 x i16> %b) {
 define <4 x i16> @test_ult_h(<4 x i16> %a, <4 x i16> %b) {
 ; RV32-LABEL: test_ult_h:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    pmsltu.h a0, a0, a2
-; RV32-NEXT:    pmsltu.h a1, a1, a3
+; RV32-NEXT:    addi sp, sp, -32
+; RV32-NEXT:    .cfi_def_cfa_offset 32
+; RV32-NEXT:    sw a3, 20(sp)
+; RV32-NEXT:    sw a1, 12(sp)
+; RV32-NEXT:    sw a2, 16(sp)
+; RV32-NEXT:    sw a0, 8(sp)
+; RV32-NEXT:    lhu a0, 22(sp)
+; RV32-NEXT:    lhu a1, 14(sp)
+; RV32-NEXT:    sltu a0, a1, a0
+; RV32-NEXT:    neg a0, a0
+; RV32-NEXT:    sh a0, 30(sp)
+; RV32-NEXT:    lhu a0, 20(sp)
+; RV32-NEXT:    lhu a1, 12(sp)
+; RV32-NEXT:    sltu a0, a1, a0
+; RV32-NEXT:    neg a0, a0
+; RV32-NEXT:    sh a0, 28(sp)
+; RV32-NEXT:    lhu a0, 18(sp)
+; RV32-NEXT:    lhu a1, 10(sp)
+; RV32-NEXT:    sltu a0, a1, a0
+; RV32-NEXT:    neg a0, a0
+; RV32-NEXT:    sh a0, 26(sp)
+; RV32-NEXT:    lhu a0, 16(sp)
+; RV32-NEXT:    lhu a1, 8(sp)
+; RV32-NEXT:    sltu a0, a1, a0
+; RV32-NEXT:    neg a0, a0
+; RV32-NEXT:    sh a0, 24(sp)
+; RV32-NEXT:    lw a0, 24(sp)
+; RV32-NEXT:    lw a1, 28(sp)
+; RV32-NEXT:    addi sp, sp, 32
+; RV32-NEXT:    .cfi_def_cfa_offset 0
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_ult_h:
@@ -3685,10 +4451,36 @@ define <4 x i16> @test_ult_h(<4 x i16> %a, <4 x i16> %b) {
 define <4 x i16> @test_ule_h(<4 x i16> %a, <4 x i16> %b) {
 ; RV32-LABEL: test_ule_h:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    pmsltu.h a0, a2, a0
-; RV32-NEXT:    pmsltu.h a1, a3, a1
-; RV32-NEXT:    not a0, a0
-; RV32-NEXT:    not a1, a1
+; RV32-NEXT:    addi sp, sp, -32
+; RV32-NEXT:    .cfi_def_cfa_offset 32
+; RV32-NEXT:    sw a1, 12(sp)
+; RV32-NEXT:    sw a3, 20(sp)
+; RV32-NEXT:    sw a0, 8(sp)
+; RV32-NEXT:    sw a2, 16(sp)
+; RV32-NEXT:    lhu a0, 14(sp)
+; RV32-NEXT:    lhu a1, 22(sp)
+; RV32-NEXT:    sltu a0, a1, a0
+; RV32-NEXT:    addi a0, a0, -1
+; RV32-NEXT:    sh a0, 30(sp)
+; RV32-NEXT:    lhu a0, 12(sp)
+; RV32-NEXT:    lhu a1, 20(sp)
+; RV32-NEXT:    sltu a0, a1, a0
+; RV32-NEXT:    addi a0, a0, -1
+; RV32-NEXT:    sh a0, 28(sp)
+; RV32-NEXT:    lhu a0, 10(sp)
+; RV32-NEXT:    lhu a1, 18(sp)
+; RV32-NEXT:    sltu a0, a1, a0
+; RV32-NEXT:    addi a0, a0, -1
+; RV32-NEXT:    sh a0, 26(sp)
+; RV32-NEXT:    lhu a0, 8(sp)
+; RV32-NEXT:    lhu a1, 16(sp)
+; RV32-NEXT:    sltu a0, a1, a0
+; RV32-NEXT:    addi a0, a0, -1
+; RV32-NEXT:    sh a0, 24(sp)
+; RV32-NEXT:    lw a0, 24(sp)
+; RV32-NEXT:    lw a1, 28(sp)
+; RV32-NEXT:    addi sp, sp, 32
+; RV32-NEXT:    .cfi_def_cfa_offset 0
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_ule_h:
@@ -3704,8 +4496,36 @@ define <4 x i16> @test_ule_h(<4 x i16> %a, <4 x i16> %b) {
 define <4 x i16> @test_ugt_h(<4 x i16> %a, <4 x i16> %b) {
 ; RV32-LABEL: test_ugt_h:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    pmsltu.h a0, a2, a0
-; RV32-NEXT:    pmsltu.h a1, a3, a1
+; RV32-NEXT:    addi sp, sp, -32
+; RV32-NEXT:    .cfi_def_cfa_offset 32
+; RV32-NEXT:    sw a1, 12(sp)
+; RV32-NEXT:    sw a3, 20(sp)
+; RV32-NEXT:    sw a0, 8(sp)
+; RV32-NEXT:    sw a2, 16(sp)
+; RV32-NEXT:    lhu a0, 14(sp)
+; RV32-NEXT:    lhu a1, 22(sp)
+; RV32-NEXT:    sltu a0, a1, a0
+; RV32-NEXT:    neg a0, a0
+; RV32-NEXT:    sh a0, 30(sp)
+; RV32-NEXT:    lhu a0, 12(sp)
+; RV32-NEXT:    lhu a1, 20(sp)
+; RV32-NEXT:    sltu a0, a1, a0
+; RV32-NEXT:    neg a0, a0
+; RV32-NEXT:    sh a0, 28(sp)
+; RV32-NEXT:    lhu a0, 10(sp)
+; RV32-NEXT:    lhu a1, 18(sp)
+; RV32-NEXT:    sltu a0, a1, a0
+; RV32-NEXT:    neg a0, a0
+; RV32-NEXT:    sh a0, 26(sp)
+; RV32-NEXT:    lhu a0, 8(sp)
+; RV32-NEXT:    lhu a1, 16(sp)
+; RV32-NEXT:    sltu a0, a1, a0
+; RV32-NEXT:    neg a0, a0
+; RV32-NEXT:    sh a0, 24(sp)
+; RV32-NEXT:    lw a0, 24(sp)
+; RV32-NEXT:    lw a1, 28(sp)
+; RV32-NEXT:    addi sp, sp, 32
+; RV32-NEXT:    .cfi_def_cfa_offset 0
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_ugt_h:
@@ -3720,10 +4540,36 @@ define <4 x i16> @test_ugt_h(<4 x i16> %a, <4 x i16> %b) {
 define <4 x i16> @test_uge_h(<4 x i16> %a, <4 x i16> %b) {
 ; RV32-LABEL: test_uge_h:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    pmsltu.h a0, a0, a2
-; RV32-NEXT:    pmsltu.h a1, a1, a3
-; RV32-NEXT:    not a0, a0
-; RV32-NEXT:    not a1, a1
+; RV32-NEXT:    addi sp, sp, -32
+; RV32-NEXT:    .cfi_def_cfa_offset 32
+; RV32-NEXT:    sw a3, 20(sp)
+; RV32-NEXT:    sw a1, 12(sp)
+; RV32-NEXT:    sw a2, 16(sp)
+; RV32-NEXT:    sw a0, 8(sp)
+; RV32-NEXT:    lhu a0, 22(sp)
+; RV32-NEXT:    lhu a1, 14(sp)
+; RV32-NEXT:    sltu a0, a1, a0
+; RV32-NEXT:    addi a0, a0, -1
+; RV32-NEXT:    sh a0, 30(sp)
+; RV32-NEXT:    lhu a0, 20(sp)
+; RV32-NEXT:    lhu a1, 12(sp)
+; RV32-NEXT:    sltu a0, a1, a0
+; RV32-NEXT:    addi a0, a0, -1
+; RV32-NEXT:    sh a0, 28(sp)
+; RV32-NEXT:    lhu a0, 18(sp)
+; RV32-NEXT:    lhu a1, 10(sp)
+; RV32-NEXT:    sltu a0, a1, a0
+; RV32-NEXT:    addi a0, a0, -1
+; RV32-NEXT:    sh a0, 26(sp)
+; RV32-NEXT:    lhu a0, 16(sp)
+; RV32-NEXT:    lhu a1, 8(sp)
+; RV32-NEXT:    sltu a0, a1, a0
+; RV32-NEXT:    addi a0, a0, -1
+; RV32-NEXT:    sh a0, 24(sp)
+; RV32-NEXT:    lw a0, 24(sp)
+; RV32-NEXT:    lw a1, 28(sp)
+; RV32-NEXT:    addi sp, sp, 32
+; RV32-NEXT:    .cfi_def_cfa_offset 0
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_uge_h:
@@ -3740,8 +4586,64 @@ define <4 x i16> @test_uge_h(<4 x i16> %a, <4 x i16> %b) {
 define <8 x i8> @test_eq_b(<8 x i8> %a, <8 x i8> %b) {
 ; RV32-LABEL: test_eq_b:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    pmseq.b a0, a0, a2
-; RV32-NEXT:    pmseq.b a1, a1, a3
+; RV32-NEXT:    addi sp, sp, -32
+; RV32-NEXT:    .cfi_def_cfa_offset 32
+; RV32-NEXT:    sw a3, 20(sp)
+; RV32-NEXT:    sw a1, 12(sp)
+; RV32-NEXT:    sw a2, 16(sp)
+; RV32-NEXT:    sw a0, 8(sp)
+; RV32-NEXT:    lbu a0, 23(sp)
+; RV32-NEXT:    lbu a1, 15(sp)
+; RV32-NEXT:    xor a0, a1, a0
+; RV32-NEXT:    snez a0, a0
+; RV32-NEXT:    addi a0, a0, -1
+; RV32-NEXT:    sb a0, 31(sp)
+; RV32-NEXT:    lbu a0, 22(sp)
+; RV32-NEXT:    lbu a1, 14(sp)
+; RV32-NEXT:    xor a0, a1, a0
+; RV32-NEXT:    snez a0, a0
+; RV32-NEXT:    addi a0, a0, -1
+; RV32-NEXT:    sb a0, 30(sp)
+; RV32-NEXT:    lbu a0, 21(sp)
+; RV32-NEXT:    lbu a1, 13(sp)
+; RV32-NEXT:    xor a0, a1, a0
+; RV32-NEXT:    snez a0, a0
+; RV32-NEXT:    addi a0, a0, -1
+; RV32-NEXT:    sb a0, 29(sp)
+; RV32-NEXT:    lbu a0, 20(sp)
+; RV32-NEXT:    lbu a1, 12(sp)
+; RV32-NEXT:    xor a0, a1, a0
+; RV32-NEXT:    snez a0, a0
+; RV32-NEXT:    addi a0, a0, -1
+; RV32-NEXT:    sb a0, 28(sp)
+; RV32-NEXT:    lbu a0, 19(sp)
+; RV32-NEXT:    lbu a1, 11(sp)
+; RV32-NEXT:    xor a0, a1, a0
+; RV32-NEXT:    snez a0, a0
+; RV32-NEXT:    addi a0, a0, -1
+; RV32-NEXT:    sb a0, 27(sp)
+; RV32-NEXT:    lbu a0, 18(sp)
+; RV32-NEXT:    lbu a1, 10(sp)
+; RV32-NEXT:    xor a0, a1, a0
+; RV32-NEXT:    snez a0, a0
+; RV32-NEXT:    addi a0, a0, -1
+; RV32-NEXT:    sb a0, 26(sp)
+; RV32-NEXT:    lbu a0, 17(sp)
+; RV32-NEXT:    lbu a1, 9(sp)
+; RV32-NEXT:    xor a0, a1, a0
+; RV32-NEXT:    snez a0, a0
+; RV32-NEXT:    addi a0, a0, -1
+; RV32-NEXT:    sb a0, 25(sp)
+; RV32-NEXT:    lbu a0, 16(sp)
+; RV32-NEXT:    lbu a1, 8(sp)
+; RV32-NEXT:    xor a0, a1, a0
+; RV32-NEXT:    snez a0, a0
+; RV32-NEXT:    addi a0, a0, -1
+; RV32-NEXT:    sb a0, 24(sp)
+; RV32-NEXT:    lw a0, 24(sp)
+; RV32-NEXT:    lw a1, 28(sp)
+; RV32-NEXT:    addi sp, sp, 32
+; RV32-NEXT:    .cfi_def_cfa_offset 0
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_eq_b:
@@ -3756,10 +4658,64 @@ define <8 x i8> @test_eq_b(<8 x i8> %a, <8 x i8> %b) {
 define <8 x i8> @test_ne_b(<8 x i8> %a, <8 x i8> %b) {
 ; RV32-LABEL: test_ne_b:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    pmseq.b a0, a0, a2
-; RV32-NEXT:    pmseq.b a1, a1, a3
-; RV32-NEXT:    not a0, a0
-; RV32-NEXT:    not a1, a1
+; RV32-NEXT:    addi sp, sp, -32
+; RV32-NEXT:    .cfi_def_cfa_offset 32
+; RV32-NEXT:    sw a3, 20(sp)
+; RV32-NEXT:    sw a1, 12(sp)
+; RV32-NEXT:    sw a2, 16(sp)
+; RV32-NEXT:    sw a0, 8(sp)
+; RV32-NEXT:    lbu a0, 23(sp)
+; RV32-NEXT:    lbu a1, 15(sp)
+; RV32-NEXT:    xor a0, a1, a0
+; RV32-NEXT:    seqz a0, a0
+; RV32-NEXT:    addi a0, a0, -1
+; RV32-NEXT:    sb a0, 31(sp)
+; RV32-NEXT:    lbu a0, 22(sp)
+; RV32-NEXT:    lbu a1, 14(sp)
+; RV32-NEXT:    xor a0, a1, a0
+; RV32-NEXT:    seqz a0, a0
+; RV32-NEXT:    addi a0, a0, -1
+; RV32-NEXT:    sb a0, 30(sp)
+; RV32-NEXT:    lbu a0, 21(sp)
+; RV32-NEXT:    lbu a1, 13(sp)
+; RV32-NEXT:    xor a0, a1, a0
+; RV32-NEXT:    seqz a0, a0
+; RV32-NEXT:    addi a0, a0, -1
+; RV32-NEXT:    sb a0, 29(sp)
+; RV32-NEXT:    lbu a0, 20(sp)
+; RV32-NEXT:    lbu a1, 12(sp)
+; RV32-NEXT:    xor a0, a1, a0
+; RV32-NEXT:    seqz a0, a0
+; RV32-NEXT:    addi a0, a0, -1
+; RV32-NEXT:    sb a0, 28(sp)
+; RV32-NEXT:    lbu a0, 19(sp)
+; RV32-NEXT:    lbu a1, 11(sp)
+; RV32-NEXT:    xor a0, a1, a0
+; RV32-NEXT:    seqz a0, a0
+; RV32-NEXT:    addi a0, a0, -1
+; RV32-NEXT:    sb a0, 27(sp)
+; RV32-NEXT:    lbu a0, 18(sp)
+; RV32-NEXT:    lbu a1, 10(sp)
+; RV32-NEXT:    xor a0, a1, a0
+; RV32-NEXT:    seqz a0, a0
+; RV32-NEXT:    addi a0, a0, -1
+; RV32-NEXT:    sb a0, 26(sp)
+; RV32-NEXT:    lbu a0, 17(sp)
+; RV32-NEXT:    lbu a1, 9(sp)
+; RV32-NEXT:    xor a0, a1, a0
+; RV32-NEXT:    seqz a0, a0
+; RV32-NEXT:    addi a0, a0, -1
+; RV32-NEXT:    sb a0, 25(sp)
+; RV32-NEXT:    lbu a0, 16(sp)
+; RV32-NEXT:    lbu a1, 8(sp)
+; RV32-NEXT:    xor a0, a1, a0
+; RV32-NEXT:    seqz a0, a0
+; RV32-NEXT:    addi a0, a0, -1
+; RV32-NEXT:    sb a0, 24(sp)
+; RV32-NEXT:    lw a0, 24(sp)
+; RV32-NEXT:    lw a1, 28(sp)
+; RV32-NEXT:    addi sp, sp, 32
+; RV32-NEXT:    .cfi_def_cfa_offset 0
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_ne_b:
@@ -3775,8 +4731,56 @@ define <8 x i8> @test_ne_b(<8 x i8> %a, <8 x i8> %b) {
 define <8 x i8> @test_slt_b(<8 x i8> %a, <8 x i8> %b) {
 ; RV32-LABEL: test_slt_b:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    pmslt.b a0, a0, a2
-; RV32-NEXT:    pmslt.b a1, a1, a3
+; RV32-NEXT:    addi sp, sp, -32
+; RV32-NEXT:    .cfi_def_cfa_offset 32
+; RV32-NEXT:    sw a3, 20(sp)
+; RV32-NEXT:    sw a1, 12(sp)
+; RV32-NEXT:    sw a2, 16(sp)
+; RV32-NEXT:    sw a0, 8(sp)
+; RV32-NEXT:    lb a0, 23(sp)
+; RV32-NEXT:    lb a1, 15(sp)
+; RV32-NEXT:    slt a0, a1, a0
+; RV32-NEXT:    neg a0, a0
+; RV32-NEXT:    sb a0, 31(sp)
+; RV32-NEXT:    lb a0, 22(sp)
+; RV32-NEXT:    lb a1, 14(sp)
+; RV32-NEXT:    slt a0, a1, a0
+; RV32-NEXT:    neg a0, a0
+; RV32-NEXT:    sb a0, 30(sp)
+; RV32-NEXT:    lb a0, 21(sp)
+; RV32-NEXT:    lb a1, 13(sp)
+; RV32-NEXT:    slt a0, a1, a0
+; RV32-NEXT:    neg a0, a0
+; RV32-NEXT:    sb a0, 29(sp)
+; RV32-NEXT:    lb a0, 20(sp)
+; RV32-NEXT:    lb a1, 12(sp)
+; RV32-NEXT:    slt a0, a1, a0
+; RV32-NEXT:    neg a0, a0
+; RV32-NEXT:    sb a0, 28(sp)
+; RV32-NEXT:    lb a0, 19(sp)
+; RV32-NEXT:    lb a1, 11(sp)
+; RV32-NEXT:    slt a0, a1, a0
+; RV32-NEXT:    neg a0, a0
+; RV32-NEXT:    sb a0, 27(sp)
+; RV32-NEXT:    lb a0, 18(sp)
+; RV32-NEXT:    lb a1, 10(sp)
+; RV32-NEXT:    slt a0, a1, a0
+; RV32-NEXT:    neg a0, a0
+; RV32-NEXT:    sb a0, 26(sp)
+; RV32-NEXT:    lb a0, 17(sp)
+; RV32-NEXT:    lb a1, 9(sp)
+; RV32-NEXT:    slt a0, a1, a0
+; RV32-NEXT:    neg a0, a0
+; RV32-NEXT:    sb a0, 25(sp)
+; RV32-NEXT:    lb a0, 16(sp)
+; RV32-NEXT:    lb a1, 8(sp)
+; RV32-NEXT:    slt a0, a1, a0
+; RV32-NEXT:    neg a0, a0
+; RV32-NEXT:    sb a0, 24(sp)
+; RV32-NEXT:    lw a0, 24(sp)
+; RV32-NEXT:    lw a1, 28(sp)
+; RV32-NEXT:    addi sp, sp, 32
+; RV32-NEXT:    .cfi_def_cfa_offset 0
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_slt_b:
@@ -3791,10 +4795,56 @@ define <8 x i8> @test_slt_b(<8 x i8> %a, <8 x i8> %b) {
 define <8 x i8> @test_sle_b(<8 x i8> %a, <8 x i8> %b) {
 ; RV32-LABEL: test_sle_b:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    pmslt.b a0, a2, a0
-; RV32-NEXT:    pmslt.b a1, a3, a1
-; RV32-NEXT:    not a0, a0
-; RV32-NEXT:    not a1, a1
+; RV32-NEXT:    addi sp, sp, -32
+; RV32-NEXT:    .cfi_def_cfa_offset 32
+; RV32-NEXT:    sw a1, 12(sp)
+; RV32-NEXT:    sw a3, 20(sp)
+; RV32-NEXT:    sw a0, 8(sp)
+; RV32-NEXT:    sw a2, 16(sp)
+; RV32-NEXT:    lb a0, 15(sp)
+; RV32-NEXT:    lb a1, 23(sp)
+; RV32-NEXT:    slt a0, a1, a0
+; RV32-NEXT:    addi a0, a0, -1
+; RV32-NEXT:    sb a0, 31(sp)
+; RV32-NEXT:    lb a0, 14(sp)
+; RV32-NEXT:    lb a1, 22(sp)
+; RV32-NEXT:    slt a0, a1, a0
+; RV32-NEXT:    addi a0, a0, -1
+; RV32-NEXT:    sb a0, 30(sp)
+; RV32-NEXT:    lb a0, 13(sp)
+; RV32-NEXT:    lb a1, 21(sp)
+; RV32-NEXT:    slt a0, a1, a0
+; RV32-NEXT:    addi a0, a0, -1
+; RV32-NEXT:    sb a0, 29(sp)
+; RV32-NEXT:    lb a0, 12(sp)
+; RV32-NEXT:    lb a1, 20(sp)
+; RV32-NEXT:    slt a0, a1, a0
+; RV32-NEXT:    addi a0, a0, -1
+; RV32-NEXT:    sb a0, 28(sp)
+; RV32-NEXT:    lb a0, 11(sp)
+; RV32-NEXT:    lb a1, 19(sp)
+; RV32-NEXT:    slt a0, a1, a0
+; RV32-NEXT:    addi a0, a0, -1
+; RV32-NEXT:    sb a0, 27(sp)
+; RV32-NEXT:    lb a0, 10(sp)
+; RV32-NEXT:    lb a1, 18(sp)
+; RV32-NEXT:    slt a0, a1, a0
+; RV32-NEXT:    addi a0, a0, -1
+; RV32-NEXT:    sb a0, 26(sp)
+; RV32-NEXT:    lb a0, 9(sp)
+; RV32-NEXT:    lb a1, 17(sp)
+; RV32-NEXT:    slt a0, a1, a0
+; RV32-NEXT:    addi a0, a0, -1
+; RV32-NEXT:    sb a0, 25(sp)
+; RV32-NEXT:    lb a0, 8(sp)
+; RV32-NEXT:    lb a1, 16(sp)
+; RV32-NEXT:    slt a0, a1, a0
+; RV32-NEXT:    addi a0, a0, -1
+; RV32-NEXT:    sb a0, 24(sp)
+; RV32-NEXT:    lw a0, 24(sp)
+; RV32-NEXT:    lw a1, 28(sp)
+; RV32-NEXT:    addi sp, sp, 32
+; RV32-NEXT:    .cfi_def_cfa_offset 0
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_sle_b:
@@ -3810,8 +4860,56 @@ define <8 x i8> @test_sle_b(<8 x i8> %a, <8 x i8> %b) {
 define <8 x i8> @test_sgt_b(<8 x i8> %a, <8 x i8> %b) {
 ; RV32-LABEL: test_sgt_b:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    pmslt.b a0, a2, a0
-; RV32-NEXT:    pmslt.b a1, a3, a1
+; RV32-NEXT:    addi sp, sp, -32
+; RV32-NEXT:    .cfi_def_cfa_offset 32
+; RV32-NEXT:    sw a1, 12(sp)
+; RV32-NEXT:    sw a3, 20(sp)
+; RV32-NEXT:    sw a0, 8(sp)
+; RV32-NEXT:    sw a2, 16(sp)
+; RV32-NEXT:    lb a0, 15(sp)
+; RV32-NEXT:    lb a1, 23(sp)
+; RV32-NEXT:    slt a0, a1, a0
+; RV32-NEXT:    neg a0, a0
+; RV32-NEXT:    sb a0, 31(sp)
+; RV32-NEXT:    lb a0, 14(sp)
+; RV32-NEXT:    lb a1, 22(sp)
+; RV32-NEXT:    slt a0, a1, a0
+; RV32-NEXT:    neg a0, a0
+; RV32-NEXT:    sb a0, 30(sp)
+; RV32-NEXT:    lb a0, 13(sp)
+; RV32-NEXT:    lb a1, 21(sp)
+; RV32-NEXT:    slt a0, a1, a0
+; RV32-NEXT:    neg a0, a0
+; RV32-NEXT:    sb a0, 29(sp)
+; RV32-NEXT:    lb a0, 12(sp)
+; RV32-NEXT:    lb a1, 20(sp)
+; RV32-NEXT:    slt a0, a1, a0
+; RV32-NEXT:    neg a0, a0
+; RV32-NEXT:    sb a0, 28(sp)
+; RV32-NEXT:    lb a0, 11(sp)
+; RV32-NEXT:    lb a1, 19(sp)
+; RV32-NEXT:    slt a0, a1, a0
+; RV32-NEXT:    neg a0, a0
+; RV32-NEXT:    sb a0, 27(sp)
+; RV32-NEXT:    lb a0, 10(sp)
+; RV32-NEXT:    lb a1, 18(sp)
+; RV32-NEXT:    slt a0, a1, a0
+; RV32-NEXT:    neg a0, a0
+; RV32-NEXT:    sb a0, 26(sp)
+; RV32-NEXT:    lb a0, 9(sp)
+; RV32-NEXT:    lb a1, 17(sp)
+; RV32-NEXT:    slt a0, a1, a0
+; RV32-NEXT:    neg a0, a0
+; RV32-NEXT:    sb a0, 25(sp)
+; RV32-NEXT:    lb a0, 8(sp)
+; RV32-NEXT:    lb a1, 16(sp)
+; RV32-NEXT:    slt a0, a1, a0
+; RV32-NEXT:    neg a0, a0
+; RV32-NEXT:    sb a0, 24(sp)
+; RV32-NEXT:    lw a0, 24(sp)
+; RV32-NEXT:    lw a1, 28(sp)
+; RV32-NEXT:    addi sp, sp, 32
+; RV32-NEXT:    .cfi_def_cfa_offset 0
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_sgt_b:
@@ -3826,10 +4924,56 @@ define <8 x i8> @test_sgt_b(<8 x i8> %a, <8 x i8> %b) {
 define <8 x i8> @test_sge_b(<8 x i8> %a, <8 x i8> %b) {
 ; RV32-LABEL: test_sge_b:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    pmslt.b a0, a0, a2
-; RV32-NEXT:    pmslt.b a1, a1, a3
-; RV32-NEXT:    not a0, a0
-; RV32-NEXT:    not a1, a1
+; RV32-NEXT:    addi sp, sp, -32
+; RV32-NEXT:    .cfi_def_cfa_offset 32
+; RV32-NEXT:    sw a3, 20(sp)
+; RV32-NEXT:    sw a1, 12(sp)
+; RV32-NEXT:    sw a2, 16(sp)
+; RV32-NEXT:    sw a0, 8(sp)
+; RV32-NEXT:    lb a0, 23(sp)
+; RV32-NEXT:    lb a1, 15(sp)
+; RV32-NEXT:    slt a0, a1, a0
+; RV32-NEXT:    addi a0, a0, -1
+; RV32-NEXT:    sb a0, 31(sp)
+; RV32-NEXT:    lb a0, 22(sp)
+; RV32-NEXT:    lb a1, 14(sp)
+; RV32-NEXT:    slt a0, a1, a0
+; RV32-NEXT:    addi a0, a0, -1
+; RV32-NEXT:    sb a0, 30(sp)
+; RV32-NEXT:    lb a0, 21(sp)
+; RV32-NEXT:    lb a1, 13(sp)
+; RV32-NEXT:    slt a0, a1, a0
+; RV32-NEXT:    addi a0, a0, -1
+; RV32-NEXT:    sb a0, 29(sp)
+; RV32-NEXT:    lb a0, 20(sp)
+; RV32-NEXT:    lb a1, 12(sp)
+; RV32-NEXT:    slt a0, a1, a0
+; RV32-NEXT:    addi a0, a0, -1
+; RV32-NEXT:    sb a0, 28(sp)
+; RV32-NEXT:    lb a0, 19(sp)
+; RV32-NEXT:    lb a1, 11(sp)
+; RV32-NEXT:    slt a0, a1, a0
+; RV32-NEXT:    addi a0, a0, -1
+; RV32-NEXT:    sb a0, 27(sp)
+; RV32-NEXT:    lb a0, 18(sp)
+; RV32-NEXT:    lb a1, 10(sp)
+; RV32-NEXT:    slt a0, a1, a0
+; RV32-NEXT:    addi a0, a0, -1
+; RV32-NEXT:    sb a0, 26(sp)
+; RV32-NEXT:    lb a0, 17(sp)
+; RV32-NEXT:    lb a1, 9(sp)
+; RV32-NEXT:    slt a0, a1, a0
+; RV32-NEXT:    addi a0, a0, -1
+; RV32-NEXT:    sb a0, 25(sp)
+; RV32-NEXT:    lb a0, 16(sp)
+; RV32-NEXT:    lb a1, 8(sp)
+; RV32-NEXT:    slt a0, a1, a0
+; RV32-NEXT:    addi a0, a0, -1
+; RV32-NEXT:    sb a0, 24(sp)
+; RV32-NEXT:    lw a0, 24(sp)
+; RV32-NEXT:    lw a1, 28(sp)
+; RV32-NEXT:    addi sp, sp, 32
+; RV32-NEXT:    .cfi_def_cfa_offset 0
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_sge_b:
@@ -3845,8 +4989,56 @@ define <8 x i8> @test_sge_b(<8 x i8> %a, <8 x i8> %b) {
 define <8 x i8> @test_ult_b(<8 x i8> %a, <8 x i8> %b) {
 ; RV32-LABEL: test_ult_b:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    pmsltu.b a0, a0, a2
-; RV32-NEXT:    pmsltu.b a1, a1, a3
+; RV32-NEXT:    addi sp, sp, -32
+; RV32-NEXT:    .cfi_def_cfa_offset 32
+; RV32-NEXT:    sw a3, 20(sp)
+; RV32-NEXT:    sw a1, 12(sp)
+; RV32-NEXT:    sw a2, 16(sp)
+; RV32-NEXT:    sw a0, 8(sp)
+; RV32-NEXT:    lbu a0, 23(sp)
+; RV32-NEXT:    lbu a1, 15(sp)
+; RV32-NEXT:    sltu a0, a1, a0
+; RV32-NEXT:    neg a0, a0
+; RV32-NEXT:    sb a0, 31(sp)
+; RV32-NEXT:    lbu a0, 22(sp)
+; RV32-NEXT:    lbu a1, 14(sp)
+; RV32-NEXT:    sltu a0, a1, a0
+; RV32-NEXT:    neg a0, a0
+; RV32-NEXT:    sb a0, 30(sp)
+; RV32-NEXT:    lbu a0, 21(sp)
+; RV32-NEXT:    lbu a1, 13(sp)
+; RV32-NEXT:    sltu a0, a1, a0
+; RV32-NEXT:    neg a0, a0
+; RV32-NEXT:    sb a0, 29(sp)
+; RV32-NEXT:    lbu a0, 20(sp)
+; RV32-NEXT:    lbu a1, 12(sp)
+; RV32-NEXT:    sltu a0, a1, a0
+; RV32-NEXT:    neg a0, a0
+; RV32-NEXT:    sb a0, 28(sp)
+; RV32-NEXT:    lbu a0, 19(sp)
+; RV32-NEXT:    lbu a1, 11(sp)
+; RV32-NEXT:    sltu a0, a1, a0
+; RV32-NEXT:    neg a0, a0
+; RV32-NEXT:    sb a0, 27(sp)
+; RV32-NEXT:    lbu a0, 18(sp)
+; RV32-NEXT:    lbu a1, 10(sp)
+; RV32-NEXT:    sltu a0, a1, a0
+; RV32-NEXT:    neg a0, a0
+; RV32-NEXT:    sb a0, 26(sp)
+; RV32-NEXT:    lbu a0, 17(sp)
+; RV32-NEXT:    lbu a1, 9(sp)
+; RV32-NEXT:    sltu a0, a1, a0
+; RV32-NEXT:    neg a0, a0
+; RV32-NEXT:    sb a0, 25(sp)
+; RV32-NEXT:    lbu a0, 16(sp)
+; RV32-NEXT:    lbu a1, 8(sp)
+; RV32-NEXT:    sltu a0, a1, a0
+; RV32-NEXT:    neg a0, a0
+; RV32-NEXT:    sb a0, 24(sp)
+; RV32-NEXT:    lw a0, 24(sp)
+; RV32-NEXT:    lw a1, 28(sp)
+; RV32-NEXT:    addi sp, sp, 32
+; RV32-NEXT:    .cfi_def_cfa_offset 0
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_ult_b:
@@ -3861,10 +5053,56 @@ define <8 x i8> @test_ult_b(<8 x i8> %a, <8 x i8> %b) {
 define <8 x i8> @test_ule_b(<8 x i8> %a, <8 x i8> %b) {
 ; RV32-LABEL: test_ule_b:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    pmsltu.b a0, a2, a0
-; RV32-NEXT:    pmsltu.b a1, a3, a1
-; RV32-NEXT:    not a0, a0
-; RV32-NEXT:    not a1, a1
+; RV32-NEXT:    addi sp, sp, -32
+; RV32-NEXT:    .cfi_def_cfa_offset 32
+; RV32-NEXT:    sw a1, 12(sp)
+; RV32-NEXT:    sw a3, 20(sp)
+; RV32-NEXT:    sw a0, 8(sp)
+; RV32-NEXT:    sw a2, 16(sp)
+; RV32-NEXT:    lbu a0, 15(sp)
+; RV32-NEXT:    lbu a1, 23(sp)
+; RV32-NEXT:    sltu a0, a1, a0
+; RV32-NEXT:    addi a0, a0, -1
+; RV32-NEXT:    sb a0, 31(sp)
+; RV32-NEXT:    lbu a0, 14(sp)
+; RV32-NEXT:    lbu a1, 22(sp)
+; RV32-NEXT:    sltu a0, a1, a0
+; RV32-NEXT:    addi a0, a0, -1
+; RV32-NEXT:    sb a0, 30(sp)
+; RV32-NEXT:    lbu a0, 13(sp)
+; RV32-NEXT:    lbu a1, 21(sp)
+; RV32-NEXT:    sltu a0, a1, a0
+; RV32-NEXT:    addi a0, a0, -1
+; RV32-NEXT:    sb a0, 29(sp)
+; RV32-NEXT:    lbu a0, 12(sp)
+; RV32-NEXT:    lbu a1, 20(sp)
+; RV32-NEXT:    sltu a0, a1, a0
+; RV32-NEXT:    addi a0, a0, -1
+; RV32-NEXT:    sb a0, 28(sp)
+; RV32-NEXT:    lbu a0, 11(sp)
+; RV32-NEXT:    lbu a1, 19(sp)
+; RV32-NEXT:    sltu a0, a1, a0
+; RV32-NEXT:    addi a0, a0, -1
+; RV32-NEXT:    sb a0, 27(sp)
+; RV32-NEXT:    lbu a0, 10(sp)
+; RV32-NEXT:    lbu a1, 18(sp)
+; RV32-NEXT:    sltu a0, a1, a0
+; RV32-NEXT:    addi a0, a0, -1
+; RV32-NEXT:    sb a0, 26(sp)
+; RV32-NEXT:    lbu a0, 9(sp)
+; RV32-NEXT:    lbu a1, 17(sp)
+; RV32-NEXT:    sltu a0, a1, a0
+; RV32-NEXT:    addi a0, a0, -1
+; RV32-NEXT:    sb a0, 25(sp)
+; RV32-NEXT:    lbu a0, 8(sp)
+; RV32-NEXT:    lbu a1, 16(sp)
+; RV32-NEXT:    sltu a0, a1, a0
+; RV32-NEXT:    addi a0, a0, -1
+; RV32-NEXT:    sb a0, 24(sp)
+; RV32-NEXT:    lw a0, 24(sp)
+; RV32-NEXT:    lw a1, 28(sp)
+; RV32-NEXT:    addi sp, sp, 32
+; RV32-NEXT:    .cfi_def_cfa_offset 0
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_ule_b:
@@ -3880,8 +5118,56 @@ define <8 x i8> @test_ule_b(<8 x i8> %a, <8 x i8> %b) {
 define <8 x i8> @test_ugt_b(<8 x i8> %a, <8 x i8> %b) {
 ; RV32-LABEL: test_ugt_b:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    pmsltu.b a0, a2, a0
-; RV32-NEXT:    pmsltu.b a1, a3, a1
+; RV32-NEXT:    addi sp, sp, -32
+; RV32-NEXT:    .cfi_def_cfa_offset 32
+; RV32-NEXT:    sw a1, 12(sp)
+; RV32-NEXT:    sw a3, 20(sp)
+; RV32-NEXT:    sw a0, 8(sp)
+; RV32-NEXT:    sw a2, 16(sp)
+; RV32-NEXT:    lbu a0, 15(sp)
+; RV32-NEXT:    lbu a1, 23(sp)
+; RV32-NEXT:    sltu a0, a1, a0
+; RV32-NEXT:    neg a0, a0
+; RV32-NEXT:    sb a0, 31(sp)
+; RV32-NEXT:    lbu a0, 14(sp)
+; RV32-NEXT:    lbu a1, 22(sp)
+; RV32-NEXT:    sltu a0, a1, a0
+; RV32-NEXT:    neg a0, a0
+; RV32-NEXT:    sb a0, 30(sp)
+; RV32-NEXT:    lbu a0, 13(sp)
+; RV32-NEXT:    lbu a1, 21(sp)
+; RV32-NEXT:    sltu a0, a1, a0
+; RV32-NEXT:    neg a0, a0
+; RV32-NEXT:    sb a0, 29(sp)
+; RV32-NEXT:    lbu a0, 12(sp)
+; RV32-NEXT:    lbu a1, 20(sp)
+; RV32-NEXT:    sltu a0, a1, a0
+; RV32-NEXT:    neg a0, a0
+; RV32-NEXT:    sb a0, 28(sp)
+; RV32-NEXT:    lbu a0, 11(sp)
+; RV32-NEXT:    lbu a1, 19(sp)
+; RV32-NEXT:    sltu a0, a1, a0
+; RV32-NEXT:    neg a0, a0
+; RV32-NEXT:    sb a0, 27(sp)
+; RV32-NEXT:    lbu a0, 10(sp)
+; RV32-NEXT:    lbu a1, 18(sp)
+; RV32-NEXT:    sltu a0, a1, a0
+; RV32-NEXT:    neg a0, a0
+; RV32-NEXT:    sb a0, 26(sp)
+; RV32-NEXT:    lbu a0, 9(sp)
+; RV32-NEXT:    lbu a1, 17(sp)
+; RV32-NEXT:    sltu a0, a1, a0
+; RV32-NEXT:    neg a0, a0
+; RV32-NEXT:    sb a0, 25(sp)
+; RV32-NEXT:    lbu a0, 8(sp)
+; RV32-NEXT:    lbu a1, 16(sp)
+; RV32-NEXT:    sltu a0, a1, a0
+; RV32-NEXT:    neg a0, a0
+; RV32-NEXT:    sb a0, 24(sp)
+; RV32-NEXT:    lw a0, 24(sp)
+; RV32-NEXT:    lw a1, 28(sp)
+; RV32-NEXT:    addi sp, sp, 32
+; RV32-NEXT:    .cfi_def_cfa_offset 0
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_ugt_b:
@@ -3896,10 +5182,56 @@ define <8 x i8> @test_ugt_b(<8 x i8> %a, <8 x i8> %b) {
 define <8 x i8> @test_uge_b(<8 x i8> %a, <8 x i8> %b) {
 ; RV32-LABEL: test_uge_b:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    pmsltu.b a0, a0, a2
-; RV32-NEXT:    pmsltu.b a1, a1, a3
-; RV32-NEXT:    not a0, a0
-; RV32-NEXT:    not a1, a1
+; RV32-NEXT:    addi sp, sp, -32
+; RV32-NEXT:    .cfi_def_cfa_offset 32
+; RV32-NEXT:    sw a3, 20(sp)
+; RV32-NEXT:    sw a1, 12(sp)
+; RV32-NEXT:    sw a2, 16(sp)
+; RV32-NEXT:    sw a0, 8(sp)
+; RV32-NEXT:    lbu a0, 23(sp)
+; RV32-NEXT:    lbu a1, 15(sp)
+; RV32-NEXT:    sltu a0, a1, a0
+; RV32-NEXT:    addi a0, a0, -1
+; RV32-NEXT:    sb a0, 31(sp)
+; RV32-NEXT:    lbu a0, 22(sp)
+; RV32-NEXT:    lbu a1, 14(sp)
+; RV32-NEXT:    sltu a0, a1, a0
+; RV32-NEXT:    addi a0, a0, -1
+; RV32-NEXT:    sb a0, 30(sp)
+; RV32-NEXT:    lbu a0, 21(sp)
+; RV32-NEXT:    lbu a1, 13(sp)
+; RV32-NEXT:    sltu a0, a1, a0
+; RV32-NEXT:    addi a0, a0, -1
+; RV32-NEXT:    sb a0, 29(sp)
+; RV32-NEXT:    lbu a0, 20(sp)
+; RV32-NEXT:    lbu a1, 12(sp)
+; RV32-NEXT:    sltu a0, a1, a0
+; RV32-NEXT:    addi a0, a0, -1
+; RV32-NEXT:    sb a0, 28(sp)
+; RV32-NEXT:    lbu a0, 19(sp)
+; RV32-NEXT:    lbu a1, 11(sp)
+; RV32-NEXT:    sltu a0, a1, a0
+; RV32-NEXT:    addi a0, a0, -1
+; RV32-NEXT:    sb a0, 27(sp)
+; RV32-NEXT:    lbu a0, 18(sp)
+; RV32-NEXT:    lbu a1, 10(sp)
+; RV32-NEXT:    sltu a0, a1, a0
+; RV32-NEXT:    addi a0, a0, -1
+; RV32-NEXT:    sb a0, 26(sp)
+; RV32-NEXT:    lbu a0, 17(sp)
+; RV32-NEXT:    lbu a1, 9(sp)
+; RV32-NEXT:    sltu a0, a1, a0
+; RV32-NEXT:    addi a0, a0, -1
+; RV32-NEXT:    sb a0, 25(sp)
+; RV32-NEXT:    lbu a0, 16(sp)
+; RV32-NEXT:    lbu a1, 8(sp)
+; RV32-NEXT:    sltu a0, a1, a0
+; RV32-NEXT:    addi a0, a0, -1
+; RV32-NEXT:    sb a0, 24(sp)
+; RV32-NEXT:    lw a0, 24(sp)
+; RV32-NEXT:    lw a1, 28(sp)
+; RV32-NEXT:    addi sp, sp, 32
+; RV32-NEXT:    .cfi_def_cfa_offset 0
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_uge_b:
@@ -3916,12 +5248,12 @@ define <8 x i8> @test_uge_b(<8 x i8> %a, <8 x i8> %b) {
 define <2 x i32> @test_eq_w(<2 x i32> %a, <2 x i32> %b) {
 ; RV32-LABEL: test_eq_w:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    xor a0, a0, a2
 ; RV32-NEXT:    xor a1, a1, a3
-; RV32-NEXT:    snez a0, a0
+; RV32-NEXT:    xor a0, a0, a2
 ; RV32-NEXT:    snez a1, a1
-; RV32-NEXT:    addi a0, a0, -1
+; RV32-NEXT:    snez a0, a0
 ; RV32-NEXT:    addi a1, a1, -1
+; RV32-NEXT:    addi a0, a0, -1
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_eq_w:
@@ -3936,12 +5268,12 @@ define <2 x i32> @test_eq_w(<2 x i32> %a, <2 x i32> %b) {
 define <2 x i32> @test_ne_w(<2 x i32> %a, <2 x i32> %b) {
 ; RV32-LABEL: test_ne_w:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    xor a0, a0, a2
 ; RV32-NEXT:    xor a1, a1, a3
-; RV32-NEXT:    seqz a0, a0
+; RV32-NEXT:    xor a0, a0, a2
 ; RV32-NEXT:    seqz a1, a1
-; RV32-NEXT:    addi a0, a0, -1
+; RV32-NEXT:    seqz a0, a0
 ; RV32-NEXT:    addi a1, a1, -1
+; RV32-NEXT:    addi a0, a0, -1
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_ne_w:
@@ -3957,10 +5289,10 @@ define <2 x i32> @test_ne_w(<2 x i32> %a, <2 x i32> %b) {
 define <2 x i32> @test_slt_w(<2 x i32> %a, <2 x i32> %b) {
 ; RV32-LABEL: test_slt_w:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    slt a0, a0, a2
 ; RV32-NEXT:    slt a1, a1, a3
-; RV32-NEXT:    neg a0, a0
+; RV32-NEXT:    slt a0, a0, a2
 ; RV32-NEXT:    neg a1, a1
+; RV32-NEXT:    neg a0, a0
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_slt_w:
@@ -3975,10 +5307,10 @@ define <2 x i32> @test_slt_w(<2 x i32> %a, <2 x i32> %b) {
 define <2 x i32> @test_sle_w(<2 x i32> %a, <2 x i32> %b) {
 ; RV32-LABEL: test_sle_w:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    slt a0, a2, a0
 ; RV32-NEXT:    slt a1, a3, a1
-; RV32-NEXT:    addi a0, a0, -1
+; RV32-NEXT:    slt a0, a2, a0
 ; RV32-NEXT:    addi a1, a1, -1
+; RV32-NEXT:    addi a0, a0, -1
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_sle_w:
@@ -3994,10 +5326,10 @@ define <2 x i32> @test_sle_w(<2 x i32> %a, <2 x i32> %b) {
 define <2 x i32> @test_sgt_w(<2 x i32> %a, <2 x i32> %b) {
 ; RV32-LABEL: test_sgt_w:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    slt a0, a2, a0
 ; RV32-NEXT:    slt a1, a3, a1
-; RV32-NEXT:    neg a0, a0
+; RV32-NEXT:    slt a0, a2, a0
 ; RV32-NEXT:    neg a1, a1
+; RV32-NEXT:    neg a0, a0
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_sgt_w:
@@ -4012,10 +5344,10 @@ define <2 x i32> @test_sgt_w(<2 x i32> %a, <2 x i32> %b) {
 define <2 x i32> @test_sge_w(<2 x i32> %a, <2 x i32> %b) {
 ; RV32-LABEL: test_sge_w:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    slt a0, a0, a2
 ; RV32-NEXT:    slt a1, a1, a3
-; RV32-NEXT:    addi a0, a0, -1
+; RV32-NEXT:    slt a0, a0, a2
 ; RV32-NEXT:    addi a1, a1, -1
+; RV32-NEXT:    addi a0, a0, -1
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_sge_w:
@@ -4031,10 +5363,10 @@ define <2 x i32> @test_sge_w(<2 x i32> %a, <2 x i32> %b) {
 define <2 x i32> @test_ult_w(<2 x i32> %a, <2 x i32> %b) {
 ; RV32-LABEL: test_ult_w:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    sltu a0, a0, a2
 ; RV32-NEXT:    sltu a1, a1, a3
-; RV32-NEXT:    neg a0, a0
+; RV32-NEXT:    sltu a0, a0, a2
 ; RV32-NEXT:    neg a1, a1
+; RV32-NEXT:    neg a0, a0
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_ult_w:
@@ -4049,10 +5381,10 @@ define <2 x i32> @test_ult_w(<2 x i32> %a, <2 x i32> %b) {
 define <2 x i32> @test_ule_w(<2 x i32> %a, <2 x i32> %b) {
 ; RV32-LABEL: test_ule_w:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    sltu a0, a2, a0
 ; RV32-NEXT:    sltu a1, a3, a1
-; RV32-NEXT:    addi a0, a0, -1
+; RV32-NEXT:    sltu a0, a2, a0
 ; RV32-NEXT:    addi a1, a1, -1
+; RV32-NEXT:    addi a0, a0, -1
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_ule_w:
@@ -4068,10 +5400,10 @@ define <2 x i32> @test_ule_w(<2 x i32> %a, <2 x i32> %b) {
 define <2 x i32> @test_ugt_w(<2 x i32> %a, <2 x i32> %b) {
 ; RV32-LABEL: test_ugt_w:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    sltu a0, a2, a0
 ; RV32-NEXT:    sltu a1, a3, a1
-; RV32-NEXT:    neg a0, a0
+; RV32-NEXT:    sltu a0, a2, a0
 ; RV32-NEXT:    neg a1, a1
+; RV32-NEXT:    neg a0, a0
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_ugt_w:
@@ -4086,10 +5418,10 @@ define <2 x i32> @test_ugt_w(<2 x i32> %a, <2 x i32> %b) {
 define <2 x i32> @test_uge_w(<2 x i32> %a, <2 x i32> %b) {
 ; RV32-LABEL: test_uge_w:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    sltu a0, a0, a2
 ; RV32-NEXT:    sltu a1, a1, a3
-; RV32-NEXT:    addi a0, a0, -1
+; RV32-NEXT:    sltu a0, a0, a2
 ; RV32-NEXT:    addi a1, a1, -1
+; RV32-NEXT:    addi a0, a0, -1
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_uge_w:
@@ -4106,8 +5438,7 @@ define <2 x i32> @test_uge_w(<2 x i32> %a, <2 x i32> %b) {
 define <4 x i16> @test_smin_h(<4 x i16> %a, <4 x i16> %b) {
 ; RV32-LABEL: test_smin_h:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    pmin.h a0, a0, a2
-; RV32-NEXT:    pmin.h a1, a1, a3
+; RV32-NEXT:    pmin.dh a0, a0, a2
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_smin_h:
@@ -4121,8 +5452,7 @@ define <4 x i16> @test_smin_h(<4 x i16> %a, <4 x i16> %b) {
 define <4 x i16> @test_umin_h(<4 x i16> %a, <4 x i16> %b) {
 ; RV32-LABEL: test_umin_h:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    pminu.h a0, a0, a2
-; RV32-NEXT:    pminu.h a1, a1, a3
+; RV32-NEXT:    pminu.dh a0, a0, a2
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_umin_h:
@@ -4136,8 +5466,7 @@ define <4 x i16> @test_umin_h(<4 x i16> %a, <4 x i16> %b) {
 define <8 x i8> @test_smin_b(<8 x i8> %a, <8 x i8> %b) {
 ; RV32-LABEL: test_smin_b:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    pmin.b a0, a0, a2
-; RV32-NEXT:    pmin.b a1, a1, a3
+; RV32-NEXT:    pmin.db a0, a0, a2
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_smin_b:
@@ -4151,8 +5480,7 @@ define <8 x i8> @test_smin_b(<8 x i8> %a, <8 x i8> %b) {
 define <8 x i8> @test_umin_b(<8 x i8> %a, <8 x i8> %b) {
 ; RV32-LABEL: test_umin_b:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    pminu.b a0, a0, a2
-; RV32-NEXT:    pminu.b a1, a1, a3
+; RV32-NEXT:    pminu.db a0, a0, a2
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_umin_b:
@@ -4166,8 +5494,7 @@ define <8 x i8> @test_umin_b(<8 x i8> %a, <8 x i8> %b) {
 define <2 x i32> @test_smin_w(<2 x i32> %a, <2 x i32> %b) {
 ; RV32-LABEL: test_smin_w:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    min a0, a0, a2
-; RV32-NEXT:    min a1, a1, a3
+; RV32-NEXT:    pmin.dw a0, a0, a2
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_smin_w:
@@ -4181,8 +5508,7 @@ define <2 x i32> @test_smin_w(<2 x i32> %a, <2 x i32> %b) {
 define <2 x i32> @test_umin_w(<2 x i32> %a, <2 x i32> %b) {
 ; RV32-LABEL: test_umin_w:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    minu a0, a0, a2
-; RV32-NEXT:    minu a1, a1, a3
+; RV32-NEXT:    pminu.dw a0, a0, a2
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_umin_w:
@@ -4196,8 +5522,7 @@ define <2 x i32> @test_umin_w(<2 x i32> %a, <2 x i32> %b) {
 define <4 x i16> @test_smax_h(<4 x i16> %a, <4 x i16> %b) {
 ; RV32-LABEL: test_smax_h:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    pmax.h a0, a0, a2
-; RV32-NEXT:    pmax.h a1, a1, a3
+; RV32-NEXT:    pmax.dh a0, a0, a2
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_smax_h:
@@ -4211,8 +5536,7 @@ define <4 x i16> @test_smax_h(<4 x i16> %a, <4 x i16> %b) {
 define <4 x i16> @test_umax_h(<4 x i16> %a, <4 x i16> %b) {
 ; RV32-LABEL: test_umax_h:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    pmaxu.h a0, a0, a2
-; RV32-NEXT:    pmaxu.h a1, a1, a3
+; RV32-NEXT:    pmaxu.dh a0, a0, a2
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_umax_h:
@@ -4226,8 +5550,7 @@ define <4 x i16> @test_umax_h(<4 x i16> %a, <4 x i16> %b) {
 define <8 x i8> @test_smax_b(<8 x i8> %a, <8 x i8> %b) {
 ; RV32-LABEL: test_smax_b:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    pmax.b a0, a0, a2
-; RV32-NEXT:    pmax.b a1, a1, a3
+; RV32-NEXT:    pmax.db a0, a0, a2
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_smax_b:
@@ -4241,8 +5564,7 @@ define <8 x i8> @test_smax_b(<8 x i8> %a, <8 x i8> %b) {
 define <8 x i8> @test_umax_b(<8 x i8> %a, <8 x i8> %b) {
 ; RV32-LABEL: test_umax_b:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    pmaxu.b a0, a0, a2
-; RV32-NEXT:    pmaxu.b a1, a1, a3
+; RV32-NEXT:    pmaxu.db a0, a0, a2
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_umax_b:
@@ -4256,8 +5578,7 @@ define <8 x i8> @test_umax_b(<8 x i8> %a, <8 x i8> %b) {
 define <2 x i32> @test_smax_w(<2 x i32> %a, <2 x i32> %b) {
 ; RV32-LABEL: test_smax_w:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    max a0, a0, a2
-; RV32-NEXT:    max a1, a1, a3
+; RV32-NEXT:    pmax.dw a0, a0, a2
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_smax_w:
@@ -4271,8 +5592,7 @@ define <2 x i32> @test_smax_w(<2 x i32> %a, <2 x i32> %b) {
 define <2 x i32> @test_umax_w(<2 x i32> %a, <2 x i32> %b) {
 ; RV32-LABEL: test_umax_w:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    maxu a0, a0, a2
-; RV32-NEXT:    maxu a1, a1, a3
+; RV32-NEXT:    pmaxu.dw a0, a0, a2
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_umax_w:
@@ -4287,14 +5607,49 @@ define <2 x i32> @test_umax_w(<2 x i32> %a, <2 x i32> %b) {
 define <4 x i16> @test_select_v4i16(i1 %cond, <4 x i16> %a, <4 x i16> %b) {
 ; RV32-LABEL: test_select_v4i16:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    andi a5, a0, 1
-; RV32-NEXT:    mv a0, a1
-; RV32-NEXT:    bnez a5, .LBB205_2
+; RV32-NEXT:    addi sp, sp, -32
+; RV32-NEXT:    .cfi_def_cfa_offset 32
+; RV32-NEXT:    andi a0, a0, 1
+; RV32-NEXT:    sw a4, 20(sp)
+; RV32-NEXT:    sw a2, 12(sp)
+; RV32-NEXT:    sw a3, 16(sp)
+; RV32-NEXT:    sw a1, 8(sp)
+; RV32-NEXT:    bnez a0, .LBB205_5
 ; RV32-NEXT:  # %bb.1:
-; RV32-NEXT:    mv a0, a3
-; RV32-NEXT:    mv a2, a4
+; RV32-NEXT:    lh a1, 22(sp)
+; RV32-NEXT:    sh a1, 30(sp)
+; RV32-NEXT:    beqz a0, .LBB205_6
 ; RV32-NEXT:  .LBB205_2:
-; RV32-NEXT:    mv a1, a2
+; RV32-NEXT:    lh a1, 12(sp)
+; RV32-NEXT:    sh a1, 28(sp)
+; RV32-NEXT:    beqz a0, .LBB205_7
+; RV32-NEXT:  .LBB205_3:
+; RV32-NEXT:    lh a1, 10(sp)
+; RV32-NEXT:    sh a1, 26(sp)
+; RV32-NEXT:    beqz a0, .LBB205_8
+; RV32-NEXT:  .LBB205_4:
+; RV32-NEXT:    lh a0, 8(sp)
+; RV32-NEXT:    j .LBB205_9
+; RV32-NEXT:  .LBB205_5:
+; RV32-NEXT:    lh a1, 14(sp)
+; RV32-NEXT:    sh a1, 30(sp)
+; RV32-NEXT:    bnez a0, .LBB205_2
+; RV32-NEXT:  .LBB205_6:
+; RV32-NEXT:    lh a1, 20(sp)
+; RV32-NEXT:    sh a1, 28(sp)
+; RV32-NEXT:    bnez a0, .LBB205_3
+; RV32-NEXT:  .LBB205_7:
+; RV32-NEXT:    lh a1, 18(sp)
+; RV32-NEXT:    sh a1, 26(sp)
+; RV32-NEXT:    bnez a0, .LBB205_4
+; RV32-NEXT:  .LBB205_8:
+; RV32-NEXT:    lh a0, 16(sp)
+; RV32-NEXT:  .LBB205_9:
+; RV32-NEXT:    sh a0, 24(sp)
+; RV32-NEXT:    lw a0, 24(sp)
+; RV32-NEXT:    lw a1, 28(sp)
+; RV32-NEXT:    addi sp, sp, 32
+; RV32-NEXT:    .cfi_def_cfa_offset 0
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_select_v4i16:
@@ -4313,14 +5668,81 @@ define <4 x i16> @test_select_v4i16(i1 %cond, <4 x i16> %a, <4 x i16> %b) {
 define <8 x i8> @test_select_v8i8(i1 %cond, <8 x i8> %a, <8 x i8> %b) {
 ; RV32-LABEL: test_select_v8i8:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    andi a5, a0, 1
-; RV32-NEXT:    mv a0, a1
-; RV32-NEXT:    bnez a5, .LBB206_2
+; RV32-NEXT:    addi sp, sp, -32
+; RV32-NEXT:    .cfi_def_cfa_offset 32
+; RV32-NEXT:    andi a0, a0, 1
+; RV32-NEXT:    sw a4, 20(sp)
+; RV32-NEXT:    sw a2, 12(sp)
+; RV32-NEXT:    sw a3, 16(sp)
+; RV32-NEXT:    sw a1, 8(sp)
+; RV32-NEXT:    bnez a0, .LBB206_9
 ; RV32-NEXT:  # %bb.1:
-; RV32-NEXT:    mv a0, a3
-; RV32-NEXT:    mv a2, a4
+; RV32-NEXT:    lbu a1, 23(sp)
+; RV32-NEXT:    sb a1, 31(sp)
+; RV32-NEXT:    beqz a0, .LBB206_10
 ; RV32-NEXT:  .LBB206_2:
-; RV32-NEXT:    mv a1, a2
+; RV32-NEXT:    lbu a1, 14(sp)
+; RV32-NEXT:    sb a1, 30(sp)
+; RV32-NEXT:    beqz a0, .LBB206_11
+; RV32-NEXT:  .LBB206_3:
+; RV32-NEXT:    lbu a1, 13(sp)
+; RV32-NEXT:    sb a1, 29(sp)
+; RV32-NEXT:    beqz a0, .LBB206_12
+; RV32-NEXT:  .LBB206_4:
+; RV32-NEXT:    lbu a1, 12(sp)
+; RV32-NEXT:    sb a1, 28(sp)
+; RV32-NEXT:    beqz a0, .LBB206_13
+; RV32-NEXT:  .LBB206_5:
+; RV32-NEXT:    lbu a1, 11(sp)
+; RV32-NEXT:    sb a1, 27(sp)
+; RV32-NEXT:    beqz a0, .LBB206_14
+; RV32-NEXT:  .LBB206_6:
+; RV32-NEXT:    lbu a1, 10(sp)
+; RV32-NEXT:    sb a1, 26(sp)
+; RV32-NEXT:    beqz a0, .LBB206_15
+; RV32-NEXT:  .LBB206_7:
+; RV32-NEXT:    lbu a1, 9(sp)
+; RV32-NEXT:    sb a1, 25(sp)
+; RV32-NEXT:    beqz a0, .LBB206_16
+; RV32-NEXT:  .LBB206_8:
+; RV32-NEXT:    lbu a0, 8(sp)
+; RV32-NEXT:    j .LBB206_17
+; RV32-NEXT:  .LBB206_9:
+; RV32-NEXT:    lbu a1, 15(sp)
+; RV32-NEXT:    sb a1, 31(sp)
+; RV32-NEXT:    bnez a0, .LBB206_2
+; RV32-NEXT:  .LBB206_10:
+; RV32-NEXT:    lbu a1, 22(sp)
+; RV32-NEXT:    sb a1, 30(sp)
+; RV32-NEXT:    bnez a0, .LBB206_3
+; RV32-NEXT:  .LBB206_11:
+; RV32-NEXT:    lbu a1, 21(sp)
+; RV32-NEXT:    sb a1, 29(sp)
+; RV32-NEXT:    bnez a0, .LBB206_4
+; RV32-NEXT:  .LBB206_12:
+; RV32-NEXT:    lbu a1, 20(sp)
+; RV32-NEXT:    sb a1, 28(sp)
+; RV32-NEXT:    bnez a0, .LBB206_5
+; RV32-NEXT:  .LBB206_13:
+; RV32-NEXT:    lbu a1, 19(sp)
+; RV32-NEXT:    sb a1, 27(sp)
+; RV32-NEXT:    bnez a0, .LBB206_6
+; RV32-NEXT:  .LBB206_14:
+; RV32-NEXT:    lbu a1, 18(sp)
+; RV32-NEXT:    sb a1, 26(sp)
+; RV32-NEXT:    bnez a0, .LBB206_7
+; RV32-NEXT:  .LBB206_15:
+; RV32-NEXT:    lbu a1, 17(sp)
+; RV32-NEXT:    sb a1, 25(sp)
+; RV32-NEXT:    bnez a0, .LBB206_8
+; RV32-NEXT:  .LBB206_16:
+; RV32-NEXT:    lbu a0, 16(sp)
+; RV32-NEXT:  .LBB206_17:
+; RV32-NEXT:    sb a0, 24(sp)
+; RV32-NEXT:    lw a0, 24(sp)
+; RV32-NEXT:    lw a1, 28(sp)
+; RV32-NEXT:    addi sp, sp, 32
+; RV32-NEXT:    .cfi_def_cfa_offset 0
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_select_v8i8:
@@ -4340,12 +5762,13 @@ define <2 x i32> @test_select_v2i32(i1 %cond, <2 x i32> %a, <2 x i32> %b) {
 ; RV32-LABEL: test_select_v2i32:
 ; RV32:       # %bb.0:
 ; RV32-NEXT:    andi a5, a0, 1
-; RV32-NEXT:    mv a0, a1
 ; RV32-NEXT:    bnez a5, .LBB207_2
 ; RV32-NEXT:  # %bb.1:
 ; RV32-NEXT:    mv a0, a3
-; RV32-NEXT:    mv a2, a4
+; RV32-NEXT:    mv a1, a4
+; RV32-NEXT:    ret
 ; RV32-NEXT:  .LBB207_2:
+; RV32-NEXT:    mv a0, a1
 ; RV32-NEXT:    mv a1, a2
 ; RV32-NEXT:    ret
 ;
@@ -4366,10 +5789,62 @@ define <2 x i32> @test_select_v2i32(i1 %cond, <2 x i32> %a, <2 x i32> %b) {
 define <4 x i16> @test_vselect_v4i16(<4 x i16> %a, <4 x i16> %b, <4 x i16> %c) {
 ; RV32-LABEL: test_vselect_v4i16:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    pmseq.h a1, a1, a3
-; RV32-NEXT:    pmseq.h a0, a0, a2
-; RV32-NEXT:    merge a0, a2, a4
-; RV32-NEXT:    merge a1, a3, a5
+; RV32-NEXT:    addi sp, sp, -32
+; RV32-NEXT:    .cfi_def_cfa_offset 32
+; RV32-NEXT:    sw a2, 8(sp)
+; RV32-NEXT:    sw a0, 0(sp)
+; RV32-NEXT:    sw a3, 12(sp)
+; RV32-NEXT:    sw a1, 4(sp)
+; RV32-NEXT:    lhu a0, 8(sp)
+; RV32-NEXT:    lhu a1, 10(sp)
+; RV32-NEXT:    lhu a2, 12(sp)
+; RV32-NEXT:    lhu a3, 14(sp)
+; RV32-NEXT:    lhu a6, 0(sp)
+; RV32-NEXT:    lhu a7, 2(sp)
+; RV32-NEXT:    lhu t0, 4(sp)
+; RV32-NEXT:    lhu t1, 6(sp)
+; RV32-NEXT:    xor a6, a6, a0
+; RV32-NEXT:    xor a7, a7, a1
+; RV32-NEXT:    xor t0, t0, a2
+; RV32-NEXT:    xor t1, t1, a3
+; RV32-NEXT:    snez a6, a6
+; RV32-NEXT:    snez a7, a7
+; RV32-NEXT:    snez t0, t0
+; RV32-NEXT:    snez t1, t1
+; RV32-NEXT:    addi a7, a7, -1
+; RV32-NEXT:    addi t0, t0, -1
+; RV32-NEXT:    addi t1, t1, -1
+; RV32-NEXT:    zext.h t0, t0
+; RV32-NEXT:    zext.h t1, t1
+; RV32-NEXT:    sw a4, 16(sp)
+; RV32-NEXT:    sw a5, 20(sp)
+; RV32-NEXT:    beqz t1, .LBB208_2
+; RV32-NEXT:  # %bb.1:
+; RV32-NEXT:    lh a3, 22(sp)
+; RV32-NEXT:  .LBB208_2:
+; RV32-NEXT:    addi a6, a6, -1
+; RV32-NEXT:    zext.h a4, a7
+; RV32-NEXT:    sh a3, 30(sp)
+; RV32-NEXT:    beqz t0, .LBB208_4
+; RV32-NEXT:  # %bb.3:
+; RV32-NEXT:    lh a2, 20(sp)
+; RV32-NEXT:  .LBB208_4:
+; RV32-NEXT:    zext.h a3, a6
+; RV32-NEXT:    sh a2, 28(sp)
+; RV32-NEXT:    beqz a4, .LBB208_6
+; RV32-NEXT:  # %bb.5:
+; RV32-NEXT:    lh a1, 18(sp)
+; RV32-NEXT:  .LBB208_6:
+; RV32-NEXT:    sh a1, 26(sp)
+; RV32-NEXT:    beqz a3, .LBB208_8
+; RV32-NEXT:  # %bb.7:
+; RV32-NEXT:    lh a0, 16(sp)
+; RV32-NEXT:  .LBB208_8:
+; RV32-NEXT:    sh a0, 24(sp)
+; RV32-NEXT:    lw a0, 24(sp)
+; RV32-NEXT:    lw a1, 28(sp)
+; RV32-NEXT:    addi sp, sp, 32
+; RV32-NEXT:    .cfi_def_cfa_offset 0
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_vselect_v4i16:
@@ -4385,10 +5860,110 @@ define <4 x i16> @test_vselect_v4i16(<4 x i16> %a, <4 x i16> %b, <4 x i16> %c) {
 define <8 x i8> @test_vselect_v8i8(<8 x i8> %a, <8 x i8> %b, <8 x i8> %c) {
 ; RV32-LABEL: test_vselect_v8i8:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    pmsltu.b a1, a1, a3
-; RV32-NEXT:    pmsltu.b a0, a0, a2
-; RV32-NEXT:    merge a0, a2, a4
-; RV32-NEXT:    merge a1, a3, a5
+; RV32-NEXT:    addi sp, sp, -48
+; RV32-NEXT:    .cfi_def_cfa_offset 48
+; RV32-NEXT:    sw s0, 44(sp) # 4-byte Folded Spill
+; RV32-NEXT:    sw s1, 40(sp) # 4-byte Folded Spill
+; RV32-NEXT:    sw s2, 36(sp) # 4-byte Folded Spill
+; RV32-NEXT:    .cfi_offset s0, -4
+; RV32-NEXT:    .cfi_offset s1, -8
+; RV32-NEXT:    .cfi_offset s2, -12
+; RV32-NEXT:    sw a2, 8(sp)
+; RV32-NEXT:    sw a0, 0(sp)
+; RV32-NEXT:    sw a3, 12(sp)
+; RV32-NEXT:    sw a1, 4(sp)
+; RV32-NEXT:    lbu a0, 8(sp)
+; RV32-NEXT:    lbu a1, 9(sp)
+; RV32-NEXT:    lbu a2, 10(sp)
+; RV32-NEXT:    lbu a3, 11(sp)
+; RV32-NEXT:    lbu a6, 0(sp)
+; RV32-NEXT:    lbu t0, 1(sp)
+; RV32-NEXT:    lbu t2, 2(sp)
+; RV32-NEXT:    lbu t4, 3(sp)
+; RV32-NEXT:    lbu a7, 12(sp)
+; RV32-NEXT:    lbu t1, 13(sp)
+; RV32-NEXT:    lbu t3, 14(sp)
+; RV32-NEXT:    lbu t5, 15(sp)
+; RV32-NEXT:    lbu t6, 4(sp)
+; RV32-NEXT:    lbu s0, 5(sp)
+; RV32-NEXT:    lbu s1, 6(sp)
+; RV32-NEXT:    lbu s2, 7(sp)
+; RV32-NEXT:    sltu t6, t6, a7
+; RV32-NEXT:    sltu s0, s0, t1
+; RV32-NEXT:    sltu s1, s1, t3
+; RV32-NEXT:    sltu s2, s2, t5
+; RV32-NEXT:    neg s0, s0
+; RV32-NEXT:    neg s1, s1
+; RV32-NEXT:    neg s2, s2
+; RV32-NEXT:    zext.b s1, s1
+; RV32-NEXT:    zext.b s2, s2
+; RV32-NEXT:    sw a4, 16(sp)
+; RV32-NEXT:    sw a5, 20(sp)
+; RV32-NEXT:    beqz s2, .LBB209_2
+; RV32-NEXT:  # %bb.1:
+; RV32-NEXT:    lbu t5, 23(sp)
+; RV32-NEXT:  .LBB209_2:
+; RV32-NEXT:    sltu a5, t4, a3
+; RV32-NEXT:    neg t6, t6
+; RV32-NEXT:    zext.b a4, s0
+; RV32-NEXT:    sb t5, 31(sp)
+; RV32-NEXT:    beqz s1, .LBB209_4
+; RV32-NEXT:  # %bb.3:
+; RV32-NEXT:    lbu t3, 22(sp)
+; RV32-NEXT:  .LBB209_4:
+; RV32-NEXT:    sltu t2, t2, a2
+; RV32-NEXT:    neg t4, a5
+; RV32-NEXT:    zext.b a5, t6
+; RV32-NEXT:    sb t3, 30(sp)
+; RV32-NEXT:    beqz a4, .LBB209_6
+; RV32-NEXT:  # %bb.5:
+; RV32-NEXT:    lbu t1, 21(sp)
+; RV32-NEXT:  .LBB209_6:
+; RV32-NEXT:    sltu t0, t0, a1
+; RV32-NEXT:    neg t2, t2
+; RV32-NEXT:    zext.b a4, t4
+; RV32-NEXT:    sb t1, 29(sp)
+; RV32-NEXT:    beqz a5, .LBB209_8
+; RV32-NEXT:  # %bb.7:
+; RV32-NEXT:    lbu a7, 20(sp)
+; RV32-NEXT:  .LBB209_8:
+; RV32-NEXT:    sltu a6, a6, a0
+; RV32-NEXT:    neg t0, t0
+; RV32-NEXT:    zext.b a5, t2
+; RV32-NEXT:    sb a7, 28(sp)
+; RV32-NEXT:    beqz a4, .LBB209_10
+; RV32-NEXT:  # %bb.9:
+; RV32-NEXT:    lbu a3, 19(sp)
+; RV32-NEXT:  .LBB209_10:
+; RV32-NEXT:    neg a6, a6
+; RV32-NEXT:    zext.b a4, t0
+; RV32-NEXT:    sb a3, 27(sp)
+; RV32-NEXT:    beqz a5, .LBB209_12
+; RV32-NEXT:  # %bb.11:
+; RV32-NEXT:    lbu a2, 18(sp)
+; RV32-NEXT:  .LBB209_12:
+; RV32-NEXT:    zext.b a3, a6
+; RV32-NEXT:    sb a2, 26(sp)
+; RV32-NEXT:    beqz a4, .LBB209_14
+; RV32-NEXT:  # %bb.13:
+; RV32-NEXT:    lbu a1, 17(sp)
+; RV32-NEXT:  .LBB209_14:
+; RV32-NEXT:    sb a1, 25(sp)
+; RV32-NEXT:    beqz a3, .LBB209_16
+; RV32-NEXT:  # %bb.15:
+; RV32-NEXT:    lbu a0, 16(sp)
+; RV32-NEXT:  .LBB209_16:
+; RV32-NEXT:    sb a0, 24(sp)
+; RV32-NEXT:    lw a0, 24(sp)
+; RV32-NEXT:    lw a1, 28(sp)
+; RV32-NEXT:    lw s0, 44(sp) # 4-byte Folded Reload
+; RV32-NEXT:    lw s1, 40(sp) # 4-byte Folded Reload
+; RV32-NEXT:    lw s2, 36(sp) # 4-byte Folded Reload
+; RV32-NEXT:    .cfi_restore s0
+; RV32-NEXT:    .cfi_restore s1
+; RV32-NEXT:    .cfi_restore s2
+; RV32-NEXT:    addi sp, sp, 48
+; RV32-NEXT:    .cfi_def_cfa_offset 0
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_vselect_v8i8:
@@ -4404,13 +5979,17 @@ define <8 x i8> @test_vselect_v8i8(<8 x i8> %a, <8 x i8> %b, <8 x i8> %c) {
 define <2 x i32> @test_vselect_v2i32(<2 x i32> %a, <2 x i32> %b, <2 x i32> %c) {
 ; RV32-LABEL: test_vselect_v2i32:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    blt a2, a0, .LBB210_2
+; RV32-NEXT:    slt a0, a2, a0
+; RV32-NEXT:    slt a1, a3, a1
+; RV32-NEXT:    neg a1, a1
+; RV32-NEXT:    neg a0, a0
+; RV32-NEXT:    bnez a1, .LBB210_2
 ; RV32-NEXT:  # %bb.1:
-; RV32-NEXT:    mv a4, a2
+; RV32-NEXT:    mv a5, a3
 ; RV32-NEXT:  .LBB210_2:
-; RV32-NEXT:    blt a3, a1, .LBB210_4
+; RV32-NEXT:    bnez a0, .LBB210_4
 ; RV32-NEXT:  # %bb.3:
-; RV32-NEXT:    mv a5, a3
+; RV32-NEXT:    mv a4, a2
 ; RV32-NEXT:  .LBB210_4:
 ; RV32-NEXT:    padd.dw a0, a4, zero
 ; RV32-NEXT:    ret
@@ -4428,12 +6007,30 @@ define <2 x i32> @test_vselect_v2i32(<2 x i32> %a, <2 x i32> %b, <2 x i32> %c) {
 define <4 x i16> @test_bswap_v4i16(<4 x i16> %a) {
 ; RV32-LABEL: test_bswap_v4i16:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    psrli.h a2, a0, 8
-; RV32-NEXT:    pslli.h a0, a0, 8
-; RV32-NEXT:    or a0, a0, a2
-; RV32-NEXT:    psrli.h a2, a1, 8
-; RV32-NEXT:    pslli.h a1, a1, 8
-; RV32-NEXT:    or a1, a1, a2
+; RV32-NEXT:    addi sp, sp, -16
+; RV32-NEXT:    .cfi_def_cfa_offset 16
+; RV32-NEXT:    sw a1, 4(sp)
+; RV32-NEXT:    lh a1, 6(sp)
+; RV32-NEXT:    sw a0, 0(sp)
+; RV32-NEXT:    rev8 a0, a1
+; RV32-NEXT:    srli a0, a0, 16
+; RV32-NEXT:    sh a0, 14(sp)
+; RV32-NEXT:    lh a0, 4(sp)
+; RV32-NEXT:    rev8 a0, a0
+; RV32-NEXT:    srli a0, a0, 16
+; RV32-NEXT:    sh a0, 12(sp)
+; RV32-NEXT:    lh a0, 2(sp)
+; RV32-NEXT:    rev8 a0, a0
+; RV32-NEXT:    srli a0, a0, 16
+; RV32-NEXT:    sh a0, 10(sp)
+; RV32-NEXT:    lh a0, 0(sp)
+; RV32-NEXT:    rev8 a0, a0
+; RV32-NEXT:    srli a0, a0, 16
+; RV32-NEXT:    sh a0, 8(sp)
+; RV32-NEXT:    lw a0, 8(sp)
+; RV32-NEXT:    lw a1, 12(sp)
+; RV32-NEXT:    addi sp, sp, 16
+; RV32-NEXT:    .cfi_def_cfa_offset 0
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_bswap_v4i16:
@@ -4449,8 +6046,8 @@ define <4 x i16> @test_bswap_v4i16(<4 x i16> %a) {
 define <2 x i32> @test_bswap_v2i32(<2 x i32> %a) {
 ; RV32-LABEL: test_bswap_v2i32:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    rev8 a0, a0
 ; RV32-NEXT:    rev8 a1, a1
+; RV32-NEXT:    rev8 a0, a0
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_bswap_v2i32:
@@ -4475,39 +6072,46 @@ define <2 x i32> @test_bswap_v2i32(<2 x i32> %a) {
 define <8 x i8> @test_bitreverse_v8i8(<8 x i8> %a) {
 ; RV32-LABEL: test_bitreverse_v8i8:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    psrli.b a2, a0, 4
-; RV32-NEXT:    pli.b a3, 15
-; RV32-NEXT:    pli.b a4, 51
-; RV32-NEXT:    psrli.b a5, a1, 4
-; RV32-NEXT:    and a2, a2, a3
-; RV32-NEXT:    and a0, a0, a3
-; RV32-NEXT:    and a5, a5, a3
-; RV32-NEXT:    and a1, a1, a3
-; RV32-NEXT:    pli.b a3, 85
-; RV32-NEXT:    pslli.b a0, a0, 4
-; RV32-NEXT:    pslli.b a1, a1, 4
-; RV32-NEXT:    or a0, a2, a0
-; RV32-NEXT:    or a1, a5, a1
-; RV32-NEXT:    psrli.b a2, a0, 2
-; RV32-NEXT:    and a0, a0, a4
-; RV32-NEXT:    psrli.b a5, a1, 2
-; RV32-NEXT:    and a1, a1, a4
-; RV32-NEXT:    and a2, a2, a4
-; RV32-NEXT:    pslli.b a0, a0, 2
-; RV32-NEXT:    and a4, a5, a4
-; RV32-NEXT:    pslli.b a1, a1, 2
-; RV32-NEXT:    or a0, a2, a0
-; RV32-NEXT:    or a1, a4, a1
-; RV32-NEXT:    psrli.b a2, a0, 1
-; RV32-NEXT:    and a0, a0, a3
-; RV32-NEXT:    psrli.b a4, a1, 1
-; RV32-NEXT:    and a1, a1, a3
-; RV32-NEXT:    and a2, a2, a3
-; RV32-NEXT:    pslli.b a0, a0, 1
-; RV32-NEXT:    and a3, a4, a3
-; RV32-NEXT:    pslli.b a1, a1, 1
-; RV32-NEXT:    or a0, a2, a0
-; RV32-NEXT:    or a1, a3, a1
+; RV32-NEXT:    addi sp, sp, -16
+; RV32-NEXT:    .cfi_def_cfa_offset 16
+; RV32-NEXT:    sw a1, 4(sp)
+; RV32-NEXT:    lbu a1, 7(sp)
+; RV32-NEXT:    sw a0, 0(sp)
+; RV32-NEXT:    rev a0, a1
+; RV32-NEXT:    srli a0, a0, 24
+; RV32-NEXT:    sb a0, 15(sp)
+; RV32-NEXT:    lbu a0, 6(sp)
+; RV32-NEXT:    rev a0, a0
+; RV32-NEXT:    srli a0, a0, 24
+; RV32-NEXT:    sb a0, 14(sp)
+; RV32-NEXT:    lbu a0, 5(sp)
+; RV32-NEXT:    rev a0, a0
+; RV32-NEXT:    srli a0, a0, 24
+; RV32-NEXT:    sb a0, 13(sp)
+; RV32-NEXT:    lbu a0, 4(sp)
+; RV32-NEXT:    rev a0, a0
+; RV32-NEXT:    srli a0, a0, 24
+; RV32-NEXT:    sb a0, 12(sp)
+; RV32-NEXT:    lbu a0, 3(sp)
+; RV32-NEXT:    rev a0, a0
+; RV32-NEXT:    srli a0, a0, 24
+; RV32-NEXT:    sb a0, 11(sp)
+; RV32-NEXT:    lbu a0, 2(sp)
+; RV32-NEXT:    rev a0, a0
+; RV32-NEXT:    srli a0, a0, 24
+; RV32-NEXT:    sb a0, 10(sp)
+; RV32-NEXT:    lbu a0, 1(sp)
+; RV32-NEXT:    rev a0, a0
+; RV32-NEXT:    srli a0, a0, 24
+; RV32-NEXT:    sb a0, 9(sp)
+; RV32-NEXT:    lbu a0, 0(sp)
+; RV32-NEXT:    rev a0, a0
+; RV32-NEXT:    srli a0, a0, 24
+; RV32-NEXT:    sb a0, 8(sp)
+; RV32-NEXT:    lw a0, 8(sp)
+; RV32-NEXT:    lw a1, 12(sp)
+; RV32-NEXT:    addi sp, sp, 16
+; RV32-NEXT:    .cfi_def_cfa_offset 0
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_bitreverse_v8i8:
@@ -4538,45 +6142,30 @@ define <8 x i8> @test_bitreverse_v8i8(<8 x i8> %a) {
 define <4 x i16> @test_bitreverse_v4i16(<4 x i16> %a) {
 ; RV32-LABEL: test_bitreverse_v4i16:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    psrli.h a2, a0, 8
-; RV32-NEXT:    pslli.h a0, a0, 8
-; RV32-NEXT:    pli.b a3, 15
-; RV32-NEXT:    pli.b a4, 51
-; RV32-NEXT:    psrli.h a5, a1, 8
-; RV32-NEXT:    pslli.h a1, a1, 8
-; RV32-NEXT:    or a0, a0, a2
-; RV32-NEXT:    or a1, a1, a5
-; RV32-NEXT:    psrli.h a2, a0, 4
-; RV32-NEXT:    and a0, a0, a3
-; RV32-NEXT:    psrli.h a5, a1, 4
-; RV32-NEXT:    and a1, a1, a3
-; RV32-NEXT:    and a2, a2, a3
-; RV32-NEXT:    and a3, a5, a3
-; RV32-NEXT:    pli.b a5, 85
-; RV32-NEXT:    pslli.h a0, a0, 4
-; RV32-NEXT:    pslli.h a1, a1, 4
-; RV32-NEXT:    or a0, a2, a0
-; RV32-NEXT:    or a1, a3, a1
-; RV32-NEXT:    psrli.h a2, a0, 2
-; RV32-NEXT:    and a0, a0, a4
-; RV32-NEXT:    psrli.h a3, a1, 2
-; RV32-NEXT:    and a1, a1, a4
-; RV32-NEXT:    and a2, a2, a4
-; RV32-NEXT:    pslli.h a0, a0, 2
-; RV32-NEXT:    and a3, a3, a4
-; RV32-NEXT:    pslli.h a1, a1, 2
-; RV32-NEXT:    or a0, a2, a0
-; RV32-NEXT:    or a1, a3, a1
-; RV32-NEXT:    psrli.h a2, a0, 1
-; RV32-NEXT:    and a0, a0, a5
-; RV32-NEXT:    psrli.h a3, a1, 1
-; RV32-NEXT:    and a1, a1, a5
-; RV32-NEXT:    and a2, a2, a5
-; RV32-NEXT:    pslli.h a0, a0, 1
-; RV32-NEXT:    and a3, a3, a5
-; RV32-NEXT:    pslli.h a1, a1, 1
-; RV32-NEXT:    or a0, a2, a0
-; RV32-NEXT:    or a1, a3, a1
+; RV32-NEXT:    addi sp, sp, -16
+; RV32-NEXT:    .cfi_def_cfa_offset 16
+; RV32-NEXT:    sw a1, 4(sp)
+; RV32-NEXT:    lh a1, 6(sp)
+; RV32-NEXT:    sw a0, 0(sp)
+; RV32-NEXT:    rev a0, a1
+; RV32-NEXT:    srli a0, a0, 16
+; RV32-NEXT:    sh a0, 14(sp)
+; RV32-NEXT:    lh a0, 4(sp)
+; RV32-NEXT:    rev a0, a0
+; RV32-NEXT:    srli a0, a0, 16
+; RV32-NEXT:    sh a0, 12(sp)
+; RV32-NEXT:    lh a0, 2(sp)
+; RV32-NEXT:    rev a0, a0
+; RV32-NEXT:    srli a0, a0, 16
+; RV32-NEXT:    sh a0, 10(sp)
+; RV32-NEXT:    lh a0, 0(sp)
+; RV32-NEXT:    rev a0, a0
+; RV32-NEXT:    srli a0, a0, 16
+; RV32-NEXT:    sh a0, 8(sp)
+; RV32-NEXT:    lw a0, 8(sp)
+; RV32-NEXT:    lw a1, 12(sp)
+; RV32-NEXT:    addi sp, sp, 16
+; RV32-NEXT:    .cfi_def_cfa_offset 0
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_bitreverse_v4i16:
@@ -4610,8 +6199,8 @@ define <4 x i16> @test_bitreverse_v4i16(<4 x i16> %a) {
 define <2 x i32> @test_bitreverse_v2i32(<2 x i32> %a) {
 ; RV32-LABEL: test_bitreverse_v2i32:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    rev a0, a0
 ; RV32-NEXT:    rev a1, a1
+; RV32-NEXT:    rev a0, a0
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_bitreverse_v2i32:
diff --git a/llvm/test/CodeGen/RISCV/rvp-unaligned-load-store.ll b/llvm/test/CodeGen/RISCV/rvp-unaligned-load-store.ll
index 4a43dad8519e5..566d8a0c7c288 100644
--- a/llvm/test/CodeGen/RISCV/rvp-unaligned-load-store.ll
+++ b/llvm/test/CodeGen/RISCV/rvp-unaligned-load-store.ll
@@ -11,22 +11,22 @@
 define void @test_load_v4i8_align1(ptr %ret_ptr, ptr %a_ptr) {
 ; CHECK-RV32-LABEL: test_load_v4i8_align1:
 ; CHECK-RV32:       # %bb.0:
-; CHECK-RV32-NEXT:    lbu a2, 4(a1)
-; CHECK-RV32-NEXT:    lbu a3, 5(a1)
-; CHECK-RV32-NEXT:    lbu a4, 6(a1)
-; CHECK-RV32-NEXT:    lbu a5, 7(a1)
-; CHECK-RV32-NEXT:    lbu a6, 1(a1)
-; CHECK-RV32-NEXT:    lbu a7, 2(a1)
-; CHECK-RV32-NEXT:    lbu t0, 3(a1)
-; CHECK-RV32-NEXT:    lbu a1, 0(a1)
+; CHECK-RV32-NEXT:    lbu a2, 0(a1)
+; CHECK-RV32-NEXT:    lbu a3, 1(a1)
+; CHECK-RV32-NEXT:    lbu a4, 2(a1)
+; CHECK-RV32-NEXT:    lbu a5, 3(a1)
+; CHECK-RV32-NEXT:    lbu a6, 5(a1)
+; CHECK-RV32-NEXT:    lbu a7, 6(a1)
+; CHECK-RV32-NEXT:    lbu t0, 7(a1)
+; CHECK-RV32-NEXT:    lbu a1, 4(a1)
 ; CHECK-RV32-NEXT:    ppaire.b a4, a4, a5
 ; CHECK-RV32-NEXT:    ppaire.b a2, a2, a3
 ; CHECK-RV32-NEXT:    ppaire.b a3, a7, t0
 ; CHECK-RV32-NEXT:    ppaire.b a1, a1, a6
 ; CHECK-RV32-NEXT:    pack a2, a2, a4
 ; CHECK-RV32-NEXT:    pack a1, a1, a3
-; CHECK-RV32-NEXT:    sw a1, 0(a0)
-; CHECK-RV32-NEXT:    sw a2, 4(a0)
+; CHECK-RV32-NEXT:    sw a2, 0(a0)
+; CHECK-RV32-NEXT:    sw a1, 4(a0)
 ; CHECK-RV32-NEXT:    ret
 ;
 ; CHECK-RV64-LABEL: test_load_v4i8_align1:
@@ -129,14 +129,14 @@ define void @test_store_v4i8_align1(ptr %a_ptr, ptr %b_ptr) {
 define void @test_load_v4i8_align2(ptr %ret_ptr, ptr %a_ptr) {
 ; CHECK-RV32-LABEL: test_load_v4i8_align2:
 ; CHECK-RV32:       # %bb.0:
-; CHECK-RV32-NEXT:    lhu a2, 2(a1)
-; CHECK-RV32-NEXT:    lhu a3, 4(a1)
-; CHECK-RV32-NEXT:    lhu a4, 6(a1)
-; CHECK-RV32-NEXT:    lhu a1, 0(a1)
-; CHECK-RV32-NEXT:    pack a3, a3, a4
-; CHECK-RV32-NEXT:    pack a1, a1, a2
-; CHECK-RV32-NEXT:    sw a1, 0(a0)
-; CHECK-RV32-NEXT:    sw a3, 4(a0)
+; CHECK-RV32-NEXT:    lhu a2, 0(a1)
+; CHECK-RV32-NEXT:    lhu a3, 2(a1)
+; CHECK-RV32-NEXT:    lhu a4, 4(a1)
+; CHECK-RV32-NEXT:    lhu a1, 6(a1)
+; CHECK-RV32-NEXT:    pack a2, a2, a3
+; CHECK-RV32-NEXT:    pack a1, a4, a1
+; CHECK-RV32-NEXT:    sw a2, 0(a0)
+; CHECK-RV32-NEXT:    sw a1, 4(a0)
 ; CHECK-RV32-NEXT:    ret
 ;
 ; CHECK-RV64-LABEL: test_load_v4i8_align2:
@@ -393,22 +393,22 @@ define void @test_store_v2i16_align2(ptr %a_ptr, ptr %b_ptr) {
 define void @test_load_v8i8_align1(ptr %ret_ptr, ptr %a_ptr) {
 ; CHECK-RV32-LABEL: test_load_v8i8_align1:
 ; CHECK-RV32:       # %bb.0:
-; CHECK-RV32-NEXT:    lbu a2, 4(a1)
-; CHECK-RV32-NEXT:    lbu a3, 5(a1)
-; CHECK-RV32-NEXT:    lbu a4, 6(a1)
-; CHECK-RV32-NEXT:    lbu a5, 7(a1)
-; CHECK-RV32-NEXT:    lbu a6, 1(a1)
-; CHECK-RV32-NEXT:    lbu a7, 2(a1)
-; CHECK-RV32-NEXT:    lbu t0, 3(a1)
-; CHECK-RV32-NEXT:    lbu a1, 0(a1)
+; CHECK-RV32-NEXT:    lbu a2, 0(a1)
+; CHECK-RV32-NEXT:    lbu a3, 1(a1)
+; CHECK-RV32-NEXT:    lbu a4, 2(a1)
+; CHECK-RV32-NEXT:    lbu a5, 3(a1)
+; CHECK-RV32-NEXT:    lbu a6, 5(a1)
+; CHECK-RV32-NEXT:    lbu a7, 6(a1)
+; CHECK-RV32-NEXT:    lbu t0, 7(a1)
+; CHECK-RV32-NEXT:    lbu a1, 4(a1)
 ; CHECK-RV32-NEXT:    ppaire.b a4, a4, a5
 ; CHECK-RV32-NEXT:    ppaire.b a2, a2, a3
 ; CHECK-RV32-NEXT:    ppaire.b a3, a7, t0
 ; CHECK-RV32-NEXT:    ppaire.b a1, a1, a6
 ; CHECK-RV32-NEXT:    pack a2, a2, a4
 ; CHECK-RV32-NEXT:    pack a1, a1, a3
-; CHECK-RV32-NEXT:    sw a1, 0(a0)
-; CHECK-RV32-NEXT:    sw a2, 4(a0)
+; CHECK-RV32-NEXT:    sw a2, 0(a0)
+; CHECK-RV32-NEXT:    sw a1, 4(a0)
 ; CHECK-RV32-NEXT:    ret
 ;
 ; CHECK-RV64-LABEL: test_load_v8i8_align1:
@@ -511,14 +511,14 @@ define void @test_store_v8i8_align1(ptr %a_ptr, ptr %b_ptr) {
 define void @test_load_v8i8_align2(ptr %ret_ptr, ptr %a_ptr) {
 ; CHECK-RV32-LABEL: test_load_v8i8_align2:
 ; CHECK-RV32:       # %bb.0:
-; CHECK-RV32-NEXT:    lhu a2, 2(a1)
-; CHECK-RV32-NEXT:    lhu a3, 4(a1)
-; CHECK-RV32-NEXT:    lhu a4, 6(a1)
-; CHECK-RV32-NEXT:    lhu a1, 0(a1)
-; CHECK-RV32-NEXT:    pack a3, a3, a4
-; CHECK-RV32-NEXT:    pack a1, a1, a2
-; CHECK-RV32-NEXT:    sw a1, 0(a0)
-; CHECK-RV32-NEXT:    sw a3, 4(a0)
+; CHECK-RV32-NEXT:    lhu a2, 0(a1)
+; CHECK-RV32-NEXT:    lhu a3, 2(a1)
+; CHECK-RV32-NEXT:    lhu a4, 4(a1)
+; CHECK-RV32-NEXT:    lhu a1, 6(a1)
+; CHECK-RV32-NEXT:    pack a2, a2, a3
+; CHECK-RV32-NEXT:    pack a1, a4, a1
+; CHECK-RV32-NEXT:    sw a2, 0(a0)
+; CHECK-RV32-NEXT:    sw a1, 4(a0)
 ; CHECK-RV32-NEXT:    ret
 ;
 ; CHECK-RV64-LABEL: test_load_v8i8_align2:
@@ -600,22 +600,22 @@ define void @test_store_v8i8_align2(ptr %a_ptr, ptr %b_ptr) {
 define void @test_load_v4i16_align1(ptr %ret_ptr, ptr %a_ptr) {
 ; CHECK-RV32-LABEL: test_load_v4i16_align1:
 ; CHECK-RV32:       # %bb.0:
-; CHECK-RV32-NEXT:    lbu a2, 4(a1)
-; CHECK-RV32-NEXT:    lbu a3, 5(a1)
-; CHECK-RV32-NEXT:    lbu a4, 6(a1)
-; CHECK-RV32-NEXT:    lbu a5, 7(a1)
-; CHECK-RV32-NEXT:    lbu a6, 1(a1)
-; CHECK-RV32-NEXT:    lbu a7, 2(a1)
-; CHECK-RV32-NEXT:    lbu t0, 3(a1)
-; CHECK-RV32-NEXT:    lbu a1, 0(a1)
+; CHECK-RV32-NEXT:    lbu a2, 0(a1)
+; CHECK-RV32-NEXT:    lbu a3, 1(a1)
+; CHECK-RV32-NEXT:    lbu a4, 2(a1)
+; CHECK-RV32-NEXT:    lbu a5, 3(a1)
+; CHECK-RV32-NEXT:    lbu a6, 5(a1)
+; CHECK-RV32-NEXT:    lbu a7, 6(a1)
+; CHECK-RV32-NEXT:    lbu t0, 7(a1)
+; CHECK-RV32-NEXT:    lbu a1, 4(a1)
 ; CHECK-RV32-NEXT:    ppaire.b a4, a4, a5
 ; CHECK-RV32-NEXT:    ppaire.b a2, a2, a3
 ; CHECK-RV32-NEXT:    ppaire.b a3, a7, t0
 ; CHECK-RV32-NEXT:    ppaire.b a1, a1, a6
 ; CHECK-RV32-NEXT:    pack a2, a2, a4
 ; CHECK-RV32-NEXT:    pack a1, a1, a3
-; CHECK-RV32-NEXT:    sw a1, 0(a0)
-; CHECK-RV32-NEXT:    sw a2, 4(a0)
+; CHECK-RV32-NEXT:    sw a2, 0(a0)
+; CHECK-RV32-NEXT:    sw a1, 4(a0)
 ; CHECK-RV32-NEXT:    ret
 ;
 ; CHECK-RV64-LABEL: test_load_v4i16_align1:
@@ -718,14 +718,14 @@ define void @test_store_v4i16_align1(ptr %a_ptr, ptr %b_ptr) {
 define void @test_load_v4i16_align2(ptr %ret_ptr, ptr %a_ptr) {
 ; CHECK-RV32-LABEL: test_load_v4i16_align2:
 ; CHECK-RV32:       # %bb.0:
-; CHECK-RV32-NEXT:    lhu a2, 2(a1)
-; CHECK-RV32-NEXT:    lhu a3, 4(a1)
-; CHECK-RV32-NEXT:    lhu a4, 6(a1)
-; CHECK-RV32-NEXT:    lhu a1, 0(a1)
-; CHECK-RV32-NEXT:    pack a3, a3, a4
-; CHECK-RV32-NEXT:    pack a1, a1, a2
-; CHECK-RV32-NEXT:    sw a1, 0(a0)
-; CHECK-RV32-NEXT:    sw a3, 4(a0)
+; CHECK-RV32-NEXT:    lhu a2, 0(a1)
+; CHECK-RV32-NEXT:    lhu a3, 2(a1)
+; CHECK-RV32-NEXT:    lhu a4, 4(a1)
+; CHECK-RV32-NEXT:    lhu a1, 6(a1)
+; CHECK-RV32-NEXT:    pack a2, a2, a3
+; CHECK-RV32-NEXT:    pack a1, a4, a1
+; CHECK-RV32-NEXT:    sw a2, 0(a0)
+; CHECK-RV32-NEXT:    sw a1, 4(a0)
 ; CHECK-RV32-NEXT:    ret
 ;
 ; CHECK-RV64-LABEL: test_load_v4i16_align2:
@@ -877,22 +877,22 @@ define void @test_store_v4i16_align4(ptr %a_ptr, ptr %b_ptr) {
 define void @test_load_v2i32_align1(ptr %ret_ptr, ptr %a_ptr) {
 ; CHECK-RV32-LABEL: test_load_v2i32_align1:
 ; CHECK-RV32:       # %bb.0:
-; CHECK-RV32-NEXT:    lbu a2, 0(a1)
-; CHECK-RV32-NEXT:    lbu a3, 1(a1)
-; CHECK-RV32-NEXT:    lbu a4, 2(a1)
-; CHECK-RV32-NEXT:    lbu a5, 3(a1)
-; CHECK-RV32-NEXT:    lbu a6, 5(a1)
-; CHECK-RV32-NEXT:    lbu a7, 6(a1)
-; CHECK-RV32-NEXT:    lbu t0, 7(a1)
-; CHECK-RV32-NEXT:    lbu a1, 4(a1)
+; CHECK-RV32-NEXT:    lbu a2, 4(a1)
+; CHECK-RV32-NEXT:    lbu a3, 5(a1)
+; CHECK-RV32-NEXT:    lbu a4, 6(a1)
+; CHECK-RV32-NEXT:    lbu a5, 7(a1)
+; CHECK-RV32-NEXT:    lbu a6, 1(a1)
+; CHECK-RV32-NEXT:    lbu a7, 2(a1)
+; CHECK-RV32-NEXT:    lbu t0, 3(a1)
+; CHECK-RV32-NEXT:    lbu a1, 0(a1)
 ; CHECK-RV32-NEXT:    ppaire.b a4, a4, a5
 ; CHECK-RV32-NEXT:    ppaire.b a2, a2, a3
 ; CHECK-RV32-NEXT:    ppaire.b a3, a7, t0
 ; CHECK-RV32-NEXT:    ppaire.b a1, a1, a6
 ; CHECK-RV32-NEXT:    pack a2, a2, a4
 ; CHECK-RV32-NEXT:    pack a1, a1, a3
-; CHECK-RV32-NEXT:    sw a2, 0(a0)
-; CHECK-RV32-NEXT:    sw a1, 4(a0)
+; CHECK-RV32-NEXT:    sw a1, 0(a0)
+; CHECK-RV32-NEXT:    sw a2, 4(a0)
 ; CHECK-RV32-NEXT:    ret
 ;
 ; CHECK-RV64-LABEL: test_load_v2i32_align1:
@@ -995,14 +995,14 @@ define void @test_store_v2i32_align1(ptr %a_ptr, ptr %b_ptr) {
 define void @test_load_v2i32_align2(ptr %ret_ptr, ptr %a_ptr) {
 ; CHECK-RV32-LABEL: test_load_v2i32_align2:
 ; CHECK-RV32:       # %bb.0:
-; CHECK-RV32-NEXT:    lhu a2, 0(a1)
-; CHECK-RV32-NEXT:    lhu a3, 2(a1)
-; CHECK-RV32-NEXT:    lhu a4, 4(a1)
-; CHECK-RV32-NEXT:    lhu a1, 6(a1)
-; CHECK-RV32-NEXT:    pack a2, a2, a3
-; CHECK-RV32-NEXT:    pack a1, a4, a1
-; CHECK-RV32-NEXT:    sw a2, 0(a0)
-; CHECK-RV32-NEXT:    sw a1, 4(a0)
+; CHECK-RV32-NEXT:    lhu a2, 2(a1)
+; CHECK-RV32-NEXT:    lhu a3, 4(a1)
+; CHECK-RV32-NEXT:    lhu a4, 6(a1)
+; CHECK-RV32-NEXT:    lhu a1, 0(a1)
+; CHECK-RV32-NEXT:    pack a3, a3, a4
+; CHECK-RV32-NEXT:    pack a1, a1, a2
+; CHECK-RV32-NEXT:    sw a1, 0(a0)
+; CHECK-RV32-NEXT:    sw a3, 4(a0)
 ; CHECK-RV32-NEXT:    ret
 ;
 ; CHECK-RV64-LABEL: test_load_v2i32_align2:

>From ec81d6f3e6d928c82e44a397eac451ea2c7aaf1b Mon Sep 17 00:00:00 2001
From: Craig Topper <craig.topper at sifive.com>
Date: Mon, 11 May 2026 22:43:13 -0700
Subject: [PATCH 2/3] fixup! update comment

---
 llvm/lib/Target/RISCV/RISCVInstrInfoP.td | 20 ++++++++++++--------
 1 file changed, 12 insertions(+), 8 deletions(-)

diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoP.td b/llvm/lib/Target/RISCV/RISCVInstrInfoP.td
index 67b8a045f7870..04100fd92fcec 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoP.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoP.td
@@ -1942,15 +1942,19 @@ def IncImm : SDNodeXForm<imm, [{
                                      N->getValueType(0));
 }]>;
 
-def SDT_RISCVBuildPairGPRVec : SDTypeProfile<1, 2, [SDTCisSubVecOfVec<1, 0>,
+def SDT_RISCVBuildPairGPRVec : SDTypeProfile<1, 2, [SDTCisVec<0>,
+                                                    SDTCisVT<1, i32>,
                                                     SDTCisSameAs<1, 2>]>;
-def SDT_RISCVSplitGPRVec : SDTypeProfile<2, 1, [SDTCisSubVecOfVec<0, 2>,
-                                                SDTCisSameAs<0, 1>]>;
-
-// These nodes are used to handle 64-bit vectors on R32. They're equivalent to
-// concat_vectors and a pair of extract_subvectors. We're using custom nodes to
-// prevent some generic DAG combines from pushing the extract_subvectors
-// through 64-bit operations. These may be temporary.
+def SDT_RISCVSplitGPRVec : SDTypeProfile<2, 1, [SDTCisVT<0, i32>,
+                                                SDTCisSameAs<0, 1>,
+                                                SDTCisVec<2>]>;
+
+// These nodes are used to handle 64-bit vector arguments and returns on RV32.
+// One side is a pair of i32 GPRs, the other is a 64-bit vector.
+// TOD: We might be able to use 32-bit vectors with concat_vectors/build_vector
+// and extract_subvector/extract_vectorelt instead. Using custom nodes prevents
+// 64-bit vector aithmetic operations in our lit tests from being split until
+// we can tune some generic combines.
 def RISCVBuildPairGPRVec : RVSDNode<"BuildPairGPRVec",
                                     SDT_RISCVBuildPairGPRVec>;
 def RISCVSplitGPRVec     : RVSDNode<"SplitGPRVec", SDT_RISCVSplitGPRVec>;

>From 2fb62e7bd19cedfef4776f01a11f0d9f28216c9c Mon Sep 17 00:00:00 2001
From: Craig Topper <craig.topper at sifive.com>
Date: Mon, 11 May 2026 22:46:54 -0700
Subject: [PATCH 3/3] fixup! Remove LegalizeVectorOps.cpp change to avoid
 affecting AMDGPU.

---
 .../SelectionDAG/LegalizeVectorOps.cpp        |   3 -
 llvm/test/CodeGen/RISCV/rvp-simd-64.ll        | 480 +++++++++++++++++-
 2 files changed, 458 insertions(+), 25 deletions(-)

diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp
index 162b6f69edb81..eb89a0f129df4 100644
--- a/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp
@@ -1394,9 +1394,6 @@ void VectorLegalizer::Expand(SDNode *Node, SmallVectorImpl<SDValue> &Results) {
     Results.push_back(ExpandLOOP_DEPENDENCE_MASK(Node));
     return;
 
-  case ISD::AND:
-  case ISD::OR:
-  case ISD::XOR:
   case ISD::FADD:
   case ISD::FMUL:
   case ISD::FMA:
diff --git a/llvm/test/CodeGen/RISCV/rvp-simd-64.ll b/llvm/test/CodeGen/RISCV/rvp-simd-64.ll
index bba99b9a0cd64..6c6ee5ebcf6a8 100644
--- a/llvm/test/CodeGen/RISCV/rvp-simd-64.ll
+++ b/llvm/test/CodeGen/RISCV/rvp-simd-64.ll
@@ -68,8 +68,32 @@ define <8 x i8> @test_psub_b(<8 x i8> %a, <8 x i8> %b) {
 define <4 x i16> @test_and_h(<4 x i16> %a, <4 x i16> %b) {
 ; RV32-LABEL: test_and_h:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    and a1, a1, a3
-; RV32-NEXT:    and a0, a0, a2
+; RV32-NEXT:    addi sp, sp, -32
+; RV32-NEXT:    .cfi_def_cfa_offset 32
+; RV32-NEXT:    sw a3, 20(sp)
+; RV32-NEXT:    sw a1, 12(sp)
+; RV32-NEXT:    sw a2, 16(sp)
+; RV32-NEXT:    sw a0, 8(sp)
+; RV32-NEXT:    lh a0, 22(sp)
+; RV32-NEXT:    lh a1, 14(sp)
+; RV32-NEXT:    and a0, a1, a0
+; RV32-NEXT:    sh a0, 30(sp)
+; RV32-NEXT:    lh a0, 20(sp)
+; RV32-NEXT:    lh a1, 12(sp)
+; RV32-NEXT:    and a0, a1, a0
+; RV32-NEXT:    sh a0, 28(sp)
+; RV32-NEXT:    lh a0, 18(sp)
+; RV32-NEXT:    lh a1, 10(sp)
+; RV32-NEXT:    and a0, a1, a0
+; RV32-NEXT:    sh a0, 26(sp)
+; RV32-NEXT:    lh a0, 16(sp)
+; RV32-NEXT:    lh a1, 8(sp)
+; RV32-NEXT:    and a0, a1, a0
+; RV32-NEXT:    sh a0, 24(sp)
+; RV32-NEXT:    lw a0, 24(sp)
+; RV32-NEXT:    lw a1, 28(sp)
+; RV32-NEXT:    addi sp, sp, 32
+; RV32-NEXT:    .cfi_def_cfa_offset 0
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_and_h:
@@ -83,8 +107,32 @@ define <4 x i16> @test_and_h(<4 x i16> %a, <4 x i16> %b) {
 define <4 x i16> @test_or_h(<4 x i16> %a, <4 x i16> %b) {
 ; RV32-LABEL: test_or_h:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    or a1, a1, a3
-; RV32-NEXT:    or a0, a0, a2
+; RV32-NEXT:    addi sp, sp, -32
+; RV32-NEXT:    .cfi_def_cfa_offset 32
+; RV32-NEXT:    sw a3, 20(sp)
+; RV32-NEXT:    sw a1, 12(sp)
+; RV32-NEXT:    sw a2, 16(sp)
+; RV32-NEXT:    sw a0, 8(sp)
+; RV32-NEXT:    lh a0, 22(sp)
+; RV32-NEXT:    lh a1, 14(sp)
+; RV32-NEXT:    or a0, a1, a0
+; RV32-NEXT:    sh a0, 30(sp)
+; RV32-NEXT:    lh a0, 20(sp)
+; RV32-NEXT:    lh a1, 12(sp)
+; RV32-NEXT:    or a0, a1, a0
+; RV32-NEXT:    sh a0, 28(sp)
+; RV32-NEXT:    lh a0, 18(sp)
+; RV32-NEXT:    lh a1, 10(sp)
+; RV32-NEXT:    or a0, a1, a0
+; RV32-NEXT:    sh a0, 26(sp)
+; RV32-NEXT:    lh a0, 16(sp)
+; RV32-NEXT:    lh a1, 8(sp)
+; RV32-NEXT:    or a0, a1, a0
+; RV32-NEXT:    sh a0, 24(sp)
+; RV32-NEXT:    lw a0, 24(sp)
+; RV32-NEXT:    lw a1, 28(sp)
+; RV32-NEXT:    addi sp, sp, 32
+; RV32-NEXT:    .cfi_def_cfa_offset 0
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_or_h:
@@ -98,8 +146,32 @@ define <4 x i16> @test_or_h(<4 x i16> %a, <4 x i16> %b) {
 define <4 x i16> @test_xor_h(<4 x i16> %a, <4 x i16> %b) {
 ; RV32-LABEL: test_xor_h:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    xor a1, a1, a3
-; RV32-NEXT:    xor a0, a0, a2
+; RV32-NEXT:    addi sp, sp, -32
+; RV32-NEXT:    .cfi_def_cfa_offset 32
+; RV32-NEXT:    sw a3, 20(sp)
+; RV32-NEXT:    sw a1, 12(sp)
+; RV32-NEXT:    sw a2, 16(sp)
+; RV32-NEXT:    sw a0, 8(sp)
+; RV32-NEXT:    lh a0, 22(sp)
+; RV32-NEXT:    lh a1, 14(sp)
+; RV32-NEXT:    xor a0, a1, a0
+; RV32-NEXT:    sh a0, 30(sp)
+; RV32-NEXT:    lh a0, 20(sp)
+; RV32-NEXT:    lh a1, 12(sp)
+; RV32-NEXT:    xor a0, a1, a0
+; RV32-NEXT:    sh a0, 28(sp)
+; RV32-NEXT:    lh a0, 18(sp)
+; RV32-NEXT:    lh a1, 10(sp)
+; RV32-NEXT:    xor a0, a1, a0
+; RV32-NEXT:    sh a0, 26(sp)
+; RV32-NEXT:    lh a0, 16(sp)
+; RV32-NEXT:    lh a1, 8(sp)
+; RV32-NEXT:    xor a0, a1, a0
+; RV32-NEXT:    sh a0, 24(sp)
+; RV32-NEXT:    lw a0, 24(sp)
+; RV32-NEXT:    lw a1, 28(sp)
+; RV32-NEXT:    addi sp, sp, 32
+; RV32-NEXT:    .cfi_def_cfa_offset 0
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_xor_h:
@@ -113,8 +185,32 @@ define <4 x i16> @test_xor_h(<4 x i16> %a, <4 x i16> %b) {
 define <4 x i16> @test_andn_h(<4 x i16> %a, <4 x i16> %b) {
 ; RV32-LABEL: test_andn_h:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    andn a1, a1, a3
+; RV32-NEXT:    addi sp, sp, -32
+; RV32-NEXT:    .cfi_def_cfa_offset 32
+; RV32-NEXT:    sw a2, 16(sp)
+; RV32-NEXT:    sw a3, 20(sp)
+; RV32-NEXT:    lh a2, 16(sp)
+; RV32-NEXT:    lh a3, 18(sp)
+; RV32-NEXT:    lh a4, 20(sp)
+; RV32-NEXT:    lh a5, 22(sp)
+; RV32-NEXT:    sw a1, 12(sp)
+; RV32-NEXT:    lh a1, 14(sp)
+; RV32-NEXT:    sw a0, 8(sp)
+; RV32-NEXT:    andn a0, a1, a5
+; RV32-NEXT:    sh a0, 30(sp)
+; RV32-NEXT:    lh a0, 12(sp)
+; RV32-NEXT:    andn a0, a0, a4
+; RV32-NEXT:    sh a0, 28(sp)
+; RV32-NEXT:    lh a0, 10(sp)
+; RV32-NEXT:    andn a0, a0, a3
+; RV32-NEXT:    sh a0, 26(sp)
+; RV32-NEXT:    lh a0, 8(sp)
 ; RV32-NEXT:    andn a0, a0, a2
+; RV32-NEXT:    sh a0, 24(sp)
+; RV32-NEXT:    lw a0, 24(sp)
+; RV32-NEXT:    lw a1, 28(sp)
+; RV32-NEXT:    addi sp, sp, 32
+; RV32-NEXT:    .cfi_def_cfa_offset 0
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_andn_h:
@@ -129,8 +225,32 @@ define <4 x i16> @test_andn_h(<4 x i16> %a, <4 x i16> %b) {
 define <4 x i16> @test_orn_h(<4 x i16> %a, <4 x i16> %b) {
 ; RV32-LABEL: test_orn_h:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    orn a1, a1, a3
+; RV32-NEXT:    addi sp, sp, -32
+; RV32-NEXT:    .cfi_def_cfa_offset 32
+; RV32-NEXT:    sw a2, 16(sp)
+; RV32-NEXT:    sw a3, 20(sp)
+; RV32-NEXT:    lh a2, 16(sp)
+; RV32-NEXT:    lh a3, 18(sp)
+; RV32-NEXT:    lh a4, 20(sp)
+; RV32-NEXT:    lh a5, 22(sp)
+; RV32-NEXT:    sw a1, 12(sp)
+; RV32-NEXT:    lh a1, 14(sp)
+; RV32-NEXT:    sw a0, 8(sp)
+; RV32-NEXT:    orn a0, a1, a5
+; RV32-NEXT:    sh a0, 30(sp)
+; RV32-NEXT:    lh a0, 12(sp)
+; RV32-NEXT:    orn a0, a0, a4
+; RV32-NEXT:    sh a0, 28(sp)
+; RV32-NEXT:    lh a0, 10(sp)
+; RV32-NEXT:    orn a0, a0, a3
+; RV32-NEXT:    sh a0, 26(sp)
+; RV32-NEXT:    lh a0, 8(sp)
 ; RV32-NEXT:    orn a0, a0, a2
+; RV32-NEXT:    sh a0, 24(sp)
+; RV32-NEXT:    lw a0, 24(sp)
+; RV32-NEXT:    lw a1, 28(sp)
+; RV32-NEXT:    addi sp, sp, 32
+; RV32-NEXT:    .cfi_def_cfa_offset 0
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_orn_h:
@@ -145,8 +265,32 @@ define <4 x i16> @test_orn_h(<4 x i16> %a, <4 x i16> %b) {
 define <4 x i16> @test_xnor_h(<4 x i16> %a, <4 x i16> %b) {
 ; RV32-LABEL: test_xnor_h:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    xnor a1, a3, a1
-; RV32-NEXT:    xnor a0, a2, a0
+; RV32-NEXT:    addi sp, sp, -32
+; RV32-NEXT:    .cfi_def_cfa_offset 32
+; RV32-NEXT:    sw a0, 8(sp)
+; RV32-NEXT:    sw a2, 16(sp)
+; RV32-NEXT:    sw a1, 12(sp)
+; RV32-NEXT:    sw a3, 20(sp)
+; RV32-NEXT:    lh a0, 8(sp)
+; RV32-NEXT:    lh a1, 10(sp)
+; RV32-NEXT:    lh a2, 12(sp)
+; RV32-NEXT:    lh a3, 14(sp)
+; RV32-NEXT:    lh a4, 22(sp)
+; RV32-NEXT:    lh a5, 20(sp)
+; RV32-NEXT:    lh a6, 18(sp)
+; RV32-NEXT:    lh a7, 16(sp)
+; RV32-NEXT:    xnor a3, a4, a3
+; RV32-NEXT:    xnor a2, a5, a2
+; RV32-NEXT:    xnor a1, a6, a1
+; RV32-NEXT:    xnor a0, a7, a0
+; RV32-NEXT:    sh a0, 24(sp)
+; RV32-NEXT:    sh a1, 26(sp)
+; RV32-NEXT:    sh a2, 28(sp)
+; RV32-NEXT:    sh a3, 30(sp)
+; RV32-NEXT:    lw a0, 24(sp)
+; RV32-NEXT:    lw a1, 28(sp)
+; RV32-NEXT:    addi sp, sp, 32
+; RV32-NEXT:    .cfi_def_cfa_offset 0
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_xnor_h:
@@ -162,8 +306,48 @@ define <4 x i16> @test_xnor_h(<4 x i16> %a, <4 x i16> %b) {
 define <8 x i8> @test_and_b(<8 x i8> %a, <8 x i8> %b) {
 ; RV32-LABEL: test_and_b:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    and a1, a1, a3
-; RV32-NEXT:    and a0, a0, a2
+; RV32-NEXT:    addi sp, sp, -32
+; RV32-NEXT:    .cfi_def_cfa_offset 32
+; RV32-NEXT:    sw a3, 20(sp)
+; RV32-NEXT:    sw a1, 12(sp)
+; RV32-NEXT:    sw a2, 16(sp)
+; RV32-NEXT:    sw a0, 8(sp)
+; RV32-NEXT:    lbu a0, 23(sp)
+; RV32-NEXT:    lbu a1, 15(sp)
+; RV32-NEXT:    and a0, a1, a0
+; RV32-NEXT:    sb a0, 31(sp)
+; RV32-NEXT:    lbu a0, 22(sp)
+; RV32-NEXT:    lbu a1, 14(sp)
+; RV32-NEXT:    and a0, a1, a0
+; RV32-NEXT:    sb a0, 30(sp)
+; RV32-NEXT:    lbu a0, 21(sp)
+; RV32-NEXT:    lbu a1, 13(sp)
+; RV32-NEXT:    and a0, a1, a0
+; RV32-NEXT:    sb a0, 29(sp)
+; RV32-NEXT:    lbu a0, 20(sp)
+; RV32-NEXT:    lbu a1, 12(sp)
+; RV32-NEXT:    and a0, a1, a0
+; RV32-NEXT:    sb a0, 28(sp)
+; RV32-NEXT:    lbu a0, 19(sp)
+; RV32-NEXT:    lbu a1, 11(sp)
+; RV32-NEXT:    and a0, a1, a0
+; RV32-NEXT:    sb a0, 27(sp)
+; RV32-NEXT:    lbu a0, 18(sp)
+; RV32-NEXT:    lbu a1, 10(sp)
+; RV32-NEXT:    and a0, a1, a0
+; RV32-NEXT:    sb a0, 26(sp)
+; RV32-NEXT:    lbu a0, 17(sp)
+; RV32-NEXT:    lbu a1, 9(sp)
+; RV32-NEXT:    and a0, a1, a0
+; RV32-NEXT:    sb a0, 25(sp)
+; RV32-NEXT:    lbu a0, 16(sp)
+; RV32-NEXT:    lbu a1, 8(sp)
+; RV32-NEXT:    and a0, a1, a0
+; RV32-NEXT:    sb a0, 24(sp)
+; RV32-NEXT:    lw a0, 24(sp)
+; RV32-NEXT:    lw a1, 28(sp)
+; RV32-NEXT:    addi sp, sp, 32
+; RV32-NEXT:    .cfi_def_cfa_offset 0
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_and_b:
@@ -177,8 +361,48 @@ define <8 x i8> @test_and_b(<8 x i8> %a, <8 x i8> %b) {
 define <8 x i8> @test_or_b(<8 x i8> %a, <8 x i8> %b) {
 ; RV32-LABEL: test_or_b:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    or a1, a1, a3
-; RV32-NEXT:    or a0, a0, a2
+; RV32-NEXT:    addi sp, sp, -32
+; RV32-NEXT:    .cfi_def_cfa_offset 32
+; RV32-NEXT:    sw a3, 20(sp)
+; RV32-NEXT:    sw a1, 12(sp)
+; RV32-NEXT:    sw a2, 16(sp)
+; RV32-NEXT:    sw a0, 8(sp)
+; RV32-NEXT:    lbu a0, 23(sp)
+; RV32-NEXT:    lbu a1, 15(sp)
+; RV32-NEXT:    or a0, a1, a0
+; RV32-NEXT:    sb a0, 31(sp)
+; RV32-NEXT:    lbu a0, 22(sp)
+; RV32-NEXT:    lbu a1, 14(sp)
+; RV32-NEXT:    or a0, a1, a0
+; RV32-NEXT:    sb a0, 30(sp)
+; RV32-NEXT:    lbu a0, 21(sp)
+; RV32-NEXT:    lbu a1, 13(sp)
+; RV32-NEXT:    or a0, a1, a0
+; RV32-NEXT:    sb a0, 29(sp)
+; RV32-NEXT:    lbu a0, 20(sp)
+; RV32-NEXT:    lbu a1, 12(sp)
+; RV32-NEXT:    or a0, a1, a0
+; RV32-NEXT:    sb a0, 28(sp)
+; RV32-NEXT:    lbu a0, 19(sp)
+; RV32-NEXT:    lbu a1, 11(sp)
+; RV32-NEXT:    or a0, a1, a0
+; RV32-NEXT:    sb a0, 27(sp)
+; RV32-NEXT:    lbu a0, 18(sp)
+; RV32-NEXT:    lbu a1, 10(sp)
+; RV32-NEXT:    or a0, a1, a0
+; RV32-NEXT:    sb a0, 26(sp)
+; RV32-NEXT:    lbu a0, 17(sp)
+; RV32-NEXT:    lbu a1, 9(sp)
+; RV32-NEXT:    or a0, a1, a0
+; RV32-NEXT:    sb a0, 25(sp)
+; RV32-NEXT:    lbu a0, 16(sp)
+; RV32-NEXT:    lbu a1, 8(sp)
+; RV32-NEXT:    or a0, a1, a0
+; RV32-NEXT:    sb a0, 24(sp)
+; RV32-NEXT:    lw a0, 24(sp)
+; RV32-NEXT:    lw a1, 28(sp)
+; RV32-NEXT:    addi sp, sp, 32
+; RV32-NEXT:    .cfi_def_cfa_offset 0
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_or_b:
@@ -192,8 +416,48 @@ define <8 x i8> @test_or_b(<8 x i8> %a, <8 x i8> %b) {
 define <8 x i8> @test_xor_b(<8 x i8> %a, <8 x i8> %b) {
 ; RV32-LABEL: test_xor_b:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    xor a1, a1, a3
-; RV32-NEXT:    xor a0, a0, a2
+; RV32-NEXT:    addi sp, sp, -32
+; RV32-NEXT:    .cfi_def_cfa_offset 32
+; RV32-NEXT:    sw a3, 20(sp)
+; RV32-NEXT:    sw a1, 12(sp)
+; RV32-NEXT:    sw a2, 16(sp)
+; RV32-NEXT:    sw a0, 8(sp)
+; RV32-NEXT:    lbu a0, 23(sp)
+; RV32-NEXT:    lbu a1, 15(sp)
+; RV32-NEXT:    xor a0, a1, a0
+; RV32-NEXT:    sb a0, 31(sp)
+; RV32-NEXT:    lbu a0, 22(sp)
+; RV32-NEXT:    lbu a1, 14(sp)
+; RV32-NEXT:    xor a0, a1, a0
+; RV32-NEXT:    sb a0, 30(sp)
+; RV32-NEXT:    lbu a0, 21(sp)
+; RV32-NEXT:    lbu a1, 13(sp)
+; RV32-NEXT:    xor a0, a1, a0
+; RV32-NEXT:    sb a0, 29(sp)
+; RV32-NEXT:    lbu a0, 20(sp)
+; RV32-NEXT:    lbu a1, 12(sp)
+; RV32-NEXT:    xor a0, a1, a0
+; RV32-NEXT:    sb a0, 28(sp)
+; RV32-NEXT:    lbu a0, 19(sp)
+; RV32-NEXT:    lbu a1, 11(sp)
+; RV32-NEXT:    xor a0, a1, a0
+; RV32-NEXT:    sb a0, 27(sp)
+; RV32-NEXT:    lbu a0, 18(sp)
+; RV32-NEXT:    lbu a1, 10(sp)
+; RV32-NEXT:    xor a0, a1, a0
+; RV32-NEXT:    sb a0, 26(sp)
+; RV32-NEXT:    lbu a0, 17(sp)
+; RV32-NEXT:    lbu a1, 9(sp)
+; RV32-NEXT:    xor a0, a1, a0
+; RV32-NEXT:    sb a0, 25(sp)
+; RV32-NEXT:    lbu a0, 16(sp)
+; RV32-NEXT:    lbu a1, 8(sp)
+; RV32-NEXT:    xor a0, a1, a0
+; RV32-NEXT:    sb a0, 24(sp)
+; RV32-NEXT:    lw a0, 24(sp)
+; RV32-NEXT:    lw a1, 28(sp)
+; RV32-NEXT:    addi sp, sp, 32
+; RV32-NEXT:    .cfi_def_cfa_offset 0
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_xor_b:
@@ -207,8 +471,48 @@ define <8 x i8> @test_xor_b(<8 x i8> %a, <8 x i8> %b) {
 define <8 x i8> @test_andn_b(<8 x i8> %a, <8 x i8> %b) {
 ; RV32-LABEL: test_andn_b:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    andn a1, a1, a3
+; RV32-NEXT:    addi sp, sp, -32
+; RV32-NEXT:    .cfi_def_cfa_offset 32
+; RV32-NEXT:    sw a2, 16(sp)
+; RV32-NEXT:    sw a3, 20(sp)
+; RV32-NEXT:    lbu a2, 16(sp)
+; RV32-NEXT:    lbu a3, 17(sp)
+; RV32-NEXT:    lbu a4, 18(sp)
+; RV32-NEXT:    lbu a5, 19(sp)
+; RV32-NEXT:    lbu a6, 20(sp)
+; RV32-NEXT:    lbu a7, 21(sp)
+; RV32-NEXT:    lbu t0, 22(sp)
+; RV32-NEXT:    lbu t1, 23(sp)
+; RV32-NEXT:    sw a1, 12(sp)
+; RV32-NEXT:    lbu a1, 15(sp)
+; RV32-NEXT:    sw a0, 8(sp)
+; RV32-NEXT:    andn a0, a1, t1
+; RV32-NEXT:    sb a0, 31(sp)
+; RV32-NEXT:    lbu a0, 14(sp)
+; RV32-NEXT:    andn a0, a0, t0
+; RV32-NEXT:    sb a0, 30(sp)
+; RV32-NEXT:    lbu a0, 13(sp)
+; RV32-NEXT:    andn a0, a0, a7
+; RV32-NEXT:    sb a0, 29(sp)
+; RV32-NEXT:    lbu a0, 12(sp)
+; RV32-NEXT:    andn a0, a0, a6
+; RV32-NEXT:    sb a0, 28(sp)
+; RV32-NEXT:    lbu a0, 11(sp)
+; RV32-NEXT:    andn a0, a0, a5
+; RV32-NEXT:    sb a0, 27(sp)
+; RV32-NEXT:    lbu a0, 10(sp)
+; RV32-NEXT:    andn a0, a0, a4
+; RV32-NEXT:    sb a0, 26(sp)
+; RV32-NEXT:    lbu a0, 9(sp)
+; RV32-NEXT:    andn a0, a0, a3
+; RV32-NEXT:    sb a0, 25(sp)
+; RV32-NEXT:    lbu a0, 8(sp)
 ; RV32-NEXT:    andn a0, a0, a2
+; RV32-NEXT:    sb a0, 24(sp)
+; RV32-NEXT:    lw a0, 24(sp)
+; RV32-NEXT:    lw a1, 28(sp)
+; RV32-NEXT:    addi sp, sp, 32
+; RV32-NEXT:    .cfi_def_cfa_offset 0
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_andn_b:
@@ -223,8 +527,48 @@ define <8 x i8> @test_andn_b(<8 x i8> %a, <8 x i8> %b) {
 define <8 x i8> @test_orn_b(<8 x i8> %a, <8 x i8> %b) {
 ; RV32-LABEL: test_orn_b:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    orn a1, a1, a3
+; RV32-NEXT:    addi sp, sp, -32
+; RV32-NEXT:    .cfi_def_cfa_offset 32
+; RV32-NEXT:    sw a2, 16(sp)
+; RV32-NEXT:    sw a3, 20(sp)
+; RV32-NEXT:    lbu a2, 16(sp)
+; RV32-NEXT:    lbu a3, 17(sp)
+; RV32-NEXT:    lbu a4, 18(sp)
+; RV32-NEXT:    lbu a5, 19(sp)
+; RV32-NEXT:    lbu a6, 20(sp)
+; RV32-NEXT:    lbu a7, 21(sp)
+; RV32-NEXT:    lbu t0, 22(sp)
+; RV32-NEXT:    lbu t1, 23(sp)
+; RV32-NEXT:    sw a1, 12(sp)
+; RV32-NEXT:    lbu a1, 15(sp)
+; RV32-NEXT:    sw a0, 8(sp)
+; RV32-NEXT:    orn a0, a1, t1
+; RV32-NEXT:    sb a0, 31(sp)
+; RV32-NEXT:    lbu a0, 14(sp)
+; RV32-NEXT:    orn a0, a0, t0
+; RV32-NEXT:    sb a0, 30(sp)
+; RV32-NEXT:    lbu a0, 13(sp)
+; RV32-NEXT:    orn a0, a0, a7
+; RV32-NEXT:    sb a0, 29(sp)
+; RV32-NEXT:    lbu a0, 12(sp)
+; RV32-NEXT:    orn a0, a0, a6
+; RV32-NEXT:    sb a0, 28(sp)
+; RV32-NEXT:    lbu a0, 11(sp)
+; RV32-NEXT:    orn a0, a0, a5
+; RV32-NEXT:    sb a0, 27(sp)
+; RV32-NEXT:    lbu a0, 10(sp)
+; RV32-NEXT:    orn a0, a0, a4
+; RV32-NEXT:    sb a0, 26(sp)
+; RV32-NEXT:    lbu a0, 9(sp)
+; RV32-NEXT:    orn a0, a0, a3
+; RV32-NEXT:    sb a0, 25(sp)
+; RV32-NEXT:    lbu a0, 8(sp)
 ; RV32-NEXT:    orn a0, a0, a2
+; RV32-NEXT:    sb a0, 24(sp)
+; RV32-NEXT:    lw a0, 24(sp)
+; RV32-NEXT:    lw a1, 28(sp)
+; RV32-NEXT:    addi sp, sp, 32
+; RV32-NEXT:    .cfi_def_cfa_offset 0
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_orn_b:
@@ -239,8 +583,52 @@ define <8 x i8> @test_orn_b(<8 x i8> %a, <8 x i8> %b) {
 define <8 x i8> @test_xnor_b(<8 x i8> %a, <8 x i8> %b) {
 ; RV32-LABEL: test_xnor_b:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    xnor a1, a3, a1
-; RV32-NEXT:    xnor a0, a2, a0
+; RV32-NEXT:    addi sp, sp, -32
+; RV32-NEXT:    .cfi_def_cfa_offset 32
+; RV32-NEXT:    sw s0, 28(sp) # 4-byte Folded Spill
+; RV32-NEXT:    .cfi_offset s0, -4
+; RV32-NEXT:    sw a0, 0(sp)
+; RV32-NEXT:    sw a2, 8(sp)
+; RV32-NEXT:    sw a1, 4(sp)
+; RV32-NEXT:    sw a3, 12(sp)
+; RV32-NEXT:    lbu a0, 0(sp)
+; RV32-NEXT:    lbu a1, 1(sp)
+; RV32-NEXT:    lbu a2, 2(sp)
+; RV32-NEXT:    lbu a3, 3(sp)
+; RV32-NEXT:    lbu a4, 4(sp)
+; RV32-NEXT:    lbu a5, 5(sp)
+; RV32-NEXT:    lbu a6, 6(sp)
+; RV32-NEXT:    lbu a7, 7(sp)
+; RV32-NEXT:    lbu t0, 12(sp)
+; RV32-NEXT:    lbu t1, 13(sp)
+; RV32-NEXT:    lbu t2, 14(sp)
+; RV32-NEXT:    lbu t3, 15(sp)
+; RV32-NEXT:    lbu t4, 8(sp)
+; RV32-NEXT:    lbu t5, 9(sp)
+; RV32-NEXT:    lbu t6, 10(sp)
+; RV32-NEXT:    lbu s0, 11(sp)
+; RV32-NEXT:    xnor a7, t3, a7
+; RV32-NEXT:    xnor a6, t2, a6
+; RV32-NEXT:    xnor a5, t1, a5
+; RV32-NEXT:    xnor a4, t0, a4
+; RV32-NEXT:    xnor a3, s0, a3
+; RV32-NEXT:    xnor a2, t6, a2
+; RV32-NEXT:    xnor a1, t5, a1
+; RV32-NEXT:    xnor a0, t4, a0
+; RV32-NEXT:    sb a4, 20(sp)
+; RV32-NEXT:    sb a5, 21(sp)
+; RV32-NEXT:    sb a6, 22(sp)
+; RV32-NEXT:    sb a7, 23(sp)
+; RV32-NEXT:    sb a0, 16(sp)
+; RV32-NEXT:    sb a1, 17(sp)
+; RV32-NEXT:    sb a2, 18(sp)
+; RV32-NEXT:    sb a3, 19(sp)
+; RV32-NEXT:    lw a0, 16(sp)
+; RV32-NEXT:    lw a1, 20(sp)
+; RV32-NEXT:    lw s0, 28(sp) # 4-byte Folded Reload
+; RV32-NEXT:    .cfi_restore s0
+; RV32-NEXT:    addi sp, sp, 32
+; RV32-NEXT:    .cfi_def_cfa_offset 0
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_xnor_b:
@@ -349,8 +737,26 @@ define <2 x i32> @test_xnor_w(<2 x i32> %a, <2 x i32> %b) {
 define <4 x i16> @test_not_h(<4 x i16> %a) {
 ; RV32-LABEL: test_not_h:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    not a1, a1
+; RV32-NEXT:    addi sp, sp, -16
+; RV32-NEXT:    .cfi_def_cfa_offset 16
+; RV32-NEXT:    sw a1, 4(sp)
+; RV32-NEXT:    lh a1, 6(sp)
+; RV32-NEXT:    sw a0, 0(sp)
+; RV32-NEXT:    not a0, a1
+; RV32-NEXT:    sh a0, 14(sp)
+; RV32-NEXT:    lh a0, 4(sp)
+; RV32-NEXT:    not a0, a0
+; RV32-NEXT:    sh a0, 12(sp)
+; RV32-NEXT:    lh a0, 2(sp)
+; RV32-NEXT:    not a0, a0
+; RV32-NEXT:    sh a0, 10(sp)
+; RV32-NEXT:    lh a0, 0(sp)
 ; RV32-NEXT:    not a0, a0
+; RV32-NEXT:    sh a0, 8(sp)
+; RV32-NEXT:    lw a0, 8(sp)
+; RV32-NEXT:    lw a1, 12(sp)
+; RV32-NEXT:    addi sp, sp, 16
+; RV32-NEXT:    .cfi_def_cfa_offset 0
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_not_h:
@@ -364,8 +770,38 @@ define <4 x i16> @test_not_h(<4 x i16> %a) {
 define <8 x i8> @test_not_b(<8 x i8> %a) {
 ; RV32-LABEL: test_not_b:
 ; RV32:       # %bb.0:
-; RV32-NEXT:    not a1, a1
+; RV32-NEXT:    addi sp, sp, -16
+; RV32-NEXT:    .cfi_def_cfa_offset 16
+; RV32-NEXT:    sw a1, 4(sp)
+; RV32-NEXT:    lbu a1, 7(sp)
+; RV32-NEXT:    sw a0, 0(sp)
+; RV32-NEXT:    not a0, a1
+; RV32-NEXT:    sb a0, 15(sp)
+; RV32-NEXT:    lbu a0, 6(sp)
 ; RV32-NEXT:    not a0, a0
+; RV32-NEXT:    sb a0, 14(sp)
+; RV32-NEXT:    lbu a0, 5(sp)
+; RV32-NEXT:    not a0, a0
+; RV32-NEXT:    sb a0, 13(sp)
+; RV32-NEXT:    lbu a0, 4(sp)
+; RV32-NEXT:    not a0, a0
+; RV32-NEXT:    sb a0, 12(sp)
+; RV32-NEXT:    lbu a0, 3(sp)
+; RV32-NEXT:    not a0, a0
+; RV32-NEXT:    sb a0, 11(sp)
+; RV32-NEXT:    lbu a0, 2(sp)
+; RV32-NEXT:    not a0, a0
+; RV32-NEXT:    sb a0, 10(sp)
+; RV32-NEXT:    lbu a0, 1(sp)
+; RV32-NEXT:    not a0, a0
+; RV32-NEXT:    sb a0, 9(sp)
+; RV32-NEXT:    lbu a0, 0(sp)
+; RV32-NEXT:    not a0, a0
+; RV32-NEXT:    sb a0, 8(sp)
+; RV32-NEXT:    lw a0, 8(sp)
+; RV32-NEXT:    lw a1, 12(sp)
+; RV32-NEXT:    addi sp, sp, 16
+; RV32-NEXT:    .cfi_def_cfa_offset 0
 ; RV32-NEXT:    ret
 ;
 ; RV64-LABEL: test_not_b:



More information about the llvm-commits mailing list