-
Notifications
You must be signed in to change notification settings - Fork 775
Description
I've been experimenting with enabling the CFG Simplification optimization pass. In the process, I came across what I think might be a bug in z code generation. The problem can be seen with this test case:
public class Foo {
static byte barr[] = new byte[] {-1};
static int ival = 255;
static byte bval;
public static final boolean sub() {
bval = barr[0];
return (barr[0] & 255) == barr[0];
}
public static final void main(String[] args) {
System.out.println(sub());
System.out.println(sub());
}
}
The expected result is
false
false
However, with the following command invocation, an incorrect result is produced by the JIT compiled method Foo.sub:
$ TR_enableSimplifyBooleanStore=yes TR_enableCFGSimplificaiton=yes ./jdk8u472-b07/bin/java -Xjit:limit={Foo.sub*},disableAsyncCompilation,count=1,disableOptTransformations={O^O\ LOAD\ EXTENSION*} Foo
false
true
The problem appears to be that a bu2i operation — representing the result of barr[0] & 255 — is not resulting in a zero extension. The initial load from barr[0] is held in GPR_0039 as a sign-extended value, copied to GPR_0040 and stored into the bval field, but then that sign extended value is used directly in the comparison with GPR_0040 in the CRJ operation.
n21n ( 0) istore Foo.bval B[#402 Static] [flags 0x301 0x0 ] [ 0x3ff6b004ea0] bci=[-1,5,7] rc=0 vc=92 vn=- li=2 udi=- nc=1
n20n ( 1) b2i (in GPR_0040) [ 0x3ff6b004e50] bci=[-1,5,7] rc=1 vc=92 vn=- li=2 udi=- nc=1
n17n ( 1) bloadi <array-shadow>[#253 Shadow] [flags 0x80000601 0x0 ] (in GPR_0039) (cannotOverflow ) [ 0x3ff6b004d60] bci=[-1,4,7] rc=1 vc=92 vn=- li=2 udi=- nc=1 flg=0x1000
n16n ( 0) aladd (X>=0 internalPtr ) [ 0x3ff6b004d10] bci=[-1,4,7] rc=0 vc=94 vn=- li=2 udi=- nc=2 flg=0x8100
n7n ( 0) ==>aload (in &GPR_0032) (X!=0 )
n15n ( 0) lconst 8 (highWordZero X!=0 X>=0 ) [ 0x3ff6b004cc0] bci=[-1,4,7] rc=0 vc=92 vn=- li=2 udi=- nc=0 flg=0x4104
------------------------------
[ 0x3ff6b100750] LB GPR_0039, Shadow[<array-shadow>] 8(&GPR_0032)
[ 0x3ff6b100890] LBR GPR_0040,GPR_0039
[ 0x3ff6b100b10] LGFI GPR_0042,1640760
[ 0x3ff6b100c20] ST GPR_0040, Static[Foo.bval B] 0(GPR_0042)
============================================================
; Live regs: GPR=2 FPR=0 VRF=0 {GPR_0040, GPR_0039}
------------------------------
n99n ( 0) treetop [ 0x3ff6b080eb0] bci=[-1,22,8] rc=0 vc=92 vn=- li=2 udi=- nc=1
n50n ( 2) icmpeq () [ 0x3ff6b0057b0] bci=[-1,22,8] rc=2 vc=92 vn=- li=2 udi=- nc=2 flg=0x20
n20n ( 1) ==>b2i (in GPR_0040)
n35n ( 1) bu2i (X>=0 ) [ 0x3ff6b005300] bci=[-1,16,8] rc=1 vc=92 vn=- li=2 udi=- nc=1 flg=0x100
n17n ( 1) ==>bloadi (in GPR_0039) (cannotOverflow )
------------------------------
------------------------------
n99n ( 0) treetop [ 0x3ff6b080eb0] bci=[-1,22,8] rc=0 vc=92 vn=- li=2 udi=- nc=1
n50n ( 1) icmpeq (in GPR_0043) () [ 0x3ff6b0057b0] bci=[-1,22,8] rc=1 vc=92 vn=- li=2 udi=- nc=2 flg=0x20
n20n ( 0) ==>b2i (in GPR_0040)
n35n ( 0) bu2i (in GPR_0039) (X>=0 ) [ 0x3ff6b005300] bci=[-1,16,8] rc=0 vc=92 vn=- li=2 udi=- nc=1 flg=0x100
n17n ( 0) ==>bloadi (in GPR_0039) (cannotOverflow )
------------------------------
[ 0x3ff6b1011f0] LHI GPR_0043,0x1
[ 0x3ff6b1013c0] Label L0033: # (Start of internal control flow)
[ 0x3ff6b1012d0] CRJ GPR_0039,GPR_0040,Label L0034,BH(mask=0x8),
[ 0x3ff6b1014a0] XR GPR_0043,GPR_0043
[ 0x3ff6b101b40] assocreg
[ 0x3ff6b101580] Label L0034: # (End of internal control flow)
Without CFG simplification, the zero extension is performed on GPR_0039 by an LLCR operation before the comparison:
n21n ( 0) istore Foo.bval B[#402 Static] [flags 0x301 0x0 ] [ 0x3ff8ccafea0] bci=[-1,5,7] rc=0 vc=107 vn=- li=2 udi=- nc=1
n20n ( 1) b2i (in GPR_0040) [ 0x3ff8ccafe50] bci=[-1,5,7] rc=1 vc=107 vn=- li=2 udi=- nc=1
n17n ( 1) bloadi <array-shadow>[#253 Shadow] [flags 0x80000601 0x0 ] (in GPR_0039) (cannotOverflow ) [ 0x3ff8ccafd60] bci=[-1,4,7] rc=1 vc=107 vn=- li=2 udi=- nc=1 flg=0x1000
n16n ( 0) aladd (X>=0 internalPtr ) [ 0x3ff8ccafd10] bci=[-1,4,7] rc=0 vc=109 vn=- li=2 udi=- nc=2 flg=0x8100
n7n ( 0) ==>aload (in &GPR_0032) (X!=0 )
n15n ( 0) lconst 8 (highWordZero X!=0 X>=0 ) [ 0x3ff8ccafcc0] bci=[-1,4,7] rc=0 vc=107 vn=- li=2 udi=- nc=0 flg=0x4104
------------------------------
[ 0x3ff8cdbb1e0] LB GPR_0039, Shadow[<array-shadow>] 8(&GPR_0032)
[ 0x3ff8cdbb320] LBR GPR_0040,GPR_0039
[ 0x3ff8cdbb5a0] LGFI GPR_0042,182071096
[ 0x3ff8cdbb6b0] ST GPR_0040, Static[Foo.bval B] 0(GPR_0042)
============================================================
; Live regs: GPR=2 FPR=0 VRF=0 {GPR_0040, GPR_0039}
------------------------------
n50n ( 0) ificmpne --> block_4 BBStart at n1n () [ 0x3ff8ccb07b0] bci=[-1,22,8] rc=0 vc=107 vn=- li=2 udi=- nc=2 flg=0x20
n35n ( 1) bu2i (X>=0 ) [ 0x3ff8ccb0300] bci=[-1,16,8] rc=1 vc=107 vn=- li=2 udi=- nc=1 flg=0x100
n17n ( 1) ==>bloadi (in GPR_0039) (cannotOverflow )
n20n ( 1) ==>b2i (in GPR_0040)
------------------------------
------------------------------
n50n ( 0) ificmpne --> block_4 BBStart at n1n () [ 0x3ff8ccb07b0] bci=[-1,22,8] rc=0 vc=107 vn=- li=2 udi=- nc=2 flg=0x20
n35n ( 0) bu2i (in GPR_0039) (X>=0 ) [ 0x3ff8ccb0300] bci=[-1,16,8] rc=0 vc=107 vn=- li=2 udi=- nc=1 flg=0x100
n17n ( 0) ==>bloadi (in GPR_0039) (cannotOverflow )
n20n ( 0) ==>b2i (in GPR_0040)
------------------------------
[ 0x3ff8cdbba70] LLCR GPR_0039,GPR_0039
[ 0x3ff8cdbbb50] CRJ GPR_0040,GPR_0039,Label L0017,BNH(mask=0x6),