Home | History | Annotate | Download | only in LoopAccessAnalysis
      1 ; RUN: opt -loop-accesses -analyze < %s | FileCheck %s
      2 
      3 ; The runtime memory check code and the access grouping
      4 ; algorithm both assume that the start and end values
      5 ; for an access range are ordered (start <= stop).
      6 ; When generating checks for accesses with negative stride
      7 ; we need to take this into account and swap the interval
      8 ; ends.
      9 ;
     10 ;   for (i = 0; i < 10000; i++) {
     11 ;     B[i] = A[15000 - i] * 3;
     12 ;   }
     13 
     14 target datalayout = "e-m:e-i64:64-i128:128-n32:64-S128"
     15 target triple = "aarch64--linux-gnueabi"
     16 
     17 ; CHECK: function 'f':
     18 ; CHECK: (Low: (20000 + %a) High: (60000 + %a))
     19 
     20 @B = common global i32* null, align 8
     21 @A = common global i32* null, align 8
     22 
     23 define void @f() {
     24 entry:
     25   %a = load i32*, i32** @A, align 8
     26   %b = load i32*, i32** @B, align 8
     27   br label %for.body
     28 
     29 for.body:                                         ; preds = %for.body, %entry
     30   %idx = phi i64 [ 0, %entry ], [ %add, %for.body ]
     31   %negidx = sub i64 15000, %idx
     32 
     33   %arrayidxA0 = getelementptr inbounds i32, i32* %a, i64 %negidx
     34   %loadA0 = load i32, i32* %arrayidxA0, align 2
     35 
     36   %res = mul i32 %loadA0, 3
     37 
     38   %add = add nuw nsw i64 %idx, 1
     39 
     40   %arrayidxB = getelementptr inbounds i32, i32* %b, i64 %idx
     41   store i32 %res, i32* %arrayidxB, align 2
     42 
     43   %exitcond = icmp eq i64 %idx, 10000
     44   br i1 %exitcond, label %for.end, label %for.body
     45 
     46 for.end:                                          ; preds = %for.body
     47   ret void
     48 }
     49 
     50 ; CHECK: function 'g':
     51 ; When the stride is not constant, we are forced to do umin/umax to get
     52 ; the interval limits.
     53 
     54 ;   for (i = 0; i < 10000; i++) {
     55 ;     B[i] = A[15000 - step * i] * 3;
     56 ;   }
     57 
     58 ; Here it is not obvious what the limits are, since 'step' could be negative.
     59 
     60 ; CHECK: Low: (-1 + (-1 * ((-60001 + (-1 * %a)) umax (-60001 + (40000 * %step) + (-1 * %a)))))
     61 ; CHECK: High: ((60000 + %a) umax (60000 + (-40000 * %step) + %a))
     62 
     63 define void @g(i64 %step) {
     64 entry:
     65   %a = load i32*, i32** @A, align 8
     66   %b = load i32*, i32** @B, align 8
     67   br label %for.body
     68 
     69 for.body:                                         ; preds = %for.body, %entry
     70   %idx = phi i64 [ 0, %entry ], [ %add, %for.body ]
     71   %idx_mul = mul i64 %idx, %step
     72   %negidx = sub i64 15000, %idx_mul
     73 
     74   %arrayidxA0 = getelementptr inbounds i32, i32* %a, i64 %negidx
     75   %loadA0 = load i32, i32* %arrayidxA0, align 2
     76 
     77   %res = mul i32 %loadA0, 3
     78 
     79   %add = add nuw nsw i64 %idx, 1
     80 
     81   %arrayidxB = getelementptr inbounds i32, i32* %b, i64 %idx
     82   store i32 %res, i32* %arrayidxB, align 2
     83 
     84   %exitcond = icmp eq i64 %idx, 10000
     85   br i1 %exitcond, label %for.end, label %for.body
     86 
     87 for.end:                                          ; preds = %for.body
     88   ret void
     89 }
     90