2 ; RUN: opt < %s -S -debug -passes=loop-vectorize -mcpu=slm 2>&1 | FileCheck %s --check-prefix=SLM
4 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
5 target triple = "x86_64-unknown-linux-gnu"
7 define i8 @mul_i8(ptr %dataA, ptr %dataB, i32 %N) {
9 %cmp12 = icmp eq i32 %N, 0
10 br i1 %cmp12, label %for.cond.cleanup, label %for.body.preheader
12 for.body.preheader: ; preds = %entry
13 %wide.trip.count = zext i32 %N to i64
16 for.cond.cleanup.loopexit: ; preds = %for.body
17 %phitmp = trunc i32 %add4 to i8
18 br label %for.cond.cleanup
20 for.cond.cleanup: ; preds = %for.cond.cleanup.loopexit, %entry
21 %acc.0.lcssa = phi i8 [ 0, %entry ], [ %phitmp, %for.cond.cleanup.loopexit ]
24 for.body: ; preds = %for.body.preheader, %for.body
25 %indvars.iv = phi i64 [ %indvars.iv.next, %for.body ], [ 0, %for.body.preheader ]
26 %acc.013 = phi i32 [ %add4, %for.body ], [ 0, %for.body.preheader ]
27 %arrayidx = getelementptr inbounds i8, ptr %dataA, i64 %indvars.iv
28 %0 = load i8, ptr %arrayidx, align 1
29 %conv = sext i8 %0 to i32
30 %arrayidx2 = getelementptr inbounds i8, ptr %dataB, i64 %indvars.iv
31 %1 = load i8, ptr %arrayidx2, align 1
32 %conv3 = sext i8 %1 to i32
33 ; sources of the mul is sext\sext from i8
34 ; use pmullw\sext seq.
35 ; SLM: cost of 3 for VF 2 {{.*}} mul nsw i32 %conv3, %conv
36 %mul = mul nsw i32 %conv3, %conv
37 ; sources of the mul is zext\sext from i8
38 ; use pmulhw\pmullw\pshuf
39 ; SLM: cost of 2 for VF 2 {{.*}} mul nsw i32 %conv4, %conv
40 %conv4 = zext i8 %1 to i32
41 %mul2 = mul nsw i32 %conv4, %conv
42 %sum0 = add i32 %mul, %mul2
43 ; sources of the mul is zext\zext from i8
45 ; SLM: cost of 2 for VF 2 {{.*}} mul nsw i32 %conv5, %conv4
46 %conv5 = zext i8 %0 to i32
47 %mul3 = mul nsw i32 %conv5, %conv4
48 %sum1 = add i32 %sum0, %mul3
49 ; sources of the mul is sext\-120
51 ; SLM: cost of 3 for VF 2 {{.*}} mul nsw i32 -120, %conv3
52 %mul4 = mul nsw i32 -120, %conv3
53 %sum2 = add i32 %sum1, %mul4
54 ; sources of the mul is sext\250
55 ; use pmulhw\pmullw\pshuf
56 ; SLM: cost of 2 for VF 2 {{.*}} mul nsw i32 250, %conv3
57 %mul5 = mul nsw i32 250, %conv3
58 %sum3 = add i32 %sum2, %mul5
59 ; sources of the mul is zext\-120
60 ; use pmulhw\pmullw\pshuf
61 ; SLM: cost of 2 for VF 2 {{.*}} mul nsw i32 -120, %conv4
62 %mul6 = mul nsw i32 -120, %conv4
63 %sum4 = add i32 %sum3, %mul6
64 ; sources of the mul is zext\250
66 ; SLM: cost of 2 for VF 2 {{.*}} mul nsw i32 250, %conv4
67 %mul7 = mul nsw i32 250, %conv4
68 %sum5 = add i32 %sum4, %mul7
69 %add = add i32 %acc.013, 5
70 %add4 = add i32 %add, %sum5
71 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
72 %exitcond = icmp eq i64 %indvars.iv.next, %wide.trip.count
73 br i1 %exitcond, label %for.cond.cleanup.loopexit, label %for.body
76 define i16 @mul_i16(ptr %dataA, ptr %dataB, i32 %N) {
78 %cmp12 = icmp eq i32 %N, 0
79 br i1 %cmp12, label %for.cond.cleanup, label %for.body.preheader
81 for.body.preheader: ; preds = %entry
82 %wide.trip.count = zext i32 %N to i64
85 for.cond.cleanup.loopexit: ; preds = %for.body
86 %phitmp = trunc i32 %add4 to i16
87 br label %for.cond.cleanup
89 for.cond.cleanup: ; preds = %for.cond.cleanup.loopexit, %entry
90 %acc.0.lcssa = phi i16 [ 0, %entry ], [ %phitmp, %for.cond.cleanup.loopexit ]
93 for.body: ; preds = %for.body.preheader, %for.body
94 %indvars.iv = phi i64 [ %indvars.iv.next, %for.body ], [ 0, %for.body.preheader ]
95 %acc.013 = phi i32 [ %add4, %for.body ], [ 0, %for.body.preheader ]
96 %arrayidx = getelementptr inbounds i16, ptr %dataA, i64 %indvars.iv
97 %0 = load i16, ptr %arrayidx, align 1
98 %conv = sext i16 %0 to i32
99 %arrayidx2 = getelementptr inbounds i16, ptr %dataB, i64 %indvars.iv
100 %1 = load i16, ptr %arrayidx2, align 1
101 %conv3 = sext i16 %1 to i32
102 ; sources of the mul is sext\sext from i16
103 ; use pmulhw\pmullw\pshuf seq.
104 ; SLM: cost of 3 for VF 4 {{.*}} mul nsw i32 %conv3, %conv
105 %mul = mul nsw i32 %conv3, %conv
106 ; sources of the mul is zext\sext from i16
108 ; SLM: cost of 2 for VF 4 {{.*}} mul nsw i32 %conv4, %conv
109 %conv4 = zext i16 %1 to i32
110 %mul2 = mul nsw i32 %conv4, %conv
111 %sum0 = add i32 %mul, %mul2
112 ; sources of the mul is zext\zext from i16
113 ; use pmulhw\pmullw\zext
114 ; SLM: cost of 2 for VF 4 {{.*}} mul nsw i32 %conv5, %conv4
115 %conv5 = zext i16 %0 to i32
116 %mul3 = mul nsw i32 %conv5, %conv4
117 %sum1 = add i32 %sum0, %mul3
118 ; sources of the mul is sext\-32000
119 ; use pmulhw\pmullw\sext
120 ; SLM: cost of 2 for VF 4 {{.*}} mul nsw i32 -32000, %conv3
121 %mul4 = mul nsw i32 -32000, %conv3
122 %sum2 = add i32 %sum1, %mul4
123 ; sources of the mul is sext\64000
125 ; SLM: cost of 11 for VF 4 {{.*}} mul nsw i32 64000, %conv3
126 %mul5 = mul nsw i32 64000, %conv3
127 %sum3 = add i32 %sum2, %mul5
128 ; sources of the mul is zext\-32000
130 ; SLM: cost of 11 for VF 4 {{.*}} mul nsw i32 -32000, %conv4
131 %mul6 = mul nsw i32 -32000, %conv4
132 %sum4 = add i32 %sum3, %mul6
133 ; sources of the mul is zext\64000
134 ; use pmulhw\pmullw\zext
135 ; SLM: cost of 5 for VF 4 {{.*}} mul nsw i32 250, %conv4
136 %mul7 = mul nsw i32 250, %conv4
137 %sum5 = add i32 %sum4, %mul7
138 %add = add i32 %acc.013, 5
139 %add4 = add i32 %add, %sum5
140 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
141 %exitcond = icmp eq i64 %indvars.iv.next, %wide.trip.count
142 br i1 %exitcond, label %for.cond.cleanup.loopexit, label %for.body