__intN patch 3/5: main __int128 -> __intN conversion.
diff mbox

Message ID 201410082127.s98LRGn7032386@greed.delorie.com
State New
Headers show

Commit Message

DJ Delorie Oct. 8, 2014, 9:27 p.m. UTC
> >       if (same_type_p (TYPE_MAIN_VARIANT (t1), long_long_unsigned_type_node)
> >           || same_type_p (TYPE_MAIN_VARIANT (t2), long_long_unsigned_type_node))
> >         return build_type_attribute_variant (long_long_unsigned_type_node,
> >                                              attributes);
> 
> Your patch only compares t1/t2 to int_n_trees[i].signed_type.

Checking the code before this logic, we can make some assumptions:

  /* Both real or both integers; use the one with greater precision.  */
* we can assume the two types have the same precision

  /* The types are the same; no need to do anything fancy.  */
* we can assume the two types are different

In the case of non-128 __intN, checking only for signed *should* work
- the only other type that's the same precision but a different type
*is* the unsigned variant (enforced in toplev.c).

Even in the case of __int128, if either type is signed __int128 and
the other type is different AT ALL, the result will be unsigned
__int128 if either type is unsigned, or signed __int128.

But a new patch which checks everything anyway is attached :-)

Comments

Jason Merrill Oct. 9, 2014, 1:40 p.m. UTC | #1
OK, thanks.

Jason
DJ Delorie Oct. 13, 2014, 8:54 p.m. UTC | #2
This is what I ended up with for the test case.  It was a bit tricky
since it only works with msp430x (not msp430) and requires the gnu
extensions.  Is this OK?  If so, is there anything else, or can I
check the whole mess in yet?


// { dg-do compile { target msp430*-*-* } }
// { dg-options "-std=gnu++11" }
// { dg-skip-if "" { msp430*-*-* } { "-mcpu=msp430" } { "" } }

__int20 x;

__int20 foo (__int20 a, unsigned __int20 b)
{
  return a + b;
}

// { dg-final { scan-assembler "\n_?_Z3foou5int20u6uint20\[: \t\n\]" } }
Jason Merrill Oct. 14, 2014, 1:35 p.m. UTC | #3
On 10/13/2014 04:54 PM, DJ Delorie wrote:
> This is what I ended up with for the test case.  It was a bit tricky
> since it only works with msp430x (not msp430) and requires the gnu
> extensions.  Is this OK?  If so, is there anything else, or can I
> check the whole mess in yet?

Go ahead.

Jason
DJ Delorie Oct. 14, 2014, 7:44 p.m. UTC | #4
> > extensions.  Is this OK?  If so, is there anything else, or can I
> > check the whole mess in yet?
> 
> Go ahead.

Thanks!  Committed.

Patch
diff mbox

Index: typeck.c
===================================================================
--- typeck.c	(revision 216012)
+++ typeck.c	(working copy)
@@ -270,6 +270,7 @@ 
   enum tree_code code1 = TREE_CODE (t1);
   enum tree_code code2 = TREE_CODE (t2);
   tree attributes;
+  int i;
 
 
   /* In what follows, we slightly generalize the rules given in [expr] so
@@ -364,17 +365,6 @@ 
 		    : long_long_integer_type_node);
 	  return build_type_attribute_variant (t, attributes);
 	}
-      if (int128_integer_type_node != NULL_TREE
-	  && (same_type_p (TYPE_MAIN_VARIANT (t1),
-			   int128_integer_type_node)
-	      || same_type_p (TYPE_MAIN_VARIANT (t2),
-			      int128_integer_type_node)))
-	{
-	  tree t = ((TYPE_UNSIGNED (t1) || TYPE_UNSIGNED (t2))
-		    ? int128_unsigned_type_node
-		    : int128_integer_type_node);
-	  return build_type_attribute_variant (t, attributes);
-	}
 
       /* Go through the same procedure, but for longs.  */
       if (same_type_p (TYPE_MAIN_VARIANT (t1), long_unsigned_type_node)
@@ -388,6 +378,26 @@ 
 		    ? long_unsigned_type_node : long_integer_type_node);
 	  return build_type_attribute_variant (t, attributes);
 	}
+
+      /* For __intN types, either the type is __int128 (and is lower
+	 priority than the types checked above, but higher than other
+	 128-bit types) or it's known to not be the same size as other
+	 types (enforced in toplev.c).  Prefer the unsigned type. */
+      for (i = 0; i < NUM_INT_N_ENTS; i ++)
+	{
+	  if (int_n_enabled_p [i]
+	      && (same_type_p (TYPE_MAIN_VARIANT (t1), int_n_trees[i].signed_type)
+		  || same_type_p (TYPE_MAIN_VARIANT (t2), int_n_trees[i].signed_type)
+		  || same_type_p (TYPE_MAIN_VARIANT (t1), int_n_trees[i].unsigned_type)
+		  || same_type_p (TYPE_MAIN_VARIANT (t2), int_n_trees[i].unsigned_type)))
+	    {
+	      tree t = ((TYPE_UNSIGNED (t1) || TYPE_UNSIGNED (t2))
+			? int_n_trees[i].unsigned_type
+			: int_n_trees[i].signed_type);
+	      return build_type_attribute_variant (t, attributes);
+	    }
+	}
+
       /* Otherwise prefer the unsigned one.  */
       if (TYPE_UNSIGNED (t1))
 	return build_type_attribute_variant (t1, attributes);