[llvm] [Arch64][SVE] Lower svrev_* to llvm.vector.reverse and fold svrev(svrev(x)) -> x (PR #116422)

Sander de Smalen via llvm-commits llvm-commits at lists.llvm.org
Fri May 2 00:39:59 PDT 2025


================
@@ -2674,6 +2675,52 @@ static std::optional<Instruction *> instCombinePTrue(InstCombiner &IC,
   return std::nullopt;
 }
 
+static std::optional<Instruction *> instCombineSVERev(InstCombiner &IC,
+                                                      IntrinsicInst &II) {
+  // rev(rev(x)) -> x
+  switch (II.getIntrinsicID()) {
+  default:
+    return std::nullopt;
+
+  case Intrinsic::aarch64_sve_rev:
+  case Intrinsic::aarch64_sve_rev_b16:
+  case Intrinsic::aarch64_sve_rev_b32:
+  case Intrinsic::aarch64_sve_rev_b64: {
+    Value *InnerArg = II.getArgOperand(0);
+    IntrinsicInst *InnerRev = dyn_cast<IntrinsicInst>(InnerArg);
+    // Fold rev(rev(x)) -> x, if intrinsic IDs match and InnerRev has one use
+    if (InnerRev && InnerRev->getIntrinsicID() == II.getIntrinsicID() &&
+        InnerRev->hasOneUse())
+      return IC.replaceInstUsesWith(II, InnerRev->getArgOperand(0));
+
+    return std::nullopt;
+  }
+
+  case Intrinsic::aarch64_sve_revb:
+  case Intrinsic::aarch64_sve_revd:
+  case Intrinsic::aarch64_sve_revh:
+  case Intrinsic::aarch64_sve_revw: {
+    Value *InnerArg = II.getArgOperand(2);
+    IntrinsicInst *InnerRev = dyn_cast<IntrinsicInst>(InnerArg);
+
+    // Early exit if InnerRev != outerId and doesn't only have one use
+    if (!InnerRev || InnerRev->getIntrinsicID() != II.getIntrinsicID() ||
+        !InnerRev->hasOneUse())
+      return std::nullopt;
+
+    Value *OuterPred = II.getArgOperand(0);
+    Value *OuterPassThru = II.getArgOperand(1);
+    Value *InnerPred = InnerRev->getArgOperand(0);
+    Value *InnerPassThru = InnerRev->getArgOperand(1);
----------------
sdesmalen-arm wrote:

These variables are all unused.

https://github.com/llvm/llvm-project/pull/116422


More information about the llvm-commits mailing list