[PATCH] D89699: [ExtVector] Make .even/.odd/.lo/.hi return vectors for single elements.

Florian Hahn via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Mon Oct 19 06:54:14 PDT 2020


fhahn created this revision.
fhahn added reviewers: rjmccall, jfb, scanon, rsmith, hfinkel.
Herald added a subscriber: dexonsmith.
Herald added a project: clang.
fhahn requested review of this revision.

Currently the 'swizzle' accessors .even/.odd/.lo/.hi return a scalar
instead of a vector with a single element when the result has a single
element. The current behavior of Clang can lead to unexpected failures
when working with ext_vector_types  in templates that paramterize the
number of elements.

In the example below, currently `c.even` returns a scalar, which is then
converted to `char` and broadcasted to both elements of `b`.

  typedef uint16_t __attribute__ ((__ext_vector_type__(2))) ushort2;
  typedef uint8_t  __attribute__ ((__ext_vector_type__(2))) uchar2;
  
  ushort2 c = 0x0102;
  uchar2 b = (uchar2) c.even;

This patch changes the behavior so that swizzels return single element
vectors in that case. This should make the behavior consistent with
vectors with more than 1 element.

Just from looking at the implementation, it seems like the current
behavior is mostly a side-effect of the implementation, where the
handling of element accesses and swizzels is combined.

This patch changes existing behavior and may break some code that relies
on the current behavior. Unfortunately I could not find any
specification for the ext_vector_type so it is hard to tell if the
existing behavior is actually intentional or not. At least there are no
unit tests for the current behavior.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D89699

Files:
  clang/lib/Sema/SemaExprMember.cpp
  clang/test/CodeGen/ext-vector.c
  clang/test/Sema/ext_vector_components.c


Index: clang/test/Sema/ext_vector_components.c
===================================================================
--- clang/test/Sema/ext_vector_components.c
+++ 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 at -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 at -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 at -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 at -1 {{returning 'float __attribute__((ext_vector_type(1)))' (vector of 1 'float' value) from a function with incompatible result type 'float'}}
Index: clang/test/CodeGen/ext-vector.c
===================================================================
--- clang/test/CodeGen/ext-vector.c
+++ 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 {{.*}} <i32 10, i32 11, i32 12, i32 13>
   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> <i32 1, i32 3>
+  // 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> <i32 0, i32 2>
+  // 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> <i32 0, i32 1>
+  // 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> <i32 2, i32 3>
+  // 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> <i32 1, i32 3>
+  // 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> <i32 0, i32 1, i32 undef, i32 undef>
+  // CHECK-NEXT: [[RES:%.+]] = shufflevector <4 x float> [[L5_VEC4_2]], <4 x float> [[ODD3]], <4 x i32> <i32 0, i32 1, i32 4, i32 5>
+  // 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> <i32 1>
+  // 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> <i32 1>
+  // 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;
+}
Index: clang/lib/Sema/SemaExprMember.cpp
===================================================================
--- clang/lib/Sema/SemaExprMember.cpp
+++ 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;


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D89699.299040.patch
Type: text/x-patch
Size: 5230 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20201019/a42bb7fd/attachment-0001.bin>


More information about the cfe-commits mailing list