Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
* [PATCH] Vector to scalar casting and widening
@ 2012-11-13 14:10 Andrew Burgess
  2012-11-19 21:17 ` Tom Tromey
  0 siblings, 1 reply; 14+ messages in thread
From: Andrew Burgess @ 2012-11-13 14:10 UTC (permalink / raw)
  To: gdb-patches

I'd like to change the way gdb handles scalar to vector widening.  I
believe that the changes I propose will bring gdb expression evaluation
into line with how gcc handles these things; this seems a good thing to me,
but I'd be interested to hear why anyone things we should stick with the
current scheme.

The problem I have is the current behaviour when casting from scalar to
vector.  We first cast the scalar to the element type of the vector, then
replicate the (truncated) scalar to fill each element of the vector.

The gcc behaviour is to only allow casting from scalar to vector, and from
vector to vector when the lengths of the scalar and the vector, or the two
vectors, match.

On my local target I have instructions that process registers as though
they were vectors of different sizes, so an instruction might treat the
register as a single 64-bit value, two 32-bit values, four 16-bit values,
and so on.  We have types for each different vector size, and it's not
uncommon to cast a register between types.

You'll notice the gcc behaviour matches this perfectly while the gdb
behaviour can truncate values when casting between types.

One place where gcc does replicate scalars to create vectors is in binary
operations on vectors, so you can have "vector + scalar", this will then
add 'scalar' to each element of 'vector'.  This seems like a good thing,
and seems to be something a lot of vector supporting targets actually have
in hardware.

gcc restricts the scalar to vector replication within binary operations to
only expanding the type to avoid loosing significant bits.  So a vector of
type 'int' could for example be added to a scalar 'short' or 'char', but
not to a 'long long'.

I've included a simple test file and gdb command script which shows the
current behaviour of gdb.

The patch does the following:

 1. Casting scalar to vector or vector to vector is only allowed when the
 lengths of the two types are equal.

 2. Binary operations on a vector and a scalar will first create a
 temporary vector by replicating scalar, then perform the operation on the
 two vectors.  We will error if casting the scalar to the element type of
 the vector causes truncation of the value.

OK to commit?

Thanks,

Andrew

##### EXAMPLE FILES #####

/* File: vec.c

   I'm using gcc 4.7.2 on GNU/Linux (RHEL 5.7) on x86-64.

   Compile using: gcc -DBROKEN -g -o vec vec.c
   to test constructs that will not compile.

   Compile using: gcc -g -o vec vec.c
   to test only constructs that do compile.
*/

#include <stdio.h>

#define VEC_TYPE(btype, count) \
  typedef btype btype ## count \
  __attribute__ ((vector_size (count * sizeof (btype)))); \
  void print_ ## btype ## count ( const char *name, btype ## count var ) \
  { \
    int i; \
    printf ("%s = { %lld", name, var[0]); \
    for (i = 1; i < count; ++i) \
    { \
      printf (", %lld", var[i]); \
    } \
    printf (" }\n");  \
  }

VEC_TYPE (char, 4)
VEC_TYPE (char, 8)

VEC_TYPE (int, 2)
VEC_TYPE (int, 4)

int ia = 1;
short sa = 1;
long long lla = 1;

void
breakpt ()
{
  /* Breakpt */
}

int
main ()
{
  char4 c4a = { 1, 2, 3, 4};
  char4 c4b = (char4) 1;

#if BROKEN
  char4 c4c = 1;
  char4 c4d = ia;
  char4 c4e = sa;
  char4 c4f = lla;
#endif

  char4 c4g = (char4) ia;

#if BROKEN
  char4 c4h = (char4) sa;
  char4 c4i = (char4) lla;
#endif

  int4 i4a = { 1, 2, 3, 4};
  int2 i2a = { 1, 2};
  int2 i2b = (int2) lla;
  
#if BROKEN
  char4 c4j = i4a;
  char4 c4k = (char4) i4a;
  char8 c8a = i2a;
#endif

  char8 c8b = (char8) i2a;

  print_char4 ("c4b", c4b);
  print_int4 ("i4a", i4a);
  print_char8 ("c8b", c8b);
  print_int2 ("i2b", i2b);

  return 0; /* Break Here */
}

/* END: vec.c */


# START: vec.gdb

set height 0
set trace-commands 1

break 81

run

print c4b
print (char4) 1

print i2b
print lla
print (int2) lla

# The following don't compile
# under gcc 4.7.2
print (char4) sa
print (char4) lla
print (char4) i4a

quit

# END: vec.gdb

##### PATCH #####

gdb/ChangeLog

2012-11-13  Andrew Burgess  <aburgess@broadcom.com>

	* valarith.c (vector_widen): New function for replicating a scalar
	into a vector.
	(value_binop): Use vector_widen to convert scalar to vector rather
	than value_cast.
	* valops.c (value_casst): Update logic for casting between vector
	types, and for casting from scalar to vector.


 
diff --git a/gdb/valarith.c b/gdb/valarith.c
index c457f4a..81d6868 100644
--- a/gdb/valarith.c
+++ b/gdb/valarith.c
@@ -1347,6 +1347,47 @@ scalar_binop (struct value *arg1, struct value *arg2, enum exp_opcode op)
   return val;
 }
 
+/* Widen a scalar value SCALAR_VALUE to vector type VECTOR_TYPE by
+   replicating SCALAR_VALUE for each element of the vector.  Only scalar
+   types that can be cast to the type of one element of the vector are
+   acceptable.  The newly created vector value is returned upon success,
+   otherwise an error is thrown.  */
+
+static struct value *
+vector_widen (struct value *scalar_value, struct type *vector_type)
+{
+  /* Widen the scalar to a vector.  */
+  struct type *eltype, *scalar_type;
+  struct value *val, *elval;
+  LONGEST low_bound, high_bound;
+  int i;
+
+  gdb_assert (TYPE_CODE (check_typedef (vector_type)) == TYPE_CODE_ARRAY);
+  gdb_assert (TYPE_VECTOR (vector_type));
+
+  if (!get_array_bounds (vector_type, &low_bound, &high_bound))
+    error (_("Could not determine the vector bounds"));
+
+  eltype = check_typedef (TYPE_TARGET_TYPE (vector_type));
+  elval = value_cast (eltype, scalar_value);
+
+  scalar_type = check_typedef (value_type (scalar_value));
+
+  /* If we reduced the length of the scalar then check we didn't loose any
+     important bits.  */
+  if (TYPE_LENGTH (eltype) < TYPE_LENGTH (scalar_type)
+      && !value_equal (elval, scalar_value))
+    error (_("conversion of scalar to vector involves truncation"));
+
+  val = allocate_value (vector_type);
+  for (i = 0; i < high_bound - low_bound + 1; i++)
+    /* Duplicate the contents of elval into the destination vector.  */
+    memcpy (value_contents_writeable (val) + (i * TYPE_LENGTH (eltype)),
+	    value_contents_all (elval), TYPE_LENGTH (eltype));
+
+  return val;
+}
+
 /* Performs a binary operation on two vector operands by calling scalar_binop
    for each pair of vector components.  */
 
@@ -1426,7 +1467,9 @@ value_binop (struct value *arg1, struct value *arg2, enum exp_opcode op)
 	  && !is_integral_type (t))
 	error (_("Argument to operation not a number or boolean."));
 
-      *v = value_cast (t1_is_vec ? type1 : type2, *v);
+      /* Replicate the scalar value to make a vector value.  */
+      *v = vector_widen (*v, t1_is_vec ? type1 : type2);
+
       val = vector_binop (arg1, arg2, op);
     }
 
diff --git a/gdb/valops.c b/gdb/valops.c
index 502fb0d..c8d7c8b 100644
--- a/gdb/valops.c
+++ b/gdb/valops.c
@@ -546,29 +546,14 @@ value_cast (struct type *type, struct value *arg2)
 	 minus one, instead of biasing the normal case.  */
       return value_from_longest (type, -1);
     }
-  else if (code1 == TYPE_CODE_ARRAY && TYPE_VECTOR (type) && scalar)
-    {
-      /* Widen the scalar to a vector.  */
-      struct type *eltype;
-      struct value *val;
-      LONGEST low_bound, high_bound;
-      int i;
-
-      if (!get_array_bounds (type, &low_bound, &high_bound))
-	error (_("Could not determine the vector bounds"));
-
-      eltype = check_typedef (TYPE_TARGET_TYPE (type));
-      arg2 = value_cast (eltype, arg2);
-      val = allocate_value (type);
-
-      for (i = 0; i < high_bound - low_bound + 1; i++)
-	{
-	  /* Duplicate the contents of arg2 into the destination vector.  */
-	  memcpy (value_contents_writeable (val) + (i * TYPE_LENGTH (eltype)),
-		  value_contents_all (arg2), TYPE_LENGTH (eltype));
-	}
-      return val;
-    }
+  else if (code1 == TYPE_CODE_ARRAY && TYPE_VECTOR (type)
+	   && code2 == TYPE_CODE_ARRAY && TYPE_VECTOR (type2)
+	   && TYPE_LENGTH (type) != TYPE_LENGTH (type2))
+    error (_("can't convert between vector values of different size"));
+  else if (code1 == TYPE_CODE_ARRAY && TYPE_VECTOR (type)
+	   && scalar
+	   && TYPE_LENGTH (type) != TYPE_LENGTH (type2))
+    error (_("can only cast scalar to vector of same size"));
   else if (TYPE_LENGTH (type) == TYPE_LENGTH (type2))
     {
       if (code1 == TYPE_CODE_PTR && code2 == TYPE_CODE_PTR)





gdb/testsuite/ChangeLog

2012-11-13  Andrew Burgess  <aburgess@broadcom.com>

	* gdb.base/gnu_vector.c: New variable for use in tests.
	* gdb.base/gnu_vector.exp: Update and extend tests to reflect
	changes in scalar to vector casting and widening.
	* gdb.python/py-type.c: New variables for use in tests.
	* gdb.python/py-type.exp: Update vector related tests to reflect
	changes in scalar to vector casting and widening.

diff --git a/gdb/testsuite/gdb.base/gnu_vector.c b/gdb/testsuite/gdb.base/gnu_vector.c
index a2a218f..5b7c98b 100644
--- a/gdb/testsuite/gdb.base/gnu_vector.c
+++ b/gdb/testsuite/gdb.base/gnu_vector.c
@@ -31,6 +31,7 @@ int ia = 2;
 int ib = 1;
 float fa = 2;
 float fb = 1;
+long long lla = 0x0000000100000001ll;
 char4 c4 = {1, 2, 3, 4};
 int4 i4a = {2, 4, 8, 16};
 int4 i4b = {1, 2, 8, 4};
diff --git a/gdb/testsuite/gdb.base/gnu_vector.exp b/gdb/testsuite/gdb.base/gnu_vector.exp
index baba119..eaba6f2 100644
--- a/gdb/testsuite/gdb.base/gnu_vector.exp
+++ b/gdb/testsuite/gdb.base/gnu_vector.exp
@@ -82,32 +82,52 @@ gdb_test "print f4a / f4b" "\\\$$decimal = \\{2, 2, 1, 4\\}"
 gdb_test "print +f4a" "\\\$$decimal = \\{2, 4, 8, 16\\}"
 gdb_test "print -f4a" "\\\$$decimal = \\{-2, -4, -8, -16\\}"
 
-# Test scalar to vector widening
-gdb_test "print (int2) 1" "\\\$$decimal = \\{1, 1\\}"
-gdb_test "print (longlong2) 2" "\\\$$decimal = \\{2, 2\\}"
-gdb_test "print (float2) 3" "\\\$$decimal = \\{3, 3\\}"
-gdb_test "print (double2) 4" "\\\$$decimal = \\{4, 4\\}"
-gdb_test "print (char4) 12" "\\\$$decimal = \\{12, 12, 12, 12\\}"
-gdb_test "print (uint4) ia" "\\\$$decimal = \\{2, 2, 2, 2\\}"
-gdb_test "print (int4) -3" "\\\$$decimal = \\{-3, -3, -3, -3\\}"
-gdb_test "print (float4) 4" "\\\$$decimal = \\{4, 4, 4, 4\\}"
-
+# When casting to vector the input type must have the same length as
+# the total length of the vector.
+gdb_test "print (char4) 0x01010101" "\\\$$decimal = \\{1, 1, 1, 1\\}"
+gdb_test "print (char4) ia" "\\\$$decimal = \\{2, 0, 0, 0\\}"
+gdb_test "print (int2) lla" "\\\$$decimal = \\{1, 1\\}"
+
+gdb_test "print (int2) 1" "can only cast scalar to vector of same size"
+gdb_test "print (longlong2) 2" "can only cast scalar to vector of same size"
+gdb_test "print (float2) 3" "can only cast scalar to vector of same size"
+gdb_test "print (double2) 4" "can only cast scalar to vector of same size"
+gdb_test "print (uint4) ia" "can only cast scalar to vector of same size"
+gdb_test "print (int4) -3" "can only cast scalar to vector of same size"
+gdb_test "print (float4) 4" "can only cast scalar to vector of same size"
+
+gdb_test "print i4b = ia" "can only cast scalar to vector of same size"
+gdb_test "print i4a = 3" "can only cast scalar to vector of same size"
+gdb_test "print f4a = fb" "can only cast scalar to vector of same size"
+gdb_test "print f4b = 2" "can only cast scalar to vector of same size"
+
+gdb_test "print c4 + lla" "conversion of scalar to vector involves truncation"
+gdb_test "print i4a + lla" "conversion of scalar to vector involves truncation"
+gdb_test "print lla + c4" "conversion of scalar to vector involves truncation"
+gdb_test "print lla + i4a" "conversion of scalar to vector involves truncation"
+
+gdb_test "print c4 + ib" "\\\$$decimal = \\{2, 3, 4, 5\\}"
 gdb_test "print i4a + ib" "\\\$$decimal = \\{3, 5, 9, 17\\}"
+gdb_test "print i4a + 1" "\\\$$decimal = \\{3, 5, 9, 17\\}"
+gdb_test "print 1 + i4a" "\\\$$decimal = \\{3, 5, 9, 17\\}"
 gdb_test "print fa - f4b" "\\\$$decimal = \\{1, 0, -6, -2\\}"
+gdb_test "print 2 - f4b" "\\\$$decimal = \\{1, 0, -6, -2\\}"
 gdb_test "print f4a * fb" "\\\$$decimal = \\{2, 4, 8, 16\\}"
+gdb_test "print f4a * 1" "\\\$$decimal = \\{2, 4, 8, 16\\}"
 gdb_test "print ia / i4b" "\\\$$decimal = \\{2, 1, 0, 0\\}"
+gdb_test "print 2 / i4b" "\\\$$decimal = \\{2, 1, 0, 0\\}"
 gdb_test "print i4a % ib" "\\\$$decimal = \\{0, 0, 0, 0\\}"
-
+gdb_test "print i4a % 1" "\\\$$decimal = \\{0, 0, 0, 0\\}"
 gdb_test "print ia & i4b" "\\\$$decimal = \\{0, 2, 0, 0\\}"
+gdb_test "print 2 & i4b" "\\\$$decimal = \\{0, 2, 0, 0\\}"
 gdb_test "print i4a | ib" "\\\$$decimal = \\{3, 5, 9, 17\\}"
+gdb_test "print i4a | 1" "\\\$$decimal = \\{3, 5, 9, 17\\}"
 gdb_test "print ia ^ i4b" "\\\$$decimal = \\{3, 0, 10, 6\\}"
+gdb_test "print 2 ^ i4b" "\\\$$decimal = \\{3, 0, 10, 6\\}"
 gdb_test "print i4a << ib" "\\\$$decimal = \\{4, 8, 16, 32\\}"
+gdb_test "print i4a << 1" "\\\$$decimal = \\{4, 8, 16, 32\\}"
 gdb_test "print i4a >> ib" "\\\$$decimal = \\{1, 2, 4, 8\\}"
-
-gdb_test "print i4b = ia" "\\\$$decimal = \\{2, 2, 2, 2\\}"
-gdb_test "print i4a = 3" "\\\$$decimal = \\{3, 3, 3, 3\\}"
-gdb_test "print f4a = fb" "\\\$$decimal = \\{1, 1, 1, 1\\}"
-gdb_test "print f4b = 2" "\\\$$decimal = \\{2, 2, 2, 2\\}"
+gdb_test "print i4a >> 1" "\\\$$decimal = \\{1, 2, 4, 8\\}"
 
 gdb_test "print i4a = \{2, 4, 8, 16\}" "\\\$$decimal = \\{2, 4, 8, 16\\}"
 gdb_test "print i4a <<= ib" "\\\$$decimal = \\{4, 8, 16, 32\\}"
diff --git a/gdb/testsuite/gdb.python/py-type.c b/gdb/testsuite/gdb.python/py-type.c
index bf39443..c57a2e8 100644
--- a/gdb/testsuite/gdb.python/py-type.c
+++ b/gdb/testsuite/gdb.python/py-type.c
@@ -15,6 +15,8 @@
    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
+#include <stdint.h>
+
 struct s
 {
   int a;
@@ -50,6 +52,9 @@ enum E
 { v1, v2, v3
 };
 
+uint64_t vec_data_1 = 0x0000000100000001ull;
+uint64_t vec_data_2 = 0x0000000100000002ull;
+
 int
 main ()
 {
diff --git a/gdb/testsuite/gdb.python/py-type.exp b/gdb/testsuite/gdb.python/py-type.exp
index b997c51..5791bb6 100644
--- a/gdb/testsuite/gdb.python/py-type.exp
+++ b/gdb/testsuite/gdb.python/py-type.exp
@@ -125,15 +125,18 @@ proc test_fields {lang} {
   # Test gdb.Type.vector.
   # Note: vectors cast differently than arrays.  Here ar[0] is replicated
   # for the size of the vector.
-  gdb_py_test_silent_cmd \
-      "python vec1 = ar\[0\].cast(ar\[0\].type.vector(1))" "set vec1" 1
+  gdb_py_test_silent_cmd "print vec_data_1" "print value (vec_data_1)" 1
+  gdb_py_test_silent_cmd "python vec_data_1 = gdb.history (0)" "get value (vec_data_1) from history" 1
+
+  gdb_py_test_silent_cmd "print vec_data_2" "print value (vec_data_2)" 1
+  gdb_py_test_silent_cmd "python vec_data_2 = gdb.history (0)" "get value (vec_data_2) from history" 1
+
+  gdb_py_test_silent_cmd "python vec1 = vec_data_1.cast(ar\[0\].type.vector(1))" "set vec1" 1
   gdb_test "python print vec1" ".1, 1." "cast to vector with one argument"
-  gdb_py_test_silent_cmd \
-      "python vec2 = ar\[0\].cast(ar\[0\].type.vector(0, 1))" "set vec2" 1
+  gdb_py_test_silent_cmd "python vec2 = vec_data_1.cast(ar\[0\].type.vector(0, 1))" "set vec2" 1
   gdb_test "python print vec2" ".1, 1." "cast to vector with two arguments"
   gdb_test "python print vec1 == vec2" "True"
-  gdb_py_test_silent_cmd \
-      "python vec3 = ar\[1\].cast(ar\[1\].type.vector(1))" "set vec3" 1
+  gdb_py_test_silent_cmd "python vec3 = vec_data_2.cast(ar\[0\].type.vector(1))" "set vec3" 1
   gdb_test "python print vec1 == vec3" "False"
 }


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH] Vector to scalar casting and widening
  2012-11-13 14:10 [PATCH] Vector to scalar casting and widening Andrew Burgess
@ 2012-11-19 21:17 ` Tom Tromey
  2012-11-23 16:26   ` Andrew Burgess
  0 siblings, 1 reply; 14+ messages in thread
From: Tom Tromey @ 2012-11-19 21:17 UTC (permalink / raw)
  To: Andrew Burgess; +Cc: gdb-patches

>>>>> "Andrew" == Andrew Burgess <aburgess@broadcom.com> writes:

Andrew> I'd like to change the way gdb handles scalar to vector
Andrew> widening.  I believe that the changes I propose will bring gdb
Andrew> expression evaluation into line with how gcc handles these
Andrew> things; this seems a good thing to me, but I'd be interested to
Andrew> hear why anyone things we should stick with the current scheme.

I agree that we should generally follow the compiler.

In this case what I would suggest is looking up the original vector
patches to gdb to see whether there is some rationale given for the
chosen behavior.

I'm in favor of this change unless that research turns up something; in
which case we should probably discuss it more.

Andrew> +static struct value *
Andrew> +vector_widen (struct value *scalar_value, struct type *vector_type)
Andrew> +{
Andrew> +  /* Widen the scalar to a vector.  */
Andrew> +  struct type *eltype, *scalar_type;
Andrew> +  struct value *val, *elval;
Andrew> +  LONGEST low_bound, high_bound;
Andrew> +  int i;
Andrew> +
Andrew> +  gdb_assert (TYPE_CODE (check_typedef (vector_type)) == TYPE_CODE_ARRAY);
Andrew> +  gdb_assert (TYPE_VECTOR (vector_type));
Andrew> +
Andrew> +  if (!get_array_bounds (vector_type, &low_bound, &high_bound))
Andrew> +    error (_("Could not determine the vector bounds"));
Andrew> +
Andrew> +  eltype = check_typedef (TYPE_TARGET_TYPE (vector_type));
Andrew> +  elval = value_cast (eltype, scalar_value);

I think check_typedef is being applied inconsistently here.
I'd suggest starting the function with a call to the macro:

    CHECK_TYPEDEF (vector_type);

then you can drop check_typedef from the first assert.

Andrew> +  else if (code1 == TYPE_CODE_ARRAY && TYPE_VECTOR (type)
Andrew> +	   && code2 == TYPE_CODE_ARRAY && TYPE_VECTOR (type2)
Andrew> +	   && TYPE_LENGTH (type) != TYPE_LENGTH (type2))
Andrew> +    error (_("can't convert between vector values of different size"));

I didn't see a test case for this error.
Could you add one?

Andrew> +++ b/gdb/testsuite/gdb.base/gnu_vector.c
Andrew> @@ -31,6 +31,7 @@ int ia = 2;
Andrew>  int ib = 1;
Andrew>  float fa = 2;
Andrew>  float fb = 1;
Andrew> +long long lla = 0x0000000100000001ll;

Here I don't think we can assume that lla has a particular size, can we?
But since this is a gcc-specific test, I think you can work around it by
using the 'mode' attribute to pick a particular size.

Andrew> +++ b/gdb/testsuite/gdb.python/py-type.c
Andrew> @@ -15,6 +15,8 @@
Andrew>     You should have received a copy of the GNU General Public License
Andrew>     along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
Andrew> +#include <stdint.h>

I'm mildly concerned that this will mean that we can't run this test on
some platform.  But only mildly, I'm inclined to let it go.

Tom


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH] Vector to scalar casting and widening
  2012-11-19 21:17 ` Tom Tromey
