diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp --- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp @@ -4293,15 +4293,22 @@ MVT ContainerVT = getContainerForFixedLengthVector(DAG, RotateVT, Subtarget); SDValue VL = getDefaultVLOps(RotateVT, ContainerVT, DL, DAG, Subtarget).second; - SDValue RotateAmtSplat = DAG.getNode( - RISCVISD::VMV_V_X_VL, DL, ContainerVT, DAG.getUNDEF(ContainerVT), - DAG.getConstant(RotateAmt, DL, Subtarget.getXLenVT()), VL); - RotateAmtSplat = - convertFromScalableVector(RotateVT, RotateAmtSplat, DAG, Subtarget); + SDValue Op = DAG.getBitcast(RotateVT, SVN->getOperand(0)); + + SDValue Rotate; + // A rotate of an i16 by 8 bits either direction is equivalent to a byteswap, + // so canonicalize to vrev8. + if (RotateVT.getScalarType() == MVT::i16 && RotateAmt == 8) { + Rotate = DAG.getNode(ISD::BSWAP, DL, RotateVT, Op); + } else { + SDValue RotateAmtSplat = DAG.getNode( + RISCVISD::VMV_V_X_VL, DL, ContainerVT, DAG.getUNDEF(ContainerVT), + DAG.getConstant(RotateAmt, DL, Subtarget.getXLenVT()), VL); + RotateAmtSplat = + convertFromScalableVector(RotateVT, RotateAmtSplat, DAG, Subtarget); + Rotate = DAG.getNode(ISD::ROTL, DL, RotateVT, Op, RotateAmtSplat); + } - SDValue Rotate = - DAG.getNode(ISD::ROTL, DL, RotateVT, - DAG.getBitcast(RotateVT, SVN->getOperand(0)), RotateAmtSplat); return DAG.getBitcast(VT, Rotate); } diff --git a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-shuffle-reverse.ll b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-shuffle-reverse.ll --- a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-shuffle-reverse.ll +++ b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-shuffle-reverse.ll @@ -180,7 +180,7 @@ ; ZVBB-LABEL: reverse_v2i8: ; ZVBB: # %bb.0: ; ZVBB-NEXT: vsetivli zero, 1, e16, mf4, ta, ma -; ZVBB-NEXT: vror.vi v8, v8, 8 +; ZVBB-NEXT: vrev8.v v8, v8 ; ZVBB-NEXT: ret %res = call <2 x i8> @llvm.experimental.vector.reverse.v2i8(<2 x i8> %a) ret <2 x i8> %res diff --git a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-shuffle-rotate.ll b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-shuffle-rotate.ll --- a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-shuffle-rotate.ll +++ b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-shuffle-rotate.ll @@ -202,13 +202,13 @@ ; ZVBB-V-LABEL: shuffle_v8i8_as_i16: ; ZVBB-V: # %bb.0: ; ZVBB-V-NEXT: vsetivli zero, 4, e16, mf2, ta, ma -; ZVBB-V-NEXT: vror.vi v8, v8, 8 +; ZVBB-V-NEXT: vrev8.v v8, v8 ; ZVBB-V-NEXT: ret ; ; ZVBB-ZVE32X-LABEL: shuffle_v8i8_as_i16: ; ZVBB-ZVE32X: # %bb.0: ; ZVBB-ZVE32X-NEXT: vsetivli zero, 4, e16, m2, ta, ma -; ZVBB-ZVE32X-NEXT: vror.vi v8, v8, 8 +; ZVBB-ZVE32X-NEXT: vrev8.v v8, v8 ; ZVBB-ZVE32X-NEXT: ret %shuffle = shufflevector <8 x i8> %v, <8 x i8> poison, <8 x i32> ret <8 x i8> %shuffle