brintos

brintos / llvm-project-archived public Read only

0
0
Text · 14.1 KiB · 2579918 Raw
332 lines · plain
1; RUN: opt -mtriple armv7-linux-gnueabihf -passes=loop-vectorize -S %s -debug-only=loop-vectorize --disable-output -o /dev/null 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=LINUX2; RUN: opt -mtriple armv8-linux-gnu -passes=loop-vectorize -S %s -debug-only=loop-vectorize --disable-output -o /dev/null 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=LINUX3; RUN: opt -mtriple armv8.1.m-none-eabi -mattr=+mve.fp -passes=loop-vectorize -S %s -debug-only=loop-vectorize --disable-output -o /dev/null 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=MVE4; RUN: opt -mtriple armv7-unknwon-darwin -passes=loop-vectorize -S %s -debug-only=loop-vectorize --disable-output -o /dev/null 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=DARWIN5; REQUIRES: asserts6 7target datalayout = "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64"8 9; Testing the ability of the loop vectorizer to tell when SIMD is safe or not10; regarding IEEE 754 standard.11; On Linux, we only want the vectorizer to work when -ffast-math flag is set,12; because NEON is not IEEE compliant.13; Darwin, on the other hand, doesn't support subnormals, and all optimizations14; are allowed, even without -ffast-math.15 16; Integer loops are always vectorizeable17; CHECK: Checking a loop in 'sumi'18; CHECK: We can vectorize this loop!19define void @sumi(ptr noalias nocapture readonly %A, ptr noalias nocapture readonly %B, ptr noalias nocapture %C, i32 %N) {20entry:21  %cmp5 = icmp eq i32 %N, 022  br i1 %cmp5, label %for.end, label %for.body.preheader23 24for.body.preheader:                               ; preds = %entry25  br label %for.body26 27for.body:                                         ; preds = %for.body.preheader, %for.body28  %i.06 = phi i32 [ %inc, %for.body ], [ 0, %for.body.preheader ]29  %arrayidx = getelementptr inbounds i32, ptr %A, i32 %i.0630  %0 = load i32, ptr %arrayidx, align 431  %arrayidx1 = getelementptr inbounds i32, ptr %B, i32 %i.0632  %1 = load i32, ptr %arrayidx1, align 433  %mul = mul nsw i32 %1, %034  %arrayidx2 = getelementptr inbounds i32, ptr %C, i32 %i.0635  store i32 %mul, ptr %arrayidx2, align 436  %inc = add nuw nsw i32 %i.06, 137  %exitcond = icmp eq i32 %inc, %N38  br i1 %exitcond, label %for.end.loopexit, label %for.body39 40for.end.loopexit:                                 ; preds = %for.body41  br label %for.end42 43for.end:                                          ; preds = %for.end.loopexit, %entry44  ret void45}46 47; Floating-point loops need fast-math to be vectorizeable48; LINUX: Checking a loop in 'sumf'49; LINUX: Potentially unsafe FP op prevents vectorization50; MVE: Checking a loop in 'sumf'51; MVE: We can vectorize this loop!52; DARWIN: Checking a loop in 'sumf'53; DARWIN: We can vectorize this loop!54define void @sumf(ptr noalias nocapture readonly %A, ptr noalias nocapture readonly %B, ptr noalias nocapture %C, i32 %N) {55entry:56  %cmp5 = icmp eq i32 %N, 057  br i1 %cmp5, label %for.end, label %for.body.preheader58 59for.body.preheader:                               ; preds = %entry60  br label %for.body61 62for.body:                                         ; preds = %for.body.preheader, %for.body63  %i.06 = phi i32 [ %inc, %for.body ], [ 0, %for.body.preheader ]64  %arrayidx = getelementptr inbounds float, ptr %A, i32 %i.0665  %0 = load float, ptr %arrayidx, align 466  %arrayidx1 = getelementptr inbounds float, ptr %B, i32 %i.0667  %1 = load float, ptr %arrayidx1, align 468  %mul = fmul float %0, %169  %arrayidx2 = getelementptr inbounds float, ptr %C, i32 %i.0670  store float %mul, ptr %arrayidx2, align 471  %inc = add nuw nsw i32 %i.06, 172  %exitcond = icmp eq i32 %inc, %N73  br i1 %exitcond, label %for.end.loopexit, label %for.body74 75for.end.loopexit:                                 ; preds = %for.body76  br label %for.end77 78for.end:                                          ; preds = %for.end.loopexit, %entry79  ret void80}81 82; Integer loops are always vectorizeable83; CHECK: Checking a loop in 'redi'84; CHECK: We can vectorize this loop!85define i32 @redi(ptr noalias nocapture readonly %a, ptr noalias nocapture readonly %b, i32 %N) {86entry:87  br label %for.body.preheader88 89for.body.preheader:                               ; preds = %entry90  br label %for.body91 92for.body:                                         ; preds = %for.body.preheader, %for.body93  %i.07 = phi i32 [ %inc, %for.body ], [ 0, %for.body.preheader ]94  %Red.06 = phi i32 [ %add, %for.body ], [ 0, %for.body.preheader ]95  %arrayidx = getelementptr inbounds i32, ptr %a, i32 %i.0796  %0 = load i32, ptr %arrayidx, align 497  %arrayidx1 = getelementptr inbounds i32, ptr %b, i32 %i.0798  %1 = load i32, ptr %arrayidx1, align 499  %mul = mul nsw i32 %1, %0100  %add = add nsw i32 %mul, %Red.06101  %inc = add nuw nsw i32 %i.07, 1102  %exitcond = icmp eq i32 %inc, %N103  br i1 %exitcond, label %for.end.loopexit, label %for.body104 105for.end.loopexit:                                 ; preds = %for.body106  %add.lcssa = phi i32 [ %add, %for.body ]107  br label %for.end108 109for.end:                                          ; preds = %for.end.loopexit110  ret i32 %add.lcssa111}112 113; Floating-point loops need fast-math to be vectorizeable114; LINUX: Checking a loop in 'redf'115; LINUX: Potentially unsafe FP op prevents vectorization116; MVE: Checking a loop in 'redf'117; MVE: We can vectorize this loop!118; DARWIN: Checking a loop in 'redf'119; DARWIN: We can vectorize this loop!120define float @redf(ptr noalias nocapture readonly %a, ptr noalias nocapture readonly %b, i32 %N) {121entry:122  br label %for.body.preheader123 124for.body.preheader:                               ; preds = %entry125  br label %for.body126 127for.body:                                         ; preds = %for.body.preheader, %for.body128  %i.07 = phi i32 [ %inc, %for.body ], [ 0, %for.body.preheader ]129  %Red.06 = phi float [ %add, %for.body ], [ 0.0e+00, %for.body.preheader ]130  %arrayidx = getelementptr inbounds float, ptr %a, i32 %i.07131  %0 = load float, ptr %arrayidx, align 4132  %arrayidx1 = getelementptr inbounds float, ptr %b, i32 %i.07133  %1 = load float, ptr %arrayidx1, align 4134  %mul = fmul float %0, %1135  %add = fadd float %Red.06, %mul136  %inc = add nuw nsw i32 %i.07, 1137  %exitcond = icmp eq i32 %inc, %N138  br i1 %exitcond, label %for.end.loopexit, label %for.body139 140for.end.loopexit:                                 ; preds = %for.body141  %add.lcssa = phi float [ %add, %for.body ]142  br label %for.end143 144for.end:                                          ; preds = %for.end.loopexit145  ret float %add.lcssa146}147 148; Make sure calls that turn into builtins are also covered149; LINUX: Checking a loop in 'fabs'150; LINUX: Potentially unsafe FP op prevents vectorization151; DARWIN: Checking a loop in 'fabs'152; DARWIN: We can vectorize this loop!153define void @fabs(ptr noalias nocapture readonly %A, ptr noalias nocapture readonly %B, ptr noalias nocapture %C, i32 %N) {154entry:155  %cmp10 = icmp eq i32 %N, 0156  br i1 %cmp10, label %for.end, label %for.body157 158for.body:                                         ; preds = %entry, %for.body159  %i.011 = phi i32 [ %inc, %for.body ], [ 0, %entry ]160  %arrayidx = getelementptr inbounds float, ptr %A, i32 %i.011161  %0 = load float, ptr %arrayidx, align 4162  %arrayidx1 = getelementptr inbounds float, ptr %B, i32 %i.011163  %1 = load float, ptr %arrayidx1, align 4164  %fabsf = tail call float @fabsf(float %1) #1165  %conv3 = fmul float %0, %fabsf166  %arrayidx4 = getelementptr inbounds float, ptr %C, i32 %i.011167  store float %conv3, ptr %arrayidx4, align 4168  %inc = add nuw nsw i32 %i.011, 1169  %exitcond = icmp eq i32 %inc, %N170  br i1 %exitcond, label %for.end, label %for.body171 172for.end:                                          ; preds = %for.body, %entry173  ret void174}175 176; Integer loops are always vectorizeable177; CHECK: Checking a loop in 'sumi_fast'178; CHECK: We can vectorize this loop!179define void @sumi_fast(ptr noalias nocapture readonly %A, ptr noalias nocapture readonly %B, ptr noalias nocapture %C, i32 %N) {180entry:181  %cmp5 = icmp eq i32 %N, 0182  br i1 %cmp5, label %for.end, label %for.body.preheader183 184for.body.preheader:                               ; preds = %entry185  br label %for.body186 187for.body:                                         ; preds = %for.body.preheader, %for.body188  %i.06 = phi i32 [ %inc, %for.body ], [ 0, %for.body.preheader ]189  %arrayidx = getelementptr inbounds i32, ptr %A, i32 %i.06190  %0 = load i32, ptr %arrayidx, align 4191  %arrayidx1 = getelementptr inbounds i32, ptr %B, i32 %i.06192  %1 = load i32, ptr %arrayidx1, align 4193  %mul = mul nsw i32 %1, %0194  %arrayidx2 = getelementptr inbounds i32, ptr %C, i32 %i.06195  store i32 %mul, ptr %arrayidx2, align 4196  %inc = add nuw nsw i32 %i.06, 1197  %exitcond = icmp eq i32 %inc, %N198  br i1 %exitcond, label %for.end.loopexit, label %for.body199 200for.end.loopexit:                                 ; preds = %for.body201  br label %for.end202 203for.end:                                          ; preds = %for.end.loopexit, %entry204  ret void205}206 207; Floating-point loops can be vectorizeable with fast-math208; CHECK: Checking a loop in 'sumf_fast'209; CHECK: We can vectorize this loop!210define void @sumf_fast(ptr noalias nocapture readonly %A, ptr noalias nocapture readonly %B, ptr noalias nocapture %C, i32 %N) {211entry:212  %cmp5 = icmp eq i32 %N, 0213  br i1 %cmp5, label %for.end, label %for.body.preheader214 215for.body.preheader:                               ; preds = %entry216  br label %for.body217 218for.body:                                         ; preds = %for.body.preheader, %for.body219  %i.06 = phi i32 [ %inc, %for.body ], [ 0, %for.body.preheader ]220  %arrayidx = getelementptr inbounds float, ptr %A, i32 %i.06221  %0 = load float, ptr %arrayidx, align 4222  %arrayidx1 = getelementptr inbounds float, ptr %B, i32 %i.06223  %1 = load float, ptr %arrayidx1, align 4224  %mul = fmul fast float %1, %0225  %arrayidx2 = getelementptr inbounds float, ptr %C, i32 %i.06226  store float %mul, ptr %arrayidx2, align 4227  %inc = add nuw nsw i32 %i.06, 1228  %exitcond = icmp eq i32 %inc, %N229  br i1 %exitcond, label %for.end.loopexit, label %for.body230 231for.end.loopexit:                                 ; preds = %for.body232  br label %for.end233 234for.end:                                          ; preds = %for.end.loopexit, %entry235  ret void236}237 238; Integer loops are always vectorizeable239; CHECK: Checking a loop in 'redi_fast'240; CHECK: We can vectorize this loop!241define i32 @redi_fast(ptr noalias nocapture readonly %a, ptr noalias nocapture readonly %b, i32 %N) {242entry:243  %cmp5 = icmp eq i32 %N, 0244  br i1 %cmp5, label %for.end, label %for.body.preheader245 246for.body.preheader:                               ; preds = %entry247  br label %for.body248 249for.body:                                         ; preds = %for.body.preheader, %for.body250  %i.07 = phi i32 [ %inc, %for.body ], [ 0, %for.body.preheader ]251  %Red.06 = phi i32 [ %add, %for.body ], [ 0, %for.body.preheader ]252  %arrayidx = getelementptr inbounds i32, ptr %a, i32 %i.07253  %0 = load i32, ptr %arrayidx, align 4254  %arrayidx1 = getelementptr inbounds i32, ptr %b, i32 %i.07255  %1 = load i32, ptr %arrayidx1, align 4256  %mul = mul nsw i32 %1, %0257  %add = add nsw i32 %mul, %Red.06258  %inc = add nuw nsw i32 %i.07, 1259  %exitcond = icmp eq i32 %inc, %N260  br i1 %exitcond, label %for.end.loopexit, label %for.body261 262for.end.loopexit:                                 ; preds = %for.body263  %add.lcssa = phi i32 [ %add, %for.body ]264  br label %for.end265 266for.end:                                          ; preds = %for.end.loopexit, %entry267  %Red.0.lcssa = phi i32 [ 0, %entry ], [ %add.lcssa, %for.end.loopexit ]268  ret i32 %Red.0.lcssa269}270 271; Floating-point loops can be vectorizeable with fast-math272; CHECK: Checking a loop in 'redf_fast'273; CHECK: We can vectorize this loop!274define float @redf_fast(ptr noalias nocapture readonly %a, ptr noalias nocapture readonly %b, i32 %N) {275entry:276  br label %for.body.preheader277 278for.body.preheader:                               ; preds = %entry279  br label %for.body280 281for.body:                                         ; preds = %for.body.preheader, %for.body282  %i.07 = phi i32 [ %inc, %for.body ], [ 0, %for.body.preheader ]283  %Red.06 = phi float [ %add, %for.body ], [ 0.0e+00, %for.body.preheader ]284  %arrayidx = getelementptr inbounds float, ptr %a, i32 %i.07285  %0 = load float, ptr %arrayidx, align 4286  %arrayidx1 = getelementptr inbounds float, ptr %b, i32 %i.07287  %1 = load float, ptr %arrayidx1, align 4288  %mul = fmul fast float %1, %0289  %add = fadd fast float %mul, %Red.06290  %inc = add nuw nsw i32 %i.07, 1291  %exitcond = icmp eq i32 %inc, %N292  br i1 %exitcond, label %for.end.loopexit, label %for.body293 294for.end.loopexit:                                 ; preds = %for.body295  %add.lcssa = phi float [ %add, %for.body ]296  br label %for.end297 298for.end:                                          ; preds = %for.end.loopexit299  ret float %add.lcssa300}301 302; Make sure calls that turn into builtins are also covered303; CHECK: Checking a loop in 'fabs_fast'304; CHECK: We can vectorize this loop!305define void @fabs_fast(ptr noalias nocapture readonly %A, ptr noalias nocapture readonly %B, ptr noalias nocapture %C, i32 %N) {306entry:307  %cmp10 = icmp eq i32 %N, 0308  br i1 %cmp10, label %for.end, label %for.body309 310for.body:                                         ; preds = %entry, %for.body311  %i.011 = phi i32 [ %inc, %for.body ], [ 0, %entry ]312  %arrayidx = getelementptr inbounds float, ptr %A, i32 %i.011313  %0 = load float, ptr %arrayidx, align 4314  %arrayidx1 = getelementptr inbounds float, ptr %B, i32 %i.011315  %1 = load float, ptr %arrayidx1, align 4316  %fabsf = tail call fast float @fabsf(float %1) #2317  %conv3 = fmul fast float %fabsf, %0318  %arrayidx4 = getelementptr inbounds float, ptr %C, i32 %i.011319  store float %conv3, ptr %arrayidx4, align 4320  %inc = add nuw nsw i32 %i.011, 1321  %exitcond = icmp eq i32 %inc, %N322  br i1 %exitcond, label %for.end, label %for.body323 324for.end:                                          ; preds = %for.body, %entry325  ret void326}327 328declare float @fabsf(float)329 330attributes #1 = { nounwind readnone "disable-tail-calls"="false" "less-precise-fpmad"="false" "frame-pointer"="all" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="cortex-a8" "target-features"="+dsp,+neon,+vfp3" "use-soft-float"="false" }331attributes #2 = { nounwind readnone "disable-tail-calls"="false" "less-precise-fpmad"="false" "frame-pointer"="all" "no-infs-fp-math"="true" "no-nans-fp-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="cortex-a8" "target-features"="+dsp,+neon,+vfp3" "use-soft-float"="false" }332