Source/JavaScriptCore/ChangeLog

 12014-01-27 Filip Pizlo <fpizlo@apple.com>
 2
 3 FTL ArithMod case needs to be factored for hackability and correctness rather than just minimizing the amount of code
 4 https://bugs.webkit.org/show_bug.cgi?id=127709
 5
 6 Rubber stamped by Mark Hahnenberg.
 7
 8 Roll out part of r156784.
 9
 10 * ftl/FTLLowerDFGToLLVM.cpp:
 11 (JSC::FTL::LowerDFGToLLVM::compileNode):
 12 (JSC::FTL::LowerDFGToLLVM::compileArithDiv):
 13 (JSC::FTL::LowerDFGToLLVM::compileArithMod):
 14
1152014-01-27 Mark Hahnenberg <mhahnenberg@apple.com>
216
317 Added missing files to the branch.
162867

Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp

@@private:
314314 compileArithMul();
315315 break;
316316 case ArithDiv:
 317 compileArithDiv();
 318 break;
317319 case ArithMod:
318  compileArithDivMod();
 320 compileArithMod();
319321 break;
320322 case ArithMin:
321323 case ArithMax:

@@private:
10741076 }
10751077 }
10761078
1077  void compileArithDivMod()
 1079 void compileArithDiv()
10781080 {
10791081 switch (m_node->binaryUseKind()) {
10801082 case Int32Use: {
10811083 LValue numerator = lowInt32(m_node->child1());
10821084 LValue denominator = lowInt32(m_node->child2());
10831085
1084  LBasicBlock unsafeDenominator = FTL_NEW_BLOCK(m_out, ("ArithDivMod unsafe denominator"));
1085  LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("ArithDivMod continuation"));
1086  LBasicBlock done = FTL_NEW_BLOCK(m_out, ("ArithDivMod done"));
 1086 LBasicBlock unsafeDenominator = FTL_NEW_BLOCK(m_out, ("ArithDiv unsafe denominator"));
 1087 LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("ArithDiv continuation"));
 1088 LBasicBlock done = FTL_NEW_BLOCK(m_out, ("ArithDiv done"));
10871089
10881090 Vector<ValueFromBlock, 3> results;
10891091

@@private:
11051107 // If the denominator is not zero (i.e. it's -1 because we're guarded by the
11061108 // check above) and the numerator is -2^31 then the result should be -2^31.
11071109
1108  LBasicBlock divByZero = FTL_NEW_BLOCK(m_out, ("ArithDivMod divide by zero"));
1109  LBasicBlock notDivByZero = FTL_NEW_BLOCK(m_out, ("ArithDivMod not divide by zero"));
1110  LBasicBlock neg2ToThe31ByNeg1 = FTL_NEW_BLOCK(m_out, ("ArithDivMod -2^31/-1"));
 1110 LBasicBlock divByZero = FTL_NEW_BLOCK(m_out, ("ArithDiv divide by zero"));
 1111 LBasicBlock notDivByZero = FTL_NEW_BLOCK(m_out, ("ArithDiv not divide by zero"));
 1112 LBasicBlock neg2ToThe31ByNeg1 = FTL_NEW_BLOCK(m_out, ("ArithDiv -2^31/-1"));
11111113
11121114 m_out.branch(m_out.isZero32(denominator), divByZero, notDivByZero);
11131115

@@private:
11191121 m_out.branch(m_out.equal(numerator, neg2ToThe31), neg2ToThe31ByNeg1, continuation);
11201122
11211123 m_out.appendTo(neg2ToThe31ByNeg1, continuation);
1122  if (m_node->op() == ArithDiv)
1123  results.append(m_out.anchor(neg2ToThe31));
1124  else
1125  results.append(m_out.anchor(m_out.int32Zero));
 1124 results.append(m_out.anchor(neg2ToThe31));
11261125 m_out.jump(done);
11271126 }
11281127
11291128 m_out.appendTo(continuation, done);
11301129
11311130 if (shouldCheckNegativeZero(m_node->arithMode())) {
1132  LBasicBlock zeroNumerator = FTL_NEW_BLOCK(m_out, ("ArithDivMod zero numerator"));
1133  LBasicBlock numeratorContinuation = FTL_NEW_BLOCK(m_out, ("ArithDivMod numerator continuation"));
 1131 LBasicBlock zeroNumerator = FTL_NEW_BLOCK(m_out, ("ArithDiv zero numerator"));
 1132 LBasicBlock numeratorContinuation = FTL_NEW_BLOCK(m_out, ("ArithDiv numerator continuation"));
11341133
11351134 m_out.branch(m_out.isZero32(numerator), zeroNumerator, numeratorContinuation);
11361135

@@private:
11441143 m_out.appendTo(numeratorContinuation, innerLastNext);
11451144 }
11461145
1147  LValue divModResult = m_node->op() == ArithDiv
1148  ? m_out.div(numerator, denominator)
1149  : m_out.rem(numerator, denominator);
 1146 LValue result = m_out.div(numerator, denominator);
11501147
11511148 if (shouldCheckOverflow(m_node->arithMode())) {
11521149 speculate(
11531150 Overflow, noValue(), 0,
1154  m_out.notEqual(m_out.mul(divModResult, denominator), numerator));
 1151 m_out.notEqual(m_out.mul(result, denominator), numerator));
11551152 }
11561153
1157  results.append(m_out.anchor(divModResult));
 1154 results.append(m_out.anchor(result));
