This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Fix build_range_check on 1 .. signed_max ranges (PR middle-end/37882)


Hi!

signed_type_for may return a type with bigger precision than the precision
of the passed type, e.g. type_for_size langhook's comment says:
  /* Given PRECISION and UNSIGNEDP, return a suitable type-tree for an
     integer type with at least that precision.  */
In the
/* Optimize (c>=1) && (c<=127) into (signed char)c > 0.  */
optimization, precision at least as wide as c's isn't good enough,
we need exactly the same precision.
The following patch fixes it.  We could call build_nonstandard_integer_type
unconditionally, but that would in the common case where precision is sane
unnecessarily create a new type and as fold is used also in the FEs, I think
it is better to use the standard types if possible.

Ok for trunk/4.3 if bootstrap/regtest passes?

2008-10-22  Jakub Jelinek  <jakub@redhat.com>

	PR middle-end/37882
	* fold-const.c (build_range_type): For 1 .. signed_max
	range call build_nonstandard_inter_type if signed_type_for
	returned a type with bigger precision.

	* gcc.c-torture/execute/pr37882.c: New test.

--- gcc/fold-const.c.jj	2008-10-20 12:36:10.000000000 +0200
+++ gcc/fold-const.c	2008-10-22 12:11:13.000000000 +0200
@@ -4503,7 +4503,12 @@ build_range_check (tree type, tree exp, 
 	{
 	  if (TYPE_UNSIGNED (etype))
 	    {
-	      etype = signed_type_for (etype);
+	      tree signed_etype = signed_type_for (etype);
+	      if (TYPE_PRECISION (signed_etype) != TYPE_PRECISION (etype))
+		etype
+		  = build_nonstandard_integer_type (TYPE_PRECISION (etype), 0);
+	      else
+		etype = signed_etype;
 	      exp = fold_convert (etype, exp);
 	    }
 	  return fold_build2 (GT_EXPR, type, exp,
--- gcc/testsuite/gcc.c-torture/execute/pr37882.c.jj	2008-10-22 12:14:42.000000000 +0200
+++ gcc/testsuite/gcc.c-torture/execute/pr37882.c	2008-10-22 12:14:25.000000000 +0200
@@ -0,0 +1,16 @@
+/* PR middle-end/37882 */
+
+struct S
+{
+  int a : 21;
+  unsigned char b : 3;
+} s;
+
+int
+main ()
+{
+  s.b = 4;
+  if (s.b > 0 && s.b < 4)
+    __builtin_abort ();
+  return 0;
+}

	Jakub


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]