-
Bug
-
Resolution: Fixed
-
P4
-
repo-riscv-port
-
riscv
-
linux
The following Test can reproduce the bug:
```
// Test.java
public class Test {
static void print(int a) {
System.out.println(a);
}
static void foo(int x, long y) {
int z = x | (int)y;
if (z > 0) {
print(z);
}
}
public static void main(String[] args) {
int x = 7;
long y = 21474836472L;
for (int i = 0; i < 20000; i++) {
foo(x, y);
}
}
}
```
Command:
```
java -Xbatch -XX:-Inline -XX:-TieredCompilation -XX:+PrintOptoAssembly -XX:+PrintAssembly Test
```
Test will ouput `-1` in this case, which is not as expected. The OptoAssembly and assembly are as follow:
```
// Opto
01c orr R28, R11, l2i(R12) #@orI_reg_reg
020 + bgt R28, zr, B3 #@cmpI_reg_imm0_branch P=0.000000 C=6784.000000
// Assembly
0x00000040132da35c: or t3,a1,a2 ;*ior {reexecute=0 rethrow=0 return_oop=0}
; - Test::foo@3 (line 7)
0x00000040132da360: bgtz t3,0x00000040132da380 ;*ifle {reexecute=0 rethrow=0 return_oop=0}
; - Test::foo@6 (line 9)
```
Without the conversion of Long to Integer, a1 = 0x7 and a2 = 0x4FFFFFFFF. The result of `or t3, a1, a2` will be 0x4FFFFFFFF.
Since `bgtz ` will compare the full 64-bit value in `t3` with zr,`z > 0` will return true, which is incorrect.
After fixing this issue, Test will output nothing as expected since the Long type value will be convert to Integer correctly.
The corresponding OptoAssembly and assembly will be:
```
// Opto
01c addw R7, R12, zr #@convL2I_reg
020 + orr R7, R11, R7 #@orI_reg_reg
024 + bgt R7, zr, B3 #@cmpI_reg_imm0_branch P=0.000000 C=6784.000000
// Assembly
0x00000040132d935c: addw t2,a2,zero
0x00000040132d9360: or t2,a1,t2 ;*ior {reexecute=0 rethrow=0 return_oop=0}
; - Test::foo@3 (line 7)
0x00000040132d9364: bgtz t2,0x00000040132d9384 ;*ifle {reexecute=0 rethrow=0 return_oop=0}
; - Test::foo@6 (line 9)
```
```
// Test.java
public class Test {
static void print(int a) {
System.out.println(a);
}
static void foo(int x, long y) {
int z = x | (int)y;
if (z > 0) {
print(z);
}
}
public static void main(String[] args) {
int x = 7;
long y = 21474836472L;
for (int i = 0; i < 20000; i++) {
foo(x, y);
}
}
}
```
Command:
```
java -Xbatch -XX:-Inline -XX:-TieredCompilation -XX:+PrintOptoAssembly -XX:+PrintAssembly Test
```
Test will ouput `-1` in this case, which is not as expected. The OptoAssembly and assembly are as follow:
```
// Opto
01c orr R28, R11, l2i(R12) #@orI_reg_reg
020 + bgt R28, zr, B3 #@cmpI_reg_imm0_branch P=0.000000 C=6784.000000
// Assembly
0x00000040132da35c: or t3,a1,a2 ;*ior {reexecute=0 rethrow=0 return_oop=0}
; - Test::foo@3 (line 7)
0x00000040132da360: bgtz t3,0x00000040132da380 ;*ifle {reexecute=0 rethrow=0 return_oop=0}
; - Test::foo@6 (line 9)
```
Without the conversion of Long to Integer, a1 = 0x7 and a2 = 0x4FFFFFFFF. The result of `or t3, a1, a2` will be 0x4FFFFFFFF.
Since `bgtz ` will compare the full 64-bit value in `t3` with zr,`z > 0` will return true, which is incorrect.
After fixing this issue, Test will output nothing as expected since the Long type value will be convert to Integer correctly.
The corresponding OptoAssembly and assembly will be:
```
// Opto
01c addw R7, R12, zr #@convL2I_reg
020 + orr R7, R11, R7 #@orI_reg_reg
024 + bgt R7, zr, B3 #@cmpI_reg_imm0_branch P=0.000000 C=6784.000000
// Assembly
0x00000040132d935c: addw t2,a2,zero
0x00000040132d9360: or t2,a1,t2 ;*ior {reexecute=0 rethrow=0 return_oop=0}
; - Test::foo@3 (line 7)
0x00000040132d9364: bgtz t2,0x00000040132d9384 ;*ifle {reexecute=0 rethrow=0 return_oop=0}
; - Test::foo@6 (line 9)
```