This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

RFC: PR middle-end/55142: Check Pmode instead of ptr_mode for address mode


Hi,

The testcase shows -O -mx32 -maddress-mode=long -fPIC -S generates;

x.i:22:37: internal compiler error: in plus_constant, at explow.c:88
  info[0x6ffffeff - dyn->d_tag + 12] = dyn;

expand_expr_real_2 has

      /* No sense saving up arithmetic to be done
         if it's all in the wrong mode to form part of an address.
         And force_operand won't know whether to sign-extend or
         zero-extend.  */
      if ((modifier != EXPAND_SUM && modifier != EXPAND_INITIALIZER)
          || mode != ptr_mode)

With mode == SImode, Pmode == DImode and ptr_mode == SImode, we
generate wrong address.  Instead of zero-extending address
0xf7ffdd64, we sign-extend it to 0xfffffffff7ffdd64.  This patch
checks Pmode instead of ptr_mode for address mode.  It fixes the testcase
and generates a working x32 glibc. Is this patch correct?

Thanks.


H.J.
---
gcc/

2012-11-03  H.J. Lu  <hongjiu.lu@intel.com>

	PR middle-end/55142
	* expr.c (expand_expr_real_2): Check Pmode instead of ptr_mode
	for wrong address mode.

gcc/testsuite/

2012-11-03  H.J. Lu  <hongjiu.lu@intel.com>

	PR middle-end/55142
	* gcc.target/i386/pr55142.c: New file.

diff --git a/gcc/expr.c b/gcc/expr.c
index 0ad3b57..1600380 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -8290,7 +8290,7 @@ expand_expr_real_2 (sepops ops, rtx target, enum machine_mode tmode,
 	 And force_operand won't know whether to sign-extend or
 	 zero-extend.  */
       if ((modifier != EXPAND_SUM && modifier != EXPAND_INITIALIZER)
-	  || mode != ptr_mode)
+	  || mode != Pmode)
 	{
 	  expand_operands (treeop0, treeop1,
 			   subtarget, &op0, &op1, EXPAND_NORMAL);
@@ -8333,7 +8333,7 @@ expand_expr_real_2 (sepops ops, rtx target, enum machine_mode tmode,
 	 And force_operand won't know whether to sign-extend or
 	 zero-extend.  */
       if ((modifier != EXPAND_SUM && modifier != EXPAND_INITIALIZER)
-	  || mode != ptr_mode)
+	  || mode != Pmode)
 	goto binop;
 
       expand_operands (treeop0, treeop1,
diff --git a/gcc/testsuite/gcc.target/i386/pr55142.c b/gcc/testsuite/gcc.target/i386/pr55142.c
new file mode 100644
index 0000000..c8a9625
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr55142.c
@@ -0,0 +1,34 @@
+/* { dg-do compile { target { ! { ia32 } } } } */
+/* { dg-require-effective-target fpic } */
+/* { dg-options "-O2 -mx32 -maddress-mode=long -fpic" } */
+
+typedef int int32_t;
+typedef unsigned int uint32_t;
+typedef int32_t Elf32_Sword;
+typedef struct
+{
+  Elf32_Sword d_tag;
+} Elf32_Dyn;
+struct link_map
+{
+  Elf32_Dyn *l_ld;
+  Elf32_Dyn *l_info[34];
+};
+extern struct link_map _dl_rtld_map __attribute__ ((visibility ("hidden")));
+static void elf_get_dynamic_info (struct link_map *l)
+{
+  Elf32_Dyn *dyn = l->l_ld;
+  Elf32_Dyn **info;
+  info = l->l_info;
+  while (dyn->d_tag != 0)
+    {
+      if ((uint32_t) (0x6ffffeff - dyn->d_tag) < 11)
+	info[0x6ffffeff - dyn->d_tag + 12] = dyn;
+      ++dyn;
+    }
+}
+void
+foo (void)
+{
+  elf_get_dynamic_info (&_dl_rtld_map);
+}


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]