[cfe-dev] Issues with vector initialization using parentheses

Magee, Josh Joshua.Magee at am.sony.com
Thu Aug 30 19:12:25 PDT 2012


Hi, 

I noticed some issues with vector initialization using parentheses.

Consulting the Clang documentation: http://clang.llvm.org/docs/LanguageExtensions.html#vectors
See the following paragraph on Vector Literals:
"Vector literals can be used to create vectors from a set of scalars, or
vectors. Either parentheses or braces form can be used. In the parentheses form
the number of literal values specified must be one, i.e. referring to a scalar
value, or must match the size of the vector type being created. If a single
scalar literal value is specified, the scalar literal value will be replicated
to all the components of the vector type. In the brackets form any number of
literals can be specified."

They key points are that when using parentheses initialization:
Given this, my understanding is that when using parentheses initialization:
1) The number of elements in the initializer must be 1.  This value is
replicated across all vector elements.
    -or-
2) The number of elements must be equal to the size of the vector.  I.e., the
number of elements in the initialization must be the same as the number of
elements in the vector.

Using a recent TOT build of clang (r162837) the observed behaviour does not
fully match the above.

Consider the following test program:
//===========================================================
#include <stdio.h>
typedef float float4 __attribute__((ext_vector_type(4)));
int main() {

    /* Example 1 */
    float4 v1 = (float4)(1.0, 2.0, 3.0, 4.0);
    printf("v1 = (%f, %f, %f, %f)\n", v1[0], v1[1], v1[2], v1[3]);

    /* Example 2 */
    float4 v2 = (float4)(1.0, 2.0);
    printf("v2 = (%f, %f, %f, %f)\n", v2[0], v2[1], v2[2], v2[3]);

    /* Example 3 */
    float4 v3 = (float4)(1.0, 2.0, 3.0, 4.0, 5.0);
    printf("v3 = (%f, %f, %f, %f)\n", v3[0], v3[1], v3[2], v3[3]);

    return 0;
}
//===========================================================


Example 1:
----------
  float4 v1 = (float4)(1.0, 2.0, 3.0, 4.0);

Expected: (1.0, 2.0, 3.0, 4.0)
Clang produced: (4.0, 4.0, 4.0, 4.0)
Note, warnings are produced that 1.0, 2.0, and 3.0 are unused.


Example 2:
----------
  float4 v2 = (float4)(1.0, 2.0);

Expected: a compilation error
Clang produced: (2.0, 2.0, 2.0, 2.0)

Regarding this example, instead of issuing a compilation error an alternative
approach may be to initialize with the provided values and then replicate the
last value for any remaining elements.  I.e., the output would be (1.0, 2.0,
2.0, 2.0).  This would mirror the braces form nicely, which initializes any
remaining elements to 0 (i.e., (1.0, 2.0, 0.0, 0.0)).  Of course this would
require updating the Spec/Doc, but if that is not a problem then this seems
preferable over generating an error.


Example 3:
----------
  float4 v3 = (float4)(1.0, 2.0, 3.0, 4.0, 5.0);

Expected: a compilation error -or- 
          (1.0, 2.0, 3.0, 4.0) and a warning about excess initializers 
Clang produced:  (5.0, 5.0, 5.0, 5.0)

Only the parentheses form of vector initialization does not work as expected.
The braces form works as expected.


I was going to file this as a bug report, but wanted to get feedback on the ML
first.  Is my understanding of the documentation correct?  What do others think
about the suggestion in Example 2?

Thanks,
Josh




More information about the cfe-dev mailing list