Skip to content

Commit 2ac9920

Browse files
author
Yeting Kuo
committed
[RISCV] Narrow types of index operand matched pattern (shl (zext), C).
(shl (zext to iXLenVec), C) is a possible pattern in auto-vectorized code for indexed loads/stores. But extending to iXLen might be too aggressive, RVV indexed load/store instructions zero extend their indexed operand to XLEN. The patch tries to narrow the type of the zero extension. It's benefit to decrease register pressure. Reviewed By: craig.topper Differential Revision: https://reviews.llvm.org/D154687
1 parent 2d6a5ab commit 2ac9920

File tree

6 files changed

+766
-537
lines changed

6 files changed

+766
-537
lines changed

llvm/lib/Target/RISCV/RISCVISelLowering.cpp

Lines changed: 63 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1150,7 +1150,8 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
11501150
// Jumps are expensive, compared to logic
11511151
setJumpIsExpensive();
11521152

1153-
setTargetDAGCombine({ISD::INTRINSIC_WO_CHAIN, ISD::ADD, ISD::SUB, ISD::AND,
1153+
setTargetDAGCombine({ISD::INTRINSIC_VOID, ISD::INTRINSIC_W_CHAIN,
1154+
ISD::INTRINSIC_WO_CHAIN, ISD::ADD, ISD::SUB, ISD::AND,
11541155
ISD::OR, ISD::XOR, ISD::SETCC, ISD::SELECT});
11551156
if (Subtarget.is64Bit())
11561157
setTargetDAGCombine(ISD::SRA);
@@ -10623,6 +10624,46 @@ static SDValue performXORCombine(SDNode *N, SelectionDAG &DAG,
1062310624
return combineSelectAndUseCommutative(N, DAG, /*AllOnes*/ false, Subtarget);
1062410625
}
1062510626

10627+
// According to the property that indexed load/store instructions
10628+
// zero-extended their indices, \p narrowIndex tries to narrow the type of index
10629+
// operand if it is matched to pattern (shl (zext x to ty), C) and bits(x) + C <
10630+
// bits(ty).
10631+
static SDValue narrowIndex(SDValue N, SelectionDAG &DAG) {
10632+
if (N.getOpcode() != ISD::SHL || !N->hasOneUse())
10633+
return SDValue();
10634+
10635+
SDValue N0 = N.getOperand(0);
10636+
if (N0.getOpcode() != ISD::ZERO_EXTEND &&
10637+
N0.getOpcode() != RISCVISD::VZEXT_VL)
10638+
return SDValue();
10639+
if (!N0->hasOneUse())
10640+
return SDValue();
10641+
10642+
APInt ShAmt;
10643+
SDValue N1 = N.getOperand(1);
10644+
if (!ISD::isConstantSplatVector(N1.getNode(), ShAmt))
10645+
return SDValue();
10646+
10647+
SDLoc DL(N);
10648+
SDValue Src = N0.getOperand(0);
10649+
EVT SrcVT = Src.getValueType();
10650+
unsigned SrcElen = SrcVT.getScalarSizeInBits();
10651+
unsigned ShAmtV = ShAmt.getZExtValue();
10652+
unsigned NewElen = PowerOf2Ceil(SrcElen + ShAmtV);
10653+
NewElen = std::max(NewElen, 8U);
10654+
10655+
// Skip if NewElen is not narrower than the original extended type.
10656+
if (NewElen >= N0.getValueType().getScalarSizeInBits())
10657+
return SDValue();
10658+
10659+
EVT NewEltVT = EVT::getIntegerVT(*DAG.getContext(), NewElen);
10660+
EVT NewVT = SrcVT.changeVectorElementType(NewEltVT);
10661+
10662+
SDValue NewExt = DAG.getNode(N0->getOpcode(), DL, NewVT, N0->ops());
10663+
SDValue NewShAmtVec = DAG.getConstant(ShAmtV, DL, NewVT);
10664+
return DAG.getNode(ISD::SHL, DL, NewVT, NewExt, NewShAmtVec);
10665+
}
10666+
1062610667
// Replace (seteq (i64 (and X, 0xffffffff)), C1) with
1062710668
// (seteq (i64 (sext_inreg (X, i32)), C1')) where C1' is C1 sign extended from
1062810669
// bit 31. Same for setne. C1' may be cheaper to materialize and the sext_inreg
@@ -12920,8 +12961,11 @@ SDValue RISCVTargetLowering::PerformDAGCombine(SDNode *N,
1292012961
}
1292112962
break;
1292212963
}
12964+
case ISD::INTRINSIC_VOID:
12965+
case ISD::INTRINSIC_W_CHAIN:
1292312966
case ISD::INTRINSIC_WO_CHAIN: {
12924-
unsigned IntNo = N->getConstantOperandVal(0);
12967+
unsigned IntOpNo = N->getOpcode() == ISD::INTRINSIC_WO_CHAIN ? 0 : 1;
12968+
unsigned IntNo = N->getConstantOperandVal(IntOpNo);
1292512969
switch (IntNo) {
1292612970
// By default we do not combine any intrinsic.
1292712971
default:
@@ -12944,6 +12988,23 @@ SDValue RISCVTargetLowering::PerformDAGCombine(SDNode *N,
1294412988
return DAG.getConstant(-1, DL, VT);
1294512989
return DAG.getConstant(0, DL, VT);
1294612990
}
12991+
case Intrinsic::riscv_vloxei:
12992+
case Intrinsic::riscv_vloxei_mask:
12993+
case Intrinsic::riscv_vluxei:
12994+
case Intrinsic::riscv_vluxei_mask:
12995+
case Intrinsic::riscv_vsoxei:
12996+
case Intrinsic::riscv_vsoxei_mask:
12997+
case Intrinsic::riscv_vsuxei:
12998+
case Intrinsic::riscv_vsuxei_mask:
12999+
if (SDValue V = narrowIndex(N->getOperand(4), DAG)) {
13000+
SmallVector<SDValue, 8> Ops(N->ops());
13001+
Ops[4] = V;
13002+
const auto *MemSD = cast<MemIntrinsicSDNode>(N);
13003+
return DAG.getMemIntrinsicNode(N->getOpcode(), SDLoc(N), N->getVTList(),
13004+
Ops, MemSD->getMemoryVT(),
13005+
MemSD->getMemOperand());
13006+
}
13007+
return SDValue();
1294713008
}
1294813009
}
1294913010
case ISD::BITCAST: {

0 commit comments

Comments
 (0)