@@ -78,6 +78,7 @@ void GlobOpt::ArrayLowerBoundCheckHoistInfo::SetLoop(
78
78
void GlobOpt::ArrayLowerBoundCheckHoistInfo::SetLoop (
79
79
::Loop *const loop,
80
80
StackSym *const indexSym,
81
+ const int indexOffset,
81
82
const int offset,
82
83
Value *const indexValue,
83
84
const IntConstantBounds &indexConstantBounds,
@@ -91,6 +92,7 @@ void GlobOpt::ArrayLowerBoundCheckHoistInfo::SetLoop(
91
92
92
93
this ->loop = loop;
93
94
this ->indexSym = indexSym;
95
+ this ->indexOffset = indexOffset;
94
96
this ->offset = offset;
95
97
this ->indexValueNumber = indexValue->GetValueNumber ();
96
98
this ->indexValue = indexValue;
@@ -142,6 +144,7 @@ void GlobOpt::ArrayUpperBoundCheckHoistInfo::SetLoop(
142
144
void GlobOpt::ArrayUpperBoundCheckHoistInfo::SetLoop (
143
145
::Loop *const loop,
144
146
StackSym *const indexSym,
147
+ const int indexOffset,
145
148
const int offset,
146
149
Value *const indexValue,
147
150
const IntConstantBounds &indexConstantBounds,
@@ -151,7 +154,7 @@ void GlobOpt::ArrayUpperBoundCheckHoistInfo::SetLoop(
151
154
{
152
155
Assert (headSegmentLengthValue);
153
156
154
- SetLoop (loop, indexSym, offset, indexValue, indexConstantBounds, isLoopCountBasedBound);
157
+ SetLoop (loop, indexSym, indexOffset, offset, indexValue, indexConstantBounds, isLoopCountBasedBound);
155
158
this ->headSegmentLengthValue = headSegmentLengthValue;
156
159
this ->headSegmentLengthConstantBounds = headSegmentLengthConstantBounds;
157
160
}
@@ -1831,8 +1834,9 @@ void GlobOpt::GenerateLoopCountPlusOne(Loop *const loop, LoopCount *const loopCo
1831
1834
void GlobOpt::GenerateSecondaryInductionVariableBound (
1832
1835
Loop *const loop,
1833
1836
StackSym *const inductionVariableSym,
1834
- const LoopCount *const loopCount,
1837
+ LoopCount *const loopCount,
1835
1838
const int maxMagnitudeChange,
1839
+ const bool needsMagnitudeAdjustment,
1836
1840
StackSym *const boundSym)
1837
1841
{
1838
1842
Assert (loop);
@@ -1857,18 +1861,33 @@ void GlobOpt::GenerateSecondaryInductionVariableBound(
1857
1861
Assert (insertBeforeInstr);
1858
1862
Func *const func = bailOutInfo->bailOutFunc ;
1859
1863
1864
+ StackSym* loopCountSym = nullptr ;
1865
+
1866
+ // If indexOffset < maxMagnitudeChange, we need to account for the difference between them in the bound check
1867
+ // i.e. BoundCheck: inductionVariable + loopCountMinusOne * maxMagnitudeChange + maxMagnitudeChange - indexOffset <= length - offset
1868
+ // Since the BoundCheck instruction already deals with offset, we can simplify this to
1869
+ // BoundCheck: inductionVariable + loopCount * maxMagnitudeChange <= length + indexOffset - offset
1870
+ if (needsMagnitudeAdjustment)
1871
+ {
1872
+ GenerateLoopCountPlusOne (loop, loopCount);
1873
+ loopCountSym = loopCount->LoopCountSym ();
1874
+ }
1875
+ else
1876
+ {
1877
+ loopCountSym = loopCount->LoopCountMinusOneSym ();
1878
+ }
1860
1879
// intermediateValue = loopCount * maxMagnitudeChange
1861
1880
StackSym *intermediateValueSym;
1862
1881
if (maxMagnitudeChange == 1 || maxMagnitudeChange == -1 )
1863
1882
{
1864
- intermediateValueSym = loopCount-> LoopCountMinusOneSym () ;
1883
+ intermediateValueSym = loopCountSym ;
1865
1884
}
1866
1885
else
1867
1886
{
1868
1887
IR::BailOutInstr *const instr = IR::BailOutInstr::New (Js::OpCode::Mul_I4, bailOutKind, bailOutInfo, func);
1869
1888
1870
1889
instr->SetSrc1 (
1871
- IR::RegOpnd::New (loopCount-> LoopCountMinusOneSym (), loopCount-> LoopCountMinusOneSym () ->GetType (), func));
1890
+ IR::RegOpnd::New (loopCountSym, loopCountSym ->GetType (), func));
1872
1891
instr->GetSrc1 ()->SetIsJITOptimizedReg (true );
1873
1892
1874
1893
instr->SetSrc2 (IR::IntConstOpnd::New (maxMagnitudeChange, TyInt32, func, true ));
@@ -2418,6 +2437,7 @@ void GlobOpt::DetermineArrayBoundCheckHoistability(
2418
2437
loop,
2419
2438
indexSym,
2420
2439
lowerOffset,
2440
+ lowerOffset,
2421
2441
landingPadIndexValue,
2422
2442
landingPadIndexConstantBounds);
2423
2443
}
@@ -2469,11 +2489,13 @@ void GlobOpt::DetermineArrayBoundCheckHoistability(
2469
2489
// Normalize the offset such that:
2470
2490
// boundBase <= headSegmentLength + offset
2471
2491
// Where (offset = -1 - boundOffset), and -1 is to simulate < instead of <=.
2492
+ int indexOffset = upperOffset;
2472
2493
upperOffset = -1 - upperOffset;
2473
2494
2474
2495
upperHoistInfo.SetLoop (
2475
2496
loop,
2476
2497
indexSym,
2498
+ indexOffset,
2477
2499
upperOffset,
2478
2500
landingPadIndexValue,
2479
2501
landingPadIndexConstantBounds,
@@ -2619,6 +2641,7 @@ void GlobOpt::DetermineArrayBoundCheckHoistability(
2619
2641
loop,
2620
2642
indexBoundBaseSym,
2621
2643
offset,
2644
+ offset,
2622
2645
landingPadIndexBoundBaseValue,
2623
2646
landingPadIndexBoundBaseConstantBounds);
2624
2647
break ;
@@ -2643,11 +2666,13 @@ void GlobOpt::DetermineArrayBoundCheckHoistability(
2643
2666
// Normalize the offset such that:
2644
2667
// boundBase <= headSegmentLength + offset
2645
2668
// Where (offset = -1 - boundOffset), and -1 is to simulate < instead of <=.
2669
+ int indexOffset = offset;
2646
2670
offset = -1 - offset;
2647
2671
2648
2672
upperHoistInfo.SetLoop (
2649
2673
loop,
2650
2674
indexBoundBaseSym,
2675
+ indexOffset,
2651
2676
offset,
2652
2677
landingPadIndexBoundBaseValue,
2653
2678
landingPadIndexBoundBaseConstantBounds,
@@ -3139,6 +3164,7 @@ void GlobOpt::DetermineArrayBoundCheckHoistability(
3139
3164
lowerHoistInfo.SetLoop (
3140
3165
currentLoop,
3141
3166
indexLoopCountBasedBoundBaseSym,
3167
+ indexOffset,
3142
3168
offset,
3143
3169
indexLoopCountBasedBoundBaseValue,
3144
3170
indexLoopCountBasedBoundBaseConstantBounds,
@@ -3153,6 +3179,7 @@ void GlobOpt::DetermineArrayBoundCheckHoistability(
3153
3179
upperHoistInfo.SetLoop (
3154
3180
currentLoop,
3155
3181
indexLoopCountBasedBoundBaseSym,
3182
+ indexOffset,
3156
3183
offset,
3157
3184
indexLoopCountBasedBoundBaseValue,
3158
3185
indexLoopCountBasedBoundBaseConstantBounds,
0 commit comments