@ 2012-11-23 16:26   ` Andrew Burgess
  2012-11-26 14:18     ` Ulrich Weigand
  0 siblings, 1 reply; 14+ messages in thread
From: Andrew Burgess @ 2012-11-23 16:26 UTC (permalink / raw)
  To: Tom Tromey; +Cc: gdb-patches, Ken Werner, Ulrich Weigand

On 19/11/2012 9:16 PM, Tom Tromey wrote:
>>>>>> "Andrew" == Andrew Burgess <aburgess@broadcom.com> writes:
> 
> Andrew> I'd like to change the way gdb handles scalar to vector
> Andrew> widening.  I believe that the changes I propose will bring gdb
> Andrew> expression evaluation into line with how gcc handles these
> Andrew> things; this seems a good thing to me, but I'd be interested to
> Andrew> hear why anyone things we should stick with the current scheme.
> 
> I agree that we should generally follow the compiler.
> 
> In this case what I would suggest is looking up the original vector
> patches to gdb to see whether there is some rationale given for the
> chosen behavior.
> 
> I'm in favor of this change unless that research turns up something; in
> which case we should probably discuss it more.

The original change that introduced the scalar to vector casting behaviour
was added in this mail chain:
  http://sourceware.org/ml/gdb-patches/2010-09/msg00317.html
specifically,
  http://sourceware.org/ml/gdb-patches/2010-10/msg00142.html

So it would seem that the current behaviour; first cast the scalar to the
vector element type, then replicate over each element of the vector was
picked to match OpenCL behaviour, see "6.2.2 Explicit Casts" in:
  http://www.khronos.org/registry/cl/specs/opencl-1.2.pdf

I have to confess to no experience of OpenCL, so feel free to correct any
mistakes I make...

The current gdb behaviour has one case in valops.c:value_cast that
covers casting from scalar to vector.

In my original patch I have two cases in value_cast for,
 1. Vector to vector cast where the sizes are different, this is
    not allowed.
 2. Scalar to vector cast where the sizes are different, this is
    not allowed.

In order to maintain current opencl behaviour I've created a new patch,
this one has a flag on the language_defn structure to control how vector
casting functions.  I reuse the vector widening code where appropriate.
The choices then are:
 1. vector to vector cast
    1.1 This is not allowed in OpenCL (see above pdf) so I throw an error.
    1.2 This is only allowed for gcc/c vectors if they are the same size,
        otherwise throw an error.
 2. scalar to vector cast
    2.1 For OpenCL, cast scalar to vector element type and replicate.
    2.2 For gcc/c vectors, only allow if the scalar is the same size as
        the vector.

For now I've defaulted all languages to match the opencl like behaviour as
this will keep things the most consistent, I don't know if this is important
as I don't know if it's possible to create vector types in other languages
or not.

I've tested the standard non-opencl side of things, but haven't been able
to figure out how to run the opencl tests (any pointers welcome), so I don't
know if I've broken any of those tests.

> 
> Andrew> +static struct value *
> Andrew> +vector_widen (struct value *scalar_value, struct type *vector_type)
> Andrew> +{
> Andrew> +  /* Widen the scalar to a vector.  */
> Andrew> +  struct type *eltype, *scalar_type;
> Andrew> +  struct value *val, *elval;
> Andrew> +  LONGEST low_bound, high_bound;
> Andrew> +  int i;
> Andrew> +
> Andrew> +  gdb_assert (TYPE_CODE (check_typedef (vector_type)) == TYPE_CODE_ARRAY);
> Andrew> +  gdb_assert (TYPE_VECTOR (vector_type));
> Andrew> +
> Andrew> +  if (!get_array_bounds (vector_type, &low_bound, &high_bound))
> Andrew> +    error (_("Could not determine the vector bounds"));
> Andrew> +
> Andrew> +  eltype = check_typedef (TYPE_TARGET_TYPE (vector_type));
> Andrew> +  elval = value_cast (eltype, scalar_value);
> 
> I think check_typedef is being applied inconsistently here.
> I'd suggest starting the function with a call to the macro:
> 
>     CHECK_TYPEDEF (vector_type);
> 
> then you can drop check_typedef from the first assert.

Done.

> 
> Andrew> +  else if (code1 == TYPE_CODE_ARRAY && TYPE_VECTOR (type)
> Andrew> +	   && code2 == TYPE_CODE_ARRAY && TYPE_VECTOR (type2)
> Andrew> +	   && TYPE_LENGTH (type) != TYPE_LENGTH (type2))
> Andrew> +    error (_("can't convert between vector values of different size"));
> 
> I didn't see a test case for this error.
> Could you add one?

Done.

> 
> Andrew> +++ b/gdb/testsuite/gdb.base/gnu_vector.c
> Andrew> @@ -31,6 +31,7 @@ int ia = 2;
> Andrew>  int ib = 1;
> Andrew>  float fa = 2;
> Andrew>  float fb = 1;
> Andrew> +long long lla = 0x0000000100000001ll;
> 
> Here I don't think we can assume that lla has a particular size, can we?
> But since this is a gcc-specific test, I think you can work around it by
> using the 'mode' attribute to pick a particular size.

Done.

> 
> Andrew> +++ b/gdb/testsuite/gdb.python/py-type.c
> Andrew> @@ -15,6 +15,8 @@
> Andrew>     You should have received a copy of the GNU General Public License
> Andrew>     along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
>  
> Andrew> +#include <stdint.h>
> 
> I'm mildly concerned that this will mean that we can't run this test on
> some platform.  But only mildly, I'm inclined to let it go.

I've changed the test to avoid using this header file.

Cheers,
Andrew


gdb/ChangeLog

2012-11-23  Andrew Burgess  <aburgess@broadcom.com>

	Add language specific flag to control casting from scalar to
	vector types.  Allow scalar to vector widening during binary
	operations on a scalar and a vector.
	* valarith.c (vector_widen): New function for replicating a scalar
	into a vector.
	(value_binop): Use new function to convert scalar to vector rather
	than value_cast.
	* language.h (struct language_defn): Add new flag to control
	behaviour of casting between scalar and vector types.
	* valops.c (value_casst): Update logic for casting between vector
	types, and for casting from scalar to vector including a check of
	the new language flag.
	* ada-lang.c (ada_language_defn): Initialise new flag.
	* c-lang.c (c_language_defn): Initialise new flag.
	(cplus_language_defn): Initialise new flag.
	(asm_language_defn): Initialise new flag.
	(minimal_language_defn): Initialise new flag.
	* d-lang.c (d_language_defn): Initialise new flag.
	* f-lang.c (f_language_defn): Initialise new flag.
	* go-lang.c (go_language_defn): Initialise new flag.
	* jv-lang.c (java_language_defn): Initialise new flag.
	* language.c (unknown_language_defn): Initialise new flag.
	(auto_language_defn): Initialise new flag.
	(local_language_defn): Initialise new flag.
	* m2-lang.c (m2_language_defn): Initialise new flag.
	* objc-lang.c (objc_language_defn): Initialise new flag.
	* opencl-lang.c (opencl_language_defn): Initialise new flag.
	* p-lang.c (pascal_language_defn): Initialise new flag.


diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c
index e1dced5..75207b0 100644
--- a/gdb/ada-lang.c
+++ b/gdb/ada-lang.c
@@ -12616,6 +12616,7 @@ const struct language_defn ada_language_defn = {
 				   class_name_from_physname */
   ada_op_print_tab,             /* expression operators for printing */
   0,                            /* c-style arrays */
+  1,                            /* scalar to vector casting strategy */
   1,                            /* String lower bound */
   ada_get_gdb_completer_word_break_characters,
   ada_make_symbol_completion_list,
diff --git a/gdb/c-lang.c b/gdb/c-lang.c
index 84830be..91dd8c5 100644
--- a/gdb/c-lang.c
+++ b/gdb/c-lang.c
@@ -855,6 +855,7 @@ const struct language_defn c_language_defn =
 				   class_name_from_physname */
   c_op_print_tab,		/* expression operators for printing */
   1,				/* c-style arrays */
+  0,				/* scalar to vector casting strategy */
   0,				/* String lower bound */
   default_word_break_characters,
   default_make_symbol_completion_list,
@@ -978,6 +979,7 @@ const struct language_defn cplus_language_defn =
 				   class_name_from_physname */
   c_op_print_tab,		/* expression operators for printing */
   1,				/* c-style arrays */
+  0,				/* scalar to vector casting strategy */
   0,				/* String lower bound */
   default_word_break_characters,
   default_make_symbol_completion_list,
@@ -1019,6 +1021,7 @@ const struct language_defn asm_language_defn =
 				   class_name_from_physname */
   c_op_print_tab,		/* expression operators for printing */
   1,				/* c-style arrays */
+  0,				/* scalar to vector casting strategy */
   0,				/* String lower bound */
   default_word_break_characters,
   default_make_symbol_completion_list,
@@ -1065,6 +1068,7 @@ const struct language_defn minimal_language_defn =
 				   class_name_from_physname */
   c_op_print_tab,		/* expression operators for printing */
   1,				/* c-style arrays */
+  0,				/* scalar to vector casting strategy */
   0,				/* String lower bound */
   default_word_break_characters,
   default_make_symbol_completion_list,
diff --git a/gdb/d-lang.c b/gdb/d-lang.c
index 7b2c322..b7cb1b7 100644
--- a/gdb/d-lang.c
+++ b/gdb/d-lang.c
@@ -265,6 +265,7 @@ static const struct language_defn d_language_defn =
 				   class_name_from_physname.  */
   d_op_print_tab,		/* Expression operators for printing.  */
   1,				/* C-style arrays.  */
+  1,				/* scalar to vector casting strategy */
   0,				/* String lower bound.  */
   default_word_break_characters,
   default_make_symbol_completion_list,
diff --git a/gdb/f-lang.c b/gdb/f-lang.c
index 0b3645f..4c01976 100644
--- a/gdb/f-lang.c
+++ b/gdb/f-lang.c
@@ -264,6 +264,7 @@ const struct language_defn f_language_defn =
 				   class_name_from_physname */
   f_op_print_tab,		/* expression operators for printing */
   0,				/* arrays are first-class (not c-style) */
+  1,				/* scalar to vector casting strategy */
   1,				/* String lower bound */
   f_word_break_characters,
   f_make_symbol_completion_list,
diff --git a/gdb/go-lang.c b/gdb/go-lang.c
index 21f2427..194ee28 100644
--- a/gdb/go-lang.c
+++ b/gdb/go-lang.c
@@ -587,6 +587,7 @@ static const struct language_defn go_language_defn =
 				   class_name_from_physname.  */
   go_op_print_tab,		/* Expression operators for printing.  */
   1,				/* C-style arrays.  */
+  1,				/* scalar to vector casting strategy */
   0,				/* String lower bound.  */
   default_word_break_characters,
   default_make_symbol_completion_list,
diff --git a/gdb/jv-lang.c b/gdb/jv-lang.c
index 6b865dc..fa193d2 100644
--- a/gdb/jv-lang.c
+++ b/gdb/jv-lang.c
@@ -1190,6 +1190,7 @@ const struct language_defn java_language_defn =
   java_class_name_from_physname,/* Language specific class name */
   java_op_print_tab,		/* expression operators for printing */
   0,				/* not c-style arrays */
+  1,				/* scalar to vector casting strategy */
   0,				/* String lower bound */
   default_word_break_characters,
   default_make_symbol_completion_list,
diff --git a/gdb/language.c b/gdb/language.c
index 5693419..6c0298b 100644
--- a/gdb/language.c
+++ b/gdb/language.c
@@ -817,6 +817,7 @@ const struct language_defn unknown_language_defn =
 				   class_name_from_physname */
   unk_op_print_tab,		/* expression operators for printing */
   1,				/* c-style arrays */
+  0,				/* scalar to vector casting strategy */
   0,				/* String lower bound */
   default_word_break_characters,
   default_make_symbol_completion_list,
@@ -860,6 +861,7 @@ const struct language_defn auto_language_defn =
 				   class_name_from_physname */
   unk_op_print_tab,		/* expression operators for printing */
   1,				/* c-style arrays */
+  0,				/* scalar to vector casting strategy */
   0,				/* String lower bound */
   default_word_break_characters,
   default_make_symbol_completion_list,
@@ -901,6 +903,7 @@ const struct language_defn local_language_defn =
 				   class_name_from_physname */
   unk_op_print_tab,		/* expression operators for printing */
   1,				/* c-style arrays */
+  0,				/* scalar to vector casting strategy */
   0,				/* String lower bound */
   default_word_break_characters,
   default_make_symbol_completion_list,
diff --git a/gdb/language.h b/gdb/language.h
index 3a1e390..01f3da4 100644
--- a/gdb/language.h
+++ b/gdb/language.h
@@ -276,6 +276,11 @@ struct language_defn
 
     char c_style_arrays;
 
+    /* When casting from scalar to vector do we first cast scalar to
+       element type then replicate, or only allow casting when scalar and
+       vector of the same size, with no replication.  */
+    char opencl_style_vector_casting;
+
     /* Index to use for extracting the first element of a string.  */
     char string_lower_bound;
 
diff --git a/gdb/m2-lang.c b/gdb/m2-lang.c
index a87039c..0169035 100644
--- a/gdb/m2-lang.c
+++ b/gdb/m2-lang.c
@@ -394,6 +394,7 @@ const struct language_defn m2_language_defn =
 				   class_name_from_physname */
   m2_op_print_tab,		/* expression operators for printing */
   0,				/* arrays are first-class (not c-style) */
+  1,				/* scalar to vector casting strategy */
   0,				/* String lower bound */
   default_word_break_characters,
   default_make_symbol_completion_list,
diff --git a/gdb/objc-lang.c b/gdb/objc-lang.c
index e42a03c..9fbb0a2 100644
--- a/gdb/objc-lang.c
+++ b/gdb/objc-lang.c
@@ -533,6 +533,7 @@ const struct language_defn objc_language_defn = {
 				   class_name_from_physname */
   objc_op_print_tab,		/* Expression operators for printing */
   1,				/* C-style arrays */
+  1,				/* scalar to vector casting strategy */
   0,				/* String lower bound */
   default_word_break_characters,
   default_make_symbol_completion_list,
diff --git a/gdb/opencl-lang.c b/gdb/opencl-lang.c
index b8fd9b7..7702151 100644
--- a/gdb/opencl-lang.c
+++ b/gdb/opencl-lang.c
@@ -1017,6 +1017,7 @@ const struct language_defn opencl_language_defn =
 				   class_name_from_physname */
   c_op_print_tab,		/* expression operators for printing */
   1,				/* c-style arrays */
+  1,				/* scalar to vector casting strategy */
   0,				/* String lower bound */
   default_word_break_characters,
   default_make_symbol_completion_list,
diff --git a/gdb/p-lang.c b/gdb/p-lang.c
index 114efbc..5e96049 100644
--- a/gdb/p-lang.c
+++ b/gdb/p-lang.c
@@ -452,6 +452,7 @@ const struct language_defn pascal_language_defn =
   NULL,				/* Language specific class_name_from_physname */
   pascal_op_print_tab,		/* expression operators for printing */
   1,				/* c-style arrays */
+  1,				/* scalar to vector casting strategy */
   0,				/* String lower bound */
   default_word_break_characters,
   default_make_symbol_completion_list,
diff --git a/gdb/valarith.c b/gdb/valarith.c
index c457f4a..afb45e2 100644
--- a/gdb/valarith.c
+++ b/gdb/valarith.c
@@ -1347,6 +1347,49 @@ scalar_binop (struct value *arg1, struct value *arg2, enum exp_opcode op)
   return val;
 }
 
+/* Widen a scalar value SCALAR_VALUE to vector type VECTOR_TYPE by
+   replicating SCALAR_VALUE for each element of the vector.  Only scalar
+   types that can be cast to the type of one element of the vector are
+   acceptable.  The newly created vector value is returned upon success,
+   otherwise an error is thrown.  */
+
+struct value *
+value_vector_widen (struct value *scalar_value, struct type *vector_type)
+{
+  /* Widen the scalar to a vector.  */
+  struct type *eltype, *scalar_type;
+  struct value *val, *elval;
+  LONGEST low_bound, high_bound;
+  int i;
+
+  CHECK_TYPEDEF (vector_type);
+
+  gdb_assert (TYPE_CODE (vector_type) == TYPE_CODE_ARRAY
+	      && TYPE_VECTOR (vector_type));
+
+  if (!get_array_bounds (vector_type, &low_bound, &high_bound))
+    error (_("Could not determine the vector bounds"));
+
+  eltype = check_typedef (TYPE_TARGET_TYPE (vector_type));
+  elval = value_cast (eltype, scalar_value);
+
+  scalar_type = check_typedef (value_type (scalar_value));
+
+  /* If we reduced the length of the scalar then check we didn't loose any
+     important bits.  */
+  if (TYPE_LENGTH (eltype) < TYPE_LENGTH (scalar_type)
+      && !value_equal (elval, scalar_value))
+    error (_("conversion of scalar to vector involves truncation"));
+
+  val = allocate_value (vector_type);
+  for (i = 0; i < high_bound - low_bound + 1; i++)
+    /* Duplicate the contents of elval into the destination vector.  */
+    memcpy (value_contents_writeable (val) + (i * TYPE_LENGTH (eltype)),
+	    value_contents_all (elval), TYPE_LENGTH (eltype));
+
+  return val;
+}
+
 /* Performs a binary operation on two vector operands by calling scalar_binop
    for each pair of vector components.  */
 
@@ -1426,7 +1469,9 @@ value_binop (struct value *arg1, struct value *arg2, enum exp_opcode op)
 	  && !is_integral_type (t))
 	error (_("Argument to operation not a number or boolean."));
 
-      *v = value_cast (t1_is_vec ? type1 : type2, *v);
+      /* Replicate the scalar value to make a vector value.  */
+      *v = value_vector_widen (*v, t1_is_vec ? type1 : type2);
+
       val = vector_binop (arg1, arg2, op);
     }
 
