222 lines · plain
1; RUN: opt -S -mtriple=r600 -mcpu=cayman -passes=loop-vectorize,dce,instcombine -force-vector-interleave=1 -force-vector-width=4 < %s | FileCheck %s2 3; Check vectorization that would ordinarily require a runtime bounds4; check on the pointers when mixing address spaces. For now we cannot5; assume address spaces do not alias, and we can't assume that6; different pointers are directly comparable.7;8; These all test this basic loop for different combinations of address9; spaces, and swapping in globals or adding noalias.10;11;void foo(int addrspace(N)* [noalias] a, int addrspace(M)* [noalias] b, int n)12;{13; for (int i = 0; i < n; ++i)14; {15; a[i] = 3 * b[i];16; }17;}18 19; Artificial datalayout20target datalayout = "e-p:32:32:32-p1:16:16:16-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-v16:16:16-v24:32:32-v32:32:32-v48:64:64-v64:64:64-v96:128:128-v128:128:128-v192:256:256-v256:256:256-v512:512:512-v1024:1024:1024-v2048:2048:2048-n32:64"21 22 23@g_as1 = common addrspace(1) global [1024 x i32] zeroinitializer, align 1624@q_as2 = common addrspace(2) global [1024 x i32] zeroinitializer, align 1625 26; Both parameters are unidentified objects with the same address27; space, so this should vectorize normally.28define void @foo(ptr addrspace(1) %a, ptr addrspace(1) %b, i32 %n) #0 {29; CHECK-LABEL: @foo(30; CHECK: <4 x i32>31; CHECK: ret32 33entry:34 %cmp1 = icmp slt i32 0, %n35 br i1 %cmp1, label %for.body, label %for.end36 37for.body: ; preds = %entry, %for.body38 %i.02 = phi i32 [ %inc, %for.body ], [ 0, %entry ]39 %idxprom = sext i32 %i.02 to i6440 %arrayidx = getelementptr inbounds i32, ptr addrspace(1) %b, i64 %idxprom41 %0 = load i32, ptr addrspace(1) %arrayidx, align 442 %mul = mul nsw i32 %0, 343 %idxprom1 = sext i32 %i.02 to i6444 %arrayidx2 = getelementptr inbounds i32, ptr addrspace(1) %a, i64 %idxprom145 store i32 %mul, ptr addrspace(1) %arrayidx2, align 446 %inc = add nsw i32 %i.02, 147 %cmp = icmp slt i32 %inc, %n48 br i1 %cmp, label %for.body, label %for.end49 50for.end: ; preds = %for.body, %entry51 ret void52}53 54; Parameters are unidentified and different address spaces, so cannot vectorize.55define void @bar0(ptr %a, ptr addrspace(1) %b, i32 %n) #0 {56; CHECK-LABEL: @bar0(57; CHECK-NOT: <4 x i32>58; CHECK: ret59 60entry:61 %cmp1 = icmp slt i32 0, %n62 br i1 %cmp1, label %for.body, label %for.end63 64for.body: ; preds = %entry, %for.body65 %i.02 = phi i32 [ %inc, %for.body ], [ 0, %entry ]66 %idxprom = sext i32 %i.02 to i6467 %arrayidx = getelementptr inbounds i32, ptr addrspace(1) %b, i64 %idxprom68 %0 = load i32, ptr addrspace(1) %arrayidx, align 469 %mul = mul nsw i32 %0, 370 %idxprom1 = sext i32 %i.02 to i6471 %arrayidx2 = getelementptr inbounds i32, ptr %a, i64 %idxprom172 store i32 %mul, ptr %arrayidx2, align 473 %inc = add nsw i32 %i.02, 174 %cmp = icmp slt i32 %inc, %n75 br i1 %cmp, label %for.body, label %for.end76 77for.end: ; preds = %for.body, %entry78 ret void79}80 81; Swapped arguments should be the same82define void @bar1(ptr addrspace(1) %a, ptr %b, i32 %n) #0 {83; CHECK-LABEL: @bar1(84; CHECK-NOT: <4 x i32>85; CHECK: ret86 87entry:88 %cmp1 = icmp slt i32 0, %n89 br i1 %cmp1, label %for.body, label %for.end90 91for.body: ; preds = %entry, %for.body92 %i.02 = phi i32 [ %inc, %for.body ], [ 0, %entry ]93 %idxprom = sext i32 %i.02 to i6494 %arrayidx = getelementptr inbounds i32, ptr %b, i64 %idxprom95 %0 = load i32, ptr %arrayidx, align 496 %mul = mul nsw i32 %0, 397 %idxprom1 = sext i32 %i.02 to i6498 %arrayidx2 = getelementptr inbounds i32, ptr addrspace(1) %a, i64 %idxprom199 store i32 %mul, ptr addrspace(1) %arrayidx2, align 4100 %inc = add nsw i32 %i.02, 1101 %cmp = icmp slt i32 %inc, %n102 br i1 %cmp, label %for.body, label %for.end103 104for.end: ; preds = %for.body, %entry105 ret void106}107 108; We should still be able to vectorize with noalias even if the109; address spaces are different.110define void @bar2(ptr noalias %a, ptr addrspace(1) noalias %b, i32 %n) #0 {111; CHECK-LABEL: @bar2(112; CHECK: <4 x i32>113; CHECK: ret114 115entry:116 %cmp1 = icmp slt i32 0, %n117 br i1 %cmp1, label %for.body, label %for.end118 119for.body: ; preds = %entry, %for.body120 %i.02 = phi i32 [ %inc, %for.body ], [ 0, %entry ]121 %idxprom = sext i32 %i.02 to i64122 %arrayidx = getelementptr inbounds i32, ptr addrspace(1) %b, i64 %idxprom123 %0 = load i32, ptr addrspace(1) %arrayidx, align 4124 %mul = mul nsw i32 %0, 3125 %idxprom1 = sext i32 %i.02 to i64126 %arrayidx2 = getelementptr inbounds i32, ptr %a, i64 %idxprom1127 store i32 %mul, ptr %arrayidx2, align 4128 %inc = add nsw i32 %i.02, 1129 %cmp = icmp slt i32 %inc, %n130 br i1 %cmp, label %for.body, label %for.end131 132for.end: ; preds = %for.body, %entry133 ret void134}135 136; Store to identified global with different address space. This isn't137; generally safe and shouldn't be vectorized.138define void @arst0(ptr %b, i32 %n) #0 {139; CHECK-LABEL: @arst0(140; CHECK-NOT: <4 x i32>141; CHECK: ret142 143entry:144 %cmp1 = icmp slt i32 0, %n145 br i1 %cmp1, label %for.body, label %for.end146 147for.body: ; preds = %entry, %for.body148 %i.02 = phi i32 [ %inc, %for.body ], [ 0, %entry ]149 %idxprom = sext i32 %i.02 to i64150 %arrayidx = getelementptr inbounds i32, ptr %b, i64 %idxprom151 %0 = load i32, ptr %arrayidx, align 4152 %mul = mul nsw i32 %0, 3153 %idxprom1 = sext i32 %i.02 to i64154 %arrayidx2 = getelementptr inbounds [1024 x i32], ptr addrspace(1) @g_as1, i64 0, i64 %idxprom1155 store i32 %mul, ptr addrspace(1) %arrayidx2, align 4156 %inc = add nsw i32 %i.02, 1157 %cmp = icmp slt i32 %inc, %n158 br i1 %cmp, label %for.body, label %for.end159 160for.end: ; preds = %for.body, %entry161 ret void162}163 164 165; Load from identified global with different address space.166; This isn't generally safe and shouldn't be vectorized.167define void @arst1(ptr %b, i32 %n) #0 {168; CHECK-LABEL: @arst1(169; CHECK-NOT: <4 x i32>170; CHECK: ret171 172entry:173 %cmp1 = icmp slt i32 0, %n174 br i1 %cmp1, label %for.body, label %for.end175 176for.body: ; preds = %entry, %for.body177 %i.02 = phi i32 [ %inc, %for.body ], [ 0, %entry ]178 %idxprom = sext i32 %i.02 to i64179 %arrayidx = getelementptr inbounds [1024 x i32], ptr addrspace(1) @g_as1, i64 0, i64 %idxprom180 %0 = load i32, ptr addrspace(1) %arrayidx, align 4181 %mul = mul nsw i32 %0, 3182 %idxprom1 = sext i32 %i.02 to i64183 %arrayidx2 = getelementptr inbounds i32, ptr %b, i64 %idxprom1184 store i32 %mul, ptr %arrayidx2, align 4185 %inc = add nsw i32 %i.02, 1186 %cmp = icmp slt i32 %inc, %n187 br i1 %cmp, label %for.body, label %for.end188 189for.end: ; preds = %for.body, %entry190 ret void191}192 193; Read and write to 2 identified globals in different address194; spaces. This should be vectorized.195define void @aoeu(i32 %n) #0 {196; CHECK-LABEL: @aoeu(197; CHECK: <4 x i32>198; CHECK: ret199 200entry:201 %cmp1 = icmp slt i32 0, %n202 br i1 %cmp1, label %for.body, label %for.end203 204for.body: ; preds = %entry, %for.body205 %i.02 = phi i32 [ %inc, %for.body ], [ 0, %entry ]206 %idxprom = sext i32 %i.02 to i64207 %arrayidx = getelementptr inbounds [1024 x i32], ptr addrspace(2) @q_as2, i64 0, i64 %idxprom208 %0 = load i32, ptr addrspace(2) %arrayidx, align 4209 %mul = mul nsw i32 %0, 3210 %idxprom1 = sext i32 %i.02 to i64211 %arrayidx2 = getelementptr inbounds [1024 x i32], ptr addrspace(1) @g_as1, i64 0, i64 %idxprom1212 store i32 %mul, ptr addrspace(1) %arrayidx2, align 4213 %inc = add nsw i32 %i.02, 1214 %cmp = icmp slt i32 %inc, %n215 br i1 %cmp, label %for.body, label %for.end216 217for.end: ; preds = %for.body, %entry218 ret void219}220 221attributes #0 = { nounwind uwtable "less-precise-fpmad"="false" "frame-pointer"="all" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "use-soft-float"="false" }222