# RFR(S): 8210152: Optimize integer divisible by power-of-2 check

Pengfei Li (Arm Technology China) Pengfei.Li at arm.com
Mon Sep 3 05:49:46 UTC 2018

```Hi Vladimir, Dean,

> I don't see where negation is coming from for 'X % 2 == 0' expression.
> It should be only 2 instructions: 'cmp (X and 1), 0'
The 'cmp (X and 1), 0' is just what we expected. But there's redundant conditional negation coming from the possibly negative X handling in "X % 2".
For instance, X = -5, "X % 2" should be -1. So only "(X and 1)" operation is not enough. We have to negate the result.

> I will look on it next week. But it would be nice if you can provide small test to show this issue.
I've already provided a case of "if (a%2 == 0) { ... }" in JBS description. What code generated and what can be optimized are listed there.
You could see https://bugs.openjdk.java.net/browse/JDK-8210152 for details. You could also see the test case for this optimization I attached below.

> It looks like your matching may allow more patterns than expected. I was expecting it to look for < 0 or >= 0 for the conditional negation, but I don't see it.
Yes. I didn't limit the if condition to <0 or >= 0 so it will match more patterns. But nothing is going wrong if this ideal transformation applies on more cases.
In pseudo code, if someone writes:
if ( some_condition ) { x = -x; }
if ( x == 0 ) { do_something(); }
The negation in 1st if-clause could always be eliminated whatever the condition is.

--
Thanks,
Pengfei

-- my test case attached below --
public class Foo {

public static void main(String[] args) {
int[] dividends = { 0, 17, 1553, -90, -35789, 0x80000000 };
for (int i = 0; i < dividends.length; i++) {
int x = dividends[i];
System.out.println(testDivisible(x));
System.out.println(testModulo(x));
testCondNeg(x);
}
return;
}

public static int testDivisible(int x) {
// Modulo result is only for zero check
if (x % 4 == 0) {
return 444;
}
return 555;
}

public static int testModulo(int x) {
int y = x % 4;
if (y == 0) {
return 222;
}
// Modulo result is used elsewhere
System.out.println(y);
return 333;
}

public static void testCondNeg(int x) {
// Pure conditional negation
if (printAndIfNeg(x)) {
x = -x;
}
if (x == 0) {
System.out.println("zero!");
}
}

static boolean printAndIfNeg(int x) {
System.out.println(x);
return x <= 0;
}
}
```