Skip to content

Commit 5d0c01a

Browse files
committed
counted loop detection: always check iv direction exists
1 parent 51828f8 commit 5d0c01a

File tree

1 file changed

+23
-17
lines changed
  • compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/nodes/loop

1 file changed

+23
-17
lines changed

compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/nodes/loop/Loop.java

Lines changed: 23 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@
7777
import jdk.graal.compiler.nodes.debug.NeverStripMineNode;
7878
import jdk.graal.compiler.nodes.debug.NeverWriteSinkNode;
7979
import jdk.graal.compiler.nodes.extended.ValueAnchorNode;
80+
import jdk.graal.compiler.nodes.loop.InductionVariable.Direction;
8081
import jdk.graal.compiler.nodes.util.GraphUtil;
8182
import jdk.graal.compiler.phases.common.CanonicalizerPhase;
8283

@@ -316,17 +317,17 @@ public boolean detectCounted() {
316317
}
317318
CompareNode compare = (CompareNode) ifTest;
318319
Condition condition = null;
319-
InductionVariable iv = null;
320+
InductionVariable limitCheckedIV = null;
320321
ValueNode limit = null;
321322
if (isOutsideLoop(compare.getX())) {
322-
iv = getInductionVariables().get(compare.getY());
323-
if (iv != null) {
323+
limitCheckedIV = getInductionVariables().get(compare.getY());
324+
if (limitCheckedIV != null) {
324325
condition = compare.condition().asCondition().mirror();
325326
limit = compare.getX();
326327
}
327328
} else if (isOutsideLoop(compare.getY())) {
328-
iv = getInductionVariables().get(compare.getX());
329-
if (iv != null) {
329+
limitCheckedIV = getInductionVariables().get(compare.getX());
330+
if (limitCheckedIV != null) {
330331
condition = compare.condition().asCondition();
331332
limit = compare.getY();
332333
}
@@ -337,35 +338,40 @@ public boolean detectCounted() {
337338
if (negated) {
338339
condition = condition.negate();
339340
}
341+
final Direction limitCheckedIVDirection = limitCheckedIV.direction();
342+
if (limitCheckedIVDirection == null) {
343+
// we do not know which direction the stride goes
344+
return false;
345+
}
340346
boolean isLimitIncluded = false;
341347
boolean unsigned = false;
342348
switch (condition) {
343349
case EQ:
344-
if (iv.initNode() == limit) {
350+
if (limitCheckedIV.initNode() == limit) {
345351
// allow "single iteration" case
346352
isLimitIncluded = true;
347353
} else {
348354
return false;
349355
}
350356
break;
351357
case NE: {
352-
IntegerStamp initStamp = (IntegerStamp) iv.initNode().stamp(NodeView.DEFAULT);
358+
IntegerStamp initStamp = (IntegerStamp) limitCheckedIV.initNode().stamp(NodeView.DEFAULT);
353359
IntegerStamp limitStamp = (IntegerStamp) limit.stamp(NodeView.DEFAULT);
354-
IntegerStamp counterStamp = (IntegerStamp) iv.valueNode().stamp(NodeView.DEFAULT);
355-
if (iv.direction() == InductionVariable.Direction.Up) {
360+
IntegerStamp counterStamp = (IntegerStamp) limitCheckedIV.valueNode().stamp(NodeView.DEFAULT);
361+
if (limitCheckedIVDirection == InductionVariable.Direction.Up) {
356362
if (limitStamp.asConstant() != null && limitStamp.asConstant().asLong() == counterStamp.upperBound()) {
357363
// signed: i < MAX_INT
358364
} else if (limitStamp.asConstant() != null && limitStamp.asConstant().asLong() == counterStamp.unsignedUpperBound() && IntegerStamp.sameSign(initStamp, limitStamp)) {
359365
unsigned = true;
360-
} else if (!iv.isConstantStride() || !absStrideIsOne(iv) || initStamp.upperBound() > limitStamp.lowerBound()) {
366+
} else if (!limitCheckedIV.isConstantStride() || !absStrideIsOne(limitCheckedIV) || initStamp.upperBound() > limitStamp.lowerBound()) {
361367
return false;
362368
}
363-
} else if (iv.direction() == InductionVariable.Direction.Down) {
369+
} else if (limitCheckedIVDirection == InductionVariable.Direction.Down) {
364370
if (limitStamp.asConstant() != null && limitStamp.asConstant().asLong() == counterStamp.lowerBound()) {
365371
// signed: MIN_INT > i
366372
} else if (limitStamp.asConstant() != null && limitStamp.asConstant().asLong() == counterStamp.unsignedLowerBound() && IntegerStamp.sameSign(initStamp, limitStamp)) {
367373
unsigned = true;
368-
} else if (!iv.isConstantStride() || !absStrideIsOne(iv) || initStamp.lowerBound() < limitStamp.upperBound()) {
374+
} else if (!limitCheckedIV.isConstantStride() || !absStrideIsOne(limitCheckedIV) || initStamp.lowerBound() < limitStamp.upperBound()) {
369375
return false;
370376
}
371377
} else {
@@ -377,36 +383,36 @@ public boolean detectCounted() {
377383
unsigned = true; // fall through
378384
case LE:
379385
isLimitIncluded = true;
380-
if (iv.direction() != InductionVariable.Direction.Up) {
386+
if (limitCheckedIV.direction() != InductionVariable.Direction.Up) {
381387
return false;
382388
}
383389
break;
384390
case BT:
385391
unsigned = true; // fall through
386392
case LT:
387-
if (iv.direction() != InductionVariable.Direction.Up) {
393+
if (limitCheckedIV.direction() != InductionVariable.Direction.Up) {
388394
return false;
389395
}
390396
break;
391397
case AE:
392398
unsigned = true; // fall through
393399
case GE:
394400
isLimitIncluded = true;
395-
if (iv.direction() != InductionVariable.Direction.Down) {
401+
if (limitCheckedIV.direction() != InductionVariable.Direction.Down) {
396402
return false;
397403
}
398404
break;
399405
case AT:
400406
unsigned = true; // fall through
401407
case GT:
402-
if (iv.direction() != InductionVariable.Direction.Down) {
408+
if (limitCheckedIV.direction() != InductionVariable.Direction.Down) {
403409
return false;
404410
}
405411
break;
406412
default:
407413
throw GraalError.shouldNotReachHere(condition.toString()); // ExcludeFromJacocoGeneratedReport
408414
}
409-
counted = new CountedLoopInfo(this, iv, ifNode, limit, isLimitIncluded, negated ? ifNode.falseSuccessor() : ifNode.trueSuccessor(), unsigned);
415+
counted = new CountedLoopInfo(this, limitCheckedIV, ifNode, limit, isLimitIncluded, negated ? ifNode.falseSuccessor() : ifNode.trueSuccessor(), unsigned);
410416
return true;
411417
}
412418
return false;

0 commit comments

Comments
 (0)