re PR middle-end/36300 (Incorrect type used for inlined expression)
authorRichard Guenther <rguenther@suse.de>
Mon, 26 May 2008 12:38:19 +0000 (12:38 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Mon, 26 May 2008 12:38:19 +0000 (12:38 +0000)
2008-05-26  Richard Guenther  <rguenther@suse.de>

PR middle-end/36300
* fold-const.c (extract_muldiv_1): Use TYPE_OVERFLOW_WRAPS,
not TYPE_UNSIGNED.  Use TYPE_PRECISION instead of GET_MODE_SIZE.

* gcc.dg/pr36300-1.c: New testcase.
* gcc.dg/pr36300-2.c: Likewise.

From-SVN: r135913

gcc/ChangeLog
gcc/fold-const.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/pr36300-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/pr36300-2.c [new file with mode: 0644]

index 4e68ae5619ef5ddec7e3e5f60128b99259a264cc..25f86bcd988a8c834f27f155ee1659e1d09bef61 100644 (file)
@@ -1,3 +1,9 @@
+2008-05-26  Richard Guenther  <rguenther@suse.de>
+
+       PR middle-end/36300
+       * fold-const.c (extract_muldiv_1): Use TYPE_OVERFLOW_WRAPS,
+       not TYPE_UNSIGNED.  Use TYPE_PRECISION instead of GET_MODE_SIZE.
+
 2008-05-26  Daniel Franke  <franke.daniel@gmail.com>
 
        PR bootstrap/36331
index 4113dc45b21beadbcabdf6752c45a3e42a2ac4fb..25756bbb9c93d2b963e35f1b189ef56ade3c7c1a 100644 (file)
@@ -5736,17 +5736,17 @@ extract_muldiv_1 (tree t, tree c, enum tree_code code, tree wide_type,
           || BINARY_CLASS_P (op0)
           || VL_EXP_CLASS_P (op0)
           || EXPRESSION_CLASS_P (op0))
-         /* ... and is unsigned, and its type is smaller than ctype,
-            then we cannot pass through as widening.  */
-         && ((TYPE_UNSIGNED (TREE_TYPE (op0))
+         /* ... and has wrapping overflow, and its type is smaller
+            than ctype, then we cannot pass through as widening.  */
+         && ((TYPE_OVERFLOW_WRAPS (TREE_TYPE (op0))
               && ! (TREE_CODE (TREE_TYPE (op0)) == INTEGER_TYPE
                     && TYPE_IS_SIZETYPE (TREE_TYPE (op0)))
-              && (GET_MODE_SIZE (TYPE_MODE (ctype))
-                  > GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (op0)))))
+              && (TYPE_PRECISION (ctype)
+                  > TYPE_PRECISION (TREE_TYPE (op0))))
              /* ... or this is a truncation (t is narrower than op0),
                 then we cannot pass through this narrowing.  */
-             || (GET_MODE_SIZE (TYPE_MODE (type))
-                 < GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (op0))))
+             || (TYPE_PRECISION (type)
+                 < TYPE_PRECISION (TREE_TYPE (op0)))
              /* ... or signedness changes for division or modulus,
                 then we cannot pass through this conversion.  */
              || (code != MULT_EXPR
index 5060df6af49422fb8124186f007d6b5a72e93dbd..867b297b49a45abb05e1d9817136bf76ac21a89d 100644 (file)
@@ -1,3 +1,9 @@
+2008-05-26  Richard Guenther  <rguenther@suse.de>
+
+       PR middle-end/36300
+       * gcc.dg/pr36300-1.c: New testcase.
+       * gcc.dg/pr36300-2.c: Likewise.
+
 2008-05-26  Arnaud Charlet  <charlet@adacore.com>
 
        * gnat.dg/set_in_pproc.adb: New test.
diff --git a/gcc/testsuite/gcc.dg/pr36300-1.c b/gcc/testsuite/gcc.dg/pr36300-1.c
new file mode 100644 (file)
index 0000000..466522f
--- /dev/null
@@ -0,0 +1,24 @@
+/* { dg-do run } */
+/* { dg-options "-O2 -fwrapv" } */
+
+extern void abort (void);
+
+#define VALUE ((int)((long long)U1 * (long long)3) + 2)
+
+int main(void)
+{
+  int U1;
+  long long Y, Y2;
+  int t;
+
+  U1 = -2147483647-1;
+
+  Y = ((long long)(VALUE * VALUE) * 3);
+
+  t = VALUE;
+  Y2 = ((long long)(t * t) * 3);
+
+  if (Y != Y2)
+    abort ();
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/pr36300-2.c b/gcc/testsuite/gcc.dg/pr36300-2.c
new file mode 100644 (file)
index 0000000..7e7cfa2
--- /dev/null
@@ -0,0 +1,24 @@
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+
+extern void abort (void);
+
+#define VALUE (unsigned int)((int)((long long)U1 * (long long)3) + 2)
+
+int main(void)
+{
+  int U1;
+  long long Y, Y2;
+  unsigned int t;
+
+  U1 = -2147483647-1;
+
+  Y = ((long long)(int)(VALUE * VALUE) * 3);
+
+  t = VALUE;
+  Y2 = ((long long)(int)(t * t) * 3);
+
+  if (Y != Y2)
+    abort ();
+  return 0;
+}