Skip to content

Commit b0e249d

Browse files
committed
Reland "[PowerPC] Remove extend between shift and and"
The commit originally caused a bootstrap failure on the big endian PPC bot as the combine was interfering with the legalizer when applied on illegal types. This update restricts the combine to the only types for which it is actually needed. Tested on PPC BE bootstrap locally.
1 parent dea01f5 commit b0e249d

File tree

2 files changed

+49
-2
lines changed

2 files changed

+49
-2
lines changed

llvm/lib/Target/PowerPC/PPCISelLowering.cpp

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1381,8 +1381,8 @@ PPCTargetLowering::PPCTargetLowering(const PPCTargetMachine &TM,
13811381
setStackPointerRegisterToSaveRestore(isPPC64 ? PPC::X1 : PPC::R1);
13821382

13831383
// We have target-specific dag combine patterns for the following nodes:
1384-
setTargetDAGCombine({ISD::ADD, ISD::SHL, ISD::SRA, ISD::SRL, ISD::MUL,
1385-
ISD::FMA, ISD::SINT_TO_FP, ISD::BUILD_VECTOR});
1384+
setTargetDAGCombine({ISD::AND, ISD::ADD, ISD::SHL, ISD::SRA, ISD::SRL,
1385+
ISD::MUL, ISD::FMA, ISD::SINT_TO_FP, ISD::BUILD_VECTOR});
13861386
if (Subtarget.hasFPCVT())
13871387
setTargetDAGCombine(ISD::UINT_TO_FP);
13881388
setTargetDAGCombine({ISD::LOAD, ISD::STORE, ISD::BR_CC});
@@ -15496,6 +15496,30 @@ SDValue PPCTargetLowering::PerformDAGCombine(SDNode *N,
1549615496
default: break;
1549715497
case ISD::ADD:
1549815498
return combineADD(N, DCI);
15499+
case ISD::AND: {
15500+
// We don't want (and (zext (shift...)), C) if C fits in the width of the
15501+
// original input as that will prevent us from selecting optimal rotates.
15502+
// This only matters if the input to the extend is i32 widened to i64.
15503+
SDValue Op1 = N->getOperand(0);
15504+
SDValue Op2 = N->getOperand(1);
15505+
if ((Op1.getOpcode() != ISD::ZERO_EXTEND &&
15506+
Op1.getOpcode() != ISD::ANY_EXTEND) ||
15507+
!isa<ConstantSDNode>(Op2) || N->getValueType(0) != MVT::i64 ||
15508+
Op1.getOperand(0).getValueType() != MVT::i32)
15509+
break;
15510+
SDValue NarrowOp = Op1.getOperand(0);
15511+
if (NarrowOp.getOpcode() != ISD::SHL && NarrowOp.getOpcode() != ISD::SRL &&
15512+
NarrowOp.getOpcode() != ISD::ROTL && NarrowOp.getOpcode() != ISD::ROTR)
15513+
break;
15514+
15515+
uint64_t Imm = cast<ConstantSDNode>(Op2)->getZExtValue();
15516+
// Make sure that the constant is narrow enough to fit in the narrow type.
15517+
if (!isUInt<32>(Imm))
15518+
break;
15519+
SDValue ConstOp = DAG.getConstant(Imm, dl, MVT::i32);
15520+
SDValue NarrowAnd = DAG.getNode(ISD::AND, dl, MVT::i32, NarrowOp, ConstOp);
15521+
return DAG.getAnyExtOrTrunc(NarrowAnd, dl, N->getValueType(0));
15522+
}
1549915523
case ISD::SHL:
1550015524
return combineSHL(N, DCI);
1550115525
case ISD::SRA:
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 2
2+
; RUN: llc < %s -mtriple=powerpc64le-unknown-unknown -ppc-asm-full-reg-names \
3+
; RUN: -mcpu=pwr8 -verify-machineinstrs | FileCheck %s
4+
define dso_local ptr @foo(i32 noundef zeroext %arg, ptr nocapture noundef readonly %arg1, ptr noundef writeonly %arg2) local_unnamed_addr {
5+
; CHECK-LABEL: foo:
6+
; CHECK: # %bb.0: # %bb
7+
; CHECK-NEXT: rlwinm r3, r3, 31, 17, 28
8+
; CHECK-NEXT: ldx r4, r4, r3
9+
; CHECK-NEXT: clrldi r3, r4, 56
10+
; CHECK-NEXT: add r3, r5, r3
11+
; CHECK-NEXT: std r4, 0(r5)
12+
; CHECK-NEXT: blr
13+
bb:
14+
%i = lshr i32 %arg, 1
15+
%i3 = and i32 %i, 32760
16+
%i4 = zext i32 %i3 to i64
17+
%i5 = getelementptr inbounds i8, ptr %arg1, i64 %i4
18+
%i6 = load i64, ptr %i5, align 8
19+
%i7 = and i64 %i6, 255
20+
store i64 %i6, ptr %arg2, align 8
21+
%i8 = getelementptr inbounds i8, ptr %arg2, i64 %i7
22+
ret ptr %i8
23+
}

0 commit comments

Comments
 (0)