Skip to content

Commit f55d96b

Browse files
committed
[DAG][AArch64] Handle vector types when expanding sdiv/udiv into mulh
The aarch64 backend will benefit from expanding 64vector sdiv/udiv into mulh using shift(mul(ext, ext)), as the larger type size is legal and the mul(ext, ext) can efficiently use smull/umull instructions. This extends the existing code in GetMULHS to handle vector types for it. Differential Revision: https://reviews.llvm.org/D154049
1 parent 8269fd2 commit f55d96b

File tree

3 files changed

+206
-565
lines changed

3 files changed

+206
-565
lines changed

llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp

Lines changed: 24 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -5996,17 +5996,18 @@ SDValue TargetLowering::BuildSDIV(SDNode *N, SelectionDAG &DAG,
59965996
return SDValue(LoHi.getNode(), 1);
59975997
}
59985998
// If type twice as wide legal, widen and use a mul plus a shift.
5999-
if (!VT.isVector()) {
6000-
unsigned Size = VT.getSizeInBits();
6001-
EVT WideVT = EVT::getIntegerVT(*DAG.getContext(), Size * 2);
6002-
if (isOperationLegal(ISD::MUL, WideVT)) {
6003-
X = DAG.getNode(ISD::SIGN_EXTEND, dl, WideVT, X);
6004-
Y = DAG.getNode(ISD::SIGN_EXTEND, dl, WideVT, Y);
6005-
Y = DAG.getNode(ISD::MUL, dl, WideVT, X, Y);
6006-
Y = DAG.getNode(ISD::SRL, dl, WideVT, Y,
6007-
DAG.getShiftAmountConstant(EltBits, WideVT, dl));
6008-
return DAG.getNode(ISD::TRUNCATE, dl, VT, Y);
6009-
}
5999+
unsigned Size = VT.getScalarSizeInBits();
6000+
EVT WideVT = EVT::getIntegerVT(*DAG.getContext(), Size * 2);
6001+
if (VT.isVector())
6002+
WideVT = EVT::getVectorVT(*DAG.getContext(), WideVT,
6003+
VT.getVectorElementCount());
6004+
if (isOperationLegalOrCustom(ISD::MUL, WideVT)) {
6005+
X = DAG.getNode(ISD::SIGN_EXTEND, dl, WideVT, X);
6006+
Y = DAG.getNode(ISD::SIGN_EXTEND, dl, WideVT, Y);
6007+
Y = DAG.getNode(ISD::MUL, dl, WideVT, X, Y);
6008+
Y = DAG.getNode(ISD::SRL, dl, WideVT, Y,
6009+
DAG.getShiftAmountConstant(EltBits, WideVT, dl));
6010+
return DAG.getNode(ISD::TRUNCATE, dl, VT, Y);
60106011
}
60116012
return SDValue();
60126013
};
@@ -6182,17 +6183,18 @@ SDValue TargetLowering::BuildUDIV(SDNode *N, SelectionDAG &DAG,
61826183
return SDValue(LoHi.getNode(), 1);
61836184
}
61846185
// If type twice as wide legal, widen and use a mul plus a shift.
6185-
if (!VT.isVector()) {
6186-
unsigned Size = VT.getSizeInBits();
6187-
EVT WideVT = EVT::getIntegerVT(*DAG.getContext(), Size * 2);
6188-
if (isOperationLegal(ISD::MUL, WideVT)) {
6189-
X = DAG.getNode(ISD::ZERO_EXTEND, dl, WideVT, X);
6190-
Y = DAG.getNode(ISD::ZERO_EXTEND, dl, WideVT, Y);
6191-
Y = DAG.getNode(ISD::MUL, dl, WideVT, X, Y);
6192-
Y = DAG.getNode(ISD::SRL, dl, WideVT, Y,
6193-
DAG.getShiftAmountConstant(EltBits, WideVT, dl));
6194-
return DAG.getNode(ISD::TRUNCATE, dl, VT, Y);
6195-
}
6186+
unsigned Size = VT.getScalarSizeInBits();
6187+
EVT WideVT = EVT::getIntegerVT(*DAG.getContext(), Size * 2);
6188+
if (VT.isVector())
6189+
WideVT = EVT::getVectorVT(*DAG.getContext(), WideVT,
6190+
VT.getVectorElementCount());
6191+
if (isOperationLegalOrCustom(ISD::MUL, WideVT)) {
6192+
X = DAG.getNode(ISD::ZERO_EXTEND, dl, WideVT, X);
6193+
Y = DAG.getNode(ISD::ZERO_EXTEND, dl, WideVT, Y);
6194+
Y = DAG.getNode(ISD::MUL, dl, WideVT, X, Y);
6195+
Y = DAG.getNode(ISD::SRL, dl, WideVT, Y,
6196+
DAG.getShiftAmountConstant(EltBits, WideVT, dl));
6197+
return DAG.getNode(ISD::TRUNCATE, dl, VT, Y);
61966198
}
61976199
return SDValue(); // No mulhu or equivalent
61986200
};

0 commit comments

Comments
 (0)