[llvm] 976244b - [RISCV] Canonicalize vrot{l,r} to vrev8 when lowering shuffle as rotate

Luke Lau via llvm-commits llvm-commits at lists.llvm.org
Wed Aug 30 03:01:58 PDT 2023


Author: Luke Lau
Date: 2023-08-30T11:01:49+01:00
New Revision: 976244bb845ca6e59139fffdf0372e4aba962ff1

URL: https://github.com/llvm/llvm-project/commit/976244bb845ca6e59139fffdf0372e4aba962ff1
DIFF: https://github.com/llvm/llvm-project/commit/976244bb845ca6e59139fffdf0372e4aba962ff1.diff

LOG: [RISCV] Canonicalize vrot{l,r} to vrev8 when lowering shuffle as rotate

A rotate of 8 bits of an e16 vector in either direction is equivalent to a
byteswap, i.e. vrev8. There is a generic combine on ISD::ROT{L,R} to
canonicalize these rotations to byteswaps, but on fixed vectors they are
legalized before they have the chance to be combined. This patch teaches the
rotate vector_shuffle lowering to emit these rotations as byteswaps to match
the scalable vector behaviour.

Reviewed By: reames

Differential Revision: https://reviews.llvm.org/D158195

Added: 
    

Modified: 
    llvm/lib/Target/RISCV/RISCVISelLowering.cpp
    llvm/test/CodeGen/RISCV/rvv/fixed-vectors-shuffle-reverse.ll
    llvm/test/CodeGen/RISCV/rvv/fixed-vectors-shuffle-rotate.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 7ebbdcde4bea56..92d7d7a0032e46 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -4293,15 +4293,22 @@ static SDValue lowerVECTOR_SHUFFLEAsRotate(ShuffleVectorSDNode *SVN,
   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
index 2e3b8fb82f1920..d9e5fd85e73f68 100644
--- 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 @@ define <2 x i8> @reverse_v2i8(<2 x i8> %a) {
 ; 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
index 327c3c23ebb268..17a9f1bae7ad90 100644
--- 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 @@ define <8 x i8> @shuffle_v8i8_as_i16(<8 x i8> %v) {
 ; 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> <i32 1, i32 0, i32 3, i32 2, i32 5, i32 4, i32 7, i32 6>
   ret <8 x i8> %shuffle


        


More information about the llvm-commits mailing list