[PATCH] D141043: [AArch64][SVE] Avoid AND operation if both side are splat of i1 or PTRUE

Dinar Temirbulatov via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Thu Jan 5 04:14:13 PST 2023


dtemirbulatov created this revision.
dtemirbulatov added reviewers: sdesmalen, MattDevereau, CarolineConcatto, kmclaughlin, david-arm, peterwaller-arm.
Herald added subscribers: psnobl, hiraditya, kristof.beyls, tschuett.
Herald added a reviewer: efriedma.
Herald added a project: All.
dtemirbulatov requested review of this revision.
Herald added a project: LLVM.

If both sides of AND operations are i1 splat_vectors or PTRUE node then we can produce just i1 splat_vector as the result.


https://reviews.llvm.org/D141043

Files:
  llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
  llvm/test/CodeGen/AArch64/sve-intrinsics-reinterpret.ll
  llvm/test/CodeGen/AArch64/sve-splat-and-ptrue.ll


Index: llvm/test/CodeGen/AArch64/sve-splat-and-ptrue.ll
===================================================================
--- /dev/null
+++ llvm/test/CodeGen/AArch64/sve-splat-and-ptrue.ll
@@ -0,0 +1,29 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc < %s -O3 | FileCheck %s
+
+target triple = "aarch64-unknown-linux-gnu"
+
+; Ensure that a no-op 'and' get removed, when the and is constructed via a llvm.aarch64.sve.convert.to.svbool.nxv4i1 node.
+define void @bar() #0 {
+; CHECK-LABEL: bar:
+; CHECK:       // %bb.0: // %entry
+; CHECK-NEXT:    ptrue p1.b
+; CHECK-NEXT:    ptrue p0.s
+; CHECK-NEXT:    b foo
+entry:
+  %0 = tail call <vscale x 4 x i1> @llvm.aarch64.sve.ptrue.nxv4i1(i32 31)
+  %1 = tail call <vscale x 16 x i1> @llvm.aarch64.sve.convert.to.svbool.nxv4i1(<vscale x 4 x i1> %0)
+  %2 = tail call <vscale x 16 x i1> @llvm.aarch64.sve.ptrue.nxv16i1(i32 31)
+  tail call void @foo(<vscale x 16 x i1> %1, <vscale x 16 x i1> %2)
+  ret void
+}
+
+declare void @foo(<vscale x 16 x i1>, <vscale x 16 x i1>)
+
+declare <vscale x 4 x i1> @llvm.aarch64.sve.ptrue.nxv4i1(i32 immarg)
+
+declare <vscale x 16 x i1> @llvm.aarch64.sve.convert.to.svbool.nxv4i1(<vscale x 4 x i1>)
+
+declare <vscale x 16 x i1> @llvm.aarch64.sve.ptrue.nxv16i1(i32 immarg)
+
+attributes #0 = { "target-features"="+sve" }
Index: llvm/test/CodeGen/AArch64/sve-intrinsics-reinterpret.ll
===================================================================
--- llvm/test/CodeGen/AArch64/sve-intrinsics-reinterpret.ll
+++ llvm/test/CodeGen/AArch64/sve-intrinsics-reinterpret.ll
@@ -125,9 +125,7 @@
 define <vscale x 16 x i1> @chained_reinterpret() {
 ; CHECK-LABEL: chained_reinterpret:
 ; CHECK:       // %bb.0:
-; CHECK-NEXT:    ptrue p0.b
-; CHECK-NEXT:    ptrue p1.d
-; CHECK-NEXT:    and p0.b, p0/z, p0.b, p1.b
+; CHECK-NEXT:    ptrue p0.d
 ; CHECK-NEXT:    ret
   %in = tail call <vscale x 16 x i1> @llvm.aarch64.sve.ptrue.nxv16i1(i32 31)
   %cast2 = call <vscale x 2 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv2i1(<vscale x 16 x i1> %in)
Index: llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
===================================================================
--- llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -16214,6 +16214,12 @@
   return false;
 }
 
+static SDValue findRootNonReinterpretNode(SDValue Op) {
+  if (Op.getNode()->getOpcode() != AArch64ISD::REINTERPRET_CAST)
+    return Op;
+  return findRootNonReinterpretNode(Op->getOperand(0));
+}
+
 static SDValue performSVEAndCombine(SDNode *N,
                                     TargetLowering::DAGCombinerInfo &DCI) {
   if (DCI.isBeforeLegalizeOps())
@@ -16260,6 +16266,26 @@
     return DAG.getNode(Opc, DL, N->getValueType(0), And);
   }
 
+  // If both sides of AND operations are i1 splat_vectors then
+  // we can produce just i1 splat_vector as the result
+  SDValue Op0 = findRootNonReinterpretNode(Src);
+  SDValue Op1 = findRootNonReinterpretNode(N->getOperand(1));
+  if ((ISD::isConstantSplatVectorAllOnes(Op0.getNode()) ||
+       Op0.getNode()->getOpcode() == AArch64ISD::PTRUE) &&
+      (ISD::isConstantSplatVectorAllOnes(Op1.getNode()) ||
+       Op1.getNode()->getOpcode() == AArch64ISD::PTRUE)) {
+    EVT OpVT0 = Op0.getValueType();
+    EVT OpVT1 = Op1.getValueType();
+    if (OpVT0.getVectorElementType() == MVT::i1 &&
+        OpVT1.getVectorElementType() == MVT::i1) {
+      SDLoc DL(N);
+      return (OpVT0.getVectorElementCount().getKnownMinValue() >
+              OpVT1.getVectorElementCount().getKnownMinValue())
+                 ? N->getOperand(1)
+                 : Src;
+    }
+  }
+
   if (!EnableCombineMGatherIntrinsics)
     return SDValue();
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D141043.486521.patch
Type: text/x-patch
Size: 3743 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20230105/780b841a/attachment.bin>


More information about the llvm-commits mailing list