diff --git a/gdb/valops.c b/gdb/valops.c
index 502fb0d..7ade503 100644
--- a/gdb/valops.c
+++ b/gdb/valops.c
@@ -546,29 +546,33 @@ value_cast (struct type *type, struct value *arg2)
 	 minus one, instead of biasing the normal case.  */
       return value_from_longest (type, -1);
     }
-  else if (code1 == TYPE_CODE_ARRAY && TYPE_VECTOR (type) && scalar)
+  else if (code1 == TYPE_CODE_ARRAY && TYPE_VECTOR (type)
+	   && code2 == TYPE_CODE_ARRAY && TYPE_VECTOR (type2)
+	   && (current_language->opencl_style_vector_casting
+	       || TYPE_LENGTH (type) != TYPE_LENGTH (type2)))
+    {      
+      if (current_language->opencl_style_vector_casting)
+	error (_("Casting between vector types is not allowed"));
+      else
+	error (_("Cannot convert between vector values of different sizes"));
+    }
+  else if (code1 == TYPE_CODE_ARRAY && TYPE_VECTOR (type) && scalar
+	   && current_language->opencl_style_vector_casting)
     {
-      /* Widen the scalar to a vector.  */
       struct type *eltype;
-      struct value *val;
-      LONGEST low_bound, high_bound;
-      int i;
-
-      if (!get_array_bounds (type, &low_bound, &high_bound))
-	error (_("Could not determine the vector bounds"));
-
+      
+      /* Cast to the element type of the vector here as value_vector_widen
+	 will error if the scalar value is truncated by the cast.  To avoid
+	 the error, cast (and possibly truncate) here.  */
       eltype = check_typedef (TYPE_TARGET_TYPE (type));
       arg2 = value_cast (eltype, arg2);
-      val = allocate_value (type);
 
-      for (i = 0; i < high_bound - low_bound + 1; i++)
-	{
-	  /* Duplicate the contents of arg2 into the destination vector.  */
-	  memcpy (value_contents_writeable (val) + (i * TYPE_LENGTH (eltype)),
-		  value_contents_all (arg2), TYPE_LENGTH (eltype));
-	}
-      return val;
+      return value_vector_widen (arg2, type);
     }
+  else if (code1 == TYPE_CODE_ARRAY && TYPE_VECTOR (type) && scalar
+	   && (!current_language->opencl_style_vector_casting
+	       && TYPE_LENGTH (type) != TYPE_LENGTH (type2)))
+    error (_("can only cast scalar to vector of same size"));
   else if (TYPE_LENGTH (type) == TYPE_LENGTH (type2))
     {
       if (code1 == TYPE_CODE_PTR && code2 == TYPE_CODE_PTR)
diff --git a/gdb/value.h b/gdb/value.h
index 3685935..f8438dc 100644
--- a/gdb/value.h
+++ b/gdb/value.h
@@ -482,6 +482,12 @@ extern void read_value_memory (struct value *val, int embedded_offset,
 			       int stack, CORE_ADDR memaddr,
 			       gdb_byte *buffer, size_t length);
 
+/* Cast SCALAR_VALUE to the element type of VECTOR_TYPE, then replicate
+   into each element of a new vector value with VECTOR_TYPE.  */
+
+struct value *value_vector_widen (struct value *scalar_value,
+				  struct type *vector_type);
+
 \f
 
 #include "symtab.h"





gdb/testsuite/ChangeLog

2012-11-23  Andrew Burgess  <aburgess@broadcom.com>

	* gdb.base/gnu_vector.c: New variable for use in tests.
	* gdb.base/gnu_vector.exp: Update and extend tests to reflect
	changes in scalar to vector casting and widening.
	* gdb.python/py-type.c: New variables for use in tests.
	* gdb.python/py-type.exp: Update vector related tests to reflect
	changes in scalar to vector casting and widening.

diff --git a/gdb/testsuite/gdb.base/gnu_vector.c b/gdb/testsuite/gdb.base/gnu_vector.c
index a2a218f..07bc529 100644
--- a/gdb/testsuite/gdb.base/gnu_vector.c
+++ b/gdb/testsuite/gdb.base/gnu_vector.c
@@ -31,6 +31,7 @@ int ia = 2;
 int ib = 1;
 float fa = 2;
 float fb = 1;
+long long lla __attribute__ ((mode(DI))) = 0x0000000100000001ll;
 char4 c4 = {1, 2, 3, 4};
 int4 i4a = {2, 4, 8, 16};
 int4 i4b = {1, 2, 8, 4};
diff --git a/gdb/testsuite/gdb.base/gnu_vector.exp b/gdb/testsuite/gdb.base/gnu_vector.exp
index baba119..b6a1afb 100644
--- a/gdb/testsuite/gdb.base/gnu_vector.exp
+++ b/gdb/testsuite/gdb.base/gnu_vector.exp
@@ -82,32 +82,52 @@ gdb_test "print f4a / f4b" "\\\$$decimal = \\{2, 2, 1, 4\\}"
 gdb_test "print +f4a" "\\\$$decimal = \\{2, 4, 8, 16\\}"
 gdb_test "print -f4a" "\\\$$decimal = \\{-2, -4, -8, -16\\}"
 
-# Test scalar to vector widening
-gdb_test "print (int2) 1" "\\\$$decimal = \\{1, 1\\}"
-gdb_test "print (longlong2) 2" "\\\$$decimal = \\{2, 2\\}"
-gdb_test "print (float2) 3" "\\\$$decimal = \\{3, 3\\}"
-gdb_test "print (double2) 4" "\\\$$decimal = \\{4, 4\\}"
-gdb_test "print (char4) 12" "\\\$$decimal = \\{12, 12, 12, 12\\}"
-gdb_test "print (uint4) ia" "\\\$$decimal = \\{2, 2, 2, 2\\}"
-gdb_test "print (int4) -3" "\\\$$decimal = \\{-3, -3, -3, -3\\}"
-gdb_test "print (float4) 4" "\\\$$decimal = \\{4, 4, 4, 4\\}"
-
+# When casting to vector the input type must have the same length as
+# the total length of the vector.
+gdb_test "print (char4) 0x01010101" "\\\$$decimal = \\{1, 1, 1, 1\\}"
+gdb_test "print (char4) ia" "\\\$$decimal = \\{2, 0, 0, 0\\}"
+gdb_test "print (int2) lla" "\\\$$decimal = \\{1, 1\\}"
+
+gdb_test "print (int2) 1" "can only cast scalar to vector of same size"
+gdb_test "print (longlong2) 2" "can only cast scalar to vector of same size"
+gdb_test "print (float2) 3" "can only cast scalar to vector of same size"
+gdb_test "print (double2) 4" "can only cast scalar to vector of same size"
+gdb_test "print (uint4) ia" "can only cast scalar to vector of same size"
+gdb_test "print (int4) -3" "can only cast scalar to vector of same size"
+gdb_test "print (float4) 4" "can only cast scalar to vector of same size"
+
+gdb_test "print i4b = ia" "can only cast scalar to vector of same size"
+gdb_test "print i4a = 3" "can only cast scalar to vector of same size"
+gdb_test "print f4a = fb" "can only cast scalar to vector of same size"
+gdb_test "print f4b = 2" "can only cast scalar to vector of same size"
+
+gdb_test "print c4 + lla" "conversion of scalar to vector involves truncation"
+gdb_test "print i4a + lla" "conversion of scalar to vector involves truncation"
+gdb_test "print lla + c4" "conversion of scalar to vector involves truncation"
+gdb_test "print lla + i4a" "conversion of scalar to vector involves truncation"
+
+gdb_test "print c4 + ib" "\\\$$decimal = \\{2, 3, 4, 5\\}"
 gdb_test "print i4a + ib" "\\\$$decimal = \\{3, 5, 9, 17\\}"
+gdb_test "print i4a + 1" "\\\$$decimal = \\{3, 5, 9, 17\\}"
+gdb_test "print 1 + i4a" "\\\$$decimal = \\{3, 5, 9, 17\\}"
 gdb_test "print fa - f4b" "\\\$$decimal = \\{1, 0, -6, -2\\}"
+gdb_test "print 2 - f4b" "\\\$$decimal = \\{1, 0, -6, -2\\}"
 gdb_test "print f4a * fb" "\\\$$decimal = \\{2, 4, 8, 16\\}"
+gdb_test "print f4a * 1" "\\\$$decimal = \\{2, 4, 8, 16\\}"
 gdb_test "print ia / i4b" "\\\$$decimal = \\{2, 1, 0, 0\\}"
+gdb_test "print 2 / i4b" "\\\$$decimal = \\{2, 1, 0, 0\\}"
 gdb_test "print i4a % ib" "\\\$$decimal = \\{0, 0, 0, 0\\}"
-
+gdb_test "print i4a % 1" "\\\$$decimal = \\{0, 0, 0, 0\\}"
 gdb_test "print ia & i4b" "\\\$$decimal = \\{0, 2, 0, 0\\}"
+gdb_test "print 2 & i4b" "\\\$$decimal = \\{0, 2, 0, 0\\}"
 gdb_test "print i4a | ib" "\\\$$decimal = \\{3, 5, 9, 17\\}"
+gdb_test "print i4a | 1" "\\\$$decimal = \\{3, 5, 9, 17\\}"
 gdb_test "print ia ^ i4b" "\\\$$decimal = \\{3, 0, 10, 6\\}"
+gdb_test "print 2 ^ i4b" "\\\$$decimal = \\{3, 0, 10, 6\\}"
 gdb_test "print i4a << ib" "\\\$$decimal = \\{4, 8, 16, 32\\}"
+gdb_test "print i4a << 1" "\\\$$decimal = \\{4, 8, 16, 32\\}"
 gdb_test "print i4a >> ib" "\\\$$decimal = \\{1, 2, 4, 8\\}"
-
-gdb_test "print i4b = ia" "\\\$$decimal = \\{2, 2, 2, 2\\}"
-gdb_test "print i4a = 3" "\\\$$decimal = \\{3, 3, 3, 3\\}"
-gdb_test "print f4a = fb" "\\\$$decimal = \\{1, 1, 1, 1\\}"
-gdb_test "print f4b = 2" "\\\$$decimal = \\{2, 2, 2, 2\\}"
+gdb_test "print i4a >> 1" "\\\$$decimal = \\{1, 2, 4, 8\\}"
 
 gdb_test "print i4a = \{2, 4, 8, 16\}" "\\\$$decimal = \\{2, 4, 8, 16\\}"
 gdb_test "print i4a <<= ib" "\\\$$decimal = \\{4, 8, 16, 32\\}"
@@ -130,6 +150,10 @@ gdb_test "print i2 + i4a" "Cannot perform operation on vectors with different ty
 gdb_test "print f4a + f2" "Cannot perform operation on vectors with different types"
 gdb_test "print f2 + f4a" "Cannot perform operation on vectors with different types"
 
+gdb_test "print (double2) f2" "Cannot convert between vector values of different sizes"
+gdb_test "print (int4) c4" "Cannot convert between vector values of different sizes"
+gdb_test "print (char4) i4a" "Cannot convert between vector values of different sizes"
+
 # Test ptype on vector types.
 gdb_test "ptype c4" "type = char __attribute__ \\(\\(vector_size\\(4\\)\\)\\)"
 gdb_test "ptype char4" "type = char __attribute__ \\(\\(vector_size\\(4\\)\\)\\)"
diff --git a/gdb/testsuite/gdb.python/py-type.c b/gdb/testsuite/gdb.python/py-type.c
index bf39443..3412078 100644
--- a/gdb/testsuite/gdb.python/py-type.c
+++ b/gdb/testsuite/gdb.python/py-type.c
@@ -50,6 +50,9 @@ enum E
 { v1, v2, v3
 };
 
+struct s vec_data_1 = {1, 1};
+struct s vec_data_2 = {1, 2};
+
 int
 main ()
 {
diff --git a/gdb/testsuite/gdb.python/py-type.exp b/gdb/testsuite/gdb.python/py-type.exp
index 5009135..c3d0e1e 100644
--- a/gdb/testsuite/gdb.python/py-type.exp
+++ b/gdb/testsuite/gdb.python/py-type.exp
@@ -109,8 +109,8 @@ proc test_fields {lang} {
     gdb_test "python print not not st.type\['a'\].type" "True"
   
     # Test regression PR python/10805
-    gdb_py_test_silent_cmd "print ar" "print value (ar)" 1
-    gdb_py_test_silent_cmd "python ar = gdb.history (0)" "get value (ar) from history" 1
+    gdb_py_test_silent_cmd "print ar" "print value" 1
+    gdb_py_test_silent_cmd "python ar = gdb.history (0)" "get value from  history" 1
     gdb_test "python fields = ar.type.fields()"
     gdb_test "python print len(fields)" "1" "Check the number of fields"
     gdb_test "python print fields\[0\].type" "<range type>" "Check array field type"
@@ -119,22 +119,25 @@ proc test_fields {lang} {
     gdb_test "python print ar\[0\].cast(ar\[0\].type.array(1))" \
         ".1, 2." "cast to array with one argument"
     gdb_test "python print ar\[0\].cast(ar\[0\].type.array(0, 1))" \
-        ".1, 2." "cast to array with two arguments"
+	".1, 2." "cast to array with two arguments"
 
     gdb_test "python print ar\[0\].type == ar\[0\].type" "True"
 
     # Test gdb.Type.vector.
     # Note: vectors cast differently than arrays.  Here ar[0] is replicated
     # for the size of the vector.
-    gdb_py_test_silent_cmd \
-        "python vec1 = ar\[0\].cast(ar\[0\].type.vector(1))" "set vec1" 1
+    gdb_py_test_silent_cmd "print vec_data_1" "print value (vec_data_1)" 1
+    gdb_py_test_silent_cmd "python vec_data_1 = gdb.history (0)" "get value (vec_data_1) from history" 1
+
+    gdb_py_test_silent_cmd "print vec_data_2" "print value (vec_data_2)" 1
+    gdb_py_test_silent_cmd "python vec_data_2 = gdb.history (0)" "get value (vec_data_2) from history" 1
+
+    gdb_py_test_silent_cmd "python vec1 = vec_data_1.cast(ar\[0\].type.vector(1))" "set vec1" 1
     gdb_test "python print vec1" ".1, 1." "cast to vector with one argument"
-    gdb_py_test_silent_cmd \
-        "python vec2 = ar\[0\].cast(ar\[0\].type.vector(0, 1))" "set vec2" 1
+    gdb_py_test_silent_cmd "python vec2 = vec_data_1.cast(ar\[0\].type.vector(0, 1))" "set vec2" 1
     gdb_test "python print vec2" ".1, 1." "cast to vector with two arguments"
     gdb_test "python print vec1 == vec2" "True"
-    gdb_py_test_silent_cmd \
-        "python vec3 = ar\[1\].cast(ar\[1\].type.vector(1))" "set vec3" 1
+    gdb_py_test_silent_cmd "python vec3 = vec_data_2.cast(ar\[0\].type.vector(1))" "set vec3" 1
     gdb_test "python print vec1 == vec3" "False"
   }
 }



^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH] Vector to scalar casting and widening
  2012-11-23 16:26   ` Andrew Burgess
@ 2012-11-26 14:18     ` Ulrich Weigand
  2012-11-28 22:08       ` Andrew Burgess
  0 siblings, 1 reply; 14+ messages in thread
From: Ulrich Weigand @ 2012-11-26 14:18 UTC (permalink / raw)
  To: Andrew Burgess; +Cc: Tom Tromey, gdb-patches, Ken Werner

Andrew Burgess wrote:
> On 19/11/2012 9:16 PM, Tom Tromey wrote:
> >>>>>> "Andrew" == Andrew Burgess <aburgess@broadcom.com> writes:
> > 
> > Andrew> I'd like to change the way gdb handles scalar to vector
> > Andrew> widening.  I believe that the changes I propose will bring gdb
> > Andrew> expression evaluation into line with how gcc handles these
> > Andrew> things; this seems a good thing to me, but I'd be interested to
> > Andrew> hear why anyone things we should stick with the current scheme.

This difference between OpenCL semantics and GCC is a bit annoying;
for the most part, GCC vector extensions were chosen to match (or
at least extend) OpenCL semantics.  But in the particular case of
explicit conversion between integer and vector types it seems
the behaviour of the GCC extension dates way back to 2000 or so,
long before we even had OpenCL ...

Given that, I agree that we ought to match GCC's behaviour when
targeting non-OpenCL languages.

> In order to maintain current opencl behaviour I've created a new patch,
> this one has a flag on the language_defn structure to control how vector
> casting functions.  I reuse the vector widening code where appropriate.
> The choices then are:
>  1. vector to vector cast
>     1.1 This is not allowed in OpenCL (see above pdf) so I throw an error.
>     1.2 This is only allowed for gcc/c vectors if they are the same size,
>         otherwise throw an error.
>  2. scalar to vector cast
>     2.1 For OpenCL, cast scalar to vector element type and replicate.
>     2.2 For gcc/c vectors, only allow if the scalar is the same size as
>         the vector.

However, I'm not sure I like the new language_defn flag.  Generally, the
OpenCL code has kept all expression evaluation that differs from the
default behaviour local in evaluate_subexp_opencl; see e.g. the treatment
of relational operations.

Thus, I'd prefer a patch that:
 - changes the default behaviour of value_cast etc. to the GCC behaviour, and
 - adds handling of UNOP_CAST etc. to evaluate_subexp_opencl to implement the
   OpenCL semantics.

> I've tested the standard non-opencl side of things, but haven't been able
> to figure out how to run the opencl tests (any pointers welcome), so I don't
> know if I've broken any of those tests.

Unfortunately the only environment I know of to test the GDB OpenCL support
is the IBM OpenCL SDK for PowerPC.  I'll be happy to run the test for you ...

Bye,
Ulrich

-- 
  Dr. Ulrich Weigand
  GNU Toolchain for Linux on System z and Cell BE
  Ulrich.Weigand@de.ibm.com


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH] Vector to scalar casting and widening
  2012-11-26 14:18     ` Ulrich Weigand
@ 2012-11-28 22:08       ` Andrew Burgess
  2012-11-29 17:50         ` Ulrich Weigand
  0 siblings, 1 reply; 14+ messages in thread
From: Andrew Burgess @ 2012-11-28 22:08 UTC (permalink / raw)
  To: Ulrich Weigand; +Cc: tromey, gdb-patches, ken

On 26/11/2012 2:18 PM, Ulrich Weigand wrote:
> Andrew Burgess wrote:
>> On 19/11/2012 9:16 PM, Tom Tromey wrote:
>>>>>>>> "Andrew" == Andrew Burgess <aburgess@broadcom.com> writes:
>>>
>>> Andrew> I'd like to change the way gdb handles scalar to vector
>>> Andrew> widening.  I believe that the changes I propose will bring gdb
>>> Andrew> expression evaluation into line with how gcc handles these
>>> Andrew> things; this seems a good thing to me, but I'd be interested to
>>> Andrew> hear why anyone things we should stick with the current scheme.
> 
> This difference between OpenCL semantics and GCC is a bit annoying;
> for the most part, GCC vector extensions were chosen to match (or
> at least extend) OpenCL semantics.  But in the particular case of
> explicit conversion between integer and vector types it seems
> the behaviour of the GCC extension dates way back to 2000 or so,
> long before we even had OpenCL ...
> 
> Given that, I agree that we ought to match GCC's behaviour when
> targeting non-OpenCL languages.
> 
> However, I'm not sure I like the new language_defn flag.  Generally, the
> OpenCL code has kept all expression evaluation that differs from the
> default behaviour local in evaluate_subexp_opencl; see e.g. the treatment
> of relational operations.
> 
> Thus, I'd prefer a patch that:
>  - changes the default behaviour of value_cast etc. to the GCC behaviour, and
>  - adds handling of UNOP_CAST etc. to evaluate_subexp_opencl to implement the
>    OpenCL semantics.

The latest patch below is is closer to the initial patch I posted, the
behaviour of value_cast now follows GCC, and the UNOP_CAST case is handled
in evaluate_subexp_opencl.  I wasn't sure what the "etc" in the above point
referred to, I believe UNOP_CAST is all I need to catch, let me know if I've
missed anything.

> 
> Unfortunately the only environment I know of to test the GDB OpenCL support
> is the IBM OpenCL SDK for PowerPC.  I'll be happy to run the test for you ...

I've built and tested on x86-64 GNU/Linux, but I've not run any OpenCL tests.  If
you were able to give this patch a go and let me know if I've broken any of the
OpenCL tests I'd be very grateful.

Other than passing the OpenCL tests, is there any other feedback on this patch?  As
this version of the patch is so similar to the first version I posted, and Tom
seemed happy with that (I've made the suggested changes), the only part that really
needs review is the change to opencl-lang.c.

Thanks,

Andrew



gdb/ChangeLog

2012-11-27  Andrew Burgess  <aburgess@broadcom.com>

	Add language specific flag to control casting from scalar to
	vector types.  Allow scalar to vector widening during binary
	operations on a scalar and a vector.
	* valarith.c (value_vector_widen): New function for replicating a
	scalar into a vector.
	(value_binop): Use new function to convert scalar to vector rather
	than value_cast.
	* value.h (value_vector_widen): Declare new function.
	* valops.c (value_casst): Update logic for casting between vector
	types, and for casting from scalar to vector.
	* opencl-lang.c (evaluate_subexp_opencl): Handle UNOP_CAST to deal
	with OpenCL scalar to vector casting.

diff --git a/gdb/opencl-lang.c b/gdb/opencl-lang.c
index b8fd9b7..0a529fc 100644
--- a/gdb/opencl-lang.c
+++ b/gdb/opencl-lang.c
@@ -769,6 +769,56 @@ evaluate_subexp_opencl (struct type *expect_type, struct expression *exp,
 
       return opencl_logical_not (exp, arg1);
 
+    case UNOP_CAST:
+      type1 = exp->elts[*pos + 1].type;
+      (*pos) += 2;
+      arg1 = evaluate_subexp (type1, exp, pos, noside);
+      if (noside == EVAL_SKIP)
+	return value_from_longest (builtin_type (exp->gdbarch)->
+				   builtin_int, 1);
+      if (type1 != value_type (arg1))
+	{
+	  /* Casting scalar to vector is a special case for OpenCL, scalar
+	     is cast to element type of vector then replicated into each
+	     element of the vector.  First though, we need to work out if
+	     this is a scalar to vector cast; code lifted from
+	     valops.c:value_cast.  */
+	  enum type_code code1, code2;
+	  struct type *to_type;
+	  int scalar;
+
+	  to_type = check_typedef (type1);
+
+	  code1 = TYPE_CODE (to_type);
+	  code2 = TYPE_CODE (check_typedef (value_type (arg2)));
+
+	  if (code2 == TYPE_CODE_REF)
+	    code2 = TYPE_CODE (check_typedef (value_type (coerce_ref (arg2))));
+
+	  scalar = (code2 == TYPE_CODE_INT || code2 == TYPE_CODE_BOOL
+		    || code2 == TYPE_CODE_CHAR || code2 == TYPE_CODE_FLT
+		    || code2 == TYPE_CODE_DECFLOAT || code2 == TYPE_CODE_ENUM
+		    || code2 == TYPE_CODE_RANGE);
+
+	  if (code1 == TYPE_CODE_ARRAY && TYPE_VECTOR (to_type) && scalar)
+	    {
+	      struct type *eltype;
+
+	      /* Cast to the element type of the vector here as
+		 value_vector_widen will error if the scalar value is
+		 truncated by the cast.  To avoid the error, cast (and
+		 possibly truncate) here.  */
+	      eltype = check_typedef (TYPE_TARGET_TYPE (to_type));
+	      arg2 = value_cast (eltype, arg2);
+
+	      return value_vector_widen (arg2, type1);
+	    }
+	  else
+	    /* Standard cast handler.  */
+	    arg1 = value_cast (type1, arg1);
+	}
+      return arg1;
+
     /* Handle the logical operator and(&&) and or(||).  */
     case BINOP_LOGICAL_AND:
     case BINOP_LOGICAL_OR:
diff --git a/gdb/valarith.c b/gdb/valarith.c
index c457f4a..afb45e2 100644
--- a/gdb/valarith.c
+++ b/gdb/valarith.c
@@ -1347,6 +1347,49 @@ scalar_binop (struct value *arg1, struct value *arg2, enum exp_opcode op)
   return val;
 }
 
+/* Widen a scalar value SCALAR_VALUE to vector type VECTOR_TYPE by
+   replicating SCALAR_VALUE for each element of the vector.  Only scalar
+   types that can be cast to the type of one element of the vector are
+   acceptable.  The newly created vector value is returned upon success,
+   otherwise an error is thrown.  */
+
+struct value *
+value_vector_widen (struct value *scalar_value, struct type *vector_type)
+{
+  /* Widen the scalar to a vector.  */
+  struct type *eltype, *scalar_type;
+  struct value *val, *elval;
+  LONGEST low_bound, high_bound;
+  int i;
+
+  CHECK_TYPEDEF (vector_type);
+
+  gdb_assert (TYPE_CODE (vector_type) == TYPE_CODE_ARRAY
+	      && TYPE_VECTOR (vector_type));
+
+  if (!get_array_bounds (vector_type, &low_bound, &high_bound))
+    error (_("Could not determine the vector bounds"));
+
+  eltype = check_typedef (TYPE_TARGET_TYPE (vector_type));
+  elval = value_cast (eltype, scalar_value);
+
+  scalar_type = check_typedef (value_type (scalar_value));
+
+  /* If we reduced the length of the scalar then check we didn't loose any
+     important bits.  */
+  if (TYPE_LENGTH (eltype) < TYPE_LENGTH (scalar_type)
+      && !value_equal (elval, scalar_value))
+    error (_("conversion of scalar to vector involves truncation"));
+
+  val = allocate_value (vector_type);
+  for (i = 0; i < high_bound - low_bound + 1; i++)
+    /* Duplicate the contents of elval into the destination vector.  */
+    memcpy (value_contents_writeable (val) + (i * TYPE_LENGTH (eltype)),
+	    value_contents_all (elval), TYPE_LENGTH (eltype));
+
+  return val;
+}
+
 /* Performs a binary operation on two vector operands by calling scalar_binop
    for each pair of vector components.  */
 
@@ -1426,7 +1469,9 @@ value_binop (struct value *arg1, struct value *arg2, enum exp_opcode op)
 	  && !is_integral_type (t))
 	error (_("Argument to operation not a number or boolean."));
 
-      *v = value_cast (t1_is_vec ? type1 : type2, *v);
+      /* Replicate the scalar value to make a vector value.  */
+      *v = value_vector_widen (*v, t1_is_vec ? type1 : type2);
+
       val = vector_binop (arg1, arg2, op);
     }
 
