148 lines · plain
1; RUN: opt -S < %s -passes=loop-vectorize -force-vector-interleave=2 -force-vector-width=4 | FileCheck %s2; RUN: opt -S < %s -passes=loop-vectorize -force-vector-interleave=1 -force-vector-width=2 | FileCheck %s --check-prefix=FORCE-VEC3 4target datalayout = "e-m:e-i64:64-i128:128-n32:64-S128"5target triple = "aarch64"6 7; Test integer induction variable of step 2:8; for (int i = 0; i < 1024; i+=2) {9; int tmp = *A++;10; sum += i * tmp;11; }12 13; CHECK-LABEL: @ind_plus2(14; CHECK: load <4 x i32>, ptr15; CHECK: load <4 x i32>, ptr16; CHECK: mul nsw <4 x i32>17; CHECK: mul nsw <4 x i32>18; CHECK: add <4 x i32>19; CHECK: add <4 x i32>20; CHECK: %index.next = add nuw i64 %index, 821; CHECK: icmp eq i64 %index.next, 51222 23; FORCE-VEC-LABEL: @ind_plus2(24; FORCE-VEC: %wide.load = load <2 x i32>, ptr25; FORCE-VEC: mul nsw <2 x i32>26; FORCE-VEC: add <2 x i32>27; FORCE-VEC: %index.next = add nuw i64 %index, 228; FORCE-VEC: icmp eq i64 %index.next, 51229define i32 @ind_plus2(ptr %A) {30entry:31 br label %for.body32 33for.body: ; preds = %entry, %for.body34 %A.addr = phi ptr [ %A, %entry ], [ %inc.ptr, %for.body ]35 %i = phi i32 [ 0, %entry ], [ %add1, %for.body ]36 %sum = phi i32 [ 0, %entry ], [ %add, %for.body ]37 %inc.ptr = getelementptr inbounds i32, ptr %A.addr, i64 138 %0 = load i32, ptr %A.addr, align 439 %mul = mul nsw i32 %0, %i40 %add = add nsw i32 %mul, %sum41 %add1 = add nsw i32 %i, 242 %cmp = icmp slt i32 %add1, 102443 br i1 %cmp, label %for.body, label %for.end44 45for.end: ; preds = %for.body46 %add.lcssa = phi i32 [ %add, %for.body ]47 ret i32 %add.lcssa48}49 50 51; Test integer induction variable of step -2:52; for (int i = 1024; i > 0; i-=2) {53; int tmp = *A++;54; sum += i * tmp;55; }56 57; CHECK-LABEL: @ind_minus2(58; CHECK: load <4 x i32>, ptr59; CHECK: load <4 x i32>, ptr60; CHECK: mul nsw <4 x i32>61; CHECK: mul nsw <4 x i32>62; CHECK: add <4 x i32>63; CHECK: add <4 x i32>64; CHECK: %index.next = add nuw i64 %index, 865; CHECK: icmp eq i64 %index.next, 51266 67; FORCE-VEC-LABEL: @ind_minus2(68; FORCE-VEC: %wide.load = load <2 x i32>, ptr69; FORCE-VEC: mul nsw <2 x i32>70; FORCE-VEC: add <2 x i32>71; FORCE-VEC: %index.next = add nuw i64 %index, 272; FORCE-VEC: icmp eq i64 %index.next, 51273define i32 @ind_minus2(ptr %A) {74entry:75 br label %for.body76 77for.body: ; preds = %entry, %for.body78 %A.addr = phi ptr [ %A, %entry ], [ %inc.ptr, %for.body ]79 %i = phi i32 [ 1024, %entry ], [ %sub, %for.body ]80 %sum = phi i32 [ 0, %entry ], [ %add, %for.body ]81 %inc.ptr = getelementptr inbounds i32, ptr %A.addr, i64 182 %0 = load i32, ptr %A.addr, align 483 %mul = mul nsw i32 %0, %i84 %add = add nsw i32 %mul, %sum85 %sub = add nsw i32 %i, -286 %cmp = icmp sgt i32 %i, 287 br i1 %cmp, label %for.body, label %for.end88 89for.end: ; preds = %for.body90 %add.lcssa = phi i32 [ %add, %for.body ]91 ret i32 %add.lcssa92}93 94 95; Test pointer induction variable of step 2. As currently we don't support96; masked load/store, vectorization is possible but not beneficial. If loop97; vectorization is not enforced, LV will only do interleave.98; for (int i = 0; i < 1024; i++) {99; int tmp0 = *A++;100; int tmp1 = *A++;101; sum += tmp0 * tmp1;102; }103 104; CHECK-LABEL: @ptr_ind_plus2(105; CHECK: %[[V0:.*]] = load <8 x i32>106; CHECK: shufflevector <8 x i32> %[[V0]], <8 x i32> poison, <4 x i32> <i32 0, i32 2, i32 4, i32 6>107; CHECK: shufflevector <8 x i32> %[[V0]], <8 x i32> poison, <4 x i32> <i32 1, i32 3, i32 5, i32 7>108; CHECK: %[[V1:.*]] = load <8 x i32>109; CHECK: shufflevector <8 x i32> %[[V1]], <8 x i32> poison, <4 x i32> <i32 0, i32 2, i32 4, i32 6>110; CHECK: shufflevector <8 x i32> %[[V1]], <8 x i32> poison, <4 x i32> <i32 1, i32 3, i32 5, i32 7>111; CHECK: mul nsw <4 x i32>112; CHECK: mul nsw <4 x i32>113; CHECK: add <4 x i32>114; CHECK: add <4 x i32>115; CHECK: %index.next = add nuw i64 %index, 8116; CHECK: icmp eq i64 %index.next, 1024117 118; FORCE-VEC-LABEL: @ptr_ind_plus2(119; FORCE-VEC: %[[V:.*]] = load <4 x i32>120; FORCE-VEC: shufflevector <4 x i32> %[[V]], <4 x i32> poison, <2 x i32> <i32 0, i32 2>121; FORCE-VEC: shufflevector <4 x i32> %[[V]], <4 x i32> poison, <2 x i32> <i32 1, i32 3>122; FORCE-VEC: mul nsw <2 x i32>123; FORCE-VEC: add <2 x i32>124; FORCE-VEC: %index.next = add nuw i64 %index, 2125; FORCE-VEC: icmp eq i64 %index.next, 1024126define i32 @ptr_ind_plus2(ptr %A) {127entry:128 br label %for.body129 130for.body: ; preds = %for.body, %entry131 %A.addr = phi ptr [ %A, %entry ], [ %inc.ptr1, %for.body ]132 %sum = phi i32 [ 0, %entry ], [ %add, %for.body ]133 %i = phi i32 [ 0, %entry ], [ %inc, %for.body ]134 %inc.ptr = getelementptr inbounds i32, ptr %A.addr, i64 1135 %0 = load i32, ptr %A.addr, align 4136 %inc.ptr1 = getelementptr inbounds i32, ptr %A.addr, i64 2137 %1 = load i32, ptr %inc.ptr, align 4138 %mul = mul nsw i32 %1, %0139 %add = add nsw i32 %mul, %sum140 %inc = add nsw i32 %i, 1141 %exitcond = icmp eq i32 %inc, 1024142 br i1 %exitcond, label %for.end, label %for.body143 144for.end: ; preds = %for.body145 %add.lcssa = phi i32 [ %add, %for.body ]146 ret i32 %add.lcssa147}148