11581155 m_out.jump(done);
11591156
11601157 m_out.appendTo(done, lastNext);

@@private:
11641161 }
11651162
11661163 case NumberUse: {
1167  LValue C1 = lowDouble(m_node->child1());
1168  LValue C2 = lowDouble(m_node->child2());
1169  setDouble(m_node->op() == ArithDiv ? m_out.doubleDiv(C1, C2) : m_out.doubleRem(C1, C2));
 1164 setDouble(m_out.doubleDiv(
 1165 lowDouble(m_node->child1()), lowDouble(m_node->child2())));
11701166 break;
11711167 }
11721168

@@private:
11761172 }
11771173 }
11781174
 1175 void compileArithMod()
 1176 {
 1177 switch (m_node->binaryUseKind()) {
 1178 case Int32Use: {
 1179 LValue numerator = lowInt32(m_node->child1());
 1180 LValue denominator = lowInt32(m_node->child2());
 1181
 1182 LBasicBlock unsafeDenominator = FTL_NEW_BLOCK(m_out, ("ArithMod unsafe denominator"));
 1183 LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("ArithMod continuation"));
 1184 LBasicBlock done = FTL_NEW_BLOCK(m_out, ("ArithMod done"));
 1185
 1186 Vector<ValueFromBlock, 3> results;
 1187
 1188 LValue adjustedDenominator = m_out.add(denominator, m_out.int32One);
 1189
 1190 m_out.branch(m_out.above(adjustedDenominator, m_out.int32One), continuation, unsafeDenominator);
 1191
 1192 LBasicBlock lastNext = m_out.appendTo(unsafeDenominator, continuation);
 1193
 1194 LValue neg2ToThe31 = m_out.constInt32(-2147483647-1);
 1195
 1196 // FIXME: -2^31 / -1 will actually yield negative zero, so we could have a
 1197 // separate case for that. But it probably doesn't matter so much.
 1198 if (shouldCheckOverflow(m_node->arithMode())) {
 1199 LValue cond = m_out.bitOr(m_out.isZero32(denominator), m_out.equal(numerator, neg2ToThe31));
 1200 speculate(Overflow, noValue(), 0, cond);
 1201 m_out.jump(continuation);
 1202 } else {
 1203 // This is the case where we convert the result to an int after we're done. So,
 1204 // if the denominator is zero, then the result should be result should be zero.
 1205 // If the denominator is not zero (i.e. it's -1 because we're guarded by the
 1206 // check above) and the numerator is -2^31 then the result should be -2^31.
 1207
 1208 LBasicBlock modByZero = FTL_NEW_BLOCK(m_out, ("ArithMod modulo by zero"));
 1209 LBasicBlock notModByZero = FTL_NEW_BLOCK(m_out, ("ArithMod not modulo by zero"));
 1210 LBasicBlock neg2ToThe31ByNeg1 = FTL_NEW_BLOCK(m_out, ("ArithMod -2^31/-1"));
 1211
 1212 m_out.branch(m_out.isZero32(denominator), modByZero, notModByZero);
 1213
 1214 m_out.appendTo(modByZero, notModByZero);
 1215 results.append(m_out.anchor(m_out.int32Zero));
 1216 m_out.jump(done);
 1217
 1218 m_out.appendTo(notModByZero, neg2ToThe31ByNeg1);
 1219 m_out.branch(m_out.equal(numerator, neg2ToThe31), neg2ToThe31ByNeg1, continuation);
 1220
 1221 m_out.appendTo(neg2ToThe31ByNeg1, continuation);
 1222 results.append(m_out.anchor(m_out.int32Zero));
 1223 m_out.jump(done);
 1224 }
 1225
 1226 m_out.appendTo(continuation, done);
 1227
 1228 LValue remainder = m_out.rem(numerator, denominator);
 1229
 1230 if (shouldCheckNegativeZero(m_node->arithMode())) {
 1231 LBasicBlock negativeNumerator = FTL_NEW_BLOCK(m_out, ("ArithMod negative numerator"));
 1232 LBasicBlock numeratorContinuation = FTL_NEW_BLOCK(m_out, ("ArithMod numerator continuation"));
 1233
 1234 m_out.branch(
 1235 m_out.lessThan(numerator, m_out.int32Zero),
 1236 negativeNumerator, numeratorContinuation);
 1237
 1238 LBasicBlock innerLastNext = m_out.appendTo(negativeNumerator, numeratorContinuation);
 1239
 1240 speculate(NegativeZero, noValue(), 0, m_out.isZero32(remainder));
 1241
 1242 m_out.jump(numeratorContinuation);
 1243
 1244 m_out.appendTo(numeratorContinuation, innerLastNext);
 1245 }
 1246
 1247 results.append(m_out.anchor(remainder));
 1248 m_out.jump(done);
 1249
 1250 m_out.appendTo(done, lastNext);
 1251
 1252 setInt32(m_out.phi(m_out.int32, results));
 1253 break;
 1254 }
 1255
 1256 case NumberUse: {
 1257 setDouble(
 1258 m_out.doubleRem(lowDouble(m_node->child1()), lowDouble(m_node->child2())));
 1259 break;
 1260 }
 1261
 1262 default:
 1263 RELEASE_ASSERT_NOT_REACHED();
 1264 break;
 1265 }
 1266 }
 1267
11791268 void compileArithMinOrMax()
11801269 {
11811270 switch (m_node->binaryUseKind()) {
162867