[llvm] [PowerPC] catch v2i64 shift left by 1 is add case (PR #138772)

via llvm-commits llvm-commits at lists.llvm.org
Mon May 12 10:24:39 PDT 2025


https://github.com/RolandF77 updated https://github.com/llvm/llvm-project/pull/138772

>From 0955560667d16a9173ba4d35d544547eff06d71c Mon Sep 17 00:00:00 2001
From: Roland Froese <froese at ca.ibm.com>
Date: Tue, 6 May 2025 21:17:48 +0000
Subject: [PATCH 1/2] catch v2i64 shift by 1

---
 llvm/lib/Target/PowerPC/PPCISelLowering.cpp  | 35 ++++++++++++++++++++
 llvm/lib/Target/PowerPC/PPCISelLowering.h    |  1 +
 llvm/test/CodeGen/PowerPC/optimize-vector.ll |  5 +--
 llvm/test/CodeGen/PowerPC/pr47891.ll         | 23 ++++++-------
 4 files changed, 47 insertions(+), 17 deletions(-)

diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
index f9e791e4b34f8..9e562d7ca498e 100644
--- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
+++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
@@ -18456,10 +18456,45 @@ static SDValue stripModuloOnShift(const TargetLowering &TLI, SDNode *N,
   return SDValue();
 }
 
+SDValue PPCTargetLowering::combineVectorSHL(SDNode *N,
+                                            DAGCombinerInfo &DCI) const {
+  assert(N->getValueType(0).isVector() && "Vector type expected.");
+
+  SDValue N1 = N->getOperand(1);
+  if (!Subtarget.hasP8Altivec() || N1.getOpcode() != ISD::BUILD_VECTOR ||
+      !isOperationLegal(ISD::ADD, N->getValueType(0)))
+    return SDValue();
+
+  // For 64-bit there is no splat immediate so we want to catch shift by 1 here
+  // before the BUILD_VECTOR is replaced by a load.
+  EVT EltTy = N->getValueType(0).getScalarType();
+  if (EltTy != MVT::i64)
+    return SDValue();
+
+  BuildVectorSDNode *BVN = cast<BuildVectorSDNode>(N1);
+  APInt APSplatBits, APSplatUndef;
+  unsigned SplatBitSize;
+  bool HasAnyUndefs;
+  bool BVNIsConstantSplat =
+      BVN->isConstantSplat(APSplatBits, APSplatUndef, SplatBitSize,
+                           HasAnyUndefs, 0, !Subtarget.isLittleEndian());
+  if (!BVNIsConstantSplat || SplatBitSize != EltTy.getSizeInBits())
+    return SDValue();
+  uint64_t SplatBits = APSplatBits.getZExtValue();
+  if (SplatBits != 1)
+    return SDValue();
+
+  return DCI.DAG.getNode(ISD::ADD, SDLoc(N), N->getValueType(0),
+                         N->getOperand(0), N->getOperand(0));
+}
+
 SDValue PPCTargetLowering::combineSHL(SDNode *N, DAGCombinerInfo &DCI) const {
   if (auto Value = stripModuloOnShift(*this, N, DCI.DAG))
     return Value;
 
+  if (N->getValueType(0).isVector())
+    return combineVectorSHL(N, DCI);
+
   SDValue N0 = N->getOperand(0);
   ConstantSDNode *CN1 = dyn_cast<ConstantSDNode>(N->getOperand(1));
   if (!Subtarget.isISA3_0() || !Subtarget.isPPC64() ||
diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.h b/llvm/lib/Target/PowerPC/PPCISelLowering.h
index 7365f3103276c..e7e7c21b50395 100644
--- a/llvm/lib/Target/PowerPC/PPCISelLowering.h
+++ b/llvm/lib/Target/PowerPC/PPCISelLowering.h
@@ -1441,6 +1441,7 @@ namespace llvm {
     SDValue combineStoreFPToInt(SDNode *N, DAGCombinerInfo &DCI) const;
     SDValue combineFPToIntToFP(SDNode *N, DAGCombinerInfo &DCI) const;
     SDValue combineSHL(SDNode *N, DAGCombinerInfo &DCI) const;
+    SDValue combineVectorSHL(SDNode *N, DAGCombinerInfo &DCI) const;
     SDValue combineSRA(SDNode *N, DAGCombinerInfo &DCI) const;
     SDValue combineSRL(SDNode *N, DAGCombinerInfo &DCI) const;
     SDValue combineMUL(SDNode *N, DAGCombinerInfo &DCI) const;
diff --git a/llvm/test/CodeGen/PowerPC/optimize-vector.ll b/llvm/test/CodeGen/PowerPC/optimize-vector.ll
index df5ef43e8ee0c..4d5481b630c98 100644
--- a/llvm/test/CodeGen/PowerPC/optimize-vector.ll
+++ b/llvm/test/CodeGen/PowerPC/optimize-vector.ll
@@ -36,10 +36,7 @@ entry:
 define dso_local <2 x i64> @x2d(<2 x i64> noundef %x) {
 ; CHECK-LABEL: x2d:
 ; CHECK:       # %bb.0: # %entry
-; CHECK-NEXT:    addis r3, r2, .LCPI3_0 at toc@ha
-; CHECK-NEXT:    addi r3, r3, .LCPI3_0 at toc@l
-; CHECK-NEXT:    lxvd2x v3, 0, r3
-; CHECK-NEXT:    vsld v2, v2, v3
+; CHECK-NEXT:    vaddudm v2, v2, v2
 ; CHECK-NEXT:    blr
 entry:
   %add = shl <2 x i64> %x, <i64 1, i64 1>
diff --git a/llvm/test/CodeGen/PowerPC/pr47891.ll b/llvm/test/CodeGen/PowerPC/pr47891.ll
index 4e41b3ee12155..46ff074fae647 100644
--- a/llvm/test/CodeGen/PowerPC/pr47891.ll
+++ b/llvm/test/CodeGen/PowerPC/pr47891.ll
@@ -7,26 +7,17 @@
 define dso_local void @poly2_lshift1(ptr nocapture %p) local_unnamed_addr #0 {
 ; CHECK-LABEL: poly2_lshift1:
 ; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    addis r6, r2, .LCPI0_0 at toc@ha
 ; CHECK-NEXT:    li r4, 72
-; CHECK-NEXT:    addis r6, r2, .LCPI0_1 at toc@ha
 ; CHECK-NEXT:    ld r5, 64(r3)
-; CHECK-NEXT:    lxvd2x vs0, r3, r4
-; CHECK-NEXT:    addi r6, r6, .LCPI0_1 at toc@l
-; CHECK-NEXT:    lxvd2x v4, 0, r6
-; CHECK-NEXT:    addis r6, r2, .LCPI0_0 at toc@ha
 ; CHECK-NEXT:    addi r6, r6, .LCPI0_0 at toc@l
-; CHECK-NEXT:    xxswapd v2, vs0
-; CHECK-NEXT:    mtfprd f0, r5
-; CHECK-NEXT:    xxpermdi v3, v2, vs0, 2
-; CHECK-NEXT:    vsld v2, v2, v4
+; CHECK-NEXT:    lxvd2x vs0, r3, r4
 ; CHECK-NEXT:    lxvd2x v4, 0, r6
 ; CHECK-NEXT:    ld r6, 0(r3)
 ; CHECK-NEXT:    sldi r7, r6, 1
 ; CHECK-NEXT:    rotldi r6, r6, 1
 ; CHECK-NEXT:    std r7, 0(r3)
 ; CHECK-NEXT:    ld r7, 8(r3)
-; CHECK-NEXT:    vsrd v3, v3, v4
-; CHECK-NEXT:    xxlor vs0, v2, v3
 ; CHECK-NEXT:    rldimi r6, r7, 1, 0
 ; CHECK-NEXT:    rotldi r7, r7, 1
 ; CHECK-NEXT:    std r6, 8(r3)
@@ -44,6 +35,8 @@ define dso_local void @poly2_lshift1(ptr nocapture %p) local_unnamed_addr #0 {
 ; CHECK-NEXT:    std r7, 32(r3)
 ; CHECK-NEXT:    ld r7, 40(r3)
 ; CHECK-NEXT:    rldimi r6, r7, 1, 0
+; CHECK-NEXT:    xxswapd v2, vs0
+; CHECK-NEXT:    mtfprd f0, r5
 ; CHECK-NEXT:    rotldi r7, r7, 1
 ; CHECK-NEXT:    std r6, 40(r3)
 ; CHECK-NEXT:    ld r6, 48(r3)
@@ -54,10 +47,14 @@ define dso_local void @poly2_lshift1(ptr nocapture %p) local_unnamed_addr #0 {
 ; CHECK-NEXT:    rldimi r6, r7, 1, 0
 ; CHECK-NEXT:    std r6, 56(r3)
 ; CHECK-NEXT:    rotldi r6, r7, 1
-; CHECK-NEXT:    xxswapd vs0, vs0
-; CHECK-NEXT:    stxvd2x vs0, r3, r4
 ; CHECK-NEXT:    rldimi r6, r5, 1, 0
 ; CHECK-NEXT:    std r6, 64(r3)
+; CHECK-NEXT:    xxpermdi v3, v2, vs0, 2
+; CHECK-NEXT:    vsrd v3, v3, v4
+; CHECK-NEXT:    vaddudm v2, v2, v2
+; CHECK-NEXT:    xxlor vs0, v2, v3
+; CHECK-NEXT:    xxswapd vs0, vs0
+; CHECK-NEXT:    stxvd2x vs0, r3, r4
 ; CHECK-NEXT:    blr
 entry:
   %0 = load i64, ptr %p, align 8

>From 62f06a4a333d1a2f46d7026a64ca0f4f6bf902da Mon Sep 17 00:00:00 2001
From: Roland Froese <froese at ca.ibm.com>
Date: Mon, 12 May 2025 17:25:42 +0000
Subject: [PATCH 2/2] address comment

---
 llvm/lib/Target/PowerPC/PPCISelLowering.cpp | 11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
index 9e562d7ca498e..59bfec30dc211 100644
--- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
+++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
@@ -18458,16 +18458,17 @@ static SDValue stripModuloOnShift(const TargetLowering &TLI, SDNode *N,
 
 SDValue PPCTargetLowering::combineVectorSHL(SDNode *N,
                                             DAGCombinerInfo &DCI) const {
-  assert(N->getValueType(0).isVector() && "Vector type expected.");
+  EVT VT = N->getValueType(0);
+  assert(VT.isVector() && "Vector type expected.");
 
   SDValue N1 = N->getOperand(1);
   if (!Subtarget.hasP8Altivec() || N1.getOpcode() != ISD::BUILD_VECTOR ||
-      !isOperationLegal(ISD::ADD, N->getValueType(0)))
+      !isOperationLegal(ISD::ADD, VT))
     return SDValue();
 
   // For 64-bit there is no splat immediate so we want to catch shift by 1 here
   // before the BUILD_VECTOR is replaced by a load.
-  EVT EltTy = N->getValueType(0).getScalarType();
+  EVT EltTy = VT.getScalarType();
   if (EltTy != MVT::i64)
     return SDValue();
 
@@ -18484,8 +18485,8 @@ SDValue PPCTargetLowering::combineVectorSHL(SDNode *N,
   if (SplatBits != 1)
     return SDValue();
 
-  return DCI.DAG.getNode(ISD::ADD, SDLoc(N), N->getValueType(0),
-                         N->getOperand(0), N->getOperand(0));
+  SDValue N0 = N->getOperand(0);
+  return DCI.DAG.getNode(ISD::ADD, SDLoc(N), VT, N0, N0);
 }
 
 SDValue PPCTargetLowering::combineSHL(SDNode *N, DAGCombinerInfo &DCI) const {



More information about the llvm-commits mailing list