Skip to content

Commit c3fe847

Browse files
[Clang] Add option to handle behaviour of vector bool/vector pixel.
Added the option `-altivec-src-compat=[mixed,gcc,xl]`. The default at this time is `mixed`. The default behavior for clang is for all vector compares to return a scalar unless the vectors being compared are vector bool or vector pixel. In that case the compare returns a vector. With the gcc case all vector compares return vectors and in the xl case all vector compares return scalars. This patch does not change the default behavior of clang. This option will be used in future patches to implement behaviour compatibility for the vector bool/pixel types. Reviewed By: bmahjour Differential Revision: https://reviews.llvm.org/D103615
1 parent cccc7e5 commit c3fe847

File tree

10 files changed

+597
-5
lines changed

10 files changed

+597
-5
lines changed

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7441,6 +7441,12 @@ def warn_deprecated_volatile_structured_binding : Warning<
74417441
"volatile qualifier in structured binding declaration is deprecated">,
74427442
InGroup<DeprecatedVolatile>;
74437443

7444+
def warn_deprecated_altivec_src_compat : Warning<
7445+
"Current handling of vector bool and vector pixel types in this context are "
7446+
"deprecated. The default behaviour will soon change to that implied by the "
7447+
"'-altivec-compat=xl' option">,
7448+
InGroup<DiagGroup<"deprecated-altivec-src-compat">>;
7449+
74447450
def err_catch_incomplete_ptr : Error<
74457451
"cannot catch pointer to incomplete type %0">;
74467452
def err_catch_incomplete_ref : Error<

clang/include/clang/Basic/LangOptions.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,8 @@ LANGOPT(WritableStrings , 1, 0, "writable string support")
126126
LANGOPT(ConstStrings , 1, 0, "const-qualified string support")
127127
ENUM_LANGOPT(LaxVectorConversions, LaxVectorConversionKind, 2,
128128
LaxVectorConversionKind::All, "lax vector conversions")
129+
ENUM_LANGOPT(AltivecSrcCompat, AltivecSrcCompatKind, 2,
130+
AltivecSrcCompatKind::Default, "Altivec source compatibility")
129131
LANGOPT(ConvergentFunctions, 1, 1, "Assume convergent functions")
130132
LANGOPT(AltiVec , 1, 0, "AltiVec-style vector initializers")
131133
LANGOPT(ZVector , 1, 0, "System z vector extensions")

clang/include/clang/Basic/LangOptions.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,18 @@ class LangOptions : public LangOptionsBase {
244244
All,
245245
};
246246

247+
enum class AltivecSrcCompatKind {
248+
// All vector compares produce scalars except vector pixel and vector bool.
249+
// The types vector pixel and vector bool return vector results.
250+
Mixed,
251+
// All vector compares produce vector results as in GCC.
252+
GCC,
253+
// All vector compares produce scalars as in XL.
254+
XL,
255+
// Default clang behaviour.
256+
Default = Mixed,
257+
};
258+
247259
enum class SignReturnAddressScopeKind {
248260
/// No signing for any function.
249261
None,

clang/include/clang/Driver/Options.td

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3823,6 +3823,18 @@ def u : JoinedOrSeparate<["-"], "u">, Group<u_Group>;
38233823
def v : Flag<["-"], "v">, Flags<[CC1Option, CoreOption]>,
38243824
HelpText<"Show commands to run and use verbose output">,
38253825
MarshallingInfoFlag<HeaderSearchOpts<"Verbose">>;
3826+
def altivec_src_compat : Joined<["-"], "faltivec-src-compat=">,
3827+
Flags<[CC1Option]>, Group<f_Group>,
3828+
HelpText<"Source-level compatibility for Altivec vectors (for PowerPC "
3829+
"targets). This includes results of vector comparison (scalar for "
3830+
"'xl', vector for 'gcc') as well as behavior when initializing with "
3831+
"a scalar (splatting for 'xl', element zero only for 'gcc'). For "
3832+
"'mixed', the compatibility is as 'gcc' for 'vector bool/vector "
3833+
"pixel' and as 'xl' for other types. Current default is 'mixed'.">,
3834+
Values<"mixed,gcc,xl">,
3835+
NormalizedValuesScope<"LangOptions::AltivecSrcCompatKind">,
3836+
NormalizedValues<["Mixed", "GCC", "XL"]>,
3837+
MarshallingInfoEnum<LangOpts<"AltivecSrcCompat">, "Mixed">;
38263838
def verify_debug_info : Flag<["--"], "verify-debug-info">, Flags<[NoXarchOption]>,
38273839
HelpText<"Verify the binary representation of debug output">;
38283840
def weak_l : Joined<["-"], "weak-l">, Flags<[LinkerInput]>;

clang/lib/Driver/ToolChains/Clang.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5816,6 +5816,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
58165816
(Args.hasArg(options::OPT_mkernel) && types::isCXX(InputType)))
58175817
CmdArgs.push_back("-fapple-kext");
58185818

