1; RUN: opt < %s -loop-vectorize -force-vector-width=4 -dce -instcombine -licm -S | FileCheck %s 2 3target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" 4target triple = "x86_64-apple-macosx10.8.0" 5 6;CHECK: @reduction_sum 7;CHECK: phi <4 x i32> 8;CHECK: load <4 x i32> 9;CHECK: add <4 x i32> 10;CHECK: ret i32 11define i32 @reduction_sum(i32 %n, i32* noalias nocapture %A, i32* noalias nocapture %B) nounwind uwtable readonly noinline ssp { 12 %1 = icmp sgt i32 %n, 0 13 br i1 %1, label %.lr.ph, label %._crit_edge 14 15.lr.ph: ; preds = %0, %.lr.ph 16 %indvars.iv = phi i64 [ %indvars.iv.next, %.lr.ph ], [ 0, %0 ] 17 %sum.02 = phi i32 [ %9, %.lr.ph ], [ 0, %0 ] 18 %2 = getelementptr inbounds i32* %A, i64 %indvars.iv 19 %3 = load i32* %2, align 4 20 %4 = getelementptr inbounds i32* %B, i64 %indvars.iv 21 %5 = load i32* %4, align 4 22 %6 = trunc i64 %indvars.iv to i32 23 %7 = add i32 %sum.02, %6 24 %8 = add i32 %7, %3 25 %9 = add i32 %8, %5 26 %indvars.iv.next = add i64 %indvars.iv, 1 27 %lftr.wideiv = trunc i64 %indvars.iv.next to i32 28 %exitcond = icmp eq i32 %lftr.wideiv, %n 29 br i1 %exitcond, label %._crit_edge, label %.lr.ph 30 31._crit_edge: ; preds = %.lr.ph, %0 32 %sum.0.lcssa = phi i32 [ 0, %0 ], [ %9, %.lr.ph ] 33 ret i32 %sum.0.lcssa 34} 35 36;CHECK: @reduction_prod 37;CHECK: phi <4 x i32> 38;CHECK: load <4 x i32> 39;CHECK: mul <4 x i32> 40;CHECK: ret i32 41define i32 @reduction_prod(i32 %n, i32* noalias nocapture %A, i32* noalias nocapture %B) nounwind uwtable readonly noinline ssp { 42 %1 = icmp sgt i32 %n, 0 43 br i1 %1, label %.lr.ph, label %._crit_edge 44 45.lr.ph: ; preds = %0, %.lr.ph 46 %indvars.iv = phi i64 [ %indvars.iv.next, %.lr.ph ], [ 0, %0 ] 47 %prod.02 = phi i32 [ %9, %.lr.ph ], [ 1, %0 ] 48 %2 = getelementptr inbounds i32* %A, i64 %indvars.iv 49 %3 = load i32* %2, align 4 50 %4 = getelementptr inbounds i32* %B, i64 %indvars.iv 51 %5 = load i32* %4, align 4 52 %6 = trunc i64 %indvars.iv to i32 53 %7 = mul i32 %prod.02, %6 54 %8 = mul i32 %7, %3 55 %9 = mul i32 %8, %5 56 %indvars.iv.next = add i64 %indvars.iv, 1 57 %lftr.wideiv = trunc i64 %indvars.iv.next to i32 58 %exitcond = icmp eq i32 %lftr.wideiv, %n 59 br i1 %exitcond, label %._crit_edge, label %.lr.ph 60 61._crit_edge: ; preds = %.lr.ph, %0 62 %prod.0.lcssa = phi i32 [ 1, %0 ], [ %9, %.lr.ph ] 63 ret i32 %prod.0.lcssa 64} 65 66;CHECK: @reduction_mix 67;CHECK: phi <4 x i32> 68;CHECK: load <4 x i32> 69;CHECK: mul nsw <4 x i32> 70;CHECK: ret i32 71define i32 @reduction_mix(i32 %n, i32* noalias nocapture %A, i32* noalias nocapture %B) nounwind uwtable readonly noinline ssp { 72 %1 = icmp sgt i32 %n, 0 73 br i1 %1, label %.lr.ph, label %._crit_edge 74 75.lr.ph: ; preds = %0, %.lr.ph 76 %indvars.iv = phi i64 [ %indvars.iv.next, %.lr.ph ], [ 0, %0 ] 77 %sum.02 = phi i32 [ %9, %.lr.ph ], [ 0, %0 ] 78 %2 = getelementptr inbounds i32* %A, i64 %indvars.iv 79 %3 = load i32* %2, align 4 80 %4 = getelementptr inbounds i32* %B, i64 %indvars.iv 81 %5 = load i32* %4, align 4 82 %6 = mul nsw i32 %5, %3 83 %7 = trunc i64 %indvars.iv to i32 84 %8 = add i32 %sum.02, %7 85 %9 = add i32 %8, %6 86 %indvars.iv.next = add i64 %indvars.iv, 1 87 %lftr.wideiv = trunc i64 %indvars.iv.next to i32 88 %exitcond = icmp eq i32 %lftr.wideiv, %n 89 br i1 %exitcond, label %._crit_edge, label %.lr.ph 90 91._crit_edge: ; preds = %.lr.ph, %0 92 %sum.0.lcssa = phi i32 [ 0, %0 ], [ %9, %.lr.ph ] 93 ret i32 %sum.0.lcssa 94} 95 96;CHECK: @reduction_mul 97;CHECK: mul <4 x i32> 98;CHECK: ret i32 99define i32 @reduction_mul(i32 %n, i32* noalias nocapture %A, i32* noalias nocapture %B) nounwind uwtable readonly noinline ssp { 100 %1 = icmp sgt i32 %n, 0 101 br i1 %1, label %.lr.ph, label %._crit_edge 102 103.lr.ph: ; preds = %0, %.lr.ph 104 %indvars.iv = phi i64 [ %indvars.iv.next, %.lr.ph ], [ 0, %0 ] 105 %sum.02 = phi i32 [ %9, %.lr.ph ], [ 19, %0 ] 106 %2 = getelementptr inbounds i32* %A, i64 %indvars.iv 107 %3 = load i32* %2, align 4 108 %4 = getelementptr inbounds i32* %B, i64 %indvars.iv 109 %5 = load i32* %4, align 4 110 %6 = trunc i64 %indvars.iv to i32 111 %7 = add i32 %3, %6 112 %8 = add i32 %7, %5 113 %9 = mul i32 %8, %sum.02 114 %indvars.iv.next = add i64 %indvars.iv, 1 115 %lftr.wideiv = trunc i64 %indvars.iv.next to i32 116 %exitcond = icmp eq i32 %lftr.wideiv, %n 117 br i1 %exitcond, label %._crit_edge, label %.lr.ph 118 119._crit_edge: ; preds = %.lr.ph, %0 120 %sum.0.lcssa = phi i32 [ 0, %0 ], [ %9, %.lr.ph ] 121 ret i32 %sum.0.lcssa 122} 123 124;CHECK: @start_at_non_zero 125;CHECK: phi <4 x i32> 126;CHECK: <i32 120, i32 0, i32 0, i32 0> 127;CHECK: ret i32 128define i32 @start_at_non_zero(i32* nocapture %in, i32* nocapture %coeff, i32* nocapture %out, i32 %n) nounwind uwtable readonly ssp { 129entry: 130 %cmp7 = icmp sgt i32 %n, 0 131 br i1 %cmp7, label %for.body, label %for.end 132 133for.body: ; preds = %entry, %for.body 134 %indvars.iv = phi i64 [ %indvars.iv.next, %for.body ], [ 0, %entry ] 135 %sum.09 = phi i32 [ %add, %for.body ], [ 120, %entry ] 136 %arrayidx = getelementptr inbounds i32* %in, i64 %indvars.iv 137 %0 = load i32* %arrayidx, align 4 138 %arrayidx2 = getelementptr inbounds i32* %coeff, i64 %indvars.iv 139 %1 = load i32* %arrayidx2, align 4 140 %mul = mul nsw i32 %1, %0 141 %add = add nsw i32 %mul, %sum.09 142 %indvars.iv.next = add i64 %indvars.iv, 1 143 %lftr.wideiv = trunc i64 %indvars.iv.next to i32 144 %exitcond = icmp eq i32 %lftr.wideiv, %n 145 br i1 %exitcond, label %for.end, label %for.body 146 147for.end: ; preds = %for.body, %entry 148 %sum.0.lcssa = phi i32 [ 120, %entry ], [ %add, %for.body ] 149 ret i32 %sum.0.lcssa 150} 151 152;CHECK: @reduction_and 153;CHECK: and <4 x i32> 154;CHECK: <i32 -1, i32 -1, i32 -1, i32 -1> 155;CHECK: ret i32 156define i32 @reduction_and(i32 %n, i32* nocapture %A, i32* nocapture %B) nounwind uwtable readonly { 157entry: 158 %cmp7 = icmp sgt i32 %n, 0 159 br i1 %cmp7, label %for.body, label %for.end 160 161for.body: ; preds = %entry, %for.body 162 %indvars.iv = phi i64 [ %indvars.iv.next, %for.body ], [ 0, %entry ] 163 %result.08 = phi i32 [ %and, %for.body ], [ -1, %entry ] 164 %arrayidx = getelementptr inbounds i32* %A, i64 %indvars.iv 165 %0 = load i32* %arrayidx, align 4 166 %arrayidx2 = getelementptr inbounds i32* %B, i64 %indvars.iv 167 %1 = load i32* %arrayidx2, align 4 168 %add = add nsw i32 %1, %0 169 %and = and i32 %add, %result.08 170 %indvars.iv.next = add i64 %indvars.iv, 1 171 %lftr.wideiv = trunc i64 %indvars.iv.next to i32 172 %exitcond = icmp eq i32 %lftr.wideiv, %n 173 br i1 %exitcond, label %for.end, label %for.body 174 175for.end: ; preds = %for.body, %entry 176 %result.0.lcssa = phi i32 [ -1, %entry ], [ %and, %for.body ] 177 ret i32 %result.0.lcssa 178} 179 180;CHECK: @reduction_or 181;CHECK: or <4 x i32> 182;CHECK: ret i32 183define i32 @reduction_or(i32 %n, i32* nocapture %A, i32* nocapture %B) nounwind uwtable readonly { 184entry: 185 %cmp7 = icmp sgt i32 %n, 0 186 br i1 %cmp7, label %for.body, label %for.end 187 188for.body: ; preds = %entry, %for.body 189 %indvars.iv = phi i64 [ %indvars.iv.next, %for.body ], [ 0, %entry ] 190 %result.08 = phi i32 [ %or, %for.body ], [ 0, %entry ] 191 %arrayidx = getelementptr inbounds i32* %A, i64 %indvars.iv 192 %0 = load i32* %arrayidx, align 4 193 %arrayidx2 = getelementptr inbounds i32* %B, i64 %indvars.iv 194 %1 = load i32* %arrayidx2, align 4 195 %add = add nsw i32 %1, %0 196 %or = or i32 %add, %result.08 197 %indvars.iv.next = add i64 %indvars.iv, 1 198 %lftr.wideiv = trunc i64 %indvars.iv.next to i32 199 %exitcond = icmp eq i32 %lftr.wideiv, %n 200 br i1 %exitcond, label %for.end, label %for.body 201 202for.end: ; preds = %for.body, %entry 203 %result.0.lcssa = phi i32 [ 0, %entry ], [ %or, %for.body ] 204 ret i32 %result.0.lcssa 205} 206 207;CHECK: @reduction_xor 208;CHECK: xor <4 x i32> 209;CHECK: ret i32 210define i32 @reduction_xor(i32 %n, i32* nocapture %A, i32* nocapture %B) nounwind uwtable readonly { 211entry: 212 %cmp7 = icmp sgt i32 %n, 0 213 br i1 %cmp7, label %for.body, label %for.end 214 215for.body: ; preds = %entry, %for.body 216 %indvars.iv = phi i64 [ %indvars.iv.next, %for.body ], [ 0, %entry ] 217 %result.08 = phi i32 [ %xor, %for.body ], [ 0, %entry ] 218 %arrayidx = getelementptr inbounds i32* %A, i64 %indvars.iv 219 %0 = load i32* %arrayidx, align 4 220 %arrayidx2 = getelementptr inbounds i32* %B, i64 %indvars.iv 221 %1 = load i32* %arrayidx2, align 4 222 %add = add nsw i32 %1, %0 223 %xor = xor i32 %add, %result.08 224 %indvars.iv.next = add i64 %indvars.iv, 1 225 %lftr.wideiv = trunc i64 %indvars.iv.next to i32 226 %exitcond = icmp eq i32 %lftr.wideiv, %n 227 br i1 %exitcond, label %for.end, label %for.body 228 229for.end: ; preds = %for.body, %entry 230 %result.0.lcssa = phi i32 [ 0, %entry ], [ %xor, %for.body ] 231 ret i32 %result.0.lcssa 232} 233