diff mbox

[4.6] Fix -mcmodel=large calls (PR target/49866)

Message ID 20110727182214.GE2687@tyan-ft48-01.lab.bos.redhat.com
State New
Headers show

Commit Message

Jakub Jelinek July 27, 2011, 6:22 p.m. UTC
Hi!

As the testcase shows, 4.6 generates invalid
	jmp	*$baz
insn which fails to assemble with -O2 -mcmodel=large.  This has been fixed
by Uros on the trunk already, but with a larger patch, this patch just
backports the addition of the z constraint and uses it in all call patterns
instead of the s constraint.
Bootstrapped/regtested on x86_64-linux and i686-linux, approved by Uros
in the PR, committed to 4.6 branch and the testcase also to the trunk.

2011-07-27  Jakub Jelinek  <jakub@redhat.com>

	PR target/49866
	* config/i386/i386.md (*call_pop_1_vzeroupper, *call_pop_1,
	*sibcall_pop_1_vzeroupper, *sibcall_pop_1, *call_1_vzeroupper,
	*call_1, *sibcall_1_vzeroupper, *sibcall_1, *call_1_rex64_vzeroupper,
	*call_1_rex64, *call_1_rex64_ms_sysv_vzeroupper,
	*call_1_rex64_ms_sysv, *sibcall_1_rex64_vzeroupper,
	*sibcall_1_rex64, *call_value_pop_1_vzeroupper,
	*call_value_pop_1, *sibcall_value_pop_1_vzeroupper,
	*sibcall_value_pop_1, *call_value_1_vzeroupper,
	*call_value_1, *sibcall_value_1_vzeroupper,
	*sibcall_value_1, *call_value_1_rex64_vzeroupper,
	*call_value_1_rex64, *call_value_1_rex64_ms_sysv_vzeroupper,
	*call_value_1_rex64_ms_sysv, *sibcall_value_1_rex64_vzeroupper,
	*sibcall_value_1_rex64): Use z constraint instead of s constraint.

	Backport from mainline
	2011-05-16  Uros Bizjak  <ubizjak@gmail.com>
        
        * config/i386/constraints.md (z): New constraint.
testsuite/
	* gcc.target/i386/pr49866.c: New test.


	Jakub
diff mbox

Patch

--- gcc/config/i386/constraints.md.jj	2011-05-18 12:00:01.000000000 +0200
+++ gcc/config/i386/constraints.md	2011-07-27 14:28:06.000000000 +0200
@@ -19,7 +19,7 @@ 
 
 ;;; Unused letters:
 ;;;     B     H           T  W
-;;;           h jk          vw  z
+;;;           h jk          vw
 
 ;; Integer register constraints.
 ;; It is not necessary to define 'r' here.
@@ -105,6 +105,10 @@  (define_register_constraint "Ym"
  "TARGET_MMX && TARGET_INTER_UNIT_MOVES ? MMX_REGS : NO_REGS"
  "@internal Any MMX register, when inter-unit moves are enabled.")
 
