diff options
author | Alexandre Isoard <alexandre.isoard@gmail.com> | 2017-09-01 14:59:59 +0000 |
---|---|---|
committer | Alexandre Isoard <alexandre.isoard@gmail.com> | 2017-09-01 14:59:59 +0000 |
commit | 405728fd47a555e51196a6883d33318f22fab9a4 (patch) | |
tree | 0aa242b490a05acf28737503cd6324006e5b3951 /llvm/lib/Analysis/ModuleSummaryAnalysis.cpp | |
parent | 65528f29913a541f3d250dbee2d93a3b1db68e4d (diff) | |
download | llvm-405728fd47a555e51196a6883d33318f22fab9a4.zip llvm-405728fd47a555e51196a6883d33318f22fab9a4.tar.gz llvm-405728fd47a555e51196a6883d33318f22fab9a4.tar.bz2 |
[SCEV] Add URem support to SCEV
In LLVM IR the following code:
%r = urem <ty> %t, %b
is equivalent to
%q = udiv <ty> %t, %b
%s = mul <ty> nuw %q, %b
%r = sub <ty> nuw %t, %q ; (t / b) * b + (t % b) = t
As UDiv, Mul and Sub are already supported by SCEV, URem can be implemented
with minimal effort using that relation:
%r --> (-%b * (%t /u %b)) + %t
We implement two special cases:
- if %b is 1, the result is always 0
- if %b is a power-of-two, we produce a zext/trunc based expression instead
That is, the following code:
%r = urem i32 %t, 65536
Produces:
%r --> (zext i16 (trunc i32 %a to i16) to i32)
Note that while this helps get a tighter bound on the range analysis and the
known-bits analysis, this exposes some normalization shortcoming of SCEVs:
%div = udim i32 %a, 65536
%mul = mul i32 %div, 65536
%rem = urem i32 %a, 65536
%add = add i32 %mul, %rem
Will usually not be reduced.
llvm-svn: 312329
Diffstat (limited to 'llvm/lib/Analysis/ModuleSummaryAnalysis.cpp')
0 files changed, 0 insertions, 0 deletions