Skip to content

Commit 15090e1

Browse files
committed
take care of some todos, transforming [us]mul_lohi into
a wider mul if the wider mul is legal. llvm-svn: 121848
1 parent c3301e9 commit 15090e1

File tree

2 files changed

+47
-2
lines changed

2 files changed

+47
-2
lines changed

llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2045,15 +2045,59 @@ SDValue DAGCombiner::visitSMUL_LOHI(SDNode *N) {
20452045
SDValue Res = SimplifyNodeWithTwoResults(N, ISD::MUL, ISD::MULHS);
20462046
if (Res.getNode()) return Res;
20472047

2048-
// TODO: Transform smul_lohi to mul if the wider mul is legal!
2048+
EVT VT = N->getValueType(0);
2049+
DebugLoc DL = N->getDebugLoc();
2050+
2051+
// If the type twice as wide is legal, transform the mulhu to a wider multiply
2052+
// plus a shift.
2053+
if (VT.isSimple() && !VT.isVector()) {
2054+
MVT Simple = VT.getSimpleVT();
2055+
unsigned SimpleSize = Simple.getSizeInBits();
2056+
EVT NewVT = EVT::getIntegerVT(*DAG.getContext(), SimpleSize*2);
2057+
if (TLI.isOperationLegal(ISD::MUL, NewVT)) {
2058+
SDValue Lo = DAG.getNode(ISD::SIGN_EXTEND, DL, NewVT, N->getOperand(0));
2059+
SDValue Hi = DAG.getNode(ISD::SIGN_EXTEND, DL, NewVT, N->getOperand(1));
2060+
Lo = DAG.getNode(ISD::MUL, DL, NewVT, Lo, Hi);
2061+
// Compute the high part as N1.
2062+
Hi = DAG.getNode(ISD::SRL, DL, NewVT, Lo,
2063+
DAG.getConstant(SimpleSize, getShiftAmountTy()));
2064+
Hi = DAG.getNode(ISD::TRUNCATE, DL, VT, Hi);
2065+
// Compute the low part as N0.
2066+
Lo = DAG.getNode(ISD::TRUNCATE, DL, VT, Lo);
2067+
return CombineTo(N, Lo, Hi);
2068+
}
2069+
}
2070+
20492071
return SDValue();
20502072
}
20512073

20522074
SDValue DAGCombiner::visitUMUL_LOHI(SDNode *N) {
20532075
SDValue Res = SimplifyNodeWithTwoResults(N, ISD::MUL, ISD::MULHU);
20542076
if (Res.getNode()) return Res;
20552077

2056-
// TODO: Transform umul_lohi to mul if the wider mul is legal!
2078+
EVT VT = N->getValueType(0);
2079+
DebugLoc DL = N->getDebugLoc();
2080+
2081+
// If the type twice as wide is legal, transform the mulhu to a wider multiply
2082+
// plus a shift.
2083+
if (VT.isSimple() && !VT.isVector()) {
2084+
MVT Simple = VT.getSimpleVT();
2085+
unsigned SimpleSize = Simple.getSizeInBits();
2086+
EVT NewVT = EVT::getIntegerVT(*DAG.getContext(), SimpleSize*2);
2087+
if (TLI.isOperationLegal(ISD::MUL, NewVT)) {
2088+
SDValue Lo = DAG.getNode(ISD::ZERO_EXTEND, DL, NewVT, N->getOperand(0));
2089+
SDValue Hi = DAG.getNode(ISD::ZERO_EXTEND, DL, NewVT, N->getOperand(1));
2090+
Lo = DAG.getNode(ISD::MUL, DL, NewVT, Lo, Hi);
2091+
// Compute the high part as N1.
2092+
Hi = DAG.getNode(ISD::SRL, DL, NewVT, Lo,
2093+
DAG.getConstant(SimpleSize, getShiftAmountTy()));
2094+
Hi = DAG.getNode(ISD::TRUNCATE, DL, VT, Hi);
2095+
// Compute the low part as N0.
2096+
Lo = DAG.getNode(ISD::TRUNCATE, DL, VT, Lo);
2097+
return CombineTo(N, Lo, Hi);
2098+
}
2099+
}
2100+
20572101
return SDValue();
20582102
}
20592103

llvm/test/CodeGen/X86/divide-by-constant.ll

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ entry:
4040
%div = sdiv i16 %x, 33 ; <i32> [#uses=1]
4141
ret i16 %div
4242
; CHECK: test4:
43+
; CHECK: imull $-1985, %ecx, %ecx
4344
}
4445

4546
define i32 @test5(i32 %A) nounwind {

0 commit comments

Comments
 (0)