Pass unpromoted argument to promote_function_mode
authorhjl <hjl@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 14 Dec 2014 16:04:11 +0000 (16:04 +0000)
committerhjl <hjl@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 14 Dec 2014 16:04:11 +0000 (16:04 +0000)
This patch updates setup_incoming_promotions in combine.c to match what
is actually passed in assign_parm_setup_reg in function.c.

gcc/

PR rtl-optimization/64037
* combine.c (setup_incoming_promotions): Pass the argument
before any promotions happen to promote_function_mode.

gcc/testsuite/

PR rtl-optimization/64037
* g++.dg/pr64037.C: New test.

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

gcc/ChangeLog
gcc/combine.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/pr64037.C [new file with mode: 0644]

index e5de2c6..f8484d8 100644 (file)
@@ -1,3 +1,9 @@
+2014-12-14  H.J. Lu  <hongjiu.lu@intel.com>
+
+       PR rtl-optimization/64037
+       * combine.c (setup_incoming_promotions): Pass the argument
+       before any promotions happen to promote_function_mode.
+
 2014-12-12  Thomas Schwinge  <thomas@codesourcery.com>
 
        * config/nvptx/nvptx.h (ASM_OUTPUT_ALIGN): Define as a C statment.
index c95b493..ee7b3f9 100644 (file)
@@ -1579,8 +1579,8 @@ setup_incoming_promotions (rtx_insn *first)
       uns3 = TYPE_UNSIGNED (DECL_ARG_TYPE (arg));
 
       /* The mode and signedness of the argument as it is actually passed,
-         after any TARGET_PROMOTE_FUNCTION_ARGS-driven ABI promotions.  */
-      mode3 = promote_function_mode (DECL_ARG_TYPE (arg), mode2, &uns3,
+         see assign_parm_setup_reg in function.c.  */
+      mode3 = promote_function_mode (TREE_TYPE (arg), mode1, &uns3,
                                     TREE_TYPE (cfun->decl), 0);
 
       /* The mode of the register in which the argument is being passed.  */
index 3d96f34..c42c3fe 100644 (file)
@@ -1,3 +1,8 @@
+2014-12-14  H.J. Lu  <hongjiu.lu@intel.com>
+
+       PR rtl-optimization/64037
+       * g++.dg/pr64037.C: New test.
+
 2014-12-14  Janus Weil  <janus@gcc.gnu.org>
 
        PR fortran/63674
diff --git a/gcc/testsuite/g++.dg/pr64037.C b/gcc/testsuite/g++.dg/pr64037.C
new file mode 100644 (file)
index 0000000..e5cd0e2
--- /dev/null
@@ -0,0 +1,27 @@
+// { dg-do run { target i?86-*-* x86_64-*-* } }
+// { dg-options "-std=c++11 -Os" }
+
+enum class X : unsigned char {
+  V = 2,
+};
+
+static void
+__attribute__((noinline,noclone))
+foo(unsigned &out, unsigned a, X b)
+{
+  out = static_cast<unsigned>(b);
+}
+
+int main()
+{
+  unsigned deadbeef = 0xDEADBEEF;
+  asm volatile ("" : "+d" (deadbeef), "+c" (deadbeef));
+
+  unsigned out;
+  foo(out, 2, X::V);
+
+  if (out != 2)
+    __builtin_abort ();
+
+  return 0;
+}