Skip to content

Commit 65dc1ca

Browse files
authored
Rejit when we are doing aggressive int type specialization and attempt to convert a float to an int on a loop backedge. (#6336)
Fixes #6325 In the POC (which repros 1.11 but requires some flags to repro in master), jitting a recursive loop body creates a situation where the type specialization of a sym in the loop prepass does not match the value types that are determined inside of the loop, leading to a lossy conversion from float64 to int32 on the backedge. This change detects the attempted lossy conversion and rejits with aggressive int type specialization disabled.
1 parent f353eaa commit 65dc1ca

File tree

3 files changed

+55
-1
lines changed

3 files changed

+55
-1
lines changed

lib/Backend/GlobOpt.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12167,7 +12167,17 @@ GlobOpt::ToTypeSpecUse(IR::Instr *instr, IR::Opnd *opnd, BasicBlock *block, Valu
1216712167
const FloatConstType floatValue = valueInfo->AsFloatConstant()->FloatValue();
1216812168
if(toType == TyInt32)
1216912169
{
12170-
Assert(lossy);
12170+
// In some loop scenarios, a sym can be specialized to int32 on loop entry
12171+
// during the prepass and then subsequentely specialized to float within
12172+
// the loop, leading to an attempted lossy conversion from float64 to int32
12173+
// on the backedge. For these cases, disable aggressive int type specialization
12174+
// and try again.
12175+
if (!lossy)
12176+
{
12177+
AssertOrFailFast(DoAggressiveIntTypeSpec());
12178+
throw Js::RejitException(RejitReason::AggressiveIntTypeSpecDisabled);
12179+
}
12180+
1217112181
constOpnd =
1217212182
IR::IntConstOpnd::New(
1217312183
Js::JavascriptMath::ToInt32(floatValue),

test/Optimizer/bug_gh6325.js

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
//-------------------------------------------------------------------------------------------------------
2+
// Copyright (C) Microsoft Corporation and contributors. All rights reserved.
3+
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
4+
//-------------------------------------------------------------------------------------------------------
5+
var b = 0;
6+
7+
function test0() {
8+
var a = 100;
9+
10+
for (var i = 1; i < 6; ++i) {
11+
a;
12+
test0a();
13+
for (var j = 0; j < 1; ++j) {
14+
a = 0xffffffffff;
15+
for (var k = 0; k < 1; ++k) {
16+
i = a;
17+
+i;
18+
}
19+
}
20+
if (i == 0xffffffffff) {
21+
print('PASSED');
22+
throw new Error('exit');
23+
}
24+
}
25+
26+
function test0a() {
27+
a;
28+
b = b + 1;
29+
if (b > 100) {
30+
return;
31+
}
32+
return test0();
33+
}
34+
}
35+
36+
try { test0(); }
37+
catch {}

test/Optimizer/rlexe.xml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1628,4 +1628,11 @@
16281628
<compile-flags>-maxinterpretcount:1 -maxsimplejitruncount:1</compile-flags>
16291629
</default>
16301630
</test>
1631+
<test>
1632+
<default>
1633+
<files>bug_gh6325.js</files>
1634+
<compile-flags>-off:backend -forcejitloopbody</compile-flags>
1635+
<tags>exclude_nonative</tags>
1636+
</default>
1637+
</test>
16311638
</regress-exe>

0 commit comments

Comments
 (0)