Hello, I resend patch within new thread. Recent fallout about sibcall was caused by using 'm' constraint for sibcalls. By this wrongly combines happened on reload-pass. That patch introduces new constraint 'B' for sibcall_memory_operand.
ChangeLog 2014-05-31 Kai Tietz <kti...@redhat.com> * constrains.md (define_constrain): New 'B' constraint. * i386.md (sibcall_insn_operand): Use B instead of m constraint. ChangeLog testsuite 2014-05-31 Kai Tietz <kti...@redhat.com> * gcc.target/i386/sibcall-6.c: New test. Bootstrapped i386-unknown-linux-gnu, x86_64-unknown-linux-gnu. Ok for apply? Regards, Kai Index: constraints.md =================================================================== --- constraints.md (Revision 211089) +++ constraints.md (Arbeitskopie) @@ -18,7 +18,7 @@ ;; <http://www.gnu.org/licenses/>. ;;; Unused letters: -;;; B H +;;; H ;;; h j ;; Integer register constraints. @@ -151,6 +151,11 @@ "@internal Constant call address operand." (match_operand 0 "constant_call_address_operand")) +(define_constraint "B" + "@internal Sibcall memory operand." + (and (not (match_test "TARGET_X32")) + (match_operand 0 "sibcall_memory_operand"))) + (define_constraint "w" "@internal Call memory operand." (and (not (match_test "TARGET_X32")) Index: i386.md =================================================================== --- i386.md (Revision 211089) +++ i386.md (Arbeitskopie) @@ -11376,12 +11376,41 @@ [(set_attr "type" "call")]) (define_insn "*sibcall" - [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "Uzm")) + [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "UzB")) (match_operand 1))] "SIBLING_CALL_P (insn)" "* return ix86_output_call_insn (insn, operands[0]);" @@ -11406,7 +11435,7 @@ [(set_attr "type" "call")]) (define_insn "*sibcall_pop" - [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uzm")) + [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "UzB")) (match_operand 1)) (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) @@ -11451,7 +11480,7 @@ (define_insn "*sibcall_value" [(set (match_operand 0) - (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "Uzm")) + (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "UzB")) (match_operand 2)))] "SIBLING_CALL_P (insn)" "* return ix86_output_call_insn (insn, operands[1]);" @@ -11494,7 +11523,7 @@ (define_insn "*sibcall_value_pop" [(set (match_operand 0) - (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uzm")) + (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "UzB")) (match_operand 2))) (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) Index: gcc.target/i386/sibcall-6.c =================================================================== --- gcc.target/i386/sibcall-6.c (Revision 0) +++ gcc.target/i386/sibcall-6.c (Arbeitskopie) @@ -0,0 +1,37 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target ia32 } */ +/* { dg-options "-O2" } */ + +typedef void *ira_loop_tree_node_t; + +extern int end (int); +extern int doo (int); + +void +ira_traverse_loop_tree (int bb_p, ira_loop_tree_node_t loop_node, + void (*preorder_func) (ira_loop_tree_node_t), + void (*postorder_func) (ira_loop_tree_node_t)) +{ + int l, r = 0x1, h = 0, j = 0; + + if (preorder_func) + (*preorder_func) (loop_node); + + if (bb_p) + { + for (l = 0; l < end (l); l++) + { + r += doo (l); + h += (l + 1) * 3; + h %= (l + 1); + r -= doo (h); + j += (l + 1) * 7; + j %= (l + 1); + r += doo (j); + } + } + + if (postorder_func) + (*postorder_func) (loop_node); +} +/* { dg-final { scan-assembler "jmp[ \t]*.%eax" } } */