diff --git a/gdb/valops.c b/gdb/valops.c
index 502fb0d..8f7f9ad 100644
--- a/gdb/valops.c
+++ b/gdb/valops.c
@@ -546,29 +546,13 @@ value_cast (struct type *type, struct value *arg2)
 	 minus one, instead of biasing the normal case.  */
       return value_from_longest (type, -1);
     }
-  else if (code1 == TYPE_CODE_ARRAY && TYPE_VECTOR (type) && scalar)
-    {
-      /* Widen the scalar to a vector.  */
-      struct type *eltype;
-      struct value *val;
-      LONGEST low_bound, high_bound;
-      int i;
-
-      if (!get_array_bounds (type, &low_bound, &high_bound))
-	error (_("Could not determine the vector bounds"));
-
-      eltype = check_typedef (TYPE_TARGET_TYPE (type));
-      arg2 = value_cast (eltype, arg2);
-      val = allocate_value (type);
-
-      for (i = 0; i < high_bound - low_bound + 1; i++)
-	{
-	  /* Duplicate the contents of arg2 into the destination vector.  */
-	  memcpy (value_contents_writeable (val) + (i * TYPE_LENGTH (eltype)),
-		  value_contents_all (arg2), TYPE_LENGTH (eltype));
-	}
-      return val;
-    }
+  else if (code1 == TYPE_CODE_ARRAY && TYPE_VECTOR (type)
+	   && code2 == TYPE_CODE_ARRAY && TYPE_VECTOR (type2)
+	   && TYPE_LENGTH (type) != TYPE_LENGTH (type2))
+    error (_("Cannot convert between vector values of different sizes"));
+  else if (code1 == TYPE_CODE_ARRAY && TYPE_VECTOR (type) && scalar
+	   && TYPE_LENGTH (type) != TYPE_LENGTH (type2))
+    error (_("can only cast scalar to vector of same size"));
   else if (TYPE_LENGTH (type) == TYPE_LENGTH (type2))
     {
       if (code1 == TYPE_CODE_PTR && code2 == TYPE_CODE_PTR)
diff --git a/gdb/value.h b/gdb/value.h
index 3685935..f8438dc 100644
--- a/gdb/value.h
+++ b/gdb/value.h
@@ -482,6 +482,12 @@ extern void read_value_memory (struct value *val, int embedded_offset,
 			       int stack, CORE_ADDR memaddr,
 			       gdb_byte *buffer, size_t length);
 
+/* Cast SCALAR_VALUE to the element type of VECTOR_TYPE, then replicate
+   into each element of a new vector value with VECTOR_TYPE.  */
+
+struct value *value_vector_widen (struct value *scalar_value,
+				  struct type *vector_type);
+
 \f
 
 #include "symtab.h"





gdb/testsuite/ChangeLog

2012-11-27  Andrew Burgess  <aburgess@broadcom.com>

	* gdb.base/gnu_vector.c: New variable for use in tests.
	* gdb.base/gnu_vector.exp: Update and extend tests to reflect
	changes in scalar to vector casting and widening.
	* gdb.python/py-type.c: New variables for use in tests.
	* gdb.python/py-type.exp: Update vector related tests to reflect
	changes in scalar to vector casting and widening.
 
diff --git a/gdb/testsuite/gdb.base/gnu_vector.c b/gdb/testsuite/gdb.base/gnu_vector.c
index a2a218f..07bc529 100644
--- a/gdb/testsuite/gdb.base/gnu_vector.c
+++ b/gdb/testsuite/gdb.base/gnu_vector.c
@@ -31,6 +31,7 @@ int ia = 2;
 int ib = 1;
 float fa = 2;
 float fb = 1;
+long long lla __attribute__ ((mode(DI))) = 0x0000000100000001ll;
 char4 c4 = {1, 2, 3, 4};
 int4 i4a = {2, 4, 8, 16};
 int4 i4b = {1, 2, 8, 4};
diff --git a/gdb/testsuite/gdb.base/gnu_vector.exp b/gdb/testsuite/gdb.base/gnu_vector.exp
index baba119..b6a1afb 100644
--- a/gdb/testsuite/gdb.base/gnu_vector.exp
+++ b/gdb/testsuite/gdb.base/gnu_vector.exp
@@ -82,32 +82,52 @@ gdb_test "print f4a / f4b" "\\\$$decimal = \\{2, 2, 1, 4\\}"
 gdb_test "print +f4a" "\\\$$decimal = \\{2, 4, 8, 16\\}"
 gdb_test "print -f4a" "\\\$$decimal = \\{-2, -4, -8, -16\\}"
 
-# Test scalar to vector widening
-gdb_test "print (int2) 1" "\\\$$decimal = \\{1, 1\\}"
-gdb_test "print (longlong2) 2" "\\\$$decimal = \\{2, 2\\}"
-gdb_test "print (float2) 3" "\\\$$decimal = \\{3, 3\\}"
-gdb_test "print (double2) 4" "\\\$$decimal = \\{4, 4\\}"
-gdb_test "print (char4) 12" "\\\$$decimal = \\{12, 12, 12, 12\\}"
-gdb_test "print (uint4) ia" "\\\$$decimal = \\{2, 2, 2, 2\\}"
-gdb_test "print (int4) -3" "\\\$$decimal = \\{-3, -3, -3, -3\\}"
-gdb_test "print (float4) 4" "\\\$$decimal = \\{4, 4, 4, 4\\}"
-
+# When casting to vector the input type must have the same length as
+# the total length of the vector.
+gdb_test "print (char4) 0x01010101" "\\\$$decimal = \\{1, 1, 1, 1\\}"
+gdb_test "print (char4) ia" "\\\$$decimal = \\{2, 0, 0, 0\\}"
+gdb_test "print (int2) lla" "\\\$$decimal = \\{1, 1\\}"
+
+gdb_test "print (int2) 1" "can only cast scalar to vector of same size"
+gdb_test "print (longlong2) 2" "can only cast scalar to vector of same size"
+gdb_test "print (float2) 3" "can only cast scalar to vector of same size"
+gdb_test "print (double2) 4" "can only cast scalar to vector of same size"
+gdb_test "print (uint4) ia" "can only cast scalar to vector of same size"
+gdb_test "print (int4) -3" "can only cast scalar to vector of same size"
+gdb_test "print (float4) 4" "can only cast scalar to vector of same size"
+
+gdb_test "print i4b = ia" "can only cast scalar to vector of same size"
+gdb_test "print i4a = 3" "can only cast scalar to vector of same size"
+gdb_test "print f4a = fb" "can only cast scalar to vector of same size"
+gdb_test "print f4b = 2" "can only cast scalar to vector of same size"
+
+gdb_test "print c4 + lla" "conversion of scalar to vector involves truncation"
+gdb_test "print i4a + lla" "conversion of scalar to vector involves truncation"
+gdb_test "print lla + c4" "conversion of scalar to vector involves truncation"
+gdb_test "print lla + i4a" "conversion of scalar to vector involves truncation"
+
+gdb_test "print c4 + ib" "\\\$$decimal = \\{2, 3, 4, 5\\}"
 gdb_test "print i4a + ib" "\\\$$decimal = \\{3, 5, 9, 17\\}"
+gdb_test "print i4a + 1" "\\\$$decimal = \\{3, 5, 9, 17\\}"
+gdb_test "print 1 + i4a" "\\\$$decimal = \\{3, 5, 9, 17\\}"
 gdb_test "print fa - f4b" "\\\$$decimal = \\{1, 0, -6, -2\\}"
+gdb_test "print 2 - f4b" "\\\$$decimal = \\{1, 0, -6, -2\\}"
 gdb_test "print f4a * fb" "\\\$$decimal = \\{2, 4, 8, 16\\}"
+gdb_test "print f4a * 1" "\\\$$decimal = \\{2, 4, 8, 16\\}"
 gdb_test "print ia / i4b" "\\\$$decimal = \\{2, 1, 0, 0\\}"
+gdb_test "print 2 / i4b" "\\\$$decimal = \\{2, 1, 0, 0\\}"
 gdb_test "print i4a % ib" "\\\$$decimal = \\{0, 0, 0, 0\\}"
-
+gdb_test "print i4a % 1" "\\\$$decimal = \\{0, 0, 0, 0\\}"
 gdb_test "print ia & i4b" "\\\$$decimal = \\{0, 2, 0, 0\\}"
+gdb_test "print 2 & i4b" "\\\$$decimal = \\{0, 2, 0, 0\\}"
 gdb_test "print i4a | ib" "\\\$$decimal = \\{3, 5, 9, 17\\}"
+gdb_test "print i4a | 1" "\\\$$decimal = \\{3, 5, 9, 17\\}"
 gdb_test "print ia ^ i4b" "\\\$$decimal = \\{3, 0, 10, 6\\}"
+gdb_test "print 2 ^ i4b" "\\\$$decimal = \\{3, 0, 10, 6\\}"
 gdb_test "print i4a << ib" "\\\$$decimal = \\{4, 8, 16, 32\\}"
+gdb_test "print i4a << 1" "\\\$$decimal = \\{4, 8, 16, 32\\}"
 gdb_test "print i4a >> ib" "\\\$$decimal = \\{1, 2, 4, 8\\}"
-
-gdb_test "print i4b = ia" "\\\$$decimal = \\{2, 2, 2, 2\\}"
-gdb_test "print i4a = 3" "\\\$$decimal = \\{3, 3, 3, 3\\}"
-gdb_test "print f4a = fb" "\\\$$decimal = \\{1, 1, 1, 1\\}"
-gdb_test "print f4b = 2" "\\\$$decimal = \\{2, 2, 2, 2\\}"
+gdb_test "print i4a >> 1" "\\\$$decimal = \\{1, 2, 4, 8\\}"
 
 gdb_test "print i4a = \{2, 4, 8, 16\}" "\\\$$decimal = \\{2, 4, 8, 16\\}"
 gdb_test "print i4a <<= ib" "\\\$$decimal = \\{4, 8, 16, 32\\}"
@@ -130,6 +150,10 @@ gdb_test "print i2 + i4a" "Cannot perform operation on vectors with different ty
 gdb_test "print f4a + f2" "Cannot perform operation on vectors with different types"
 gdb_test "print f2 + f4a" "Cannot perform operation on vectors with different types"
 
+gdb_test "print (double2) f2" "Cannot convert between vector values of different sizes"
+gdb_test "print (int4) c4" "Cannot convert between vector values of different sizes"
+gdb_test "print (char4) i4a" "Cannot convert between vector values of different sizes"
+
 # Test ptype on vector types.
 gdb_test "ptype c4" "type = char __attribute__ \\(\\(vector_size\\(4\\)\\)\\)"
 gdb_test "ptype char4" "type = char __attribute__ \\(\\(vector_size\\(4\\)\\)\\)"
diff --git a/gdb/testsuite/gdb.python/py-type.c b/gdb/testsuite/gdb.python/py-type.c
index bf39443..3412078 100644
--- a/gdb/testsuite/gdb.python/py-type.c
+++ b/gdb/testsuite/gdb.python/py-type.c
@@ -50,6 +50,9 @@ enum E
 { v1, v2, v3
 };
 
+struct s vec_data_1 = {1, 1};
+struct s vec_data_2 = {1, 2};
+
 int
 main ()
 {
diff --git a/gdb/testsuite/gdb.python/py-type.exp b/gdb/testsuite/gdb.python/py-type.exp
index 5009135..f9cc90a 100644
--- a/gdb/testsuite/gdb.python/py-type.exp
+++ b/gdb/testsuite/gdb.python/py-type.exp
@@ -126,15 +126,18 @@ proc test_fields {lang} {
     # Test gdb.Type.vector.
     # Note: vectors cast differently than arrays.  Here ar[0] is replicated
     # for the size of the vector.
-    gdb_py_test_silent_cmd \
-        "python vec1 = ar\[0\].cast(ar\[0\].type.vector(1))" "set vec1" 1
+    gdb_py_test_silent_cmd "print vec_data_1" "print value (vec_data_1)" 1
+    gdb_py_test_silent_cmd "python vec_data_1 = gdb.history (0)" "get value (vec_data_1) from history" 1
+
+    gdb_py_test_silent_cmd "print vec_data_2" "print value (vec_data_2)" 1
+    gdb_py_test_silent_cmd "python vec_data_2 = gdb.history (0)" "get value (vec_data_2) from history" 1
+
+    gdb_py_test_silent_cmd "python vec1 = vec_data_1.cast(ar\[0\].type.vector(1))" "set vec1" 1
     gdb_test "python print vec1" ".1, 1." "cast to vector with one argument"
-    gdb_py_test_silent_cmd \
-        "python vec2 = ar\[0\].cast(ar\[0\].type.vector(0, 1))" "set vec2" 1
+    gdb_py_test_silent_cmd "python vec2 = vec_data_1.cast(ar\[0\].type.vector(0, 1))" "set vec2" 1
     gdb_test "python print vec2" ".1, 1." "cast to vector with two arguments"
     gdb_test "python print vec1 == vec2" "True"
-    gdb_py_test_silent_cmd \
-        "python vec3 = ar\[1\].cast(ar\[1\].type.vector(1))" "set vec3" 1
+    gdb_py_test_silent_cmd "python vec3 = vec_data_2.cast(ar\[0\].type.vector(1))" "set vec3" 1
     gdb_test "python print vec1 == vec3" "False"
   }
 }



^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH] Vector to scalar casting and widening
  2012-11-28 22:08       ` Andrew Burgess
@ 2012-11-29 17:50         ` Ulrich Weigand
  2012-11-29 18:13           ` Andrew Burgess
  2013-01-04 14:45           ` Andrew Burgess
  0 siblings, 2 replies; 14+ messages in thread
