diff --git a/compiler/src/jdk.graal.compiler.test/src/jdk/graal/compiler/core/test/SpeculativeGuardMovementTest.java b/compiler/src/jdk.graal.compiler.test/src/jdk/graal/compiler/core/test/SpeculativeGuardMovementTest.java index 178af2eafea8..2d855d78c348 100644 --- a/compiler/src/jdk.graal.compiler.test/src/jdk/graal/compiler/core/test/SpeculativeGuardMovementTest.java +++ b/compiler/src/jdk.graal.compiler.test/src/jdk/graal/compiler/core/test/SpeculativeGuardMovementTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,6 +26,8 @@ import java.util.List; +import org.junit.Test; + import jdk.graal.compiler.api.directives.GraalDirectives; import jdk.graal.compiler.core.common.GraalOptions; import jdk.graal.compiler.core.common.cfg.CFGLoop; @@ -37,8 +39,6 @@ import jdk.graal.compiler.nodes.cfg.HIRBlock; import jdk.graal.compiler.nodes.java.InstanceOfNode; import jdk.graal.compiler.options.OptionValues; -import org.junit.Test; - import jdk.vm.ci.code.InstalledCode; import jdk.vm.ci.meta.DeoptimizationReason; @@ -187,7 +187,7 @@ private boolean instanceOfGuardPresent(String toParse) { return iOf.usages().count() == 1 && iOf.usages().first() instanceof FixedGuardNode; } - private static int findDeoptLoopDepth(DeoptimizationReason reason, StructuredGraph g) { + public static int findDeoptLoopDepth(DeoptimizationReason reason, StructuredGraph g) { ControlFlowGraph cfg = ControlFlowGraph.computeForSchedule(g); assertTrue(cfg.getLoops().size() > 0, "Loop(s) in graph expected!"); diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/loop/phases/SpeculativeGuardMovementPhase.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/loop/phases/SpeculativeGuardMovementPhase.java index 3cabc82e6ea1..50e7a07cbe92 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/loop/phases/SpeculativeGuardMovementPhase.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/loop/phases/SpeculativeGuardMovementPhase.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -649,7 +649,8 @@ private OptimizedCompareTests shouldOptimizeCompare(CompareNode compare, Inducti if (boundStamp instanceof IntegerStamp && ivStamp instanceof IntegerStamp) { IntegerStamp integerBoundStamp = (IntegerStamp) boundStamp; IntegerStamp integerIvStamp = (IntegerStamp) ivStamp; - if (fitsIn32Bit(integerBoundStamp) && fitsIn32Bit(integerIvStamp)) { + NumUtil.Signedness signedness = compare.condition().isUnsigned() ? NumUtil.Signedness.UNSIGNED : NumUtil.Signedness.SIGNED; + if (fitsIn32Bit(integerBoundStamp, signedness) && fitsIn32Bit(integerIvStamp, signedness)) { fitsInInt = true; } } @@ -757,8 +758,19 @@ private static boolean optimizedCompareUnconditionalDeopt(GuardNode guard, Optim return false; } - private static boolean fitsIn32Bit(IntegerStamp stamp) { - return NumUtil.isUInt(stamp.mayBeSet()); + /** + * Returns {@code true} if the given stamp fits into a 32-bit range. If the stamp is larger + * than 32 bits, the bounds must be signed or unsigned according to {@code signedness}. + */ + private static boolean fitsIn32Bit(IntegerStamp stamp, NumUtil.Signedness signedness) { + if (stamp.getBits() <= 32) { + return true; + } + if (signedness == NumUtil.Signedness.SIGNED) { + return NumUtil.isSignedNbit(32, stamp.lowerBound()) && NumUtil.isSignedNbit(32, stamp.upperBound()); + } else { + return NumUtil.isUnsignedNbit(32, stamp.lowerBound()) && NumUtil.isUnsignedNbit(32, stamp.upperBound()); + } } private CFGLoop tryOptimizeInstanceOf(GuardNode guard, InstanceOfNode compare) {