1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-23 11:13:28 +01:00
llvm-mirror/test/Analysis/ScalarEvolution/urem-0.ll
Alexandre Isoard a49643a387 [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
2017-09-01 14:59:59 +00:00

34 lines
730 B
LLVM

; RUN: opt < %s -scalar-evolution -analyze | FileCheck %s
define i8 @foo(i8 %a) {
; CHECK-LABEL: @foo
%t0 = urem i8 %a, 27
; CHECK: %t0 = urem i8 %a, 27
; CHECK-NEXT: --> ((-27 * (%a /u 27)) + %a)
ret i8 %t0
}
define i8 @bar(i8 %a) {
; CHECK-LABEL: @bar
%t1 = urem i8 %a, 1
; CHECK: %t1 = urem i8 %a, 1
; CHECK-NEXT: --> 0
ret i8 %t1
}
define i8 @baz(i8 %a) {
; CHECK-LABEL: @baz
%t2 = urem i8 %a, 32
; CHECK: %t2 = urem i8 %a, 32
; CHECK-NEXT: --> (zext i5 (trunc i8 %a to i5) to i8)
ret i8 %t2
}
define i8 @qux(i8 %a) {
; CHECK-LABEL: @qux
%t3 = urem i8 %a, 2
; CHECK: %t3 = urem i8 %a, 2
; CHECK-NEXT: --> (zext i1 (trunc i8 %a to i1) to i8)
ret i8 %t3
}