From: Ulrich Weigand @ 2012-11-29 17:50 UTC (permalink / raw)
  To: Andrew Burgess; +Cc: tromey, gdb-patches, ken

Andrew Burgess wrote:
> On 26/11/2012 2:18 PM, Ulrich Weigand wrote:
> > Thus, I'd prefer a patch that:
> >  - changes the default behaviour of value_cast etc. to the GCC behaviour, and
> >  - adds handling of UNOP_CAST etc. to evaluate_subexp_opencl to implement the
> >    OpenCL semantics.
> 
> The latest patch below is is closer to the initial patch I posted, the
> behaviour of value_cast now follows GCC, and the UNOP_CAST case is handled
> in evaluate_subexp_opencl.  I wasn't sure what the "etc" in the above point
> referred to, I believe UNOP_CAST is all I need to catch, let me know if I've
> missed anything.

Well, there's the whole "vector <binop> scalar" issue; with your patch, this
is now only supported if the scalar type is widened, and rejected if it is
truncated.  This does not correspond to OpenCL semantics, where truncation
is explicitly supported.

Another problem: in several places in opencl-lang.c, the code calls
value_cast with the explicit assumption that this will splat a scalar
across all vector components.  Those uses would now have to be changed
to a value_cast/value_vector_widen pair, I guess.

> > Unfortunately the only environment I know of to test the GDB OpenCL support
> > is the IBM OpenCL SDK for PowerPC.  I'll be happy to run the test for you ...
> 
> I've built and tested on x86-64 GNU/Linux, but I've not run any OpenCL tests.  If
> you were able to give this patch a go and let me know if I've broken any of the
> OpenCL tests I'd be very grateful.

As expected, given the above, a whole bunch of tests fail ...

Bye,
Ulrich

-- 
  Dr. Ulrich Weigand
  GNU Toolchain for Linux on System z and Cell BE
  Ulrich.Weigand@de.ibm.com


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH] Vector to scalar casting and widening
  2012-11-29 17:50         ` Ulrich Weigand
@ 2012-11-29 18:13           ` Andrew Burgess
  2013-01-04 14:45           ` Andrew Burgess
  1 sibling, 0 replies; 14+ messages in thread
From: Andrew Burgess @ 2012-11-29 18:13 UTC (permalink / raw)
  To: Ulrich Weigand; +Cc: tromey, gdb-patches, ken

On 29/11/2012 5:49 PM, Ulrich Weigand wrote:
> 
> As expected, given the above, a whole bunch of tests fail ...
> 

Thanks for explaining.  I'll take a look at this now I understand the
issue better.

Sorry for the confusion.

Andrew



^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH] Vector to scalar casting and widening
  2012-11-29 17:50         ` Ulrich Weigand
  2012-11-29 18:13           ` Andrew Burgess
@ 2013-01-04 14:45           ` Andrew Burgess
  2013-01-07 16:23             ` Ulrich Weigand
  1 sibling, 1 reply; 14+ messages in thread
From: Andrew Burgess @ 2013-01-04 14:45 UTC (permalink / raw)
  To: Ulrich Weigand; +Cc: tromey, gdb-patches, ken

On 29/11/2012 5:49 PM, Ulrich Weigand wrote:
> Andrew Burgess wrote:
>> On 26/11/2012 2:18 PM, Ulrich Weigand wrote:
>>> Thus, I'd prefer a patch that:
>>>  - changes the default behaviour of value_cast etc. to the GCC behaviour, and
>>>  - adds handling of UNOP_CAST etc. to evaluate_subexp_opencl to implement the
>>>    OpenCL semantics.
>>
>> The latest patch below is is closer to the initial patch I posted, the
>> behaviour of value_cast now follows GCC, and the UNOP_CAST case is handled
>> in evaluate_subexp_opencl.  I wasn't sure what the "etc" in the above point
>> referred to, I believe UNOP_CAST is all I need to catch, let me know if I've
>> missed anything.
> 
> Well, there's the whole "vector <binop> scalar" issue; with your patch, this
> is now only supported if the scalar type is widened, and rejected if it is
> truncated.  This does not correspond to OpenCL semantics, where truncation
> is explicitly supported.
> 
> Another problem: in several places in opencl-lang.c, the code calls
> value_cast with the explicit assumption that this will splat a scalar
> across all vector components.  Those uses would now have to be changed
> to a value_cast/value_vector_widen pair, I guess.

I finally found time to revisit this issue.

I'm having issues with the approach you suggested, that is adding
handling for UNOP_CAST into evaludate_subexp_opencl, and would welcome
further advice on how I might move this issue forward.

In addressing the two problems you pointed out above, I first created a
new function opencl_value_cast, which I use throughout opencl-lang.c,
however, a quick grep of the codebase shows other places that call
value_cast, for example, within the varobj.c code.  I suspect that
creating an opencl_value_cast function will mean that I am introducing
bugs when, for example, we create varobj objects for opencl code.

The first issue you pointed out above "vector <binop> scalar" seems even
harder to fix.  The current problem with my patch is that I call
value_vector_widen from value_binop, which will error if the scalar
value is truncated when casting to the vector type.  For OpenCL this is
the wrong thing to do.  I don't want to add an "if (language == opencl)"
switch to value_binop, and value_binop is called extensively throughout
the codebase.  This would suggest then that it is value_vector_widen
that should change, however, this feels very much like the original
patch to which you objected.

So, to summarise the problem as I see it, your suggested solution was to
filter the different behaviours within opencl-lang.c, however, the
problem behaviours live within value_cast and value_binop, both of which
I believe are called from core gdb code, not just from opencl-lang.c, I
therefore believe there's no reliable way to intercept all calls to
these functions.

I'd like to put two other possible solutions on the table (they are
really just variations on the same theme), these would be (1) go back to
my original flag on the language structure, handle all the different
variations within value_cast or value_vector_widen, or (2) have a set of
"vector_ops" function pointers on the language structure, currently
there would be just two, "scalar_to_vector_widen" and
"scalar_to_vector_cast".  The defaults would be standard gcc C behaviour
implemented in (probably) valops.c, while opencl would provide its own
within opencl-lang.c.

Alternatively I may have just miss-understood the issue here, in which
case feel free to set me straight!

Thanks for your time,
Andrew




> 
>>> Unfortunately the only environment I know of to test the GDB OpenCL support
>>> is the IBM OpenCL SDK for PowerPC.  I'll be happy to run the test for you ...
>>
>> I've built and tested on x86-64 GNU/Linux, but I've not run any OpenCL tests.  If
>> you were able to give this patch a go and let me know if I've broken any of the
>> OpenCL tests I'd be very grateful.
> 
> As expected, given the above, a whole bunch of tests fail ...
> 
> Bye,
> Ulrich
> 



^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH] Vector to scalar casting and widening
  2013-01-04 14:45           ` Andrew Burgess
@ 2013-01-07 16:23             ` Ulrich Weigand
  2013-01-08 15:08               ` Andrew Burgess
  2013-01-09 19:08               ` Tom Tromey
  0 siblings, 2 replies; 14+ messages in thread
From: Ulrich Weigand @ 2013-01-07 16:23 UTC (permalink / raw)
  To: Andrew Burgess; +Cc: tromey, gdb-patches, ken

Andrew Burgess wrote:

> In addressing the two problems you pointed out above, I first created a
> new function opencl_value_cast, which I use throughout opencl-lang.c,
> however, a quick grep of the codebase shows other places that call
> value_cast, for example, within the varobj.c code.  I suspect that
> creating an opencl_value_cast function will mean that I am introducing
> bugs when, for example, we create varobj objects for opencl code.
>
> The first issue you pointed out above "vector <binop> scalar" seems even
> harder to fix.  The current problem with my patch is that I call
> value_vector_widen from value_binop, which will error if the scalar
> value is truncated when casting to the vector type.  For OpenCL this is
> the wrong thing to do.  I don't want to add an "if (language == opencl)"
> switch to value_binop, and value_binop is called extensively throughout
> the codebase.  This would suggest then that it is value_vector_widen
> that should change, however, this feels very much like the original
> patch to which you objected.
> 
> So, to summarise the problem as I see it, your suggested solution was to
> filter the different behaviours within opencl-lang.c, however, the
> problem behaviours live within value_cast and value_binop, both of which
> I believe are called from core gdb code, not just from opencl-lang.c, I
> therefore believe there's no reliable way to intercept all calls to
> these functions.

I don't actually think you need (or even *should*) intercept all such
calls.  Taking a step back, the underlying problem is that GDB supports
operating on expressions in various different languages that all have
their own special rules on how to perform certain operations, but maps
them all to a single GDB "value" type, with a single set of operations
on them.

My understanding of how this is supposed to work out is that GDB
"value" operations *do not* actually implement the precise semantics
of any of the languages GDB supports; rather, they implement a GDB
private semantics of "GDB value" objects.  Now, as those are private
to GDB, we are free to implement them however we wish; for pragmatic
and historical reasons, they do mostly (but not completely!) match
C semantics.

When evaluating language expressions, the eval* routines are free
to use value_* operations directly **when their semantics match the
language semantics**, but must use a different implementation when
the language requires special semantics.  (Note how e.g. the particular
C type promotions rules for binary operations are *not* implemented
in value_binop, but are handled specially in the C expression
evaluation code.)

[ For historical reasons, some of the value_* operations currently
change aspects of their behaviour depending on current_language.
This is really a bug, and we ought to (and slowly do) move away
from this.  For example, in a program employing multiple languages
simultaneously, GDB value objects might have been created from
values in a different language than the "current" one. ]

Now, as you point out, value_* operations are also used throughout
the rest of GDB (not part of expression evaluation).  This is fine,
as long as those parts **do not assume they follow any particular
language semantics, but rather the generic GDB value semantics**.

In general, I think this is in fact the case.  For example, the
value_cast uses in varobj.c you mention appear to only rely on
common properties of the GDB value semantics (casting C++ objects
between base and derived types).  If there are indeed instances
of value_ operations that assume specific C (or OpenCL) semantics,
those would have to be fixed.  [ In particular for OpenCL, I'm
quite sure that no-one outside of opencl-lang.c relies on any
particular OpenCL semantics of the value_ operations. ]

> I'd like to put two other possible solutions on the table (they are
> really just variations on the same theme), these would be (1) go back to
> my original flag on the language structure, handle all the different
> variations within value_cast or value_vector_widen, or (2) have a set of
> "vector_ops" function pointers on the language structure, currently
> there would be just two, "scalar_to_vector_widen" and
> "scalar_to_vector_cast".  The defaults would be standard gcc C behaviour
> implemented in (probably) valops.c, while opencl would provide its own
> within opencl-lang.c.

Both of these would go back to make value_ operations change their
behaviour depending on a language, which goes against the general
direction I've outlined above ...

Bye,
Ulrich

-- 
  Dr. Ulrich Weigand
  GNU Toolchain for Linux on System z and Cell BE
  Ulrich.Weigand@de.ibm.com


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH] Vector to scalar casting and widening
  2013-01-07 16:23             ` Ulrich Weigand
