diff --git a/clang/lib/Sema/SemaExprMember.cpp b/clang/lib/Sema/SemaExprMember.cpp --- a/clang/lib/Sema/SemaExprMember.cpp +++ b/clang/lib/Sema/SemaExprMember.cpp @@ -406,7 +406,7 @@ if (HexSwizzle) CompSize--; - if (CompSize == 1) + if (CompSize == 1 && !HalvingSwizzle) return vecType->getElementType(); if (HasRepeated) VK = VK_RValue; diff --git a/clang/test/CodeGen/ext-vector.c b/clang/test/CodeGen/ext-vector.c --- a/clang/test/CodeGen/ext-vector.c +++ b/clang/test/CodeGen/ext-vector.c @@ -2,6 +2,7 @@ typedef __attribute__(( ext_vector_type(4) )) float float4; typedef __attribute__(( ext_vector_type(2) )) float float2; +typedef __attribute__((ext_vector_type(1))) float float1; typedef __attribute__(( ext_vector_type(4) )) int int4; typedef __attribute__(( ext_vector_type(4) )) unsigned int uint4; @@ -17,6 +18,7 @@ return V.wzyx+V; } +float1 vec1; float2 vec2, vec2_2; float4 vec4, vec4_2; float f; @@ -338,3 +340,44 @@ // CHECK: shufflevector {{.*}} vec4_2 = vec16.sabcd; } + +void test_swizzle() { + // CHECK: [[L0_VEC4:%.+]] = load <4 x float>, <4 x float>* @vec4, align 16 + // CHECK-NEXT: [[ODD:%.+]] = shufflevector <4 x float> [[L0_VEC4]], <4 x float> undef, <2 x i32> + // CHECK-NEXT: [[L1_VEC4:%.+]] = load <4 x float>, <4 x float>* @vec4, align 16 + // CHECK-NEXT: [[EVEN:%.+]] = shufflevector <4 x float> [[L1_VEC4]], <4 x float> undef, <2 x i32> + // CHECK-NEXT: [[FADD:%.+]] = fadd <2 x float> [[ODD]], [[EVEN]] + // CHECK-NEXT: store <2 x float> [[FADD]], <2 x float>* @vec2, align 8 + vec2 = vec4.odd + vec4.even; + + // CHECK-NEXT: [[L2_VEC4:%.+]] = load <4 x float>, <4 x float>* @vec4, align 16 + // CHECK-NEXT: [[LO:%.+]] = shufflevector <4 x float> [[L2_VEC4]], <4 x float> undef, <2 x i32> + // CHECK-NEXT: [[L3_VEC4:%.+]] = load <4 x float>, <4 x float>* @vec4, align 16 + // CHECK-NEXT: [[HI:%.+]] = shufflevector <4 x float> [[L3_VEC4]], <4 x float> undef, <2 x i32> + // CHECK-NEXT: [[FSUB:%.+]] = fsub <2 x float> [[LO]], [[HI]] + // CHECK-NEXT: store <2 x float> [[FSUB]], <2 x float>* @vec2, align 8 + vec2 = vec4.lo - vec4.hi; + + // CHECK-NEXT: [[L4_VEC4:%.+]] = load <4 x float>, <4 x float>* @vec4, align 16 + // CHECK-NEXT: [[ODD2:%.+]] = shufflevector <4 x float> [[L4_VEC4]], <4 x float> undef, <2 x i32> + // CHECK-NEXT: [[L5_VEC4_2:%.+]] = load <4 x float>, <4 x float>* @vec4_2, align 16 + // CHECK-NEXT: [[ODD3:%.+]] = shufflevector <2 x float> [[ODD2]], <2 x float> undef, <4 x i32> + // CHECK-NEXT: [[RES:%.+]] = shufflevector <4 x float> [[L5_VEC4_2]], <4 x float> [[ODD3]], <4 x i32> + // CHECK-NEXT: store <4 x float> [[RES]], <4 x float>* @vec4_2, align 16 + + vec4_2.hi = vec4.odd; + + // CHECK-NEXT: [[L0_VEC2:%.+]] = load <2 x float>, <2 x float>* @vec2, align 8 + // CHECK-NEXT: [[HI_2:%.+]] = shufflevector <2 x float> [[L0_VEC2]], <2 x float> undef, <1 x i32> + // CHECK-NEXT: [[L1_VEC2:%.+]] = load <2 x float>, <2 x float>* @vec2, align 8 + // CHECK-NEXT: [[LO_2:%.+]] = shufflevector <2 x float> [[L1_VEC2]], <2 x float> undef, <1 x i32> zeroinitializer + // CHECK-NEXT: [[FADD1:%.+]] = fadd <1 x float> [[HI_2]], [[LO_2]] + // CHECK-NEXT: [[L2_VEC2:%.+]] = load <2 x float>, <2 x float>* @vec2, align 8 + // CHECK-NEXT: [[ODD_2:%.+]] = shufflevector <2 x float> [[L2_VEC2]], <2 x float> undef, <1 x i32> + // CHECK-NEXT: [[FADD2:%.+]] = fadd <1 x float> [[FADD1]], [[ODD]] + // CHECK-NEXT: [[L3_VEC2:%.+]] = load <2 x float>, <2 x float>* @vec2, align 8 + // CHECK-NEXT: [[EVEN_2:%.+]] = shufflevector <2 x float> [[L3_VEC2]], <2 x float> undef, <1 x i32> zeroinitializer + // CHECK-NEXT: [[FADD3:%.+]] = fadd <1 x float> [[FADD2]], [[EVEN_2]] + // CHECK-NEXT: store <1 x float> [[FADD3]], <1 x float>* @vec1, align 4 + vec1 = vec2.hi + vec2.lo + vec2.odd + vec2.even; +} diff --git a/clang/test/Sema/ext_vector_components.c b/clang/test/Sema/ext_vector_components.c --- a/clang/test/Sema/ext_vector_components.c +++ b/clang/test/Sema/ext_vector_components.c @@ -72,3 +72,12 @@ float2 hi(float3 x) { return x.hi; } float2 ev(float3 x) { return x.even; } float2 od(float3 x) { return x.odd; } + +float lo2(float2 x) { return x.lo; } +// expected-error@-1 {{returning 'float __attribute__((ext_vector_type(1)))' (vector of 1 'float' value) from a function with incompatible result type 'float'}} +float hi2(float2 x) { return x.hi; } +// expected-error@-1 {{returning 'float __attribute__((ext_vector_type(1)))' (vector of 1 'float' value) from a function with incompatible result type 'float'}} +float ev2(float2 x) { return x.even; } +// expected-error@-1 {{returning 'float __attribute__((ext_vector_type(1)))' (vector of 1 'float' value) from a function with incompatible result type 'float'}} +float od2(float2 x) { return x.odd; } +// expected-error@-1 {{returning 'float __attribute__((ext_vector_type(1)))' (vector of 1 'float' value) from a function with incompatible result type 'float'}}