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 <ja...@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 <ubiz...@gmail.com> * config/i386/constraints.md (z): New constraint. testsuite/ * gcc.target/i386/pr49866.c: New test. --- 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); +} Jakub