[PATCH] Added InstCombine transform for pattern " ((X % Z) + (Y % Z)) % Z -> (X + Y) % Z ".

Jasper Neumann jn at sirrida.de
Mon Sep 15 05:42:49 PDT 2014


Hello Ankur!

 > This patch implements the following transformation
 >   " ((X % Z) + (Y % Z)) % Z -> (X + Y) % Z "

An overflow (and hence a wrong transformation) can happen for large 
values of X and/or Y, and possibly Z.


The transformation is also often wrong for signed numbers when the signs 
of X and Y differ.

Example tables (m=3):

((x % 3)+(y % 3)) % 3
y\x -4  -3  -2  -1   0   1   2   3   4
-4: -2  -1   0  -2  -1   0   1  -1   0
-3: -1   0  -2  -1   0   1   2   0   1
-2:  0  -2  -1   0  -2  -1   0  -2  -1
-1: -2  -1   0  -2  -1   0   1  -1   0
  0: -1   0  -2  -1   0   1   2   0   1
  1:  0   1  -1   0   1   2   0   1   2
  2:  1   2   0   1   2   0   1   2   0
  3: -1   0  -2  -1   0   1   2   0   1
  4:  0   1  -1   0   1   2   0   1   2

(x+y) % 3
y\x -4  -3  -2  -1   0   1   2   3   4
-4: -2  -1   0  -2  -1   0  -2  -1   0
-3: -1   0  -2  -1   0  -2  -1   0   1
-2:  0  -2  -1   0  -2  -1   0   1   2
-1: -2  -1   0  -2  -1   0   1   2   0
  0: -1   0  -2  -1   0   1   2   0   1
  1:  0  -2  -1   0   1   2   0   1   2
  2: -2  -1   0   1   2   0   1   2   0
  3: -1   0   1   2   0   1   2   0   1
  4:  0   1   2   0   1   2   0   1   2

Please note that the tables are not equal.


As far as I can see, the transformation appears to be correct for 
unsigned numbers when X, Y and Z are sufficiently small, i.e. without 
any overflows happening in both formulas at the + operator.

Best regards
Jasper



More information about the llvm-commits mailing list