OSDN Git Service

PR rtl-opt/42269
authorrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 8 Dec 2009 00:44:28 +0000 (00:44 +0000)
committerrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 8 Dec 2009 00:44:28 +0000 (00:44 +0000)
        * combine.c (setup_incoming_promotions): Improve the conditions
        under which we respect the promotions applied.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@155071 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/combine.c
gcc/testsuite/gcc.c-torture/execute/pr42269-2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/alpha/pr42269-1.c [new file with mode: 0644]

index b91b638..bcccc3a 100644 (file)
@@ -1,3 +1,9 @@
+2009-12-07  Richard Henderson  <rth@redhat.com>
+
+       PR rtl-opt/42269
+       * combine.c (setup_incoming_promotions): Improve the conditions
+       under which we respect the promotions applied.
+
 2009-12-07  Eric Botcazou  <ebotcazou@adacore.com>
 
        * config/sparc/linux.h (ASM_SPEC): Pass -K PIC if -findirect-dispatch.
 2009-12-07  Eric Botcazou  <ebotcazou@adacore.com>
 
        * config/sparc/linux.h (ASM_SPEC): Pass -K PIC if -findirect-dispatch.
index 7f3f6da..f26b9e5 100644 (file)
@@ -1377,19 +1377,23 @@ setup_incoming_promotions (rtx first)
 
       /* Eliminate sign extensions in the callee when possible.  Only
          do this when:
 
       /* Eliminate sign extensions in the callee when possible.  Only
          do this when:
-        (a) a mode promotion has occurred;
-        (b) the mode of the register is the same as the mode of
+        (a) A mode promotion has occurred;
+        (b) The mode of the register is the same as the mode of
             the argument as it is passed; and
             the argument as it is passed; and
-        (c) the signedness does not change across any of the promotions; and
-        (d) when no language-level promotions (which we cannot guarantee
+        (c) Either there's no language level extension, or the extension
+            from source to end result is valid.  The later case is true
+            when the signedness of the extensions match, or when the 
+            language level extension is unsigned.  In the later case,
+            a zero extension followed by a sign extension is the same
+            as one big zero extension.
+        (d) When no language-level promotions (which we cannot guarantee
             will have been done by an external caller) are necessary,
             unless we know that this function is only ever called from
             the current compilation unit -- all of whose call sites will
             do the mode1 --> mode2 promotion.  */
       if (mode1 != mode3
           && mode3 == mode4
             will have been done by an external caller) are necessary,
             unless we know that this function is only ever called from
             the current compilation unit -- all of whose call sites will
             do the mode1 --> mode2 promotion.  */
       if (mode1 != mode3
           && mode3 == mode4
-          && uns1 == uns3
-         && (mode1 == mode2 || strictly_local))
+         && (mode1 == mode2 || ((uns1 || !uns3) && strictly_local)))
         {
          /* Record that the value was promoted from mode1 to mode3,
             so that any sign extension at the head of the current
         {
          /* Record that the value was promoted from mode1 to mode3,
             so that any sign extension at the head of the current
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr42269-2.c b/gcc/testsuite/gcc.c-torture/execute/pr42269-2.c
new file mode 100644 (file)
index 0000000..a9410d4
--- /dev/null
@@ -0,0 +1,15 @@
+/* Make sure that language + abi extensions in passing S interoperate.  */
+
+static long long __attribute__((noinline))
+foo (unsigned short s)
+{
+  return (short) s;
+}
+
+unsigned short s = 0xFFFF;
+
+int
+main (void)
+{
+  return foo (s) + 1 != 0;
+}
diff --git a/gcc/testsuite/gcc.target/alpha/pr42269-1.c b/gcc/testsuite/gcc.target/alpha/pr42269-1.c
new file mode 100644 (file)
index 0000000..5d4ef1c
--- /dev/null
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+/* { dg-final { scan-assembler-not "addl" } } */
+
+unsigned
+parity (unsigned x)
+{
+  x ^= x >> 16;
+  x ^= x >> 8;
+  x ^= x >> 4;
+  x &= 0xf;
+  return (0x6996 >> x) & 1;
+}