@ 2013-01-08 15:08               ` Andrew Burgess
  2013-01-08 19:05                 ` Ulrich Weigand
  2013-01-09 19:08               ` Tom Tromey
  1 sibling, 1 reply; 14+ messages in thread
From: Andrew Burgess @ 2013-01-08 15:08 UTC (permalink / raw)
  To: Ulrich Weigand; +Cc: tromey, gdb-patches, ken

Ulrich,

On 07/01/2013 4:23 PM, Ulrich Weigand wrote:
> Andrew Burgess wrote:
> 
>> In addressing the two problems you pointed out above, I first created a
>> new function opencl_value_cast, which I use throughout opencl-lang.c,
>> however, a quick grep of the codebase shows other places that call
>> value_cast, for example, within the varobj.c code.  I suspect that
>> creating an opencl_value_cast function will mean that I am introducing
>> bugs when, for example, we create varobj objects for opencl code.
>>
>> The first issue you pointed out above "vector <binop> scalar" seems even
>> harder to fix.  The current problem with my patch is that I call
>> value_vector_widen from value_binop, which will error if the scalar
>> value is truncated when casting to the vector type.  For OpenCL this is
>> the wrong thing to do.  I don't want to add an "if (language == opencl)"
>> switch to value_binop, and value_binop is called extensively throughout
>> the codebase.  This would suggest then that it is value_vector_widen
>> that should change, however, this feels very much like the original
>> patch to which you objected.
>>
>> So, to summarise the problem as I see it, your suggested solution was to
>> filter the different behaviours within opencl-lang.c, however, the
>> problem behaviours live within value_cast and value_binop, both of which
>> I believe are called from core gdb code, not just from opencl-lang.c, I
>> therefore believe there's no reliable way to intercept all calls to
>> these functions.
> 
> I don't actually think you need (or even *should*) intercept all such
> calls.  Taking a step back, the underlying problem is that GDB supports
> operating on expressions in various different languages that all have
> their own special rules on how to perform certain operations, but maps
> them all to a single GDB "value" type, with a single set of operations
> on them.
> 
> My understanding of how this is supposed to work out is that GDB
> "value" operations *do not* actually implement the precise semantics
> of any of the languages GDB supports; rather, they implement a GDB
> private semantics of "GDB value" objects.  Now, as those are private
> to GDB, we are free to implement them however we wish; for pragmatic
> and historical reasons, they do mostly (but not completely!) match
> C semantics.
> 
> When evaluating language expressions, the eval* routines are free
> to use value_* operations directly **when their semantics match the
> language semantics**, but must use a different implementation when
> the language requires special semantics.  (Note how e.g. the particular
> C type promotions rules for binary operations are *not* implemented
> in value_binop, but are handled specially in the C expression
> evaluation code.)
> 
> [ For historical reasons, some of the value_* operations currently
> change aspects of their behaviour depending on current_language.
> This is really a bug, and we ought to (and slowly do) move away
> from this.  For example, in a program employing multiple languages
> simultaneously, GDB value objects might have been created from
> values in a different language than the "current" one. ]
> 
> Now, as you point out, value_* operations are also used throughout
> the rest of GDB (not part of expression evaluation).  This is fine,
> as long as those parts **do not assume they follow any particular
> language semantics, but rather the generic GDB value semantics**.
> 
> In general, I think this is in fact the case.  For example, the
> value_cast uses in varobj.c you mention appear to only rely on
> common properties of the GDB value semantics (casting C++ objects
> between base and derived types).  If there are indeed instances
> of value_ operations that assume specific C (or OpenCL) semantics,
> those would have to be fixed.  [ In particular for OpenCL, I'm
> quite sure that no-one outside of opencl-lang.c relies on any
> particular OpenCL semantics of the value_ operations. ]

Thanks for taking the time to explain this all for me, apologies
for not catching on sooner.

I have a new patch which I believe should be closer to what we want,
I'd be grateful if you could test the opencl parts of this again and
let me know how it gets on.  Also any other feedback is of course
welcome too.

Thanks,
Andrew



gdb/ChangeLog

2013-01-08  Andrew Burgess  <aburgess@broadcom.com>

	* valarith.c (value_vector_widen): New function for replicating a
	scalar into a vector.
	(vector_binop): No longer static.
	(value_binop): Use value_vector_widen to widen scalar to vector
	rather than casting, this better matches gcc C behaviour.
	* valops.c (value_casst): Update logic for casting between vector
	types, and for casting from scalar to vector, try to match gcc C
	behaviour.
	* value.h (value_vector_widen, vector_binop): Declare.
	* opencl-lang.c (opencl_value_cast): New opencl specific casting
	function, handle special case for casting scalar to vector.
	(opencl_binop): Wrapper used for most biary operations, handles
	special scalar to vector casting behaviour.
	(opencl_relop): Use opencl_value_cast.
	(evaluate_subexp_opencl): Use opencl_value_cast instead of
	value_cast, and handle the UNOP_CAST case, calling
	opencl_value_cast.  Use opencl_binop for all binary operations
	that might result in a scalar to vector cast.

diff --git a/gdb/opencl-lang.c b/gdb/opencl-lang.c
index 01e02c8..896d33c 100644
--- a/gdb/opencl-lang.c
+++ b/gdb/opencl-lang.c
@@ -683,6 +683,91 @@ vector_relop (struct expression *exp, struct value *val1, struct value *val2,
   return ret;
 }
 
+/* Perform a cast of ARG into TYPE.  There's sadly a lot of duplication in
+   here from valops.c:value_cast, opencl is different only in the
+   behaviour of scalar to vector casting.  As far as possibly we're going
+   to try and delegate back to the standard value_cast function. */
+
+static struct value *
+opencl_value_cast (struct type *type, struct value *arg)
+{
+  if (type != value_type (arg))
+    {
+      /* Casting scalar to vector is a special case for OpenCL, scalar
+	 is cast to element type of vector then replicated into each
+	 element of the vector.  First though, we need to work out if
+	 this is a scalar to vector cast; code lifted from
+	 valops.c:value_cast.  */
+      enum type_code code1, code2;
+      struct type *to_type;
+      int scalar;
+
+      to_type = check_typedef (type);
+
+      code1 = TYPE_CODE (to_type);
+      code2 = TYPE_CODE (check_typedef (value_type (arg)));
+
+      if (code2 == TYPE_CODE_REF)
+	code2 = TYPE_CODE (check_typedef (value_type (coerce_ref (arg))));
+
+      scalar = (code2 == TYPE_CODE_INT || code2 == TYPE_CODE_BOOL
+		|| code2 == TYPE_CODE_CHAR || code2 == TYPE_CODE_FLT
+		|| code2 == TYPE_CODE_DECFLOAT || code2 == TYPE_CODE_ENUM
+		|| code2 == TYPE_CODE_RANGE);
+
+      if (code1 == TYPE_CODE_ARRAY && TYPE_VECTOR (to_type) && scalar)
+	{
+	  struct type *eltype;
+
+	  /* Cast to the element type of the vector here as
+	     value_vector_widen will error if the scalar value is
+	     truncated by the cast.  To avoid the error, cast (and
+	     possibly truncate) here.  */
+	  eltype = check_typedef (TYPE_TARGET_TYPE (to_type));
+	  arg = value_cast (eltype, arg);
+
+	  return value_vector_widen (arg, type);
+	}
+      else
+	/* Standard cast handler.  */
+	arg = value_cast (type, arg);
+    }
+  return arg;
+}
+
+/* Perform a binary operation on two operands.  */
+static struct value *
+opencl_binop (struct value *arg1, struct value *arg2,
+	      enum exp_opcode op)
+{
+  struct value *val;
+  struct type *type1 = check_typedef (value_type (arg1));
+  struct type *type2 = check_typedef (value_type (arg2));
+  int t1_is_vec = (TYPE_CODE (type1) == TYPE_CODE_ARRAY
+		   && TYPE_VECTOR (type1));
+  int t2_is_vec = (TYPE_CODE (type2) == TYPE_CODE_ARRAY
+		   && TYPE_VECTOR (type2));
+
+  if (!t1_is_vec && !t2_is_vec)
+    val = value_binop (arg1, arg2, op);
+  else if (t1_is_vec && t2_is_vec)
+    val = vector_binop (arg1, arg2, op);
+  else
+    {
+      /* Widen the scalar operand to a vector.  */
+      struct value **v = t1_is_vec ? &arg2 : &arg1;
+      struct type *t = t1_is_vec ? type2 : type1;
+
+      if (TYPE_CODE (t) != TYPE_CODE_FLT && !is_integral_type (t))
+	error (_("Argument to operation not a number or boolean."));
+
+      *v = opencl_value_cast (t1_is_vec ? type1 : type2, *v);
+      val = vector_binop (arg1, arg2, op);
+    }
+
+  return val;
+}
+
 /* Perform a relational operation on two operands.  */
 
 static struct value *
@@ -718,7 +803,7 @@ opencl_relop (struct expression *exp, struct value *arg1, struct value *arg2,
       if (TYPE_CODE (t) != TYPE_CODE_FLT && !is_integral_type (t))
 	error (_("Argument to operation not a number or boolean."));
 
-      *v = value_cast (t1_is_vec ? type1 : type2, *v);
+      *v = opencl_value_cast (t1_is_vec ? type1 : type2, *v);
       val = vector_relop (exp, arg1, arg2, op);
     }
 
@@ -769,6 +854,16 @@ evaluate_subexp_opencl (struct type *expect_type, struct expression *exp,
 
       return opencl_logical_not (exp, arg1);
 
+    case UNOP_CAST:
+      type1 = exp->elts[*pos + 1].type;
+      (*pos) += 2;
+      arg1 = evaluate_subexp (type1, exp, pos, noside);
+      if (noside == EVAL_SKIP)
+	return value_from_longest (builtin_type (exp->gdbarch)->
+				   builtin_int, 1);
+      arg1 = opencl_value_cast (type1, arg1);
+      return arg1;
+
     /* Handle the logical operator and(&&) and or(||).  */
     case BINOP_LOGICAL_AND:
     case BINOP_LOGICAL_OR:
@@ -852,12 +947,12 @@ evaluate_subexp_opencl (struct type *expect_type, struct expression *exp,
 	  /* Widen the scalar operand to a vector if necessary.  */
 	  if (t2_is_vec || !t3_is_vec)
 	    {
-	      arg3 = value_cast (type2, arg3);
+	      arg3 = opencl_value_cast (type2, arg3);
 	      type3 = value_type (arg3);
 	    }
 	  else if (!t2_is_vec || t3_is_vec)
 	    {
-	      arg2 = value_cast (type3, arg2);
+	      arg2 = opencl_value_cast (type3, arg2);
 	      type2 = value_type (arg2);
 	    }
 	  else if (!t2_is_vec || !t3_is_vec)
@@ -954,6 +1049,31 @@ Cannot perform conditional operation on vectors with different sizes"));
 				       "structure");
 	  }
       }
+
+    case BINOP_ADD:
+    case BINOP_SUB:
+    case BINOP_MUL:
+    case BINOP_DIV:
+    case BINOP_INTDIV:
+    case BINOP_REM:
+    case BINOP_MOD:
+    case BINOP_LSH:
+    case BINOP_RSH:
+    case BINOP_BITWISE_AND:
+    case BINOP_BITWISE_IOR:
+    case BINOP_BITWISE_XOR:
+      {
+	(*pos)++;
+	arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
+	arg2 = evaluate_subexp (value_type (arg1), exp, pos, noside);
+
+	if (noside == EVAL_SKIP)
+	  return value_from_longest (builtin_type (exp->gdbarch)->
+				     builtin_int, 1);
+
+	return opencl_binop (arg1, arg2, op);
+      }
+
     default:
       break;
     }
diff --git a/gdb/valarith.c b/gdb/valarith.c
index 074cf36..f813ede 100644
--- a/gdb/valarith.c
+++ b/gdb/valarith.c
@@ -1346,10 +1346,53 @@ scalar_binop (struct value *arg1, struct value *arg2, enum exp_opcode op)
   return val;
 }
 
+/* Widen a scalar value SCALAR_VALUE to vector type VECTOR_TYPE by
+   replicating SCALAR_VALUE for each element of the vector.  Only scalar
+   types that can be cast to the type of one element of the vector are
+   acceptable.  The newly created vector value is returned upon success,
+   otherwise an error is thrown.  */
+
+struct value *
+value_vector_widen (struct value *scalar_value, struct type *vector_type)
+{
+  /* Widen the scalar to a vector.  */
+  struct type *eltype, *scalar_type;
+  struct value *val, *elval;
+  LONGEST low_bound, high_bound;
+  int i;
+
+  CHECK_TYPEDEF (vector_type);
+
+  gdb_assert (TYPE_CODE (vector_type) == TYPE_CODE_ARRAY
+	      && TYPE_VECTOR (vector_type));
+
+  if (!get_array_bounds (vector_type, &low_bound, &high_bound))
+    error (_("Could not determine the vector bounds"));
+
+  eltype = check_typedef (TYPE_TARGET_TYPE (vector_type));
+  elval = value_cast (eltype, scalar_value);
+
+  scalar_type = check_typedef (value_type (scalar_value));
+
+  /* If we reduced the length of the scalar then check we didn't loose any
+     important bits.  */
+  if (TYPE_LENGTH (eltype) < TYPE_LENGTH (scalar_type)
+      && !value_equal (elval, scalar_value))
+    error (_("conversion of scalar to vector involves truncation"));
+
+  val = allocate_value (vector_type);
+  for (i = 0; i < high_bound - low_bound + 1; i++)
+    /* Duplicate the contents of elval into the destination vector.  */
+    memcpy (value_contents_writeable (val) + (i * TYPE_LENGTH (eltype)),
+	    value_contents_all (elval), TYPE_LENGTH (eltype));
+
+  return val;
+}
+
 /* Performs a binary operation on two vector operands by calling scalar_binop
    for each pair of vector components.  */
 
-static struct value *
+struct value *
 vector_binop (struct value *val1, struct value *val2, enum exp_opcode op)
 {
   struct value *val, *tmp, *mark;
@@ -1425,7 +1468,9 @@ value_binop (struct value *arg1, struct value *arg2, enum exp_opcode op)
 	  && !is_integral_type (t))
 	error (_("Argument to operation not a number or boolean."));
 
-      *v = value_cast (t1_is_vec ? type1 : type2, *v);
+      /* Replicate the scalar value to make a vector value.  */
+      *v = value_vector_widen (*v, t1_is_vec ? type1 : type2);
+
       val = vector_binop (arg1, arg2, op);
     }
 
diff --git a/gdb/valops.c b/gdb/valops.c
index e3d36a1..b9bc460 100644
--- a/gdb/valops.c
+++ b/gdb/valops.c
@@ -546,29 +546,13 @@ value_cast (struct type *type, struct value *arg2)
 	 minus one, instead of biasing the normal case.  */
       return value_from_longest (type, -1);
     }
-  else if (code1 == TYPE_CODE_ARRAY && TYPE_VECTOR (type) && scalar)
-    {
-      /* Widen the scalar to a vector.  */
-      struct type *eltype;
-      struct value *val;
-      LONGEST low_bound, high_bound;
-      int i;
-
-      if (!get_array_bounds (type, &low_bound, &high_bound))
-	error (_("Could not determine the vector bounds"));
-
-      eltype = check_typedef (TYPE_TARGET_TYPE (type));
-      arg2 = value_cast (eltype, arg2);
-      val = allocate_value (type);
-
-      for (i = 0; i < high_bound - low_bound + 1; i++)
-	{
-	  /* Duplicate the contents of arg2 into the destination vector.  */
-	  memcpy (value_contents_writeable (val) + (i * TYPE_LENGTH (eltype)),
-		  value_contents_all (arg2), TYPE_LENGTH (eltype));
-	}
-      return val;
-    }
+  else if (code1 == TYPE_CODE_ARRAY && TYPE_VECTOR (type)
+	   && code2 == TYPE_CODE_ARRAY && TYPE_VECTOR (type2)
+	   && TYPE_LENGTH (type) != TYPE_LENGTH (type2))
+    error (_("Cannot convert between vector values of different sizes"));
+  else if (code1 == TYPE_CODE_ARRAY && TYPE_VECTOR (type) && scalar
+	   && TYPE_LENGTH (type) != TYPE_LENGTH (type2))
+    error (_("can only cast scalar to vector of same size"));
   else if (code1 == TYPE_CODE_VOID)
     {
       return value_zero (type, not_lval);
diff --git a/gdb/value.h b/gdb/value.h
index 67f1d04..e354e7a 100644
--- a/gdb/value.h
+++ b/gdb/value.h
@@ -482,6 +482,12 @@ extern void read_value_memory (struct value *val, int embedded_offset,
 			       int stack, CORE_ADDR memaddr,
 			       gdb_byte *buffer, size_t length);
 
+/* Cast SCALAR_VALUE to the element type of VECTOR_TYPE, then replicate
+   into each element of a new vector value with VECTOR_TYPE.  */
+
+struct value *value_vector_widen (struct value *scalar_value,
+				  struct type *vector_type);
+
 \f
 
 #include "symtab.h"
@@ -601,6 +607,9 @@ extern struct value *value_concat (struct value *arg1, struct value *arg2);
 extern struct value *value_binop (struct value *arg1, struct value *arg2,
 				  enum exp_opcode op);
 
+extern struct value *vector_binop (struct value *arg1, struct value *arg2,
+				   enum exp_opcode op);
+
 extern struct value *value_ptradd (struct value *arg1, LONGEST arg2);
 
 extern LONGEST value_ptrdiff (struct value *arg1, struct value *arg2);


gdb/testsuite/ChangeLog

2013-01-08  Andrew Burgess  <aburgess@broadcom.com>

	* gdb.base/gnu_vector.c: New variable for use in tests.
	* gdb.base/gnu_vector.exp: Update and extend tests to reflect
	changes in scalar to vector casting and widening.
	* gdb.python/py-type.c: New variables for use in tests.
	* gdb.python/py-type.exp: Update vector related tests to reflect
	changes in scalar to vector casting and widening.

diff --git a/gdb/testsuite/gdb.base/gnu_vector.c b/gdb/testsuite/gdb.base/gnu_vector.c
index 76eefed..062aadb 100644
--- a/gdb/testsuite/gdb.base/gnu_vector.c
+++ b/gdb/testsuite/gdb.base/gnu_vector.c
@@ -31,6 +31,7 @@ int ia = 2;
 int ib = 1;
 float fa = 2;
 float fb = 1;
+long long lla __attribute__ ((mode(DI))) = 0x0000000100000001ll;
 char4 c4 = {1, 2, 3, 4};
 int4 i4a = {2, 4, 8, 16};
 int4 i4b = {1, 2, 8, 4};
diff --git a/gdb/testsuite/gdb.base/gnu_vector.exp b/gdb/testsuite/gdb.base/gnu_vector.exp
index 5f5b40f..f65627b 100644
--- a/gdb/testsuite/gdb.base/gnu_vector.exp
+++ b/gdb/testsuite/gdb.base/gnu_vector.exp
@@ -82,32 +82,52 @@ gdb_test "print f4a / f4b" "\\\$$decimal = \\{2, 2, 1, 4\\}"
 gdb_test "print +f4a" "\\\$$decimal = \\{2, 4, 8, 16\\}"
 gdb_test "print -f4a" "\\\$$decimal = \\{-2, -4, -8, -16\\}"
 
-# Test scalar to vector widening
-gdb_test "print (int2) 1" "\\\$$decimal = \\{1, 1\\}"
-gdb_test "print (longlong2) 2" "\\\$$decimal = \\{2, 2\\}"
-gdb_test "print (float2) 3" "\\\$$decimal = \\{3, 3\\}"
-gdb_test "print (double2) 4" "\\\$$decimal = \\{4, 4\\}"
-gdb_test "print (char4) 12" "\\\$$decimal = \\{12, 12, 12, 12\\}"
-gdb_test "print (uint4) ia" "\\\$$decimal = \\{2, 2, 2, 2\\}"
-gdb_test "print (int4) -3" "\\\$$decimal = \\{-3, -3, -3, -3\\}"
-gdb_test "print (float4) 4" "\\\$$decimal = \\{4, 4, 4, 4\\}"
-
+# When casting to vector the input type must have the same length as
+# the total length of the vector.
+gdb_test "print (char4) 0x01010101" "\\\$$decimal = \\{1, 1, 1, 1\\}"
+gdb_test "print (char4) ia" "\\\$$decimal = \\{2, 0, 0, 0\\}"
+gdb_test "print (int2) lla" "\\\$$decimal = \\{1, 1\\}"
+
+gdb_test "print (int2) 1" "can only cast scalar to vector of same size"
+gdb_test "print (longlong2) 2" "can only cast scalar to vector of same size"
+gdb_test "print (float2) 3" "can only cast scalar to vector of same size"
+gdb_test "print (double2) 4" "can only cast scalar to vector of same size"
+gdb_test "print (uint4) ia" "can only cast scalar to vector of same size"
+gdb_test "print (int4) -3" "can only cast scalar to vector of same size"
+gdb_test "print (float4) 4" "can only cast scalar to vector of same size"
+
+gdb_test "print i4b = ia" "can only cast scalar to vector of same size"
+gdb_test "print i4a = 3" "can only cast scalar to vector of same size"
+gdb_test "print f4a = fb" "can only cast scalar to vector of same size"
+gdb_test "print f4b = 2" "can only cast scalar to vector of same size"
+
+gdb_test "print c4 + lla" "conversion of scalar to vector involves truncation"
+gdb_test "print i4a + lla" "conversion of scalar to vector involves truncation"
+gdb_test "print lla + c4" "conversion of scalar to vector involves truncation"
+gdb_test "print lla + i4a" "conversion of scalar to vector involves truncation"
+
+gdb_test "print c4 + ib" "\\\$$decimal = \\{2, 3, 4, 5\\}"
 gdb_test "print i4a + ib" "\\\$$decimal = \\{3, 5, 9, 17\\}"
+gdb_test "print i4a + 1" "\\\$$decimal = \\{3, 5, 9, 17\\}"
+gdb_test "print 1 + i4a" "\\\$$decimal = \\{3, 5, 9, 17\\}"
 gdb_test "print fa - f4b" "\\\$$decimal = \\{1, 0, -6, -2\\}"
+gdb_test "print 2 - f4b" "\\\$$decimal = \\{1, 0, -6, -2\\}"
 gdb_test "print f4a * fb" "\\\$$decimal = \\{2, 4, 8, 16\\}"
+gdb_test "print f4a * 1" "\\\$$decimal = \\{2, 4, 8, 16\\}"
 gdb_test "print ia / i4b" "\\\$$decimal = \\{2, 1, 0, 0\\}"
+gdb_test "print 2 / i4b" "\\\$$decimal = \\{2, 1, 0, 0\\}"
 gdb_test "print i4a % ib" "\\\$$decimal = \\{0, 0, 0, 0\\}"
-
+gdb_test "print i4a % 1" "\\\$$decimal = \\{0, 0, 0, 0\\}"
 gdb_test "print ia & i4b" "\\\$$decimal = \\{0, 2, 0, 0\\}"
+gdb_test "print 2 & i4b" "\\\$$decimal = \\{0, 2, 0, 0\\}"
 gdb_test "print i4a | ib" "\\\$$decimal = \\{3, 5, 9, 17\\}"
+gdb_test "print i4a | 1" "\\\$$decimal = \\{3, 5, 9, 17\\}"
 gdb_test "print ia ^ i4b" "\\\$$decimal = \\{3, 0, 10, 6\\}"
+gdb_test "print 2 ^ i4b" "\\\$$decimal = \\{3, 0, 10, 6\\}"
 gdb_test "print i4a << ib" "\\\$$decimal = \\{4, 8, 16, 32\\}"
+gdb_test "print i4a << 1" "\\\$$decimal = \\{4, 8, 16, 32\\}"
 gdb_test "print i4a >> ib" "\\\$$decimal = \\{1, 2, 4, 8\\}"
-
-gdb_test "print i4b = ia" "\\\$$decimal = \\{2, 2, 2, 2\\}"
-gdb_test "print i4a = 3" "\\\$$decimal = \\{3, 3, 3, 3\\}"
-gdb_test "print f4a = fb" "\\\$$decimal = \\{1, 1, 1, 1\\}"
-gdb_test "print f4b = 2" "\\\$$decimal = \\{2, 2, 2, 2\\}"
+gdb_test "print i4a >> 1" "\\\$$decimal = \\{1, 2, 4, 8\\}"
 
 gdb_test "print i4a = \{2, 4, 8, 16\}" "\\\$$decimal = \\{2, 4, 8, 16\\}"
 gdb_test "print i4a <<= ib" "\\\$$decimal = \\{4, 8, 16, 32\\}"
@@ -130,6 +150,10 @@ gdb_test "print i2 + i4a" "Cannot perform operation on vectors with different ty
 gdb_test "print f4a + f2" "Cannot perform operation on vectors with different types"
 gdb_test "print f2 + f4a" "Cannot perform operation on vectors with different types"
 
+gdb_test "print (double2) f2" "Cannot convert between vector values of different sizes"
+gdb_test "print (int4) c4" "Cannot convert between vector values of different sizes"
+gdb_test "print (char4) i4a" "Cannot convert between vector values of different sizes"
+
 # Test ptype on vector types.
 gdb_test "ptype c4" "type = char __attribute__ \\(\\(vector_size\\(4\\)\\)\\)"
 gdb_test "ptype char4" "type = char __attribute__ \\(\\(vector_size\\(4\\)\\)\\)"
diff --git a/gdb/testsuite/gdb.python/py-type.c b/gdb/testsuite/gdb.python/py-type.c
index 641844e..03015a8 100644
--- a/gdb/testsuite/gdb.python/py-type.c
+++ b/gdb/testsuite/gdb.python/py-type.c
@@ -50,6 +50,9 @@ enum E
 { v1, v2, v3
 };
 
+struct s vec_data_1 = {1, 1};
+struct s vec_data_2 = {1, 2};
+
 int
 main ()
 {
diff --git a/gdb/testsuite/gdb.python/py-type.exp b/gdb/testsuite/gdb.python/py-type.exp
index ec59bc8..16b2de2 100644
--- a/gdb/testsuite/gdb.python/py-type.exp
+++ b/gdb/testsuite/gdb.python/py-type.exp
@@ -118,7 +118,7 @@ proc test_fields {lang} {
     # Test gdb.Type.array.
     gdb_test "python print (ar\[0\].cast(ar\[0\].type.array(1)))" \
         ".1, 2." "cast to array with one argument"
-    gdb_test "python print (ar\[0\].cast(ar\[0\].type.array(0, 1)))" \
+    gdb_test "python print ar\[0\].cast(ar\[0\].type.array(0, 1))" \
         ".1, 2." "cast to array with two arguments"
 
     gdb_test "python print (ar\[0\].type == ar\[0\].type)" "True"
@@ -126,16 +126,19 @@ proc test_fields {lang} {
     # Test gdb.Type.vector.
     # Note: vectors cast differently than arrays.  Here ar[0] is replicated
     # for the size of the vector.
-    gdb_py_test_silent_cmd \
-        "python vec1 = ar\[0\].cast(ar\[0\].type.vector(1))" "set vec1" 1
-    gdb_test "python print (vec1)" ".1, 1." "cast to vector with one argument"
-    gdb_py_test_silent_cmd \
-        "python vec2 = ar\[0\].cast(ar\[0\].type.vector(0, 1))" "set vec2" 1
-    gdb_test "python print (vec2)" ".1, 1." "cast to vector with two arguments"
-    gdb_test "python print (vec1 == vec2)" "True"
-    gdb_py_test_silent_cmd \
-        "python vec3 = ar\[1\].cast(ar\[1\].type.vector(1))" "set vec3" 1
-    gdb_test "python print (vec1 == vec3)" "False"
+    gdb_py_test_silent_cmd "print vec_data_1" "print value (vec_data_1)" 1
+    gdb_py_test_silent_cmd "python vec_data_1 = gdb.history (0)" "get value (vec_data_1) from history" 1
+
+    gdb_py_test_silent_cmd "print vec_data_2" "print value (vec_data_2)" 1
+    gdb_py_test_silent_cmd "python vec_data_2 = gdb.history (0)" "get value (vec_data_2) from history" 1
+
+    gdb_py_test_silent_cmd "python vec1 = vec_data_1.cast(ar\[0\].type.vector(1))" "set vec1" 1
+    gdb_test "python print vec1" ".1, 1." "cast to vector with one argument"
+    gdb_py_test_silent_cmd "python vec2 = vec_data_1.cast(ar\[0\].type.vector(0, 1))" "set vec2" 1
+    gdb_test "python print vec2" ".1, 1." "cast to vector with two arguments"
+    gdb_test "python print vec1 == vec2" "True"
+    gdb_py_test_silent_cmd "python vec3 = vec_data_2.cast(ar\[0\].type.vector(1))" "set vec3" 1
+    gdb_test "python print vec1 == vec3" "False"
   }
 }
 




^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH] Vector to scalar casting and widening
  2013-01-08 15:08               ` Andrew Burgess
