From 1e19ac749db3cd39fb22d58775282c0058bc3c8a Mon Sep 17 00:00:00 2001
From: Richard Henderson <rth@redhat.com>
Date: Tue, 24 Aug 2004 14:45:59 -0700
Subject: [PATCH] re PR target/16298 (ICE in output_operand)

        PR target/16298
        * config/i386/i386.c (legitimate_constant_p): Rework to not accept
        random codes within CONST.

From-SVN: r86522
---
 gcc/ChangeLog          |  6 ++++++
 gcc/config/i386/i386.c | 49 ++++++++++++++++--------------------------
 2 files changed, 25 insertions(+), 30 deletions(-)

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index ede940ec26b3..e52036f9ddac 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2004-08-24  Richard Henderson  <rth@redhat.com>
+
+	PR target/16298
+	* config/i386/i386.c (legitimate_constant_p): Rework to not accept
+	random codes within CONST.
+
 2004-08-24  James E Wilson  <wilson@specifixinc.com>
 
 	* Makefile.in (STAGEFEEDBACK_FLAGS_TO_PASS): Remove
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 22a062d6fd72..53ed7f1db5dc 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -4824,54 +4824,43 @@ darwin_local_data_pic (rtx disp)
 bool
 legitimate_constant_p (rtx x)
 {
-  rtx inner;
-
   switch (GET_CODE (x))
     {
-    case SYMBOL_REF:
-      /* TLS symbols are not constant.  */
-      if (tls_symbolic_operand (x, Pmode))
-	return false;
-      break;
-
     case CONST:
-      inner = XEXP (x, 0);
-
-      /* Offsets of TLS symbols are never valid.
-	 Discourage CSE from creating them.  */
-      if (GET_CODE (inner) == PLUS
-	  && tls_symbolic_operand (XEXP (inner, 0), Pmode))
-	return false;
+      x = XEXP (x, 0);
 
-      if (GET_CODE (inner) == PLUS)
+      if (GET_CODE (x) == PLUS)
 	{
-	  if (GET_CODE (XEXP (inner, 1)) != CONST_INT)
+	  if (GET_CODE (XEXP (x, 1)) != CONST_INT)
 	    return false;
-	  inner = XEXP (inner, 0);
+	  x = XEXP (x, 0);
 	}
 
-      if (TARGET_MACHO && darwin_local_data_pic (inner))
+      if (TARGET_MACHO && darwin_local_data_pic (x))
 	return true;
 
-      if (GET_CODE (inner) == MINUS)
-	{
-	  if (GET_CODE (XEXP (inner, 1)) != CONST_INT)
-	    return false;
-	  inner = XEXP (inner, 0);
-	}
-
       /* Only some unspecs are valid as "constants".  */
-      if (GET_CODE (inner) == UNSPEC)
-	switch (XINT (inner, 1))
+      if (GET_CODE (x) == UNSPEC)
+	switch (XINT (x, 1))
 	  {
 	  case UNSPEC_TPOFF:
 	  case UNSPEC_NTPOFF:
-	    return local_exec_symbolic_operand (XVECEXP (inner, 0, 0), Pmode);
+	    return local_exec_symbolic_operand (XVECEXP (x, 0, 0), Pmode);
 	  case UNSPEC_DTPOFF:
-	    return local_dynamic_symbolic_operand (XVECEXP (inner, 0, 0), Pmode);
+	    return local_dynamic_symbolic_operand (XVECEXP (x, 0, 0), Pmode);
 	  default:
 	    return false;
 	  }
+
+      /* We must have drilled down to a symbol.  */
+      if (!symbolic_operand (x, Pmode))
+	return false;
+      /* FALLTHRU */
+
+    case SYMBOL_REF:
+      /* TLS symbols are never valid.  */
+      if (tls_symbolic_operand (x, Pmode))
+	return false;
       break;
 
     default:
-- 
GitLab