forked from OSchip/llvm-project
[CodeGen] Fix invalid shift in mul expansion
Summary: When expanding mul in type legalization make sure the type for shift amount can actually fit the value. This fixes PR30354 https://llvm.org/bugs/show_bug.cgi?id=30354. Reviewers: hfinkel, majnemer, RKSimon Subscribers: RKSimon, llvm-commits Differential Revision: https://reviews.llvm.org/D24478 llvm-svn: 281403
This commit is contained in:
parent
59f8305305
commit
c397f0b272
|
@ -2195,18 +2195,23 @@ void DAGTypeLegalizer::ExpandIntRes_MUL(SDNode *N,
|
|||
// options. This is a trivially-generalized version of the code from
|
||||
// Hacker's Delight (itself derived from Knuth's Algorithm M from section
|
||||
// 4.3.1).
|
||||
SDValue Mask =
|
||||
DAG.getConstant(APInt::getLowBitsSet(NVT.getSizeInBits(),
|
||||
NVT.getSizeInBits() >> 1), dl, NVT);
|
||||
unsigned Bits = NVT.getSizeInBits();
|
||||
unsigned HalfBits = Bits >> 1;
|
||||
SDValue Mask = DAG.getConstant(APInt::getLowBitsSet(Bits, HalfBits), dl,
|
||||
NVT);
|
||||
SDValue LLL = DAG.getNode(ISD::AND, dl, NVT, LL, Mask);
|
||||
SDValue RLL = DAG.getNode(ISD::AND, dl, NVT, RL, Mask);
|
||||
|
||||
SDValue T = DAG.getNode(ISD::MUL, dl, NVT, LLL, RLL);
|
||||
SDValue TL = DAG.getNode(ISD::AND, dl, NVT, T, Mask);
|
||||
|
||||
SDValue Shift =
|
||||
DAG.getConstant(NVT.getSizeInBits() >> 1, dl,
|
||||
TLI.getShiftAmountTy(NVT, DAG.getDataLayout()));
|
||||
EVT ShiftAmtTy = TLI.getShiftAmountTy(NVT, DAG.getDataLayout());
|
||||
if (APInt::getMaxValue(ShiftAmtTy.getSizeInBits()).ult(HalfBits)) {
|
||||
// The type from TLI is too small to fit the shift amount we want.
|
||||
// Override it with i32. The shift will have to be legalized.
|
||||
ShiftAmtTy = MVT::i32;
|
||||
}
|
||||
SDValue Shift = DAG.getConstant(HalfBits, dl, ShiftAmtTy);
|
||||
SDValue TH = DAG.getNode(ISD::SRL, dl, NVT, T, Shift);
|
||||
SDValue LLH = DAG.getNode(ISD::SRL, dl, NVT, LL, Shift);
|
||||
SDValue RLH = DAG.getNode(ISD::SRL, dl, NVT, RL, Shift);
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue