expr.c (store_expr): Convert VOIDmode constants back to target's mode.
authorJakub Jelinek <jakub@redhat.com>
Tue, 8 Jan 2002 20:10:39 +0000 (21:10 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Tue, 8 Jan 2002 20:10:39 +0000 (21:10 +0100)
* expr.c (store_expr): Convert VOIDmode constants back to target's
mode.

* gcc.dg/20020108-1.c: New test.

From-SVN: r48658

gcc/ChangeLog
gcc/expr.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/20020108-1.c [new file with mode: 0644]

index 1151544e38239296e409ebecd8273e79cc521cad..1b95cfe60c3fc268d3573b15586e94817817d07b 100644 (file)
@@ -1,3 +1,8 @@
+2002-01-08  Jakub Jelinek  <jakub@redhat.com>
+
+       * expr.c (store_expr): Convert VOIDmode constants back to target's
+       mode.
+
 2002-01-08  Gerald Pfeifer  <pfeifer@dbai.tuwien.ac.at>
 
        * doc/invoke.texi: Markup gcc as @command.  Refer to
index 04d801de76ff0e976d917c442e9a93354bb26ade..d11df993c51bdf8d3907476cbc60f880620ccf15 100644 (file)
@@ -4041,13 +4041,19 @@ store_expr (exp, target, want_value)
         target.  Otherwise, the caller might get confused by a result whose
         mode is larger than expected.  */
 
-      if (want_value && GET_MODE (temp) != GET_MODE (target)
-         && GET_MODE (temp) != VOIDmode)
+      if (want_value && GET_MODE (temp) != GET_MODE (target))
        {
-         temp = gen_lowpart_SUBREG (GET_MODE (target), temp);
-         SUBREG_PROMOTED_VAR_P (temp) = 1;
-         SUBREG_PROMOTED_UNSIGNED_P (temp)
-           = SUBREG_PROMOTED_UNSIGNED_P (target);
+         if (GET_MODE (temp) != VOIDmode)
+           {
+             temp = gen_lowpart_SUBREG (GET_MODE (target), temp);
+             SUBREG_PROMOTED_VAR_P (temp) = 1;
+             SUBREG_PROMOTED_UNSIGNED_P (temp)
+               = SUBREG_PROMOTED_UNSIGNED_P (target);
+           }
+         else
+           temp = convert_modes (GET_MODE (target),
+                                 GET_MODE (SUBREG_REG (target)),
+                                 temp, SUBREG_PROMOTED_UNSIGNED_P (target));
        }
 
       return want_value ? temp : NULL_RTX;
index 4b432d82204296de946ad6b06b3e14c91fc5f6f9..d4f4a3ee075e60f8de4e6ae95259ad328e7e63f0 100644 (file)
@@ -1,3 +1,7 @@
+2002-01-08  Jakub Jelinek  <jakub@redhat.com>
+
+       * gcc.dg/20020108-1.c: New test.
+
 2002-01-08  H.J. Lu <hjl@gnu.org>
 
        * objc.dg/special/special.exp: Add -I${srcdir}/../../libobjc
diff --git a/gcc/testsuite/gcc.dg/20020108-1.c b/gcc/testsuite/gcc.dg/20020108-1.c
new file mode 100644 (file)
index 0000000..b91022d
--- /dev/null
@@ -0,0 +1,16 @@
+/* This testcase failed on i686 because (const_int -1) was changed into
+   (const_int 0xffff) when storing it into SImode pseudo, but was not
+   converted back to (const_int -1) when returning from store_expr,
+   eventhough target was (subreg:HI (reg/v:SI indx)).  But (const_int 0xffff)
+   is not valid general_operand in HImode.  */
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+/* { dg-options "-O2 -mcpu=i686" { target i?86-*-* } } */
+
+void
+foo (unsigned short *cp)
+{
+  unsigned short indx;
+
+  *cp = indx = 0xFFFF;
+}