Home | History | Annotate | Download | only in AArch64
      1 ; RUN: opt -mtriple=aarch64--linux-gnueabi -loop-vectorize -force-vector-width=4 -force-vector-interleave=1 < %s -S | FileCheck %s
      2 
      3 ; The following tests contain loops for which SCEV cannot determine the backedge
      4 ; taken count. This is because the backedge taken condition is produced by an
      5 ; icmp with one of the sides being a loop varying non-AddRec expression.
      6 ; However, there is a possibility to normalize this to an AddRec expression
      7 ; using SCEV predicates. This allows us to compute a 'guarded' backedge count.
      8 ; The Loop Vectorizer is able to version to loop in order to use this guarded
      9 ; backedge count and vectorize more loops.
     10 
     11 
     12 ; CHECK-LABEL: test_sge
     13 ; CHECK-LABEL: vector.scevcheck
     14 ; CHECK-LABEL: vector.body
     15 define void @test_sge(i32* noalias %A,
     16                       i32* noalias %B,
     17                       i32* noalias %C, i32 %N) {
     18 entry:
     19   %cmp13 = icmp eq i32 %N, 0
     20   br i1 %cmp13, label %for.end, label %for.body.preheader
     21 
     22 for.body.preheader:
     23   br label %for.body
     24 
     25 for.body:
     26   %indvars.iv = phi i16 [ %indvars.next, %for.body ], [ 0, %for.body.preheader ]
     27   %indvars.next = add i16 %indvars.iv, 1
     28   %indvars.ext = zext i16 %indvars.iv to i32
     29 
     30   %arrayidx = getelementptr inbounds i32, i32* %B, i32 %indvars.ext
     31   %0 = load i32, i32* %arrayidx, align 4
     32   %arrayidx3 = getelementptr inbounds i32, i32* %C, i32 %indvars.ext
     33   %1 = load i32, i32* %arrayidx3, align 4
     34 
     35   %mul4 = mul i32 %1, %0
     36 
     37   %arrayidx7 = getelementptr inbounds i32, i32* %A, i32 %indvars.ext
     38   store i32 %mul4, i32* %arrayidx7, align 4
     39 
     40   %exitcond = icmp sge i32 %indvars.ext, %N
     41   br i1 %exitcond, label %for.end.loopexit, label %for.body
     42 
     43 for.end.loopexit:
     44   br label %for.end
     45 
     46 for.end:
     47   ret void
     48 }
     49 
     50 ; CHECK-LABEL: test_uge
     51 ; CHECK-LABEL: vector.scevcheck
     52 ; CHECK-LABEL: vector.body
     53 define void @test_uge(i32* noalias %A,
     54                       i32* noalias %B,
     55                       i32* noalias %C, i32 %N, i32 %Offset) {
     56 entry:
     57   %cmp13 = icmp eq i32 %N, 0
     58   br i1 %cmp13, label %for.end, label %for.body.preheader
     59 
     60 for.body.preheader:
     61   br label %for.body
     62 
     63 for.body:
     64   %indvars.iv = phi i16 [ %indvars.next, %for.body ], [ 0, %for.body.preheader ]
     65   %indvars.next = add i16 %indvars.iv, 1
     66 
     67   %indvars.ext = sext i16 %indvars.iv to i32
     68   %indvars.access = add i32 %Offset, %indvars.ext
     69 
     70   %arrayidx = getelementptr inbounds i32, i32* %B, i32 %indvars.access
     71   %0 = load i32, i32* %arrayidx, align 4
     72   %arrayidx3 = getelementptr inbounds i32, i32* %C, i32 %indvars.access
     73   %1 = load i32, i32* %arrayidx3, align 4
     74 
     75   %mul4 = add i32 %1, %0
     76 
     77   %arrayidx7 = getelementptr inbounds i32, i32* %A, i32 %indvars.access
     78   store i32 %mul4, i32* %arrayidx7, align 4
     79 
     80   %exitcond = icmp uge i32 %indvars.ext, %N
     81   br i1 %exitcond, label %for.end.loopexit, label %for.body
     82 
     83 for.end.loopexit:
     84   br label %for.end
     85 
     86 for.end:
     87   ret void
     88 }
     89 
     90 ; CHECK-LABEL: test_ule
     91 ; CHECK-LABEL: vector.scevcheck
     92 ; CHECK-LABEL: vector.body
     93 define void @test_ule(i32* noalias %A,
     94                       i32* noalias %B,
     95                       i32* noalias %C, i32 %N,
     96                       i16 %M) {
     97 entry:
     98   %cmp13 = icmp eq i32 %N, 0
     99   br i1 %cmp13, label %for.end, label %for.body.preheader
    100 
    101 for.body.preheader:
    102   br label %for.body
    103 
    104 for.body:
    105   %indvars.iv = phi i16 [ %indvars.next, %for.body ], [ %M, %for.body.preheader ]
    106   %indvars.next = sub i16 %indvars.iv, 1
    107   %indvars.ext = zext i16 %indvars.iv to i32
    108 
    109   %arrayidx = getelementptr inbounds i32, i32* %B, i32 %indvars.ext
    110   %0 = load i32, i32* %arrayidx, align 4
    111   %arrayidx3 = getelementptr inbounds i32, i32* %C, i32 %indvars.ext
    112   %1 = load i32, i32* %arrayidx3, align 4
    113 
    114   %mul4 = mul i32 %1, %0
    115 
    116   %arrayidx7 = getelementptr inbounds i32, i32* %A, i32 %indvars.ext
    117   store i32 %mul4, i32* %arrayidx7, align 4
    118 
    119   %exitcond = icmp ule i32 %indvars.ext, %N
    120   br i1 %exitcond, label %for.end.loopexit, label %for.body
    121 
    122 for.end.loopexit:
    123   br label %for.end
    124 
    125 for.end:
    126   ret void
    127 }
    128 
    129 ; CHECK-LABEL: test_sle
    130 ; CHECK-LABEL: vector.scevcheck
    131 ; CHECK-LABEL: vector.body
    132 define void @test_sle(i32* noalias %A,
    133                    i32* noalias %B,
    134                    i32* noalias %C, i32 %N,
    135                    i16 %M) {
    136 entry:
    137   %cmp13 = icmp eq i32 %N, 0
    138   br i1 %cmp13, label %for.end, label %for.body.preheader
    139 
    140 for.body.preheader:
    141   br label %for.body
    142 
    143 for.body:
    144   %indvars.iv = phi i16 [ %indvars.next, %for.body ], [ %M, %for.body.preheader ]
    145   %indvars.next = sub i16 %indvars.iv, 1
    146   %indvars.ext = sext i16 %indvars.iv to i32
    147 
    148   %arrayidx = getelementptr inbounds i32, i32* %B, i32 %indvars.ext
    149   %0 = load i32, i32* %arrayidx, align 4
    150   %arrayidx3 = getelementptr inbounds i32, i32* %C, i32 %indvars.ext
    151   %1 = load i32, i32* %arrayidx3, align 4
    152 
    153   %mul4 = mul i32 %1, %0
    154 
    155   %arrayidx7 = getelementptr inbounds i32, i32* %A, i32 %indvars.ext
    156   store i32 %mul4, i32* %arrayidx7, align 4
    157 
    158   %exitcond = icmp sle i32 %indvars.ext, %N
    159   br i1 %exitcond, label %for.end.loopexit, label %for.body
    160 
    161 for.end.loopexit:
    162   br label %for.end
    163 
    164 for.end:
    165   ret void
    166 }
    167