re PR middle-end/16790 (Integer down cast ignored in larger expression)
authorRoger Sayle <roger@eyesopen.com>
Tue, 3 Aug 2004 21:24:32 +0000 (21:24 +0000)
committerRoger Sayle <sayle@gcc.gnu.org>
Tue, 3 Aug 2004 21:24:32 +0000 (21:24 +0000)
PR middle-end/16790
* fold-const.c (extract_muldiv_1) <NOP_EXPR>: Disallow local
truncations, not just global truncations.

* gcc.c-torture/execute/pr16790-1.c: New test case.

From-SVN: r85506

gcc/ChangeLog
gcc/fold-const.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/execute/pr16790-1.c [new file with mode: 0644]

index 9b2fc027c26e226bb28766125c20fda980b5ffa8..2825c795b1f4be567aa8b3a9454254626c2ce5ec 100644 (file)
@@ -1,3 +1,9 @@
+2004-08-03  Roger Sayle  <roger@eyesopen.com>
+
+       PR middle-end/16790
+       * fold-const.c (extract_muldiv_1) <NOP_EXPR>: Disallow local
+       truncations, not just global truncations.
+
 2004-08-03  Andrew Pinski  <apinski@apple.com>
 
        PR bootstrap/16865
index f4a6fb022d4710d9cbee82ace3b56b3f5dbe4811..503b6f094cfb0c7146f150b653b55610b52d4c6e 100644 (file)
@@ -5102,9 +5102,9 @@ extract_muldiv_1 (tree t, tree c, enum tree_code code, tree wide_type)
                     && TYPE_IS_SIZETYPE (TREE_TYPE (op0)))
               && (GET_MODE_SIZE (TYPE_MODE (ctype))
                   > GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (op0)))))
-             /* ... or its type is larger than ctype,
-                then we cannot pass through this truncation.  */
-             || (GET_MODE_SIZE (TYPE_MODE (ctype))
+             /* ... 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))))
              /* ... or signedness changes for division or modulus,
                 then we cannot pass through this conversion.  */
index 72e026ca1311ce0d6d1e74d587b3a5c0d39b3ec5..db11af67a72182646b7026098b97d34a91b74031 100644 (file)
@@ -1,3 +1,8 @@
+2004-08-03  Roger Sayle  <roger@eyesopen.com>
+
+       PR middle-end/16790
+       * gcc.c-torture/execute/pr16790-1.c: New test case.
+
 2004-08-03  Mark Mitchell  <mark@codesourcery.com>
 
        * gcc.dg/symbian1.c: New test.
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr16790-1.c b/gcc/testsuite/gcc.c-torture/execute/pr16790-1.c
new file mode 100644 (file)
index 0000000..dc6a774
--- /dev/null
@@ -0,0 +1,41 @@
+/* PR middle-end/16790.  */
+
+extern void abort ();
+
+static void test1(unsigned int u1)
+{
+  unsigned int y_final_1;
+  signed short y_middle;
+  unsigned int y_final_2;
+
+  y_final_1 = (unsigned int)( (signed short)(u1 * 2) * 3 );
+  y_middle  =                 (signed short)(u1 * 2);
+  y_final_2 = (unsigned int)( y_middle * 3 );
+
+  if (y_final_1 != y_final_2)
+    abort ();
+}
+
+
+static void test2(unsigned int u1)
+{
+  unsigned int y_final_1;
+  signed short y_middle;
+  unsigned int y_final_2;
+
+  y_final_1 = (unsigned int)( (signed short)(u1 << 1) * 3 );
+  y_middle  =                 (signed short)(u1 << 1);
+  y_final_2 = (unsigned int)( y_middle * 3 );
+
+  if (y_final_1 != y_final_2)
+    abort ();
+}
+
+
+int main()
+{
+  test1(0x4000U);
+  test2(0x4000U);
+  return 0;
+}
+