diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 4af6f0fe95fe599636026d71b203bedb34177659..a4a53a410a9f362d672fc1c6cd13d0475ff7dfe1 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,8 @@
+2002-10-01  Richard Henderson  <rth@redhat.com>
+
+	* calls.c (precompute_register_parameters): Force non-legitimate
+	constants into pseudos.
+
 2002-10-01  Nick Clifton  <nickc@redhat.com>
 
 	* config/rs6000/spe.md (spe_evrlwi): Add missing third operand
diff --git a/gcc/calls.c b/gcc/calls.c
index ffedacabbb051f1e890c0e26649734f731dd6714..d706751c16265b5900811e7a661a353806e11da2 100644
--- a/gcc/calls.c
+++ b/gcc/calls.c
@@ -876,6 +876,12 @@ precompute_register_parameters (num_actuals, args, reg_parm_seen)
 	    emit_queue ();
 	  }
 
+	/* If the value is a non-legitimate constant, force it into a
+	   pseudo now.  TLS symbols sometimes need a call to resolve.  */
+	if (CONSTANT_P (args[i].value)
+	    && !LEGITIMATE_CONSTANT_P (args[i].value))
+	  args[i].value = force_reg (args[i].mode, args[i].value);
+
 	/* If we are to promote the function arg to a wider mode,
 	   do it now.  */
 
diff --git a/gcc/testsuite/gcc.dg/tls/opt-3.c b/gcc/testsuite/gcc.dg/tls/opt-3.c
new file mode 100644
index 0000000000000000000000000000000000000000..0e56991400c4cc90b6b590ac750d0847eb1d0263
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tls/opt-3.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fpic } */
+/* { dg-options "-O2 -fpic -mregparm=3" { target i?86-*-* } } */
+
+extern __thread int i, j, k;
+extern void bar(int *, int *, int *);
+void foo(void)
+{
+  bar(&i, &j, &k);
+}