1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -slp-vectorizer -slp-threshold=-1000 -mtriple=x86_64 -S | FileCheck %s
3
4; The inputs to vector phi should remain undef.
5
6define i32 @phi3UndefInput(i1 %cond, i8 %arg0, i8 %arg1, i8 %arg2, i8 %arg3) {
7; CHECK-LABEL: @phi3UndefInput(
8; CHECK-NEXT:  entry:
9; CHECK-NEXT:    br i1 [[COND:%.*]], label [[BB2:%.*]], label [[BB3:%.*]]
10; CHECK:       bb2:
11; CHECK-NEXT:    [[TMP0:%.*]] = insertelement <4 x i8> poison, i8 [[ARG0:%.*]], i32 0
12; CHECK-NEXT:    [[TMP1:%.*]] = insertelement <4 x i8> [[TMP0]], i8 [[ARG1:%.*]], i32 1
13; CHECK-NEXT:    [[TMP2:%.*]] = insertelement <4 x i8> [[TMP1]], i8 [[ARG2:%.*]], i32 2
14; CHECK-NEXT:    [[TMP3:%.*]] = insertelement <4 x i8> [[TMP2]], i8 [[ARG3:%.*]], i32 3
15; CHECK-NEXT:    br label [[BB3]]
16; CHECK:       bb3:
17; CHECK-NEXT:    [[TMP4:%.*]] = phi <4 x i8> [ [[TMP3]], [[BB2]] ], [ <i8 0, i8 poison, i8 poison, i8 poison>, [[ENTRY:%.*]] ]
18; CHECK-NEXT:    [[TMP5:%.*]] = zext <4 x i8> [[TMP4]] to <4 x i32>
19; CHECK-NEXT:    [[TMP6:%.*]] = call i32 @llvm.vector.reduce.or.v4i32(<4 x i32> [[TMP5]])
20; CHECK-NEXT:    ret i32 [[TMP6]]
21;
22entry:
23  br i1 %cond, label %bb2, label %bb3
24
25bb2:
26  br label %bb3
27
28bb3:
29  %phi0 = phi i8 [ %arg0, %bb2 ], [ 0, %entry ]
30  %phi1 = phi i8 [ %arg1, %bb2 ], [ undef, %entry ]
31  %phi2 = phi i8 [ %arg2, %bb2 ], [ undef, %entry ]
32  %phi3 = phi i8 [ %arg3, %bb2 ], [ undef, %entry ]
33  %zext0 = zext i8 %phi0 to i32
34  %zext1 = zext i8 %phi1 to i32
35  %zext2 = zext i8 %phi2 to i32
36  %zext3 = zext i8 %phi3 to i32
37  %or1 = or i32 %zext0, %zext1
38  %or2 = or i32 %or1, %zext2
39  %or3 = or i32 %or2, %zext3
40  ret i32 %or3
41}
42
43define i32 @phi2UndefInput(i1 %cond, i8 %arg0, i8 %arg1, i8 %arg2, i8 %arg3) {
44; CHECK-LABEL: @phi2UndefInput(
45; CHECK-NEXT:  entry:
46; CHECK-NEXT:    br i1 [[COND:%.*]], label [[BB2:%.*]], label [[BB3:%.*]]
47; CHECK:       bb2:
48; CHECK-NEXT:    [[TMP0:%.*]] = insertelement <4 x i8> poison, i8 [[ARG0:%.*]], i32 0
49; CHECK-NEXT:    [[TMP1:%.*]] = insertelement <4 x i8> [[TMP0]], i8 [[ARG1:%.*]], i32 1
50; CHECK-NEXT:    [[TMP2:%.*]] = insertelement <4 x i8> [[TMP1]], i8 [[ARG2:%.*]], i32 2
51; CHECK-NEXT:    [[TMP3:%.*]] = insertelement <4 x i8> [[TMP2]], i8 [[ARG3:%.*]], i32 3
52; CHECK-NEXT:    br label [[BB3]]
53; CHECK:       bb3:
54; CHECK-NEXT:    [[TMP4:%.*]] = phi <4 x i8> [ [[TMP3]], [[BB2]] ], [ <i8 0, i8 0, i8 poison, i8 poison>, [[ENTRY:%.*]] ]
55; CHECK-NEXT:    [[TMP5:%.*]] = zext <4 x i8> [[TMP4]] to <4 x i32>
56; CHECK-NEXT:    [[TMP6:%.*]] = call i32 @llvm.vector.reduce.or.v4i32(<4 x i32> [[TMP5]])
57; CHECK-NEXT:    ret i32 [[TMP6]]
58;
59entry:
60  br i1 %cond, label %bb2, label %bb3
61
62bb2:
63  br label %bb3
64
65bb3:
66  %phi0 = phi i8 [ %arg0, %bb2 ], [ 0, %entry ]
67  %phi1 = phi i8 [ %arg1, %bb2 ], [ 0, %entry ]
68  %phi2 = phi i8 [ %arg2, %bb2 ], [ undef, %entry ]
69  %phi3 = phi i8 [ %arg3, %bb2 ], [ undef, %entry ]
70  %zext0 = zext i8 %phi0 to i32
71  %zext1 = zext i8 %phi1 to i32
72  %zext2 = zext i8 %phi2 to i32
73  %zext3 = zext i8 %phi3 to i32
74  %or1 = or i32 %zext0, %zext1
75  %or2 = or i32 %or1, %zext2
76  %or3 = or i32 %or2, %zext3
77  ret i32 %or3
78}
79
80define i32 @phi1UndefInput(i1 %cond, i8 %arg0, i8 %arg1, i8 %arg2, i8 %arg3) {
81; CHECK-LABEL: @phi1UndefInput(
82; CHECK-NEXT:  entry:
83; CHECK-NEXT:    br i1 [[COND:%.*]], label [[BB2:%.*]], label [[BB3:%.*]]
84; CHECK:       bb2:
85; CHECK-NEXT:    [[TMP0:%.*]] = insertelement <4 x i8> poison, i8 [[ARG0:%.*]], i32 0
86; CHECK-NEXT:    [[TMP1:%.*]] = insertelement <4 x i8> [[TMP0]], i8 [[ARG1:%.*]], i32 1
87; CHECK-NEXT:    [[TMP2:%.*]] = insertelement <4 x i8> [[TMP1]], i8 [[ARG2:%.*]], i32 2
88; CHECK-NEXT:    [[TMP3:%.*]] = insertelement <4 x i8> [[TMP2]], i8 [[ARG3:%.*]], i32 3
89; CHECK-NEXT:    br label [[BB3]]
90; CHECK:       bb3:
91; CHECK-NEXT:    [[TMP4:%.*]] = phi <4 x i8> [ [[TMP3]], [[BB2]] ], [ <i8 0, i8 0, i8 0, i8 poison>, [[ENTRY:%.*]] ]
92; CHECK-NEXT:    [[TMP5:%.*]] = zext <4 x i8> [[TMP4]] to <4 x i32>
93; CHECK-NEXT:    [[TMP6:%.*]] = call i32 @llvm.vector.reduce.or.v4i32(<4 x i32> [[TMP5]])
94; CHECK-NEXT:    ret i32 [[TMP6]]
95;
96entry:
97  br i1 %cond, label %bb2, label %bb3
98
99bb2:
100  br label %bb3
101
102bb3:
103  %phi0 = phi i8 [ %arg0, %bb2 ], [ 0, %entry ]
104  %phi1 = phi i8 [ %arg1, %bb2 ], [ 0, %entry ]
105  %phi2 = phi i8 [ %arg2, %bb2 ], [ 0, %entry ]
106  %phi3 = phi i8 [ %arg3, %bb2 ], [ undef, %entry ]
107  %zext0 = zext i8 %phi0 to i32
108  %zext1 = zext i8 %phi1 to i32
109  %zext2 = zext i8 %phi2 to i32
110  %zext3 = zext i8 %phi3 to i32
111  %or1 = or i32 %zext0, %zext1
112  %or2 = or i32 %or1, %zext2
113  %or3 = or i32 %or2, %zext3
114  ret i32 %or3
115}
116
117
118define i32 @phi1Undef1PoisonInput(i1 %cond, i8 %arg0, i8 %arg1, i8 %arg2, i8 %arg3) {
119; CHECK-LABEL: @phi1Undef1PoisonInput(
120; CHECK-NEXT:  entry:
121; CHECK-NEXT:    br i1 [[COND:%.*]], label [[BB2:%.*]], label [[BB3:%.*]]
122; CHECK:       bb2:
123; CHECK-NEXT:    [[TMP0:%.*]] = insertelement <4 x i8> poison, i8 [[ARG0:%.*]], i32 0
124; CHECK-NEXT:    [[TMP1:%.*]] = insertelement <4 x i8> [[TMP0]], i8 [[ARG1:%.*]], i32 1
125; CHECK-NEXT:    [[TMP2:%.*]] = insertelement <4 x i8> [[TMP1]], i8 [[ARG2:%.*]], i32 2
126; CHECK-NEXT:    [[TMP3:%.*]] = insertelement <4 x i8> [[TMP2]], i8 [[ARG3:%.*]], i32 3
127; CHECK-NEXT:    br label [[BB3]]
128; CHECK:       bb3:
129; CHECK-NEXT:    [[TMP4:%.*]] = phi <4 x i8> [ [[TMP3]], [[BB2]] ], [ <i8 0, i8 0, i8 poison, i8 poison>, [[ENTRY:%.*]] ]
130; CHECK-NEXT:    [[TMP5:%.*]] = zext <4 x i8> [[TMP4]] to <4 x i32>
131; CHECK-NEXT:    [[TMP6:%.*]] = call i32 @llvm.vector.reduce.or.v4i32(<4 x i32> [[TMP5]])
132; CHECK-NEXT:    ret i32 [[TMP6]]
133;
134entry:
135  br i1 %cond, label %bb2, label %bb3
136
137bb2:
138  br label %bb3
139
140bb3:
141  %phi0 = phi i8 [ %arg0, %bb2 ], [ 0, %entry ]
142  %phi1 = phi i8 [ %arg1, %bb2 ], [ 0, %entry ]
143  %phi2 = phi i8 [ %arg2, %bb2 ], [ poison, %entry ]
144  %phi3 = phi i8 [ %arg3, %bb2 ], [ undef, %entry ]
145  %zext0 = zext i8 %phi0 to i32
146  %zext1 = zext i8 %phi1 to i32
147  %zext2 = zext i8 %phi2 to i32
148  %zext3 = zext i8 %phi3 to i32
149  %or1 = or i32 %zext0, %zext1
150  %or2 = or i32 %or1, %zext2
151  %or3 = or i32 %or2, %zext3
152  ret i32 %or3
153}
154
155
156define i32 @phi1Undef2PoisonInputs(i1 %cond, i8 %arg0, i8 %arg1, i8 %arg2, i8 %arg3) {
157; CHECK-LABEL: @phi1Undef2PoisonInputs(
158; CHECK-NEXT:  entry:
159; CHECK-NEXT:    br i1 [[COND:%.*]], label [[BB2:%.*]], label [[BB3:%.*]]
160; CHECK:       bb2:
161; CHECK-NEXT:    [[TMP0:%.*]] = insertelement <4 x i8> poison, i8 [[ARG1:%.*]], i32 0
162; CHECK-NEXT:    [[TMP1:%.*]] = insertelement <4 x i8> [[TMP0]], i8 [[ARG0:%.*]], i32 1
163; CHECK-NEXT:    [[TMP2:%.*]] = insertelement <4 x i8> [[TMP1]], i8 [[ARG2:%.*]], i32 2
164; CHECK-NEXT:    [[TMP3:%.*]] = insertelement <4 x i8> [[TMP2]], i8 [[ARG3:%.*]], i32 3
165; CHECK-NEXT:    br label [[BB3]]
166; CHECK:       bb3:
167; CHECK-NEXT:    [[TMP4:%.*]] = phi <4 x i8> [ [[TMP3]], [[BB2]] ], [ <i8 0, i8 poison, i8 poison, i8 poison>, [[ENTRY:%.*]] ]
168; CHECK-NEXT:    [[TMP5:%.*]] = zext <4 x i8> [[TMP4]] to <4 x i32>
169; CHECK-NEXT:    [[TMP6:%.*]] = call i32 @llvm.vector.reduce.or.v4i32(<4 x i32> [[TMP5]])
170; CHECK-NEXT:    ret i32 [[TMP6]]
171;
172entry:
173  br i1 %cond, label %bb2, label %bb3
174
175bb2:
176  br label %bb3
177
178bb3:
179  %phi0 = phi i8 [ %arg0, %bb2 ], [ poison, %entry ]
180  %phi1 = phi i8 [ %arg1, %bb2 ], [ 0, %entry ]
181  %phi2 = phi i8 [ %arg2, %bb2 ], [ poison, %entry ]
182  %phi3 = phi i8 [ %arg3, %bb2 ], [ undef, %entry ]
183  %zext0 = zext i8 %phi0 to i32
184  %zext1 = zext i8 %phi1 to i32
185  %zext2 = zext i8 %phi2 to i32
186  %zext3 = zext i8 %phi3 to i32
187  %or1 = or i32 %zext0, %zext1
188  %or2 = or i32 %or1, %zext2
189  %or3 = or i32 %or2, %zext3
190  ret i32 %or3
191}
192
193define i32 @phi1Undef1PoisonGapInput(i1 %cond, i8 %arg0, i8 %arg1, i8 %arg2, i8 %arg3) {
194; CHECK-LABEL: @phi1Undef1PoisonGapInput(
195; CHECK-NEXT:  entry:
196; CHECK-NEXT:    br i1 [[COND:%.*]], label [[BB2:%.*]], label [[BB3:%.*]]
197; CHECK:       bb2:
198; CHECK-NEXT:    [[TMP0:%.*]] = insertelement <4 x i8> poison, i8 [[ARG1:%.*]], i32 0
199; CHECK-NEXT:    [[TMP1:%.*]] = insertelement <4 x i8> [[TMP0]], i8 [[ARG3:%.*]], i32 1
200; CHECK-NEXT:    [[TMP2:%.*]] = insertelement <4 x i8> [[TMP1]], i8 [[ARG0:%.*]], i32 2
201; CHECK-NEXT:    [[TMP3:%.*]] = insertelement <4 x i8> [[TMP2]], i8 [[ARG2:%.*]], i32 3
202; CHECK-NEXT:    br label [[BB3]]
203; CHECK:       bb3:
204; CHECK-NEXT:    [[TMP4:%.*]] = phi <4 x i8> [ [[TMP3]], [[BB2]] ], [ <i8 0, i8 0, i8 poison, i8 poison>, [[ENTRY:%.*]] ]
205; CHECK-NEXT:    [[TMP5:%.*]] = zext <4 x i8> [[TMP4]] to <4 x i32>
206; CHECK-NEXT:    [[TMP6:%.*]] = call i32 @llvm.vector.reduce.or.v4i32(<4 x i32> [[TMP5]])
207; CHECK-NEXT:    ret i32 [[TMP6]]
208;
209entry:
210  br i1 %cond, label %bb2, label %bb3
211
212bb2:
213  br label %bb3
214
215bb3:
216  %phi0 = phi i8 [ %arg0, %bb2 ], [ poison, %entry ]
217  %phi1 = phi i8 [ %arg1, %bb2 ], [ 0, %entry ]
218  %phi2 = phi i8 [ %arg2, %bb2 ], [ undef, %entry ]
219  %phi3 = phi i8 [ %arg3, %bb2 ], [ 0, %entry ]
220  %zext0 = zext i8 %phi0 to i32
221  %zext1 = zext i8 %phi1 to i32
222  %zext2 = zext i8 %phi2 to i32
223  %zext3 = zext i8 %phi3 to i32
224  %or1 = or i32 %zext0, %zext1
225  %or2 = or i32 %or1, %zext2
226  %or3 = or i32 %or2, %zext3
227  ret i32 %or3
228}
229