@ 2013-01-08 19:05                 ` Ulrich Weigand
  2013-01-09 19:13                   ` Tom Tromey
  0 siblings, 1 reply; 14+ messages in thread
From: Ulrich Weigand @ 2013-01-08 19:05 UTC (permalink / raw)
  To: Andrew Burgess; +Cc: tromey, gdb-patches, ken

Andrew Burgess wrote:

> I have a new patch which I believe should be closer to what we want,
> I'd be grateful if you could test the opencl parts of this again and
> let me know how it gets on.  Also any other feedback is of course
> welcome too.

Thanks, this does look like what I had been thinking of.

Unfortunately, handling of binary operations would need to be quite a
bit more complex than this: in particular, there is no handling of the
usual arithmetic promotions, pointer arithmetic, and support for the
+= etc. variants of operators.   Basically, all the special handling
done in eval.c:evaluate_subexp ...

However, when I looked at the OpenCL specs to verify what the precise
rules ought to be, I noticed that I had in fact misremembered the rule:
in fact, even in OpenCL, there is (now -- this seems to have been added
with the OpenCL 1.1 specs revision) a section on scalar to vector
promotion as part of arithmetic promotion, and this also prohibits
down-casting.  The specific rules seem to be slightly different than
the C rules, but for the most part, the effect would be very similar.
[ So existing GDB behaviour in fact is just wrong. ]

Thus, I'd be fine with removing the OpenCL special cases and just let
it use the (modified) default case.  It doesn't seem worthwhile to
exactly model the (minor) differences.  (In particular, the existing
OpenCL GDB test cases all pass as-is.)

Sorry for the extra confusion; I really should have looked up the
precise rules earlier ...


Apart from that, I've had to make another set of minor changes:

- we need to handle UNOP_CAST_TYPE in addition to UNOP_CAST

- we also need to handle BINOP_ASSIGN similarly to UNOP_CAST,
  since OpenCL also allows implicit scalar-to-vector widening
  during assignment

With those changes, as in the modified version of the patch
below, all OpenCL test cases now pass.  As far as OpenCL
is concerned, this would be OK to commit.

In fact *all* of the patch looks good to me now, but I'd ask
you wait for another couple of days in case one of the other
maintainers wants to comment ...


Thanks,
Ulrich


Index: gdb/opencl-lang.c
===================================================================
RCS file: /cvs/src/src/gdb/opencl-lang.c,v
retrieving revision 1.21
diff -u -p -r1.21 opencl-lang.c
--- gdb/opencl-lang.c	1 Jan 2013 06:32:47 -0000	1.21
+++ gdb/opencl-lang.c	8 Jan 2013 18:24:54 -0000
@@ -683,6 +683,58 @@ vector_relop (struct expression *exp, st
   return ret;
 }
 
+/* Perform a cast of ARG into TYPE.  There's sadly a lot of duplication in
+   here from valops.c:value_cast, opencl is different only in the
+   behaviour of scalar to vector casting.  As far as possibly we're going
+   to try and delegate back to the standard value_cast function. */
+
+static struct value *
+opencl_value_cast (struct type *type, struct value *arg)
+{
+  if (type != value_type (arg))
+    {
+      /* Casting scalar to vector is a special case for OpenCL, scalar
+	 is cast to element type of vector then replicated into each
+	 element of the vector.  First though, we need to work out if
+	 this is a scalar to vector cast; code lifted from
+	 valops.c:value_cast.  */
+      enum type_code code1, code2;
+      struct type *to_type;
+      int scalar;
+
+      to_type = check_typedef (type);
+
+      code1 = TYPE_CODE (to_type);
+      code2 = TYPE_CODE (check_typedef (value_type (arg)));
+
+      if (code2 == TYPE_CODE_REF)
+	code2 = TYPE_CODE (check_typedef (value_type (coerce_ref (arg))));
+
+      scalar = (code2 == TYPE_CODE_INT || code2 == TYPE_CODE_BOOL
+		|| code2 == TYPE_CODE_CHAR || code2 == TYPE_CODE_FLT
+		|| code2 == TYPE_CODE_DECFLOAT || code2 == TYPE_CODE_ENUM
+		|| code2 == TYPE_CODE_RANGE);
+
+      if (code1 == TYPE_CODE_ARRAY && TYPE_VECTOR (to_type) && scalar)
+	{
+	  struct type *eltype;
+
+	  /* Cast to the element type of the vector here as
+	     value_vector_widen will error if the scalar value is
+	     truncated by the cast.  To avoid the error, cast (and
+	     possibly truncate) here.  */
+	  eltype = check_typedef (TYPE_TARGET_TYPE (to_type));
+	  arg = value_cast (eltype, arg);
+
+	  return value_vector_widen (arg, type);
+	}
+      else
+	/* Standard cast handler.  */
+	arg = value_cast (type, arg);
+    }
+  return arg;
+}
+
 /* Perform a relational operation on two operands.  */
 
 static struct value *
@@ -718,7 +770,7 @@ opencl_relop (struct expression *exp, st
       if (TYPE_CODE (t) != TYPE_CODE_FLT && !is_integral_type (t))
 	error (_("Argument to operation not a number or boolean."));
 
-      *v = value_cast (t1_is_vec ? type1 : type2, *v);
+      *v = opencl_value_cast (t1_is_vec ? type1 : type2, *v);
       val = vector_relop (exp, arg1, arg2, op);
     }
 
