Skip to content

Commit 99f0309

Browse files
authored
[PowerPC] catch v2i64 shift left by 1 is add case (#138772)
Catch missing case in PPC BE for v2i64 x << 1 and generate x + x.
1 parent 7e8b3fe commit 99f0309

File tree

4 files changed

+48
-17
lines changed

4 files changed

+48
-17
lines changed

llvm/lib/Target/PowerPC/PPCISelLowering.cpp

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18456,10 +18456,46 @@ static SDValue stripModuloOnShift(const TargetLowering &TLI, SDNode *N,
1845618456
return SDValue();
1845718457
}
1845818458

18459+
SDValue PPCTargetLowering::combineVectorSHL(SDNode *N,
18460+
DAGCombinerInfo &DCI) const {
18461+
EVT VT = N->getValueType(0);
18462+
assert(VT.isVector() && "Vector type expected.");
18463+
18464+
SDValue N1 = N->getOperand(1);
18465+
if (!Subtarget.hasP8Altivec() || N1.getOpcode() != ISD::BUILD_VECTOR ||
18466+
!isOperationLegal(ISD::ADD, VT))
18467+
return SDValue();
18468+
18469+
// For 64-bit there is no splat immediate so we want to catch shift by 1 here
18470+
// before the BUILD_VECTOR is replaced by a load.
18471+
EVT EltTy = VT.getScalarType();
18472+
if (EltTy != MVT::i64)
18473+
return SDValue();
18474+
18475+
BuildVectorSDNode *BVN = cast<BuildVectorSDNode>(N1);
18476+
APInt APSplatBits, APSplatUndef;
18477+
unsigned SplatBitSize;
18478+
bool HasAnyUndefs;
18479+
bool BVNIsConstantSplat =
18480+
BVN->isConstantSplat(APSplatBits, APSplatUndef, SplatBitSize,
18481+
HasAnyUndefs, 0, !Subtarget.isLittleEndian());
18482+
if (!BVNIsConstantSplat || SplatBitSize != EltTy.getSizeInBits())
18483+
return SDValue();
18484+
uint64_t SplatBits = APSplatBits.getZExtValue();
18485+
if (SplatBits != 1)
18486+
return SDValue();
18487+
18488+
SDValue N0 = N->getOperand(0);
18489+
return DCI.DAG.getNode(ISD::ADD, SDLoc(N), VT, N0, N0);
18490+
}
18491+
1845918492
SDValue PPCTargetLowering::combineSHL(SDNode *N, DAGCombinerInfo &DCI) const {
1846018493
if (auto Value = stripModuloOnShift(*this, N, DCI.DAG))
1846118494
return Value;
1846218495

18496+
if (N->getValueType(0).isVector())
18497+
return combineVectorSHL(N, DCI);
18498+
1846318499
SDValue N0 = N->getOperand(0);
1846418500
ConstantSDNode *CN1 = dyn_cast<ConstantSDNode>(N->getOperand(1));
1846518501
if (!Subtarget.isISA3_0() || !Subtarget.isPPC64() ||

llvm/lib/Target/PowerPC/PPCISelLowering.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1441,6 +1441,7 @@ namespace llvm {
14411441
SDValue combineStoreFPToInt(SDNode *N, DAGCombinerInfo &DCI) const;
14421442
SDValue combineFPToIntToFP(SDNode *N, DAGCombinerInfo &DCI) const;
14431443
SDValue combineSHL(SDNode *N, DAGCombinerInfo &DCI) const;
1444+
SDValue combineVectorSHL(SDNode *N, DAGCombinerInfo &DCI) const;
14441445
SDValue combineSRA(SDNode *N, DAGCombinerInfo &DCI) const;
14451446
SDValue combineSRL(SDNode *N, DAGCombinerInfo &DCI) const;
14461447
SDValue combineMUL(SDNode *N, DAGCombinerInfo &DCI) const;

llvm/test/CodeGen/PowerPC/optimize-vector.ll

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,7 @@ entry:
3636
define dso_local <2 x i64> @x2d(<2 x i64> noundef %x) {
3737
; CHECK-LABEL: x2d:
3838
; CHECK: # %bb.0: # %entry
39-
; CHECK-NEXT: addis r3, r2, .LCPI3_0@toc@ha
40-
; CHECK-NEXT: addi r3, r3, .LCPI3_0@toc@l
41-
; CHECK-NEXT: lxvd2x v3, 0, r3
42-
; CHECK-NEXT: vsld v2, v2, v3
39+
; CHECK-NEXT: vaddudm v2, v2, v2
4340
; CHECK-NEXT: blr
4441
entry:
4542
%add = shl <2 x i64> %x, <i64 1, i64 1>

llvm/test/CodeGen/PowerPC/pr47891.ll

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,26 +7,17 @@
77
define dso_local void @poly2_lshift1(ptr nocapture %p) local_unnamed_addr #0 {
88
; CHECK-LABEL: poly2_lshift1:
99
; CHECK: # %bb.0: # %entry
10+
; CHECK-NEXT: addis r6, r2, .LCPI0_0@toc@ha
1011
; CHECK-NEXT: li r4, 72
11-
; CHECK-NEXT: addis r6, r2, .LCPI0_1@toc@ha
1212
; CHECK-NEXT: ld r5, 64(r3)
13-
; CHECK-NEXT: lxvd2x vs0, r3, r4
14-
; CHECK-NEXT: addi r6, r6, .LCPI0_1@toc@l
15-
; CHECK-NEXT: lxvd2x v4, 0, r6
16-
; CHECK-NEXT: addis r6, r2, .LCPI0_0@toc@ha
1713
; CHECK-NEXT: addi r6, r6, .LCPI0_0@toc@l
18-
; CHECK-NEXT: xxswapd v2, vs0
19-
; CHECK-NEXT: mtfprd f0, r5
20-
; CHECK-NEXT: xxpermdi v3, v2, vs0, 2
21-
; CHECK-NEXT: vsld v2, v2, v4
14+
; CHECK-NEXT: lxvd2x vs0, r3, r4
2215
; CHECK-NEXT: lxvd2x v4, 0, r6
2316
; CHECK-NEXT: ld r6, 0(r3)
2417
; CHECK-NEXT: sldi r7, r6, 1
2518
; CHECK-NEXT: rotldi r6, r6, 1
2619
; CHECK-NEXT: std r7, 0(r3)
2720
; CHECK-NEXT: ld r7, 8(r3)
28-
; CHECK-NEXT: vsrd v3, v3, v4
29-
; CHECK-NEXT: xxlor vs0, v2, v3
3021
; CHECK-NEXT: rldimi r6, r7, 1, 0
3122
; CHECK-NEXT: rotldi r7, r7, 1
3223
; CHECK-NEXT: std r6, 8(r3)
@@ -44,6 +35,8 @@ define dso_local void @poly2_lshift1(ptr nocapture %p) local_unnamed_addr #0 {
4435
; CHECK-NEXT: std r7, 32(r3)
4536
; CHECK-NEXT: ld r7, 40(r3)
4637
; CHECK-NEXT: rldimi r6, r7, 1, 0
38+
; CHECK-NEXT: xxswapd v2, vs0
39+
; CHECK-NEXT: mtfprd f0, r5
4740
; CHECK-NEXT: rotldi r7, r7, 1
4841
; CHECK-NEXT: std r6, 40(r3)
4942
; CHECK-NEXT: ld r6, 48(r3)
@@ -54,10 +47,14 @@ define dso_local void @poly2_lshift1(ptr nocapture %p) local_unnamed_addr #0 {
5447
; CHECK-NEXT: rldimi r6, r7, 1, 0
5548
; CHECK-NEXT: std r6, 56(r3)
5649
; CHECK-NEXT: rotldi r6, r7, 1
57-
; CHECK-NEXT: xxswapd vs0, vs0
58-
; CHECK-NEXT: stxvd2x vs0, r3, r4
5950
; CHECK-NEXT: rldimi r6, r5, 1, 0
6051
; CHECK-NEXT: std r6, 64(r3)
52+
; CHECK-NEXT: xxpermdi v3, v2, vs0, 2
53+
; CHECK-NEXT: vsrd v3, v3, v4
54+
; CHECK-NEXT: vaddudm v2, v2, v2
55+
; CHECK-NEXT: xxlor vs0, v2, v3
56+
; CHECK-NEXT: xxswapd vs0, vs0
57+
; CHECK-NEXT: stxvd2x vs0, r3, r4
6158
; CHECK-NEXT: blr
6259
entry:
6360
%0 = load i64, ptr %p, align 8

0 commit comments

Comments
 (0)