151 lines · plain
1; REQUIRES: asserts2; RUN: opt -mtriple=s390x-unknown-linux -mcpu=z13 -passes=loop-vectorize \3; RUN: -debug-only=loop-vectorize,vectorutils -max-interleave-group-factor=64\4; RUN: -disable-output < %s 2>&1 | FileCheck %s5;6; Check that some cost estimations for interleave groups make sense.7 8; This loop is loading four i16 values at indices [0, 1, 2, 3], with a stride9; of 4. At VF=4, memory interleaving means loading 4 * 4 * 16 bits = 2 vector10; registers. Each of the 4 vector values must then be constructed from the11; two vector registers using one vperm each, which gives a cost of 2 + 4 = 6.12;13; CHECK: LV: Checking a loop in 'fun0'14; CHECK: Cost of 6 for VF 4: INTERLEAVE-GROUP with factor 4 at %ld0, vp<%next.gep>15; CHECK: ir<%ld0> = load from index 016; CHECK: ir<%ld1> = load from index 117; CHECK: ir<%ld2> = load from index 218; CHECK: ir<%ld3> = load from index 319 20define void @fun0(ptr %ptr, ptr %dst) {21entry:22 br label %for.body23 24for.body:25 %ivptr = phi ptr [ %ptr.next, %for.body ], [ %ptr, %entry ]26 %iv = phi i64 [ %inc, %for.body ], [ 0, %entry ]27 %inc = add i64 %iv, 428 %ld0 = load i16, ptr %ivptr29 %ptr1 = getelementptr inbounds i16, ptr %ivptr, i64 130 %ld1 = load i16, ptr %ptr131 %ptr2 = getelementptr inbounds i16, ptr %ivptr, i64 232 %ld2 = load i16, ptr %ptr233 %ptr3 = getelementptr inbounds i16, ptr %ivptr, i64 334 %ld3 = load i16, ptr %ptr335 %a1 = add i16 %ld0, %ld136 %a2 = add i16 %a1, %ld237 %a3 = add i16 %a2, %ld338 %dstptr = getelementptr inbounds i16, ptr %dst, i64 %iv39 store i16 %a3, ptr %dstptr40 %ptr.next = getelementptr inbounds i16, ptr %ivptr, i64 441 %cmp = icmp eq i64 %inc, 10042 br i1 %cmp, label %for.end, label %for.body43 44for.end:45 ret void46}47 48; This loop loads one i8 value in a stride of 3. At VF=16, this means loading49; 3 vector registers, and then constructing the vector value with two vperms,50; which gives a cost of 5.51;52; CHECK: LV: Checking a loop in 'fun1'53; CHECK: Cost of 5 for VF 16: INTERLEAVE-GROUP with factor 3 at %ld0, vp<%next.gep>54; CHECK: ir<%ld0> = load from index 055define void @fun1(ptr %ptr, ptr %dst) {56entry:57 br label %for.body58 59for.body:60 %ivptr = phi ptr [ %ptr.next, %for.body ], [ %ptr, %entry ]61 %iv = phi i64 [ %inc, %for.body ], [ 0, %entry ]62 %inc = add i64 %iv, 463 %ld0 = load i8, ptr %ivptr64 %dstptr = getelementptr inbounds i8, ptr %dst, i64 %iv65 store i8 %ld0, ptr %dstptr66 %ptr.next = getelementptr inbounds i8, ptr %ivptr, i64 367 %cmp = icmp eq i64 %inc, 10068 br i1 %cmp, label %for.end, label %for.body69 70for.end:71 ret void72}73 74; This loop is loading 4 i8 values at indexes [0, 1, 2, 3], with a stride of75; 32. At VF=2, this means loading 2 vector registers, and using 4 vperms to76; produce the vector values, which gives a cost of 6.77;78; CHECK: LV: Checking a loop in 'fun2'79; CHECK: Cost of 6 for VF 2: INTERLEAVE-GROUP with factor 32 at %ld0, vp<%next.gep>80; CHECK: ir<%ld0> = load from index 081; CHECK: ir<%ld1> = load from index 182; CHECK: ir<%ld2> = load from index 283; CHECK: ir<%ld3> = load from index 384define void @fun2(ptr %ptr, ptr %dst) {85entry:86 br label %for.body87 88for.body:89 %ivptr = phi ptr [ %ptr.next, %for.body ], [ %ptr, %entry ]90 %iv = phi i64 [ %inc, %for.body ], [ 0, %entry ]91 %inc = add i64 %iv, 492 %ld0 = load i8, ptr %ivptr93 %ptr1 = getelementptr inbounds i8, ptr %ivptr, i64 194 %ld1 = load i8, ptr %ptr195 %ptr2 = getelementptr inbounds i8, ptr %ivptr, i64 296 %ld2 = load i8, ptr %ptr297 %ptr3 = getelementptr inbounds i8, ptr %ivptr, i64 398 %ld3 = load i8, ptr %ptr399 %a1 = add i8 %ld0, %ld1100 %a2 = add i8 %a1, %ld2101 %a3 = add i8 %a2, %ld3102 %dstptr = getelementptr inbounds i8, ptr %dst, i64 %iv103 store i8 %a3, ptr %dstptr104 %ptr.next = getelementptr inbounds i8, ptr %ivptr, i64 32105 %cmp = icmp eq i64 %inc, 100106 br i1 %cmp, label %for.end, label %for.body107 108for.end:109 ret void110}111 112; This loop is loading 4 i8 values at indexes [0, 1, 2, 3], with a stride of113; 30. At VF=2, this means loading 3 vector registers, and using 4 vperms to114; produce the vector values, which gives a cost of 7. This is the same loop115; as in fun2, except the stride makes the second iterations values overlap a116; vector register boundary.117;118; CHECK: LV: Checking a loop in 'fun3'119; CHECK: Cost of 7 for VF 2: INTERLEAVE-GROUP with factor 30 at %ld0, vp<%next.gep>120; CHECK: ir<%ld0> = load from index 0121; CHECK: ir<%ld1> = load from index 1122; CHECK: ir<%ld2> = load from index 2123; CHECK: ir<%ld3> = load from index 3124define void @fun3(ptr %ptr, ptr %dst) {125entry:126 br label %for.body127 128for.body:129 %ivptr = phi ptr [ %ptr.next, %for.body ], [ %ptr, %entry ]130 %iv = phi i64 [ %inc, %for.body ], [ 0, %entry ]131 %inc = add i64 %iv, 4132 %ld0 = load i8, ptr %ivptr133 %ptr1 = getelementptr inbounds i8, ptr %ivptr, i64 1134 %ld1 = load i8, ptr %ptr1135 %ptr2 = getelementptr inbounds i8, ptr %ivptr, i64 2136 %ld2 = load i8, ptr %ptr2137 %ptr3 = getelementptr inbounds i8, ptr %ivptr, i64 3138 %ld3 = load i8, ptr %ptr3139 %a1 = add i8 %ld0, %ld1140 %a2 = add i8 %a1, %ld2141 %a3 = add i8 %a2, %ld3142 %dstptr = getelementptr inbounds i8, ptr %dst, i64 %iv143 store i8 %a3, ptr %dstptr144 %ptr.next = getelementptr inbounds i8, ptr %ivptr, i64 30145 %cmp = icmp eq i64 %inc, 100146 br i1 %cmp, label %for.end, label %for.body147 148for.end:149 ret void150}151