5819+
Args.AddLastArg(CmdArgs, options::OPT_altivec_src_compat);
58195820
Args.AddLastArg(CmdArgs, options::OPT_flax_vector_conversions_EQ);
58205821
Args.AddLastArg(CmdArgs, options::OPT_fobjc_sender_dependent_dispatch);
58215822
Args.AddLastArg(CmdArgs, options::OPT_fdiagnostics_print_source_range_info);

clang/lib/Sema/SemaExpr.cpp

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12224,11 +12224,30 @@ QualType Sema::CheckVectorCompareOperands(ExprResult &LHS, ExprResult &RHS,
1222412224

1222512225
QualType LHSType = LHS.get()->getType();
1222612226

12227-
// If AltiVec, the comparison results in a numeric type, i.e.
12228-
// bool for C++, int for C
12229-
if (getLangOpts().AltiVec &&
12230-
vType->castAs<VectorType>()->getVectorKind() == VectorType::AltiVecVector)
12231-
return Context.getLogicalOperationType();
12227+
// Determine the return type of a vector compare. By default clang will return
12228+
// a scalar for all vector compares except vector bool and vector pixel.
12229+
// With the gcc compiler we will always return a vector type and with the xl
12230+
// compiler we will always return a scalar type. This switch allows choosing
12231+
// which behavior is prefered.
12232+
if (getLangOpts().AltiVec) {
12233+
switch (getLangOpts().getAltivecSrcCompat()) {
12234+
case LangOptions::AltivecSrcCompatKind::Mixed:
12235+
// If AltiVec, the comparison results in a numeric type, i.e.
12236+
// bool for C++, int for C
12237+
if (vType->castAs<VectorType>()->getVectorKind() ==
12238+
VectorType::AltiVecVector)
12239+
return Context.getLogicalOperationType();
12240+
else
12241+
Diag(Loc, diag::warn_deprecated_altivec_src_compat);
12242+
break;
12243+
case LangOptions::AltivecSrcCompatKind::GCC:
12244+
// For GCC we always return the vector type.
12245+
break;
12246+
case LangOptions::AltivecSrcCompatKind::XL:
12247+
return Context.getLogicalOperationType();
12248+
break;
12249+
}
12250+
}
1223212251

1223312252
// For non-floating point types, check for self-comparisons of the form
1223412253
// x == x, x != x, x < x, etc. These always evaluate to a constant, and
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
2+
// RUN: not %clang_cc1 -target-feature +altivec -target-feature +vsx \
3+
// RUN: -faltivec-src-compat=mixed -triple powerpc-unknown-unknown -S -emit-llvm %s -o - 2>&1 | FileCheck %s --check-prefix=ERROR
4+
// RUN: not %clang_cc1 -target-feature +altivec -target-feature +vsx \
5+
// RUN: -faltivec-src-compat=gcc -triple powerpc-unknown-unknown -S -emit-llvm %s -o - 2>&1| FileCheck %s --check-prefix=ERROR
6+
// RUN: %clang_cc1 -target-feature +altivec -target-feature +vsx \
7+
// RUN: -faltivec-src-compat=xl -triple powerpc-unknown-unknown -S -emit-llvm %s -o - | FileCheck %s
8+
// RUN: %clang -mcpu=pwr8 -faltivec-src-compat=xl --target=powerpc-unknown-unknown -S -emit-llvm %s -o - | FileCheck %s
9+
// RUN: %clang -mcpu=pwr9 -faltivec-src-compat=xl --target=powerpc-unknown-unknown -S -emit-llvm %s -o - | FileCheck %s
10+
11+
// CHECK-LABEL: @bi8(
12+
// CHECK-NEXT: entry:
13+
// CHECK-NEXT: [[A_ADDR:%.*]] = alloca <16 x i8>, align 16
14+
// CHECK-NEXT: [[B_ADDR:%.*]] = alloca <16 x i8>, align 16
15+
// CHECK-NEXT: store <16 x i8> [[A:%.*]], <16 x i8>* [[A_ADDR]], align 16
16+
// CHECK-NEXT: store <16 x i8> [[B:%.*]], <16 x i8>* [[B_ADDR]], align 16
17+
// CHECK-NEXT: [[TMP0:%.*]] = load <16 x i8>, <16 x i8>* [[A_ADDR]], align 16
18+
// CHECK-NEXT: [[TMP1:%.*]] = load <16 x i8>, <16 x i8>* [[B_ADDR]], align 16
19+
// CHECK-NEXT: [[TMP2:%.*]] = call i32 @llvm.ppc.altivec.vcmpequb.p(i32 2, <16 x i8> [[TMP0]], <16 x i8> [[TMP1]])
20+
// CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP2]], 0
21+
// CHECK-NEXT: [[TMP3:%.*]] = zext i1 [[TOBOOL]] to i64
22+
// CHECK-NEXT: [[COND:%.*]] = select i1 [[TOBOOL]], i32 3, i32 7
23+
// CHECK-NEXT: ret i32 [[COND]]
24+
//
25+
// ERROR: error: used type '__attribute__((__vector_size__(16 * sizeof(char)))) char' (vector of 16 'char' values) where arithmetic or pointer type is required
26+
int bi8(vector bool char a, vector bool char b) {
27+
return a == b ? 3 : 7;
28+
}
29+
30+
// CHECK-LABEL: @bi16(
31+
// CHECK-NEXT: entry:
32+
// CHECK-NEXT: [[A_ADDR:%.*]] = alloca <8 x i16>, align 16
33+
// CHECK-NEXT: [[B_ADDR:%.*]] = alloca <8 x i16>, align 16
34+
// CHECK-NEXT: store <8 x i16> [[A:%.*]], <8 x i16>* [[A_ADDR]], align 16
35+
// CHECK-NEXT: store <8 x i16> [[B:%.*]], <8 x i16>* [[B_ADDR]], align 16
36+
// CHECK-NEXT: [[TMP0:%.*]] = load <8 x i16>, <8 x i16>* [[A_ADDR]], align 16
37+
// CHECK-NEXT: [[TMP1:%.*]] = load <8 x i16>, <8 x i16>* [[B_ADDR]], align 16
38+
// CHECK-NEXT: [[TMP2:%.*]] = call i32 @llvm.ppc.altivec.vcmpequh.p(i32 2, <8 x i16> [[TMP0]], <8 x i16> [[TMP1]])
39+
// CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP2]], 0
40+
// CHECK-NEXT: [[TMP3:%.*]] = zext i1 [[TOBOOL]] to i64
41+
// CHECK-NEXT: [[COND:%.*]] = select i1 [[TOBOOL]], i32 3, i32 7
42+
// CHECK-NEXT: ret i32 [[COND]]
43+
//
44+
// ERROR: error: used type '__attribute__((__vector_size__(8 * sizeof(short)))) short' (vector of 8 'short' values) where arithmetic or pointer type is required
45+
int bi16(vector bool short a, vector bool short b) {
46+
return a == b ? 3 : 7;
47+
}
48+
49+
// CHECK-LABEL: @bi32(
50+
// CHECK-NEXT: entry:
51+
// CHECK-NEXT: [[A_ADDR:%.*]] = alloca <4 x i32>, align 16
52+
// CHECK-NEXT: [[B_ADDR:%.*]] = alloca <4 x i32>, align 16
53+
// CHECK-NEXT: store <4 x i32> [[A:%.*]], <4 x i32>* [[A_ADDR]], align 16
54+
// CHECK-NEXT: store <4 x i32> [[B:%.*]], <4 x i32>* [[B_ADDR]], align 16
55+
// CHECK-NEXT: [[TMP0:%.*]] = load <4 x i32>, <4 x i32>* [[A_ADDR]], align 16
56+
// CHECK-NEXT: [[TMP1:%.*]] = load <4 x i32>, <4 x i32>* [[B_ADDR]], align 16
57+
// CHECK-NEXT: [[TMP2:%.*]] = call i32 @llvm.ppc.altivec.vcmpequw.p(i32 2, <4 x i32> [[TMP0]], <4 x i32> [[TMP1]])
58+
// CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP2]], 0
59+
// CHECK-NEXT: [[TMP3:%.*]] = zext i1 [[TOBOOL]] to i64
60+
// CHECK-NEXT: [[COND:%.*]] = select i1 [[TOBOOL]], i32 3, i32 7
61+
// CHECK-NEXT: ret i32 [[COND]]
62+
//
63+
// ERROR: error: used type '__attribute__((__vector_size__(4 * sizeof(long)))) long' (vector of 4 'long' values) where arithmetic or pointer type is required
64+
int bi32(vector bool int a, vector bool int b) {
65+
return a == b ? 3 : 7;
66+
}
67+
68+
// CHECK-LABEL: @bi64(
69+
// CHECK-NEXT: entry:
70+
// CHECK-NEXT: [[A_ADDR:%.*]] = alloca <2 x i64>, align 16
71+
// CHECK-NEXT: [[B_ADDR:%.*]] = alloca <2 x i64>, align 16
72+
// CHECK-NEXT: store <2 x i64> [[A:%.*]], <2 x i64>* [[A_ADDR]], align 16
73+
// CHECK-NEXT: store <2 x i64> [[B:%.*]], <2 x i64>* [[B_ADDR]], align 16
74+
// CHECK-NEXT: [[TMP0:%.*]] = load <2 x i64>, <2 x i64>* [[A_ADDR]], align 16
75+
// CHECK-NEXT: [[TMP1:%.*]] = load <2 x i64>, <2 x i64>* [[B_ADDR]], align 16
76+
// CHECK-NEXT: [[TMP2:%.*]] = call i32 @llvm.ppc.altivec.vcmpequd.p(i32 2, <2 x i64> [[TMP0]], <2 x i64> [[TMP1]])
77+
// CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP2]], 0
78+
// CHECK-NEXT: [[TMP3:%.*]] = zext i1 [[TOBOOL]] to i64
79+
// CHECK-NEXT: [[COND:%.*]] = select i1 [[TOBOOL]], i32 3, i32 7
80+
// CHECK-NEXT: ret i32 [[COND]]
81+
//
82+
// ERROR: error: used type '__attribute__((__vector_size__(2 * sizeof(long long)))) long long' (vector of 2 'long long' values) where arithmetic or pointer type is required
83+
int bi64(vector bool long long a, vector bool long long b) {
84+
return a == b ? 3 : 7;
85+
}
86+
87+
// CHECK-LABEL: @VecPixel(
88+
// CHECK-NEXT: entry:
89+
// CHECK-NEXT: [[A_ADDR:%.*]] = alloca <8 x i16>, align 16
90+
// CHECK-NEXT: [[B_ADDR:%.*]] = alloca <8 x i16>, align 16
91+
// CHECK-NEXT: store <8 x i16> [[A:%.*]], <8 x i16>* [[A_ADDR]], align 16
92+
// CHECK-NEXT: store <8 x i16> [[B:%.*]], <8 x i16>* [[B_ADDR]], align 16
93+
// CHECK-NEXT: [[TMP0:%.*]] = load <8 x i16>, <8 x i16>* [[A_ADDR]], align 16
94+
// CHECK-NEXT: [[TMP1:%.*]] = load <8 x i16>, <8 x i16>* [[B_ADDR]], align 16
95+
// CHECK-NEXT: [[TMP2:%.*]] = call i32 @llvm.ppc.altivec.vcmpequh.p(i32 2, <8 x i16> [[TMP0]], <8 x i16> [[TMP1]])
96+
// CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP2]], 0
97+
// CHECK-NEXT: [[TMP3:%.*]] = zext i1 [[TOBOOL]] to i64
98+
// CHECK-NEXT: [[COND:%.*]] = select i1 [[TOBOOL]], i32 3, i32 7
99+
// CHECK-NEXT: ret i32 [[COND]]
100+
//
101+
// ERROR: error: used type '__attribute__((__vector_size__(8 * sizeof(short)))) short' (vector of 8 'short' values) where arithmetic or pointer type is required
102+
int VecPixel(vector pixel a, vector pixel b) {
103+
return a == b ? 3 : 7;
104+
}
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
2+
// RUN: %clang_cc1 -target-feature +altivec -target-feature +vsx \
3+
// RUN: -faltivec-src-compat=mixed -triple powerpc-unknown-unknown -S -emit-llvm %s -o - | FileCheck %s
4+
// RUN: %clang_cc1 -target-feature +altivec -target-feature +vsx \
5+
// RUN: -faltivec-src-compat=gcc -triple powerpc-unknown-unknown -S -emit-llvm %s -o - | FileCheck %s
6+
// RUN: not %clang_cc1 -target-feature +altivec -target-feature +vsx \
7+
// RUN: -faltivec-src-compat=xl -triple powerpc-unknown-unknown -S -emit-llvm %s -o - 2>&1 | FileCheck %s --check-prefix=ERROR
8+
// RUN: %clang -mcpu=pwr8 -faltivec-src-compat=gcc --target=powerpc-unknown-unknown -S -emit-llvm %s -o - | FileCheck %s
9+
// RUN: %clang -mcpu=pwr9 -faltivec-src-compat=gcc --target=powerpc-unknown-unknown -S -emit-llvm %s -o - | FileCheck %s
10+
11+
// CHECK-LABEL: @bi8(
12+
// CHECK-NEXT: entry:
13+
// CHECK-NEXT: [[A_ADDR:%.*]] = alloca <16 x i8>, align 16
14+
// CHECK-NEXT: [[B_ADDR:%.*]] = alloca <16 x i8>, align 16
15+
// CHECK-NEXT: store <16 x i8> [[A:%.*]], <16 x i8>* [[A_ADDR]], align 16
16+
// CHECK-NEXT: store <16 x i8> [[B:%.*]], <16 x i8>* [[B_ADDR]], align 16
17+
// CHECK-NEXT: [[TMP0:%.*]] = load <16 x i8>, <16 x i8>* [[A_ADDR]], align 16
18+
// CHECK-NEXT: [[TMP1:%.*]] = load <16 x i8>, <16 x i8>* [[B_ADDR]], align 16
19+
// CHECK-NEXT: [[CMP:%.*]] = icmp eq <16 x i8> [[TMP0]], [[TMP1]]
20+
// CHECK-NEXT: [[SEXT:%.*]] = sext <16 x i1> [[CMP]] to <16 x i8>
21+
// CHECK-NEXT: ret <16 x i8> [[SEXT]]
22+
//
23+
// ERROR: returning 'int' from a function with incompatible result type
24+
vector unsigned char bi8(vector bool char a, vector bool char b) {
25+
return a == b;
26+
}
27+
28+
// CHECK-LABEL: @bi16(
29+
// CHECK-NEXT: entry:
30+
// CHECK-NEXT: [[A_ADDR:%.*]] = alloca <8 x i16>, align 16
31+
// CHECK-NEXT: [[B_ADDR:%.*]] = alloca <8 x i16>, align 16
32+
// CHECK-NEXT: store <8 x i16> [[A:%.*]], <8 x i16>* [[A_ADDR]], align 16
33+
// CHECK-NEXT: store <8 x i16> [[B:%.*]], <8 x i16>* [[B_ADDR]], align 16
34+
// CHECK-NEXT: [[TMP0:%.*]] = load <8 x i16>, <8 x i16>* [[A_ADDR]], align 16
35+
// CHECK-NEXT: [[TMP1:%.*]] = load <8 x i16>, <8 x i16>* [[B_ADDR]], align 16
36+
// CHECK-NEXT: [[CMP:%.*]] = icmp eq <8 x i16> [[TMP0]], [[TMP1]]
37+
// CHECK-NEXT: [[SEXT:%.*]] = sext <8 x i1> [[CMP]] to <8 x i16>
38+
// CHECK-NEXT: ret <8 x i16> [[SEXT]]
39+
//
40+
// ERROR: returning 'int' from a function with incompatible result type
41+
vector bool short bi16(vector bool short a, vector bool short b) {
42+
return a == b;
43+
}
44+
45+
// CHECK-LABEL: @bi32(
46+
// CHECK-NEXT: entry:
47+
// CHECK-NEXT: [[A_ADDR:%.*]] = alloca <4 x i32>, align 16
48+
// CHECK-NEXT: [[B_ADDR:%.*]] = alloca <4 x i32>, align 16
49+
// CHECK-NEXT: store <4 x i32> [[A:%.*]], <4 x i32>* [[A_ADDR]], align 16
50+
// CHECK-NEXT: store <4 x i32> [[B:%.*]], <4 x i32>* [[B_ADDR]], align 16
51+
// CHECK-NEXT: [[TMP0:%.*]] = load <4 x i32>, <4 x i32>* [[A_ADDR]], align 16
52+
// CHECK-NEXT: [[TMP1:%.*]] = load <4 x i32>, <4 x i32>* [[B_ADDR]], align 16
53+
// CHECK-NEXT: [[CMP:%.*]] = icmp eq <4 x i32> [[TMP0]], [[TMP1]]
54+
// CHECK-NEXT: [[SEXT:%.*]] = sext <4 x i1> [[CMP]] to <4 x i32>
55+
// CHECK-NEXT: ret <4 x i32> [[SEXT]]
56+
//
57+
// ERROR: returning 'int' from a function with incompatible result type
58+
vector bool int bi32(vector bool int a, vector bool int b) {
59+
return a == b;
60+
}
61+
62+
// CHECK-LABEL: @bi64(
63+
// CHECK-NEXT: entry:
64+
// CHECK-NEXT: [[A_ADDR:%.*]] = alloca <2 x i64>, align 16
65+
// CHECK-NEXT: [[B_ADDR:%.*]] = alloca <2 x i64>, align 16
66+
// CHECK-NEXT: store <2 x i64> [[A:%.*]], <2 x i64>* [[A_ADDR]], align 16
67+
// CHECK-NEXT: store <2 x i64> [[B:%.*]], <2 x i64>* [[B_ADDR]], align 16
68+
// CHECK-NEXT: [[TMP0:%.*]] = load <2 x i64>, <2 x i64>* [[A_ADDR]], align 16
69+
// CHECK-NEXT: [[TMP1:%.*]] = load <2 x i64>, <2 x i64>* [[B_ADDR]], align 16
70+
// CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i64> [[TMP0]], [[TMP1]]
71+
// CHECK-NEXT: [[SEXT:%.*]] = sext <2 x i1> [[CMP]] to <2 x i64>
72+
// CHECK-NEXT: ret <2 x i64> [[SEXT]]
73+
//
74+
// ERROR: returning 'int' from a function with incompatible result type
75+
vector long long bi64(vector bool long long a, vector bool long long b) {
76+
return a == b;
77+
}
78+
79+
// CHECK-LABEL: @VecPixel(
80+
// CHECK-NEXT: entry:
81+
// CHECK-NEXT: [[A_ADDR:%.*]] = alloca <8 x i16>, align 16
82+
// CHECK-NEXT: [[B_ADDR:%.*]] = alloca <8 x i16>, align 16
83+
// CHECK-NEXT: store <8 x i16> [[A:%.*]], <8 x i16>* [[A_ADDR]], align 16
84+
// CHECK-NEXT: store <8 x i16> [[B:%.*]], <8 x i16>* [[B_ADDR]], align 16
85+
// CHECK-NEXT: [[TMP0:%.*]] = load <8 x i16>, <8 x i16>* [[A_ADDR]], align 16
86+
// CHECK-NEXT: [[TMP1:%.*]] = load <8 x i16>, <8 x i16>* [[B_ADDR]], align 16
87+
// CHECK-NEXT: [[CMP:%.*]] = icmp eq <8 x i16> [[TMP0]], [[TMP1]]
88+
// CHECK-NEXT: [[SEXT:%.*]] = sext <8 x i1> [[CMP]] to <8 x i16>
89+
// CHECK-NEXT: ret <8 x i16> [[SEXT]]
90+
//
91+
// ERROR: returning 'int' from a function with incompatible result type
92+
vector pixel VecPixel(vector pixel a, vector pixel b) {
93+
return a == b;
94+
}

0 commit comments

Comments
 (0)