+(define_constraint "z"
+  "@internal Constant call address operand."
+  (match_operand 0 "constant_call_address_operand"))
+
 ;; Integer constant constraints.
 (define_constraint "I"
   "Integer constant in the range 0 @dots{} 31, for 32-bit shifts."
--- gcc/config/i386/i386.md.jj	2011-07-27 13:45:38.000000000 +0200
+++ gcc/config/i386/i386.md	2011-07-27 14:30:16.000000000 +0200
@@ -11350,7 +11350,7 @@  (define_insn "*call_pop_0"
 
 (define_insn_and_split "*call_pop_1_vzeroupper"
   [(parallel
-    [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
+    [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
 	   (match_operand:SI 1 "" ""))
      (set (reg:SI SP_REG)
 	  (plus:SI (reg:SI SP_REG)
@@ -11365,7 +11365,7 @@  (define_insn_and_split "*call_pop_1_vzer
   [(set_attr "type" "call")])
 
 (define_insn "*call_pop_1"
-  [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
+  [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
 	 (match_operand:SI 1 "" ""))
    (set (reg:SI SP_REG)
 	(plus:SI (reg:SI SP_REG)
@@ -11380,7 +11380,7 @@  (define_insn "*call_pop_1"
 
 (define_insn_and_split "*sibcall_pop_1_vzeroupper"
  [(parallel
-   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
+   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "z,U"))
 	   (match_operand:SI 1 "" ""))
      (set (reg:SI SP_REG)
 	  (plus:SI (reg:SI SP_REG)
@@ -11395,7 +11395,7 @@  (define_insn_and_split "*sibcall_pop_1_v
   [(set_attr "type" "call")])
 
 (define_insn "*sibcall_pop_1"
-  [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
+  [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "z,U"))
 	 (match_operand:SI 1 "" ""))
    (set (reg:SI SP_REG)
 	(plus:SI (reg:SI SP_REG)
@@ -11446,7 +11446,7 @@  (define_insn "*call_0"
   [(set_attr "type" "call")])
 
 (define_insn_and_split "*call_1_vzeroupper"
-  [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
+  [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
 	 (match_operand 1 "" ""))
    (unspec [(match_operand 2 "const_int_operand" "")]
    	   UNSPEC_CALL_NEEDS_VZEROUPPER)]
@@ -11458,14 +11458,14 @@  (define_insn_and_split "*call_1_vzeroupp
   [(set_attr "type" "call")])
 
 (define_insn "*call_1"
-  [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
+  [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
 	 (match_operand 1 "" ""))]
   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
   { return ix86_output_call_insn (insn, operands[0], 0); }
   [(set_attr "type" "call")])
 
 (define_insn_and_split "*sibcall_1_vzeroupper"
-  [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
+  [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "z,U"))
 	 (match_operand 1 "" ""))
    (unspec [(match_operand 2 "const_int_operand" "")]
    	   UNSPEC_CALL_NEEDS_VZEROUPPER)]
@@ -11477,14 +11477,14 @@  (define_insn_and_split "*sibcall_1_vzero
   [(set_attr "type" "call")])
 
 (define_insn "*sibcall_1"
-  [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
+  [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "z,U"))
 	 (match_operand 1 "" ""))]
   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
   { return ix86_output_call_insn (insn, operands[0], 0); }
   [(set_attr "type" "call")])
 
 (define_insn_and_split "*call_1_rex64_vzeroupper"
-  [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
+  [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzm"))
 	 (match_operand 1 "" ""))
    (unspec [(match_operand 2 "const_int_operand" "")]
    	   UNSPEC_CALL_NEEDS_VZEROUPPER)]
@@ -11497,7 +11497,7 @@  (define_insn_and_split "*call_1_rex64_vz
   [(set_attr "type" "call")])
 
 (define_insn "*call_1_rex64"
-  [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
+  [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzm"))
 	 (match_operand 1 "" ""))]
   "TARGET_64BIT && !SIBLING_CALL_P (insn)
    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
@@ -11506,7 +11506,7 @@  (define_insn "*call_1_rex64"
 
 (define_insn_and_split "*call_1_rex64_ms_sysv_vzeroupper"
   [(parallel
-    [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
+    [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzm"))
 	   (match_operand 1 "" ""))
      (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
      (clobber (reg:TI XMM6_REG))
@@ -11531,7 +11531,7 @@  (define_insn_and_split "*call_1_rex64_ms
   [(set_attr "type" "call")])
 
 (define_insn "*call_1_rex64_ms_sysv"
-  [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
+  [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzm"))
 	 (match_operand 1 "" ""))
    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
    (clobber (reg:TI XMM6_REG))
@@ -11570,7 +11570,7 @@  (define_insn "*call_1_rex64_large"
   [(set_attr "type" "call")])
 
 (define_insn_and_split "*sibcall_1_rex64_vzeroupper"
-  [(call (mem:QI (match_operand:DI 0 "sibcall_insn_operand" "s,U"))
+  [(call (mem:QI (match_operand:DI 0 "sibcall_insn_operand" "z,U"))
 	 (match_operand 1 "" ""))
    (unspec [(match_operand 2 "const_int_operand" "")]
    	   UNSPEC_CALL_NEEDS_VZEROUPPER)]
@@ -11582,7 +11582,7 @@  (define_insn_and_split "*sibcall_1_rex64
   [(set_attr "type" "call")])
 
 (define_insn "*sibcall_1_rex64"
-  [(call (mem:QI (match_operand:DI 0 "sibcall_insn_operand" "s,U"))
+  [(call (mem:QI (match_operand:DI 0 "sibcall_insn_operand" "z,U"))
 	 (match_operand 1 "" ""))]
   "TARGET_64BIT && SIBLING_CALL_P (insn)"
   { return ix86_output_call_insn (insn, operands[0], 0); }
@@ -17576,7 +17576,7 @@  (define_insn "*call_value_pop_0"
 (define_insn_and_split "*call_value_pop_1_vzeroupper"
   [(parallel
     [(set (match_operand 0 "" "")
-	  (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
+	  (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
 		(match_operand:SI 2 "" "")))
      (set (reg:SI SP_REG)
 	  (plus:SI (reg:SI SP_REG)
@@ -17592,7 +17592,7 @@  (define_insn_and_split "*call_value_pop_
 
 (define_insn "*call_value_pop_1"
   [(set (match_operand 0 "" "")
-	(call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
+	(call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
 	      (match_operand:SI 2 "" "")))
    (set (reg:SI SP_REG)
 	(plus:SI (reg:SI SP_REG)
@@ -17604,7 +17604,7 @@  (define_insn "*call_value_pop_1"
 (define_insn_and_split "*sibcall_value_pop_1_vzeroupper"
  [(parallel
    [(set (match_operand 0 "" "")
-	  (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
+	  (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "z,U"))
 		(match_operand:SI 2 "" "")))
      (set (reg:SI SP_REG)
 	  (plus:SI (reg:SI SP_REG)
@@ -17620,7 +17620,7 @@  (define_insn_and_split "*sibcall_value_p
 
 (define_insn "*sibcall_value_pop_1"
   [(set (match_operand 0 "" "")
-	(call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
+	(call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "z,U"))
 	      (match_operand:SI 2 "" "")))
    (set (reg:SI SP_REG)
 	(plus:SI (reg:SI SP_REG)
@@ -17721,7 +17721,7 @@  (define_insn "*call_value_0_rex64_ms_sys
 
 (define_insn_and_split "*call_value_1_vzeroupper"
   [(set (match_operand 0 "" "")
-	(call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
+	(call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
 	      (match_operand:SI 2 "" "")))
    (unspec [(match_operand 3 "const_int_operand" "")]
    	   UNSPEC_CALL_NEEDS_VZEROUPPER)]
@@ -17734,7 +17734,7 @@  (define_insn_and_split "*call_value_1_vz
 
 (define_insn "*call_value_1"
   [(set (match_operand 0 "" "")
-	(call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
+	(call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
 	      (match_operand:SI 2 "" "")))]
   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
   { return ix86_output_call_insn (insn, operands[1], 1); }
@@ -17742,7 +17742,7 @@  (define_insn "*call_value_1"
 
 (define_insn_and_split "*sibcall_value_1_vzeroupper"
   [(set (match_operand 0 "" "")
-	(call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
+	(call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "z,U"))
 	      (match_operand:SI 2 "" "")))
    (unspec [(match_operand 3 "const_int_operand" "")]
    	   UNSPEC_CALL_NEEDS_VZEROUPPER)]
@@ -17755,7 +17755,7 @@  (define_insn_and_split "*sibcall_value_1
 
 (define_insn "*sibcall_value_1"
   [(set (match_operand 0 "" "")
-	(call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
+	(call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "z,U"))
 	      (match_operand:SI 2 "" "")))]
   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
   { return ix86_output_call_insn (insn, operands[1], 1); }
@@ -17763,7 +17763,7 @@  (define_insn "*sibcall_value_1"
 
 (define_insn_and_split "*call_value_1_rex64_vzeroupper"
   [(set (match_operand 0 "" "")
-	(call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
+	(call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzm"))
 	      (match_operand:DI 2 "" "")))
    (unspec [(match_operand 3 "const_int_operand" "")]
    	   UNSPEC_CALL_NEEDS_VZEROUPPER)]
@@ -17777,7 +17777,7 @@  (define_insn_and_split "*call_value_1_re
 
 (define_insn "*call_value_1_rex64"
   [(set (match_operand 0 "" "")
-	(call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
+	(call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzm"))
 	      (match_operand:DI 2 "" "")))]
   "TARGET_64BIT && !SIBLING_CALL_P (insn)
    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
@@ -17787,7 +17787,7 @@  (define_insn "*call_value_1_rex64"
 (define_insn_and_split "*call_value_1_rex64_ms_sysv_vzeroupper"
   [(parallel
     [(set (match_operand 0 "" "")
-	  (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
+	  (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzm"))
 		(match_operand:DI 2 "" "")))
      (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
      (clobber (reg:TI XMM6_REG))
@@ -17813,7 +17813,7 @@  (define_insn_and_split "*call_value_1_re
 
 (define_insn "*call_value_1_rex64_ms_sysv"
   [(set (match_operand 0 "" "")
-	(call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
+	(call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzm"))
 	      (match_operand:DI 2 "" "")))
    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
    (clobber (reg:TI XMM6_REG))
@@ -17855,7 +17855,7 @@  (define_insn "*call_value_1_rex64_large"
 
 (define_insn_and_split "*sibcall_value_1_rex64_vzeroupper"
   [(set (match_operand 0 "" "")
-	(call (mem:QI (match_operand:DI 1 "sibcall_insn_operand" "s,U"))
+	(call (mem:QI (match_operand:DI 1 "sibcall_insn_operand" "z,U"))
 	      (match_operand:DI 2 "" "")))
    (unspec [(match_operand 3 "const_int_operand" "")]
    	   UNSPEC_CALL_NEEDS_VZEROUPPER)]
@@ -17868,7 +17868,7 @@  (define_insn_and_split "*sibcall_value_1
 
 (define_insn "*sibcall_value_1_rex64"
   [(set (match_operand 0 "" "")
-	(call (mem:QI (match_operand:DI 1 "sibcall_insn_operand" "s,U"))
+	(call (mem:QI (match_operand:DI 1 "sibcall_insn_operand" "z,U"))
 	      (match_operand:DI 2 "" "")))]
   "TARGET_64BIT && SIBLING_CALL_P (insn)"
   { return ix86_output_call_insn (insn, operands[1], 1); }
--- gcc/testsuite/gcc.target/i386/pr49866.c.jj	2011-07-27 14:45:22.000000000 +0200
+++ gcc/testsuite/gcc.target/i386/pr49866.c	2011-07-27 14:46:05.000000000 +0200
@@ -0,0 +1,23 @@ 
+/* PR target/49866 */
+/* { dg-do assemble } */
+/* { dg-options "-O2 -mcmodel=large" { target lp64 } } */
+
+void fn (void *, int, int);
+int fn2 (void);
+void baz (int);
+
+static void
+foo (void *x, int y)
+{
+  int i;
+  for (i = 0; i < y; i++)
+    fn (x, fn2 (), i);
+}
+
+void
+bar (int u, int v, int w, void *x)
+{
+  baz (u);
+  foo (x, w);
+  baz (u);
+}