113 lines · plain
1; RUN: opt < %s -passes=loop-vectorize -force-vector-width=4 -S | FileCheck %s2 3; The three test-cases below are all based on modified versions of a simple copy-loop:4;5; void foo(unsigned *src, unsigned *dst, unsigned nElts) {6; for (unsigned i = 0; i < nElts; ++i) {7; unsigned tmp = src[i];8; dst[i] = tmp;9; }10; }11;12; In the first version, there are no nontemporal stores or loads, and so vectorization13; is safely done.14;15; In the second version, the store into dst[i] has the nontemporal hint. The alignment16; on X86_64 for 'unsigned' is 4, so the vector store generally will not be aligned to the17; vector size (of 16 here). Unaligned nontemporal vector stores are not supported on X86_64,18; and so the vectorization is suppressed (because when vectorizing it, the nontemoral hint19; would not be honored in the final code-gen).20;21; The third version is analogous to the second, except rather than the store, it is the22; load from 'src[i]' that has the nontemporal hint. Vectorization is suppressed in this23; case because (like stores) unaligned nontemoral vector loads are not supported on X86_64.24 25target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"26target triple = "x86_64"27 28; CHECK-LABEL: @vectorTest(29define void @vectorTest(ptr noalias readonly %src, ptr noalias %dst, i32 %nElts) {30entry:31 %cmp8 = icmp eq i32 %nElts, 032 br i1 %cmp8, label %for.cond.cleanup, label %for.body.preheader33 34for.body.preheader: ; preds = %entry35 %wide.trip.count = zext i32 %nElts to i6436 br label %for.body37 38for.cond.cleanup: ; preds = %for.body, %entry39 ret void40 41for.body: ; preds = %for.body, %for.body.preheader42 %indvars.iv = phi i64 [ 0, %for.body.preheader ], [ %indvars.iv.next, %for.body ]43; Check that we vectorized the load, and that there is no nontemporal hint.44; CHECK: %wide.load = load <4 x i32>, ptr %{{[0-9]+}}, align 4{{$}}45 %arrayidx = getelementptr inbounds i32, ptr %src, i64 %indvars.iv46 %0 = load i32, ptr %arrayidx, align 447; Check that we vectorized the store, and that there is no nontemporal hint.48; CHECK: store <4 x i32> %wide.load, ptr %{{[0-9]+}}, align 4{{$}}49 %arrayidx2 = getelementptr inbounds i32, ptr %dst, i64 %indvars.iv50 store i32 %0, ptr %arrayidx2, align 451 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 152 %exitcond = icmp eq i64 %indvars.iv.next, %wide.trip.count53 br i1 %exitcond, label %for.cond.cleanup, label %for.body54}55 56; CHECK-LABEL: @vectorNTStoreTest(57; Check that the vectorized type of the store does not appear.58; CHECK-NOT: 4 x i3259define void @vectorNTStoreTest(ptr noalias readonly %src, ptr noalias %dst, i32 %nElts) {60entry:61 %cmp8 = icmp eq i32 %nElts, 062 br i1 %cmp8, label %for.cond.cleanup, label %for.body.preheader63 64for.body.preheader: ; preds = %entry65 %wide.trip.count = zext i32 %nElts to i6466 br label %for.body67 68for.cond.cleanup: ; preds = %for.body, %entry69 ret void70 71for.body: ; preds = %for.body, %for.body.preheader72 %indvars.iv = phi i64 [ 0, %for.body.preheader ], [ %indvars.iv.next, %for.body ]73 %arrayidx = getelementptr inbounds i32, ptr %src, i64 %indvars.iv74 %0 = load i32, ptr %arrayidx, align 475 %arrayidx2 = getelementptr inbounds i32, ptr %dst, i64 %indvars.iv76; Check that the store is not vectorized and that we don't lose the !nontemporal hint in it.77; CHECK: store i32 %{{[0-9]+}}, ptr %arrayidx2, align 4, !nontemporal !478 store i32 %0, ptr %arrayidx2, align 4, !nontemporal !079 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 180 %exitcond = icmp eq i64 %indvars.iv.next, %wide.trip.count81 br i1 %exitcond, label %for.cond.cleanup, label %for.body82}83 84; CHECK-LABEL: @vectorNTLoadTest(85; Check that the vectorized type of the load does not appear.86; CHECK-NOT: 4 x i3287define void @vectorNTLoadTest(ptr noalias readonly %src, ptr noalias %dst, i32 %nElts) {88entry:89 %cmp8 = icmp eq i32 %nElts, 090 br i1 %cmp8, label %for.cond.cleanup, label %for.body.preheader91 92for.body.preheader: ; preds = %entry93 %wide.trip.count = zext i32 %nElts to i6494 br label %for.body95 96for.cond.cleanup: ; preds = %for.body, %entry97 ret void98 99for.body: ; preds = %for.body, %for.body.preheader100 %indvars.iv = phi i64 [ 0, %for.body.preheader ], [ %indvars.iv.next, %for.body ]101 %arrayidx = getelementptr inbounds i32, ptr %src, i64 %indvars.iv102; Check that the load is not vectorized and that we don't lose the !nontemporal hint in it.103; CHECK: load i32, ptr %arrayidx, align 4, !nontemporal !4104 %0 = load i32, ptr %arrayidx, align 4, !nontemporal !0105 %arrayidx2 = getelementptr inbounds i32, ptr %dst, i64 %indvars.iv106 store i32 %0, ptr %arrayidx2, align 4107 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1108 %exitcond = icmp eq i64 %indvars.iv.next, %wide.trip.count109 br i1 %exitcond, label %for.cond.cleanup, label %for.body110}111 112!0 = !{i32 1}113