Home | History | Annotate | Download | only in AArch64
      1 ; RUN: opt -slp-vectorizer -slp-threshold=-6 -S <  %s | FileCheck %s
      2 
      3 ; FIXME: The threshold is changed to keep this test case a bit smaller.
      4 ; The AArch64 cost model should not give such high costs to select statements.
      5 
      6 target datalayout = "e-m:e-i64:64-i128:128-n32:64-S128"
      7 target triple = "aarch64--linux"
      8 
      9 ; CHECK-LABEL: test_select
     10 ; CHECK: load <4 x i32>
     11 ; CHECK: load <4 x i32>
     12 ; CHECK: select <4 x i1>
     13 define i32 @test_select(i32* noalias nocapture readonly %blk1, i32* noalias nocapture readonly %blk2, i32 %lx, i32 %h) {
     14 entry:
     15   %cmp.22 = icmp sgt i32 %h, 0
     16   br i1 %cmp.22, label %for.body.lr.ph, label %for.end
     17 
     18 for.body.lr.ph:                                   ; preds = %entry
     19   %idx.ext = sext i32 %lx to i64
     20   br label %for.body
     21 
     22 for.body:                                         ; preds = %for.body, %for.body.lr.ph
     23   %s.026 = phi i32 [ 0, %for.body.lr.ph ], [ %add27, %for.body ]
     24   %j.025 = phi i32 [ 0, %for.body.lr.ph ], [ %inc, %for.body ]
     25   %p2.024 = phi i32* [ %blk2, %for.body.lr.ph ], [ %add.ptr29, %for.body ]
     26   %p1.023 = phi i32* [ %blk1, %for.body.lr.ph ], [ %add.ptr, %for.body ]
     27   %0 = load i32, i32* %p1.023, align 4
     28   %1 = load i32, i32* %p2.024, align 4
     29   %sub = sub nsw i32 %0, %1
     30   %cmp2 = icmp slt i32 %sub, 0
     31   %sub3 = sub nsw i32 0, %sub
     32   %sub3.sub = select i1 %cmp2, i32 %sub3, i32 %sub
     33   %add = add nsw i32 %sub3.sub, %s.026
     34   %arrayidx4 = getelementptr inbounds i32, i32* %p1.023, i64 1
     35   %2 = load i32, i32* %arrayidx4, align 4
     36   %arrayidx5 = getelementptr inbounds i32, i32* %p2.024, i64 1
     37   %3 = load i32, i32* %arrayidx5, align 4
     38   %sub6 = sub nsw i32 %2, %3
     39   %cmp7 = icmp slt i32 %sub6, 0
     40   %sub9 = sub nsw i32 0, %sub6
     41   %v.1 = select i1 %cmp7, i32 %sub9, i32 %sub6
     42   %add11 = add nsw i32 %add, %v.1
     43   %arrayidx12 = getelementptr inbounds i32, i32* %p1.023, i64 2
     44   %4 = load i32, i32* %arrayidx12, align 4
     45   %arrayidx13 = getelementptr inbounds i32, i32* %p2.024, i64 2
     46   %5 = load i32, i32* %arrayidx13, align 4
     47   %sub14 = sub nsw i32 %4, %5
     48   %cmp15 = icmp slt i32 %sub14, 0
     49   %sub17 = sub nsw i32 0, %sub14
     50   %sub17.sub14 = select i1 %cmp15, i32 %sub17, i32 %sub14
     51   %add19 = add nsw i32 %add11, %sub17.sub14
     52   %arrayidx20 = getelementptr inbounds i32, i32* %p1.023, i64 3
     53   %6 = load i32, i32* %arrayidx20, align 4
     54   %arrayidx21 = getelementptr inbounds i32, i32* %p2.024, i64 3
     55   %7 = load i32, i32* %arrayidx21, align 4
     56   %sub22 = sub nsw i32 %6, %7
     57   %cmp23 = icmp slt i32 %sub22, 0
     58   %sub25 = sub nsw i32 0, %sub22
     59   %v.3 = select i1 %cmp23, i32 %sub25, i32 %sub22
     60   %add27 = add nsw i32 %add19, %v.3
     61   %add.ptr = getelementptr inbounds i32, i32* %p1.023, i64 %idx.ext
     62   %add.ptr29 = getelementptr inbounds i32, i32* %p2.024, i64 %idx.ext
     63   %inc = add nuw nsw i32 %j.025, 1
     64   %exitcond = icmp eq i32 %inc, %h
     65   br i1 %exitcond, label %for.end.loopexit, label %for.body
     66 
     67 for.end.loopexit:                                 ; preds = %for.body
     68   br label %for.end
     69 
     70 for.end:                                          ; preds = %for.end.loopexit, %entry
     71   %s.0.lcssa = phi i32 [ 0, %entry ], [ %add27, %for.end.loopexit ]
     72   ret i32 %s.0.lcssa
     73 }
     74 
     75 ;; Check whether SLP can find a reduction phi whose incoming blocks are not
     76 ;; the same as the block containing the phi.
     77 ;;
     78 ;; Came from code like,
     79 ;;
     80 ;; int s = 0;
     81 ;; for (int j = 0; j < h; j++) {
     82 ;;   s += p1[0] * p2[0]
     83 ;;   s += p1[1] * p2[1];
     84 ;;   s += p1[2] * p2[2];
     85 ;;   s += p1[3] * p2[3];
     86 ;;   if (s >= lim)
     87 ;;      break;
     88 ;;   p1 += lx;
     89 ;;   p2 += lx;
     90 ;; }
     91 define i32 @reduction_with_br(i32* noalias nocapture readonly %blk1, i32* noalias nocapture readonly %blk2, i32 %lx, i32 %h, i32 %lim) {
     92 ; CHECK-LABEL: reduction_with_br
     93 ; CHECK: load <4 x i32>
     94 ; CHECK: load <4 x i32>
     95 ; CHECK: mul nsw <4 x i32>
     96 entry:
     97   %cmp.16 = icmp sgt i32 %h, 0
     98   br i1 %cmp.16, label %for.body.lr.ph, label %for.end
     99 
    100 for.body.lr.ph:                                   ; preds = %entry
    101   %idx.ext = sext i32 %lx to i64
    102   br label %for.body
    103 
    104 for.body:                                         ; preds = %for.body.lr.ph, %if.end
    105   %s.020 = phi i32 [ 0, %for.body.lr.ph ], [ %add13, %if.end ]
    106   %j.019 = phi i32 [ 0, %for.body.lr.ph ], [ %inc, %if.end ]
    107   %p2.018 = phi i32* [ %blk2, %for.body.lr.ph ], [ %add.ptr16, %if.end ]
    108   %p1.017 = phi i32* [ %blk1, %for.body.lr.ph ], [ %add.ptr, %if.end ]
    109   %0 = load i32, i32* %p1.017, align 4
    110   %1 = load i32, i32* %p2.018, align 4
    111   %mul = mul nsw i32 %1, %0
    112   %add = add nsw i32 %mul, %s.020
    113   %arrayidx2 = getelementptr inbounds i32, i32* %p1.017, i64 1
    114   %2 = load i32, i32* %arrayidx2, align 4
    115   %arrayidx3 = getelementptr inbounds i32, i32* %p2.018, i64 1
    116   %3 = load i32, i32* %arrayidx3, align 4
    117   %mul4 = mul nsw i32 %3, %2
    118   %add5 = add nsw i32 %add, %mul4
    119   %arrayidx6 = getelementptr inbounds i32, i32* %p1.017, i64 2
    120   %4 = load i32, i32* %arrayidx6, align 4
    121   %arrayidx7 = getelementptr inbounds i32, i32* %p2.018, i64 2
    122   %5 = load i32, i32* %arrayidx7, align 4
    123   %mul8 = mul nsw i32 %5, %4
    124   %add9 = add nsw i32 %add5, %mul8
    125   %arrayidx10 = getelementptr inbounds i32, i32* %p1.017, i64 3
    126   %6 = load i32, i32* %arrayidx10, align 4
    127   %arrayidx11 = getelementptr inbounds i32, i32* %p2.018, i64 3
    128   %7 = load i32, i32* %arrayidx11, align 4
    129   %mul12 = mul nsw i32 %7, %6
    130   %add13 = add nsw i32 %add9, %mul12
    131   %cmp14 = icmp slt i32 %add13, %lim
    132   br i1 %cmp14, label %if.end, label %for.end.loopexit
    133 
    134 if.end:                                           ; preds = %for.body
    135   %add.ptr = getelementptr inbounds i32, i32* %p1.017, i64 %idx.ext
    136   %add.ptr16 = getelementptr inbounds i32, i32* %p2.018, i64 %idx.ext
    137   %inc = add nuw nsw i32 %j.019, 1
    138   %cmp = icmp slt i32 %inc, %h
    139   br i1 %cmp, label %for.body, label %for.end.loopexit
    140 
    141 for.end.loopexit:                                 ; preds = %for.body, %if.end
    142   br label %for.end
    143 
    144 for.end:                                          ; preds = %for.end.loopexit, %entry
    145   %s.1 = phi i32 [ 0, %entry ], [ %add13, %for.end.loopexit ]
    146   ret i32 %s.1
    147 }
    148 
    149 ; CHECK: test_unrolled_select
    150 ; CHECK: load <8 x i8>
    151 ; CHECK: load <8 x i8>
    152 ; CHECK: select <8 x i1>
    153 define i32 @test_unrolled_select(i8* noalias nocapture readonly %blk1, i8* noalias nocapture readonly %blk2, i32 %lx, i32 %h, i32 %lim) #0 {
    154 entry:
    155   %cmp.43 = icmp sgt i32 %h, 0
    156   br i1 %cmp.43, label %for.body.lr.ph, label %for.end
    157 
    158 for.body.lr.ph:                                   ; preds = %entry
    159   %idx.ext = sext i32 %lx to i64
    160   br label %for.body
    161 
    162 for.body:                                         ; preds = %for.body.lr.ph, %if.end.86
    163   %s.047 = phi i32 [ 0, %for.body.lr.ph ], [ %add82, %if.end.86 ]
    164   %j.046 = phi i32 [ 0, %for.body.lr.ph ], [ %inc, %if.end.86 ]
    165   %p2.045 = phi i8* [ %blk2, %for.body.lr.ph ], [ %add.ptr88, %if.end.86 ]
    166   %p1.044 = phi i8* [ %blk1, %for.body.lr.ph ], [ %add.ptr, %if.end.86 ]
    167   %0 = load i8, i8* %p1.044, align 1
    168   %conv = zext i8 %0 to i32
    169   %1 = load i8, i8* %p2.045, align 1
    170   %conv2 = zext i8 %1 to i32
    171   %sub = sub nsw i32 %conv, %conv2
    172   %cmp3 = icmp slt i32 %sub, 0
    173   %sub5 = sub nsw i32 0, %sub
    174   %sub5.sub = select i1 %cmp3, i32 %sub5, i32 %sub
    175   %add = add nsw i32 %sub5.sub, %s.047
    176   %arrayidx6 = getelementptr inbounds i8, i8* %p1.044, i64 1
    177   %2 = load i8, i8* %arrayidx6, align 1
    178   %conv7 = zext i8 %2 to i32
    179   %arrayidx8 = getelementptr inbounds i8, i8* %p2.045, i64 1
    180   %3 = load i8, i8* %arrayidx8, align 1
    181   %conv9 = zext i8 %3 to i32
    182   %sub10 = sub nsw i32 %conv7, %conv9
    183   %cmp11 = icmp slt i32 %sub10, 0
    184   %sub14 = sub nsw i32 0, %sub10
    185   %v.1 = select i1 %cmp11, i32 %sub14, i32 %sub10
    186   %add16 = add nsw i32 %add, %v.1
    187   %arrayidx17 = getelementptr inbounds i8, i8* %p1.044, i64 2
    188   %4 = load i8, i8* %arrayidx17, align 1
    189   %conv18 = zext i8 %4 to i32
    190   %arrayidx19 = getelementptr inbounds i8, i8* %p2.045, i64 2
    191   %5 = load i8, i8* %arrayidx19, align 1
    192   %conv20 = zext i8 %5 to i32
    193   %sub21 = sub nsw i32 %conv18, %conv20
    194   %cmp22 = icmp slt i32 %sub21, 0
    195   %sub25 = sub nsw i32 0, %sub21
    196   %sub25.sub21 = select i1 %cmp22, i32 %sub25, i32 %sub21
    197   %add27 = add nsw i32 %add16, %sub25.sub21
    198   %arrayidx28 = getelementptr inbounds i8, i8* %p1.044, i64 3
    199   %6 = load i8, i8* %arrayidx28, align 1
    200   %conv29 = zext i8 %6 to i32
    201   %arrayidx30 = getelementptr inbounds i8, i8* %p2.045, i64 3
    202   %7 = load i8, i8* %arrayidx30, align 1
    203   %conv31 = zext i8 %7 to i32
    204   %sub32 = sub nsw i32 %conv29, %conv31
    205   %cmp33 = icmp slt i32 %sub32, 0
    206   %sub36 = sub nsw i32 0, %sub32
    207   %v.3 = select i1 %cmp33, i32 %sub36, i32 %sub32
    208   %add38 = add nsw i32 %add27, %v.3
    209   %arrayidx39 = getelementptr inbounds i8, i8* %p1.044, i64 4
    210   %8 = load i8, i8* %arrayidx39, align 1
    211   %conv40 = zext i8 %8 to i32
    212   %arrayidx41 = getelementptr inbounds i8, i8* %p2.045, i64 4
    213   %9 = load i8, i8* %arrayidx41, align 1
    214   %conv42 = zext i8 %9 to i32
    215   %sub43 = sub nsw i32 %conv40, %conv42
    216   %cmp44 = icmp slt i32 %sub43, 0
    217   %sub47 = sub nsw i32 0, %sub43
    218   %sub47.sub43 = select i1 %cmp44, i32 %sub47, i32 %sub43
    219   %add49 = add nsw i32 %add38, %sub47.sub43
    220   %arrayidx50 = getelementptr inbounds i8, i8* %p1.044, i64 5
    221   %10 = load i8, i8* %arrayidx50, align 1
    222   %conv51 = zext i8 %10 to i32
    223   %arrayidx52 = getelementptr inbounds i8, i8* %p2.045, i64 5
    224   %11 = load i8, i8* %arrayidx52, align 1
    225   %conv53 = zext i8 %11 to i32
    226   %sub54 = sub nsw i32 %conv51, %conv53
    227   %cmp55 = icmp slt i32 %sub54, 0
    228   %sub58 = sub nsw i32 0, %sub54
    229   %v.5 = select i1 %cmp55, i32 %sub58, i32 %sub54
    230   %add60 = add nsw i32 %add49, %v.5
    231   %arrayidx61 = getelementptr inbounds i8, i8* %p1.044, i64 6
    232   %12 = load i8, i8* %arrayidx61, align 1
    233   %conv62 = zext i8 %12 to i32
    234   %arrayidx63 = getelementptr inbounds i8, i8* %p2.045, i64 6
    235   %13 = load i8, i8* %arrayidx63, align 1
    236   %conv64 = zext i8 %13 to i32
    237   %sub65 = sub nsw i32 %conv62, %conv64
    238   %cmp66 = icmp slt i32 %sub65, 0
    239   %sub69 = sub nsw i32 0, %sub65
    240   %sub69.sub65 = select i1 %cmp66, i32 %sub69, i32 %sub65
    241   %add71 = add nsw i32 %add60, %sub69.sub65
    242   %arrayidx72 = getelementptr inbounds i8, i8* %p1.044, i64 7
    243   %14 = load i8, i8* %arrayidx72, align 1
    244   %conv73 = zext i8 %14 to i32
    245   %arrayidx74 = getelementptr inbounds i8, i8* %p2.045, i64 7
    246   %15 = load i8, i8* %arrayidx74, align 1
    247   %conv75 = zext i8 %15 to i32
    248   %sub76 = sub nsw i32 %conv73, %conv75
    249   %cmp77 = icmp slt i32 %sub76, 0
    250   %sub80 = sub nsw i32 0, %sub76
    251   %v.7 = select i1 %cmp77, i32 %sub80, i32 %sub76
    252   %add82 = add nsw i32 %add71, %v.7
    253   %cmp83 = icmp slt i32 %add82, %lim
    254   br i1 %cmp83, label %if.end.86, label %for.end.loopexit
    255 
    256 if.end.86:                                        ; preds = %for.body
    257   %add.ptr = getelementptr inbounds i8, i8* %p1.044, i64 %idx.ext
    258   %add.ptr88 = getelementptr inbounds i8, i8* %p2.045, i64 %idx.ext
    259   %inc = add nuw nsw i32 %j.046, 1
    260   %cmp = icmp slt i32 %inc, %h
    261   br i1 %cmp, label %for.body, label %for.end.loopexit
    262 
    263 for.end.loopexit:                                 ; preds = %for.body, %if.end.86
    264   br label %for.end
    265 
    266 for.end:                                          ; preds = %for.end.loopexit, %entry
    267   %s.1 = phi i32 [ 0, %entry ], [ %add82, %for.end.loopexit ]
    268   ret i32 %s.1
    269 }
    270 
    271