Cadd_cmpLTMask doesn't handle 64-bit tmp register properly
Tom Rodriguez
tom.rodriguez at oracle.com
Wed May 25 12:18:04 PDT 2011
Yes the assembly is very broken. I filed 7048332 for this. The standard reporting location is through http://bugreport.sun.com/bugreport though that goes through some triage before it makes it to us. It's ok to report concrete things here, particularly if you've fully diagnosed the problem. ;) Thanks for the thorough report. This may make it into 7 but it should be in the next update at worst.
tom
On May 25, 2011, at 5:49 AM, Tuure Laurinolli wrote:
> Hello,
>
> I spent yesterday tracing a bug in our software, and the trail points to
> Hotspot.
>
> Extremely short version:
>
> cadd_cmpLTMask doesnt handle 64-bit register as tmp, and generates
> subtly broken code if it receives one.
>
> Slightly longer version:
>
> After extensive inlining and elision of the full-check, the interesting
> part of
>
> @Override
> public int size() {
> if (full) {
> path = 0;
> return capacity();
> }
>
> final int result;
> if (last >= first) {
> result = last - first;
> } else {
> result = last - first + capacity();
> }
> return result;
> }
>
> compiles down to something like
>
> 11d subl R10, RDX # cadd_cmpLTMask1
> sbbl R11, R11
> andl R11, RBX
> addl R10, R11
> 127 movl [rsp + #40], R10 # spill
>
> where initially R10 is last, RBX is first, R8 is whatever and RCX is
> result of capacity(). However, looking at the code that is actually run
> with GDB, the disassembly is rather different:
>
> 0x2aaaac856d7d: sub %edx,%r10d
> 0x2aaaac856d80: sbb %ebx,%ebx
> 0x2aaaac856d82: and %ebx,%ebx
> 0x2aaaac856d84: add %ebx,%r11d
> 0x2aaaac856d87: mov %r10d,0x28(%rsp)
>
> Both and and add operate on odd registers, and the code also produces
> wrong result into [RSP+40]. Looking at the binary code, it's as follows:
>
> (gdb) x/15xb 0x2aaaac856d7d
> 0x2aaaac856d7d: 0x44 0x2b 0xd2 0x1b 0xdb 0x23
> 0xdb 0x44
> 0x2aaaac856d85: 0x03 0xdb 0x44 0x89 0x54 0x24 0x28
>
> Notably the SBB instruction is missing REX.RB prefix, which changes it
> from SBBL R11 R11 into SBBL EBX EBX and clobbers the actual EBX. Also,
> the prefix of the ADD is only REX.R, whereas it probably should be
> REX.RB, and in any case the destination register is wrong.
>
> Looking at x86_64.ad, it's clear that the code that generates this
> section (cadd_cmpLTMask) is not prepared to handle 64-bit tmp register.
> This explain missing prefixes, and also wrong destination register of
> ADD, since the high bit of reg clobbers the low bit or r/m in emit_rm().
>
> Now, where do I report this bug? Presumably there is a bug tracker
> somewhere.
>
> --
>
> Tuure Laurinolli
> Software Engineer
> Indagon Ltd.
>
More information about the hotspot-compiler-dev
mailing list