mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-25 04:02:41 +01:00
a49643a387
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
23 lines
553 B
LLVM
23 lines
553 B
LLVM
; RUN: opt < %s -scalar-evolution -analyze | FileCheck %s
|
|
|
|
define void @foo([7 x i8]* %a) {
|
|
; CHECK-LABEL: @foo
|
|
entry:
|
|
br label %bb
|
|
|
|
bb:
|
|
%idx = phi i64 [ 0, %entry ], [ %idx.incr, %bb ]
|
|
%i = udiv i64 %idx, 7
|
|
%j = urem i64 %idx, 7
|
|
%a.ptr = getelementptr [7 x i8], [7 x i8]* %a, i64 %i, i64 %j
|
|
; CHECK: %a.ptr = getelementptr [7 x i8], [7 x i8]* %a, i64 %i, i64 %j
|
|
; CHECK-NEXT: --> {%a,+,1}<nw><%bb>
|
|
%val = load i8, i8* %a.ptr
|
|
%idx.incr = add i64 %idx, 1
|
|
%test = icmp ne i64 %idx.incr, 35
|
|
br i1 %test, label %bb, label %exit
|
|
|
|
exit:
|
|
ret void
|
|
}
|