Skip to content

Commit ac07996

Browse files
committed
Fixups
1 parent e3cf243 commit ac07996

File tree

2 files changed

+55
-5
lines changed

2 files changed

+55
-5
lines changed

llvm/lib/Transforms/Vectorize/LoopVectorizationLegality.cpp

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -954,24 +954,22 @@ bool LoopVectorizationLegality::canVectorizeInstrs() {
954954
if (CI && !VFDatabase::getMappings(*CI).empty())
955955
VecCallVariantsFound = true;
956956

957-
auto canWidenInstruction = [this](Instruction const &Inst) {
957+
auto CanWidenInstruction = [this](Instruction const &Inst) {
958958
Type *InstTy = Inst.getType();
959959
if (isa<CallInst>(Inst) && isa<StructType>(InstTy) &&
960960
canWidenCallReturnType(InstTy)) {
961961
StructVecCallFound = true;
962962
// For now, we can only widen struct values returned from calls where
963963
// all users are extractvalue instructions.
964-
return llvm::all_of(Inst.uses(), [](auto &Use) {
965-
return isa<ExtractValueInst>(Use.getUser());
966-
});
964+
return llvm::all_of(Inst.users(), IsaPred<ExtractValueInst>);
967965
}
968966
return VectorType::isValidElementType(InstTy) || InstTy->isVoidTy();
969967
};
970968

971969
// Check that the instruction return type is vectorizable.
972970
// We can't vectorize casts from vector type to scalar type.
973971
// Also, we can't vectorize extractelement instructions.
974-
if (!canWidenInstruction(I) ||
972+
if (!CanWidenInstruction(I) ||
975973
(isa<CastInst>(I) &&
976974
!VectorType::isValidElementType(I.getOperand(0)->getType())) ||
977975
isa<ExtractElementInst>(I)) {

llvm/test/Transforms/LoopVectorize/struct-return.ll

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,30 @@ exit:
143143
ret void
144144
}
145145

146+
; TODO: Support vectorization in this case.
147+
; CHECK-REMARKS: remark: {{.*}} loop not vectorized: Auto-vectorization of calls that return struct types is not yet supported
148+
define void @struct_return_i32_three_results_widen(ptr noalias %in, ptr noalias writeonly %out_a) {
149+
; CHECK-LABEL: define void @struct_return_i32_three_results_widen
150+
; CHECK-NOT: vector.body:
151+
entry:
152+
br label %for.body
153+
154+
for.body:
155+
%iv = phi i64 [ 0, %entry ], [ %iv.next, %for.body ]
156+
%arrayidx = getelementptr inbounds i32, ptr %in, i64 %iv
157+
%in_val = load i32, ptr %arrayidx, align 4
158+
%call = tail call { i32, i32, i32 } @qux(i32 %in_val) #5
159+
%extract_a = extractvalue { i32, i32, i32 } %call, 0
160+
%arrayidx2 = getelementptr inbounds i32, ptr %out_a, i64 %iv
161+
store i32 %extract_a, ptr %arrayidx2, align 4
162+
%iv.next = add nuw nsw i64 %iv, 1
163+
%exitcond.not = icmp eq i64 %iv.next, 1024
164+
br i1 %exitcond.not, label %exit, label %for.body
165+
166+
exit:
167+
ret void
168+
}
169+
146170
; Negative test. Widening structs with mixed element types is not supported.
147171
; CHECK-REMARKS-COUNT: remark: {{.*}} loop not vectorized: instruction return type cannot be vectorized
148172
define void @negative_mixed_element_type_struct_return(ptr noalias %in, ptr noalias writeonly %out_a, ptr noalias writeonly %out_b) {
@@ -229,6 +253,30 @@ exit:
229253
ret void
230254
}
231255

256+
; Negative test. The second element of the struct cannot be widened.
257+
; CHECK-REMARKS-COUNT: remark: {{.*}} loop not vectorized: instruction return type cannot be vectorized
258+
define void @negative_non_widenable_element(ptr noalias %in, ptr noalias writeonly %out_a) {
259+
; CHECK-LABEL: define void @negative_non_widenable_element
260+
; CHECK-NOT: vector.body:
261+
entry:
262+
br label %for.body
263+
264+
for.body:
265+
%iv = phi i64 [ 0, %entry ], [ %iv.next, %for.body ]
266+
%arrayidx = getelementptr inbounds float, ptr %in, i64 %iv
267+
%in_val = load float, ptr %arrayidx, align 4
268+
%call = tail call { float, [1 x float] } @foo_one_non_widenable_element(float %in_val) #0
269+
%extract_a = extractvalue { float, [1 x float] } %call, 0
270+
%arrayidx2 = getelementptr inbounds float, ptr %out_a, i64 %iv
271+
store float %extract_a, ptr %arrayidx2, align 4
272+
%iv.next = add nuw nsw i64 %iv, 1
273+
%exitcond.not = icmp eq i64 %iv.next, 1024
274+
br i1 %exitcond.not, label %exit, label %for.body
275+
276+
exit:
277+
ret void
278+
}
279+
232280
; Negative test. Homogeneous structs of arrays are not supported.
233281
; CHECK-REMARKS-COUNT: remark: {{.*}} loop not vectorized: instruction return type cannot be vectorized
234282
define void @negative_struct_array_elements(ptr noalias %in, ptr noalias writeonly %out_a, ptr noalias writeonly %out_b) {
@@ -312,10 +360,13 @@ declare { float, i32 } @baz(float)
312360
declare %named_struct @bar_named(double)
313361
declare { { float, float } } @foo_nested_struct(float)
314362
declare { [2 x float] } @foo_arrays(float)
363+
declare { float, [1 x float] } @foo_one_non_widenable_element(float)
364+
declare { i32, i32, i32 } @qux(i32)
315365

316366
declare { <2 x float>, <2 x float> } @fixed_vec_foo(<2 x float>)
317367
declare { <2 x double>, <2 x double> } @fixed_vec_bar(<2 x double>)
318368
declare { <2 x float>, <2 x i32> } @fixed_vec_baz(<2 x float>)
369+
declare { <2 x i32>, <2 x i32>, <2 x i32> } @fixed_vec_qux(<2 x i32>)
319370

320371
declare { <vscale x 4 x float>, <vscale x 4 x float> } @scalable_vec_masked_foo(<vscale x 4 x float>, <vscale x 4 x i1>)
321372

@@ -324,3 +375,4 @@ attributes #1 = { nounwind "vector-function-abi-variant"="_ZGVnN2v_bar(fixed_vec
324375
attributes #2 = { nounwind "vector-function-abi-variant"="_ZGVnN2v_baz(fixed_vec_baz)" }
325376
attributes #3 = { nounwind "vector-function-abi-variant"="_ZGVsMxv_foo(scalable_vec_masked_foo)" }
326377
attributes #4 = { nounwind "vector-function-abi-variant"="_ZGVnN2v_bar_named(fixed_vec_bar)" }
378+
attributes #5 = { nounwind "vector-function-abi-variant"="_ZGVnN2v_qux(fixed_vec_qux)" }

0 commit comments

Comments
 (0)