@@ -2045,15 +2045,59 @@ SDValue DAGCombiner::visitSMUL_LOHI(SDNode *N) {
2045
2045
SDValue Res = SimplifyNodeWithTwoResults (N, ISD::MUL, ISD::MULHS);
2046
2046
if (Res.getNode ()) return Res;
2047
2047
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
+
2049
2071
return SDValue ();
2050
2072
}
2051
2073
2052
2074
SDValue DAGCombiner::visitUMUL_LOHI (SDNode *N) {
2053
2075
SDValue Res = SimplifyNodeWithTwoResults (N, ISD::MUL, ISD::MULHU);
2054
2076
if (Res.getNode ()) return Res;
2055
2077
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
+
2057
2101
return SDValue ();
2058
2102
}
2059
2103
0 commit comments