RFR: 8332368: ubsan aarch64: immediate_aarch64.cpp:298:31: runtime error: shift exponent 32 is too large for 32-bit type 'int'
Boris Ulasevich
bulasevich at openjdk.org
Thu Apr 17 12:30:27 UTC 2025
Running a linux-aarch64-server-fastdebug build with UBSAN (--enable-ubsan configure option) gives the following runtime error immediately on JVM start:
ad_aarch64.hpp:7114:11: runtime error: shift exponent 100 is too large for 32-bit type 'unsigned int'
# Pipeline_Use_Cycle_Mask::operator<<=(int) make/hotspot/ad_aarch64.hpp:7114
# Pipeline_Use_Element::step(unsigned int) make/hotspot/ad_aarch64.hpp:7168
# Pipeline_Use::step(unsigned int) make/hotspot/ad_aarch64.hpp:7216
# Scheduling::step(unsigned int) src/hotspot/share/opto/output.cpp:2116
# Scheduling::AddNodeToBundle(Node*, Block const*) src/hotspot/share/opto/output.cpp:2553
The value of 100 comes from fixed_latency, defined in AD files:
// Pipeline class for call.
pipe_class pipe_class_call()
%{
single_instruction;
fixed_latency(100);
%}
The fixed_latency value is used by the scheduler to model the occupancy of functional units over time. The occupancy is tracked using a uint mask value:
fprintf(fp_hpp, "class Pipeline_Use_Element {\n");
fprintf(fp_hpp, "protected:\n");
fprintf(fp_hpp, " // Mask of used functional units\n");
fprintf(fp_hpp, " uint _used;\n\n");
When the scheduler virtually steps over the instruction, it shifts the masks left by the instruction's latency. The problem is that 100 is greater than sizeof(uint), and left-shifting by 100 effectively zeroes the _mask, but, according to the C++ standard, this is undefined behavior.
We can find a number of fixed_latency(100) expressions in aarch64.ad, arm.ad, ppc.ad, riscv.ad, x86_64.ad files. Perhaps all of them deserve correction. I suggest leaving the AD files as they are, but limiting the shift value in case it exceeds the allowed maximum in a generated code:
void step(uint cycles) {
_used = 0;
- _mask <<= cycles;
+ uint max_shift = 8 * sizeof(_mask) - 1;
+ _mask <<= (cycles < max_shift) ? cycles : max_shift;
}
In fact, this change does not affect the current behavior; we just eliminate the undefined behavior while preserving the intended semantics.
-------------
Commit messages:
- 8332368: ubsan aarch64: immediate_aarch64.cpp:298:31: runtime error: shift exponent 32 is too large for 32-bit type 'int'
Changes: https://git.openjdk.org/jdk/pull/24696/files
Webrev: https://webrevs.openjdk.org/?repo=jdk&pr=24696&range=00
Issue: https://bugs.openjdk.org/browse/JDK-8332368
Stats: 2 lines in 1 file changed: 1 ins; 0 del; 1 mod
Patch: https://git.openjdk.org/jdk/pull/24696.diff
Fetch: git fetch https://git.openjdk.org/jdk.git pull/24696/head:pull/24696
PR: https://git.openjdk.org/jdk/pull/24696
More information about the hotspot-compiler-dev
mailing list