@@ -740,6 +792,46 @@ evaluate_subexp_opencl (struct type *exp
 
   switch (op)
     {
+    /* Handle assignment and cast operators to support OpenCL-style
+       scalar-to-vector widening.  */
+    case BINOP_ASSIGN:
+      (*pos)++;
+      arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
+      type1 = value_type (arg1);
+      arg2 = evaluate_subexp (type1, exp, pos, noside);
+
+      if (noside == EVAL_SKIP || noside == EVAL_AVOID_SIDE_EFFECTS)
+	return arg1;
+
+      if (deprecated_value_modifiable (arg1)
+	  && VALUE_LVAL (arg1) != lval_internalvar)
+	arg2 = opencl_value_cast (type1, arg2);
+
+      return value_assign (arg1, arg2);
+
+    case UNOP_CAST:
+      type1 = exp->elts[*pos + 1].type;
+      (*pos) += 2;
+      arg1 = evaluate_subexp (type1, exp, pos, noside);
+
+      if (noside == EVAL_SKIP)
+	return value_from_longest (builtin_type (exp->gdbarch)->
+				   builtin_int, 1);
+
+      return opencl_value_cast (type1, arg1);
+
+    case UNOP_CAST_TYPE:
+      (*pos)++;
+      arg1 = evaluate_subexp (NULL, exp, pos, EVAL_AVOID_SIDE_EFFECTS);
+      type1 = value_type (arg1);
+      arg1 = evaluate_subexp (type1, exp, pos, noside);
+
+      if (noside == EVAL_SKIP)
+	return value_from_longest (builtin_type (exp->gdbarch)->
+				   builtin_int, 1);
+
+      return opencl_value_cast (type1, arg1);
+
     /* Handle binary relational and equality operators that are either not
        or differently defined for GNU vectors.  */
     case BINOP_EQUAL:
@@ -852,12 +944,12 @@ evaluate_subexp_opencl (struct type *exp
 	  /* Widen the scalar operand to a vector if necessary.  */
 	  if (t2_is_vec || !t3_is_vec)
 	    {
-	      arg3 = value_cast (type2, arg3);
+	      arg3 = opencl_value_cast (type2, arg3);
 	      type3 = value_type (arg3);
 	    }
 	  else if (!t2_is_vec || t3_is_vec)
 	    {
-	      arg2 = value_cast (type3, arg2);
+	      arg2 = opencl_value_cast (type3, arg2);
 	      type2 = value_type (arg2);
 	    }
 	  else if (!t2_is_vec || !t3_is_vec)
Index: gdb/valarith.c
===================================================================
RCS file: /cvs/src/src/gdb/valarith.c,v
retrieving revision 1.107
diff -u -p -r1.107 valarith.c
--- gdb/valarith.c	1 Jan 2013 06:41:29 -0000	1.107
+++ gdb/valarith.c	8 Jan 2013 18:24:55 -0000
@@ -1346,6 +1346,49 @@ scalar_binop (struct value *arg1, struct
   return val;
 }
 
+/* Widen a scalar value SCALAR_VALUE to vector type VECTOR_TYPE by
+   replicating SCALAR_VALUE for each element of the vector.  Only scalar
+   types that can be cast to the type of one element of the vector are
+   acceptable.  The newly created vector value is returned upon success,
+   otherwise an error is thrown.  */
+
+struct value *
+value_vector_widen (struct value *scalar_value, struct type *vector_type)
+{
+  /* Widen the scalar to a vector.  */
+  struct type *eltype, *scalar_type;
+  struct value *val, *elval;
+  LONGEST low_bound, high_bound;
+  int i;
+
+  CHECK_TYPEDEF (vector_type);
+
+  gdb_assert (TYPE_CODE (vector_type) == TYPE_CODE_ARRAY
+	      && TYPE_VECTOR (vector_type));
+
+  if (!get_array_bounds (vector_type, &low_bound, &high_bound))
+    error (_("Could not determine the vector bounds"));
+
+  eltype = check_typedef (TYPE_TARGET_TYPE (vector_type));
+  elval = value_cast (eltype, scalar_value);
+
+  scalar_type = check_typedef (value_type (scalar_value));
+
+  /* If we reduced the length of the scalar then check we didn't loose any
+     important bits.  */
+  if (TYPE_LENGTH (eltype) < TYPE_LENGTH (scalar_type)
+      && !value_equal (elval, scalar_value))
+    error (_("conversion of scalar to vector involves truncation"));
+
+  val = allocate_value (vector_type);
+  for (i = 0; i < high_bound - low_bound + 1; i++)
+    /* Duplicate the contents of elval into the destination vector.  */
+    memcpy (value_contents_writeable (val) + (i * TYPE_LENGTH (eltype)),
+	    value_contents_all (elval), TYPE_LENGTH (eltype));
+
+  return val;
+}
+
 /* Performs a binary operation on two vector operands by calling scalar_binop
    for each pair of vector components.  */
 
@@ -1425,7 +1468,9 @@ value_binop (struct value *arg1, struct 
 	  && !is_integral_type (t))
 	error (_("Argument to operation not a number or boolean."));
 
-      *v = value_cast (t1_is_vec ? type1 : type2, *v);
+      /* Replicate the scalar value to make a vector value.  */
+      *v = value_vector_widen (*v, t1_is_vec ? type1 : type2);
+
       val = vector_binop (arg1, arg2, op);
     }
 
Index: gdb/valops.c
===================================================================
RCS file: /cvs/src/src/gdb/valops.c,v
retrieving revision 1.308
diff -u -p -r1.308 valops.c
--- gdb/valops.c	1 Jan 2013 06:41:29 -0000	1.308
+++ gdb/valops.c	8 Jan 2013 18:24:55 -0000
@@ -546,29 +546,13 @@ value_cast (struct type *type, struct va
 	 minus one, instead of biasing the normal case.  */
       return value_from_longest (type, -1);
     }
-  else if (code1 == TYPE_CODE_ARRAY && TYPE_VECTOR (type) && scalar)
-    {
-      /* Widen the scalar to a vector.  */
-      struct type *eltype;
-      struct value *val;
-      LONGEST low_bound, high_bound;
-      int i;
-
-      if (!get_array_bounds (type, &low_bound, &high_bound))
-	error (_("Could not determine the vector bounds"));
-
-      eltype = check_typedef (TYPE_TARGET_TYPE (type));
-      arg2 = value_cast (eltype, arg2);
-      val = allocate_value (type);
-
-      for (i = 0; i < high_bound - low_bound + 1; i++)
-	{
-	  /* Duplicate the contents of arg2 into the destination vector.  */
-	  memcpy (value_contents_writeable (val) + (i * TYPE_LENGTH (eltype)),
-		  value_contents_all (arg2), TYPE_LENGTH (eltype));
-	}
-      return val;
-    }
+  else if (code1 == TYPE_CODE_ARRAY && TYPE_VECTOR (type)
+	   && code2 == TYPE_CODE_ARRAY && TYPE_VECTOR (type2)
+	   && TYPE_LENGTH (type) != TYPE_LENGTH (type2))
+    error (_("Cannot convert between vector values of different sizes"));
+  else if (code1 == TYPE_CODE_ARRAY && TYPE_VECTOR (type) && scalar
+	   && TYPE_LENGTH (type) != TYPE_LENGTH (type2))
+    error (_("can only cast scalar to vector of same size"));
   else if (code1 == TYPE_CODE_VOID)
     {
       return value_zero (type, not_lval);
Index: gdb/value.h
===================================================================
RCS file: /cvs/src/src/gdb/value.h,v
retrieving revision 1.213
diff -u -p -r1.213 value.h
--- gdb/value.h	1 Jan 2013 06:41:29 -0000	1.213
+++ gdb/value.h	8 Jan 2013 18:24:55 -0000
@@ -482,6 +482,12 @@ extern void read_value_memory (struct va
 			       int stack, CORE_ADDR memaddr,
 			       gdb_byte *buffer, size_t length);
 
+/* Cast SCALAR_VALUE to the element type of VECTOR_TYPE, then replicate
+   into each element of a new vector value with VECTOR_TYPE.  */
+
+struct value *value_vector_widen (struct value *scalar_value,
+				  struct type *vector_type);
+
 \f
 
 #include "symtab.h"
Index: gdb/testsuite/gdb.base/gnu_vector.c
===================================================================
RCS file: /cvs/src/src/gdb/testsuite/gdb.base/gnu_vector.c,v
retrieving revision 1.7
diff -u -p -r1.7 gnu_vector.c
--- gdb/testsuite/gdb.base/gnu_vector.c	1 Jan 2013 06:33:25 -0000	1.7
+++ gdb/testsuite/gdb.base/gnu_vector.c	8 Jan 2013 18:24:56 -0000
@@ -31,6 +31,7 @@ int ia = 2;
 int ib = 1;
 float fa = 2;
 float fb = 1;
+long long lla __attribute__ ((mode(DI))) = 0x0000000100000001ll;
 char4 c4 = {1, 2, 3, 4};
 int4 i4a = {2, 4, 8, 16};
 int4 i4b = {1, 2, 8, 4};
Index: gdb/testsuite/gdb.base/gnu_vector.exp
===================================================================
RCS file: /cvs/src/src/gdb/testsuite/gdb.base/gnu_vector.exp,v
retrieving revision 1.11
diff -u -p -r1.11 gnu_vector.exp
--- gdb/testsuite/gdb.base/gnu_vector.exp	1 Jan 2013 06:33:25 -0000	1.11
+++ gdb/testsuite/gdb.base/gnu_vector.exp	8 Jan 2013 18:24:56 -0000
@@ -82,32 +82,52 @@ gdb_test "print f4a / f4b" "\\\$$decimal
 gdb_test "print +f4a" "\\\$$decimal = \\{2, 4, 8, 16\\}"
 gdb_test "print -f4a" "\\\$$decimal = \\{-2, -4, -8, -16\\}"
 
-# Test scalar to vector widening
-gdb_test "print (int2) 1" "\\\$$decimal = \\{1, 1\\}"
-gdb_test "print (longlong2) 2" "\\\$$decimal = \\{2, 2\\}"
-gdb_test "print (float2) 3" "\\\$$decimal = \\{3, 3\\}"
-gdb_test "print (double2) 4" "\\\$$decimal = \\{4, 4\\}"
-gdb_test "print (char4) 12" "\\\$$decimal = \\{12, 12, 12, 12\\}"
-gdb_test "print (uint4) ia" "\\\$$decimal = \\{2, 2, 2, 2\\}"
-gdb_test "print (int4) -3" "\\\$$decimal = \\{-3, -3, -3, -3\\}"
-gdb_test "print (float4) 4" "\\\$$decimal = \\{4, 4, 4, 4\\}"
+# When casting to vector the input type must have the same length as
+# the total length of the vector.
+gdb_test "print (char4) 0x01010101" "\\\$$decimal = \\{1, 1, 1, 1\\}"
+gdb_test "print (char4) ia" "\\\$$decimal = \\{2, 0, 0, 0\\}"
+gdb_test "print (int2) lla" "\\\$$decimal = \\{1, 1\\}"
+
+gdb_test "print (int2) 1" "can only cast scalar to vector of same size"
+gdb_test "print (longlong2) 2" "can only cast scalar to vector of same size"
+gdb_test "print (float2) 3" "can only cast scalar to vector of same size"
+gdb_test "print (double2) 4" "can only cast scalar to vector of same size"
+gdb_test "print (uint4) ia" "can only cast scalar to vector of same size"
+gdb_test "print (int4) -3" "can only cast scalar to vector of same size"
+gdb_test "print (float4) 4" "can only cast scalar to vector of same size"
+
+gdb_test "print i4b = ia" "can only cast scalar to vector of same size"
+gdb_test "print i4a = 3" "can only cast scalar to vector of same size"
+gdb_test "print f4a = fb" "can only cast scalar to vector of same size"
+gdb_test "print f4b = 2" "can only cast scalar to vector of same size"
+
+gdb_test "print c4 + lla" "conversion of scalar to vector involves truncation"
+gdb_test "print i4a + lla" "conversion of scalar to vector involves truncation"
+gdb_test "print lla + c4" "conversion of scalar to vector involves truncation"
+gdb_test "print lla + i4a" "conversion of scalar to vector involves truncation"
 
+gdb_test "print c4 + ib" "\\\$$decimal = \\{2, 3, 4, 5\\}"
 gdb_test "print i4a + ib" "\\\$$decimal = \\{3, 5, 9, 17\\}"
+gdb_test "print i4a + 1" "\\\$$decimal = \\{3, 5, 9, 17\\}"
+gdb_test "print 1 + i4a" "\\\$$decimal = \\{3, 5, 9, 17\\}"
 gdb_test "print fa - f4b" "\\\$$decimal = \\{1, 0, -6, -2\\}"
+gdb_test "print 2 - f4b" "\\\$$decimal = \\{1, 0, -6, -2\\}"
 gdb_test "print f4a * fb" "\\\$$decimal = \\{2, 4, 8, 16\\}"
+gdb_test "print f4a * 1" "\\\$$decimal = \\{2, 4, 8, 16\\}"
 gdb_test "print ia / i4b" "\\\$$decimal = \\{2, 1, 0, 0\\}"
+gdb_test "print 2 / i4b" "\\\$$decimal = \\{2, 1, 0, 0\\}"
 gdb_test "print i4a % ib" "\\\$$decimal = \\{0, 0, 0, 0\\}"
-
+gdb_test "print i4a % 1" "\\\$$decimal = \\{0, 0, 0, 0\\}"
 gdb_test "print ia & i4b" "\\\$$decimal = \\{0, 2, 0, 0\\}"
+gdb_test "print 2 & i4b" "\\\$$decimal = \\{0, 2, 0, 0\\}"
 gdb_test "print i4a | ib" "\\\$$decimal = \\{3, 5, 9, 17\\}"
+gdb_test "print i4a | 1" "\\\$$decimal = \\{3, 5, 9, 17\\}"
 gdb_test "print ia ^ i4b" "\\\$$decimal = \\{3, 0, 10, 6\\}"
+gdb_test "print 2 ^ i4b" "\\\$$decimal = \\{3, 0, 10, 6\\}"
 gdb_test "print i4a << ib" "\\\$$decimal = \\{4, 8, 16, 32\\}"
+gdb_test "print i4a << 1" "\\\$$decimal = \\{4, 8, 16, 32\\}"
 gdb_test "print i4a >> ib" "\\\$$decimal = \\{1, 2, 4, 8\\}"
-
-gdb_test "print i4b = ia" "\\\$$decimal = \\{2, 2, 2, 2\\}"
-gdb_test "print i4a = 3" "\\\$$decimal = \\{3, 3, 3, 3\\}"
-gdb_test "print f4a = fb" "\\\$$decimal = \\{1, 1, 1, 1\\}"
-gdb_test "print f4b = 2" "\\\$$decimal = \\{2, 2, 2, 2\\}"
+gdb_test "print i4a >> 1" "\\\$$decimal = \\{1, 2, 4, 8\\}"
 
 gdb_test "print i4a = \{2, 4, 8, 16\}" "\\\$$decimal = \\{2, 4, 8, 16\\}"
 gdb_test "print i4a <<= ib" "\\\$$decimal = \\{4, 8, 16, 32\\}"
@@ -130,6 +150,10 @@ gdb_test "print i2 + i4a" "Cannot perfor
 gdb_test "print f4a + f2" "Cannot perform operation on vectors with different types"
 gdb_test "print f2 + f4a" "Cannot perform operation on vectors with different types"
 
+gdb_test "print (double2) f2" "Cannot convert between vector values of different sizes"
+gdb_test "print (int4) c4" "Cannot convert between vector values of different sizes"
+gdb_test "print (char4) i4a" "Cannot convert between vector values of different sizes"
+
 # Test ptype on vector types.
 gdb_test "ptype c4" "type = char __attribute__ \\(\\(vector_size\\(4\\)\\)\\)"
 gdb_test "ptype char4" "type = char __attribute__ \\(\\(vector_size\\(4\\)\\)\\)"
Index: gdb/testsuite/gdb.python/py-type.c
===================================================================
RCS file: /cvs/src/src/gdb/testsuite/gdb.python/py-type.c,v
retrieving revision 1.8
diff -u -p -r1.8 py-type.c
--- gdb/testsuite/gdb.python/py-type.c	1 Jan 2013 06:41:26 -0000	1.8
+++ gdb/testsuite/gdb.python/py-type.c	8 Jan 2013 18:24:56 -0000
@@ -50,6 +50,9 @@ enum E
 { v1, v2, v3
 };
 
+struct s vec_data_1 = {1, 1};
+struct s vec_data_2 = {1, 2};
+
 int
 main ()
 {
Index: gdb/testsuite/gdb.python/py-type.exp
===================================================================
RCS file: /cvs/src/src/gdb/testsuite/gdb.python/py-type.exp,v
retrieving revision 1.28
diff -u -p -r1.28 py-type.exp
--- gdb/testsuite/gdb.python/py-type.exp	1 Jan 2013 06:41:26 -0000	1.28
+++ gdb/testsuite/gdb.python/py-type.exp	8 Jan 2013 18:24:56 -0000
@@ -118,7 +118,7 @@ proc test_fields {lang} {
     # Test gdb.Type.array.
     gdb_test "python print (ar\[0\].cast(ar\[0\].type.array(1)))" \
         ".1, 2." "cast to array with one argument"
-    gdb_test "python print (ar\[0\].cast(ar\[0\].type.array(0, 1)))" \
+    gdb_test "python print ar\[0\].cast(ar\[0\].type.array(0, 1))" \
         ".1, 2." "cast to array with two arguments"
 
     gdb_test "python print (ar\[0\].type == ar\[0\].type)" "True"
@@ -126,16 +126,19 @@ proc test_fields {lang} {
     # Test gdb.Type.vector.
     # Note: vectors cast differently than arrays.  Here ar[0] is replicated
     # for the size of the vector.
-    gdb_py_test_silent_cmd \
-        "python vec1 = ar\[0\].cast(ar\[0\].type.vector(1))" "set vec1" 1
-    gdb_test "python print (vec1)" ".1, 1." "cast to vector with one argument"
-    gdb_py_test_silent_cmd \
-        "python vec2 = ar\[0\].cast(ar\[0\].type.vector(0, 1))" "set vec2" 1
-    gdb_test "python print (vec2)" ".1, 1." "cast to vector with two arguments"
-    gdb_test "python print (vec1 == vec2)" "True"
-    gdb_py_test_silent_cmd \
-        "python vec3 = ar\[1\].cast(ar\[1\].type.vector(1))" "set vec3" 1
-    gdb_test "python print (vec1 == vec3)" "False"
+    gdb_py_test_silent_cmd "print vec_data_1" "print value (vec_data_1)" 1
+    gdb_py_test_silent_cmd "python vec_data_1 = gdb.history (0)" "get value (vec_data_1) from history" 1
+
+    gdb_py_test_silent_cmd "print vec_data_2" "print value (vec_data_2)" 1
+    gdb_py_test_silent_cmd "python vec_data_2 = gdb.history (0)" "get value (vec_data_2) from history" 1
+
+    gdb_py_test_silent_cmd "python vec1 = vec_data_1.cast(ar\[0\].type.vector(1))" "set vec1" 1
+    gdb_test "python print vec1" ".1, 1." "cast to vector with one argument"
+    gdb_py_test_silent_cmd "python vec2 = vec_data_1.cast(ar\[0\].type.vector(0, 1))" "set vec2" 1
+    gdb_test "python print vec2" ".1, 1." "cast to vector with two arguments"
+    gdb_test "python print vec1 == vec2" "True"
+    gdb_py_test_silent_cmd "python vec3 = vec_data_2.cast(ar\[0\].type.vector(1))" "set vec3" 1
+    gdb_test "python print vec1 == vec3" "False"
   }
 }
 

-- 
  Dr. Ulrich Weigand
  GNU Toolchain for Linux on System z and Cell BE
  Ulrich.Weigand@de.ibm.com


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH] Vector to scalar casting and widening
  2013-01-07 16:23             ` Ulrich Weigand
  2013-01-08 15:08               ` Andrew Burgess
@ 2013-01-09 19:08               ` Tom Tromey
  1 sibling, 0 replies; 14+ messages in thread
From: Tom Tromey @ 2013-01-09 19:08 UTC (permalink / raw)
  To: Ulrich Weigand; +Cc: Andrew Burgess, gdb-patches, ken

>>>>> "Ulrich" == Ulrich Weigand <uweigand@de.ibm.com> writes:

Ulrich> My understanding of how this is supposed to work out is that GDB
Ulrich> "value" operations *do not* actually implement the precise semantics
Ulrich> of any of the languages GDB supports; rather, they implement a GDB
Ulrich> private semantics of "GDB value" objects.  Now, as those are private
Ulrich> to GDB, we are free to implement them however we wish; for pragmatic
Ulrich> and historical reasons, they do mostly (but not completely!) match
Ulrich> C semantics.

[...]

Ulrich> [ For historical reasons, some of the value_* operations currently
Ulrich> change aspects of their behaviour depending on current_language.
Ulrich> This is really a bug, and we ought to (and slowly do) move away
Ulrich> from this.  For example, in a program employing multiple languages
Ulrich> simultaneously, GDB value objects might have been created from
Ulrich> values in a different language than the "current" one. ]

This seems like a good direction to me.

Tom


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH] Vector to scalar casting and widening
  2013-01-08 19:05                 ` Ulrich Weigand
@ 2013-01-09 19:13                   ` Tom Tromey
  2013-01-25 17:18                     ` Andrew Burgess
  0 siblings, 1 reply; 14+ messages in thread
From: Tom Tromey @ 2013-01-09 19:13 UTC (permalink / raw)
  To: Ulrich Weigand; +Cc: Andrew Burgess, gdb-patches, ken

>>>>> "Ulrich" == Ulrich Weigand <uweigand@de.ibm.com> writes:

Ulrich> With those changes, as in the modified version of the patch
Ulrich> below, all OpenCL test cases now pass.  As far as OpenCL
Ulrich> is concerned, this would be OK to commit.

Ulrich> In fact *all* of the patch looks good to me now, but I'd ask
Ulrich> you wait for another couple of days in case one of the other
Ulrich> maintainers wants to comment ...

It looks ok to me.

Tom


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH] Vector to scalar casting and widening
  2013-01-09 19:13                   ` Tom Tromey
@ 2013-01-25 17:18                     ` Andrew Burgess
  0 siblings, 0 replies; 14+ messages in thread
From: Andrew Burgess @ 2013-01-25 17:18 UTC (permalink / raw)
  To: Tom Tromey; +Cc: Ulrich Weigand, gdb-patches, ken

On 09/01/2013 7:13 PM, Tom Tromey wrote:
>>>>>> "Ulrich" == Ulrich Weigand <uweigand@de.ibm.com> writes:
> 
> Ulrich> With those changes, as in the modified version of the patch
> Ulrich> below, all OpenCL test cases now pass.  As far as OpenCL
> Ulrich> is concerned, this would be OK to commit.
> 
> Ulrich> In fact *all* of the patch looks good to me now, but I'd ask
> Ulrich> you wait for another couple of days in case one of the other
> Ulrich> maintainers wants to comment ...
> 
> It looks ok to me.
> 

Committed. Sorry for the delay.

Thanks,
Andrew



^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2013-01-25 17:18 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-11-13 14:10 [PATCH] Vector to scalar casting and widening Andrew Burgess
2012-11-19 21:17 ` Tom Tromey
2012-11-23 16:26   ` Andrew Burgess
2012-11-26 14:18     ` Ulrich Weigand
2012-11-28 22:08       ` Andrew Burgess
2012-11-29 17:50         ` Ulrich Weigand
2012-11-29 18:13           ` Andrew Burgess
2013-01-04 14:45           ` Andrew Burgess
2013-01-07 16:23             ` Ulrich Weigand
2013-01-08 15:08               ` Andrew Burgess
2013-01-08 19:05                 ` Ulrich Weigand
2013-01-09 19:13                   ` Tom Tromey
2013-01-25 17:18                     ` Andrew Burgess
2013-01-09 19:08               ` Tom Tromey

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox