Since Pmode is 64-bit with -maddress-mode=long for x32, indirect call via GOT slot doesn't need zero_extend. This patch limits *call_got_x32 and *call_value_got_x32 patterns to 32-bit Pmode, adds *call_got_x32_long and *call_value_got_x32_long for 64-bit Pmode.
OK for trunk if there is no regression? H.J. --- gcc/ PR target/66232 * config/i386/i386.md (*call_got_x32): Limited to 32-bit Pmode. (*call_value_got_x32): Likewise. (*call_got_x32_long): New pattern. (call_value_got_x32_long): Likewise. gcc/testsuite/ PR target/66232 * gcc.target/i386/pr66232-10.c: New test. * gcc.target/i386/pr66232-11.c: Likewise. * gcc.target/i386/pr66232-12.c: Likewise. * gcc.target/i386/pr66232-13.c: Likewise. --- gcc/config/i386/i386.md | 19 +++++++++++++++++-- gcc/testsuite/gcc.target/i386/pr66232-10.c | 13 +++++++++++++ gcc/testsuite/gcc.target/i386/pr66232-11.c | 14 ++++++++++++++ gcc/testsuite/gcc.target/i386/pr66232-12.c | 13 +++++++++++++ gcc/testsuite/gcc.target/i386/pr66232-13.c | 13 +++++++++++++ 5 files changed, 70 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/gcc.target/i386/pr66232-10.c create mode 100644 gcc/testsuite/gcc.target/i386/pr66232-11.c create mode 100644 gcc/testsuite/gcc.target/i386/pr66232-12.c create mode 100644 gcc/testsuite/gcc.target/i386/pr66232-13.c diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index 49b2216..dc61050 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -11861,7 +11861,14 @@ [(call (mem:QI (zero_extend:DI (match_operand:SI 0 "GOT_memory_operand" "Bg"))) (match_operand 1))] - "TARGET_X32" + "TARGET_X32 && Pmode == SImode" + "* return ix86_output_call_insn (insn, operands[0]);" + [(set_attr "type" "call")]) + +(define_insn "*call_got_x32_long" + [(call (mem:QI (match_operand:DI 0 "GOT_memory_operand" "Bg")) + (match_operand 1))] + "TARGET_X32 && Pmode == DImode" "* return ix86_output_call_insn (insn, operands[0]);" [(set_attr "type" "call")]) @@ -12038,7 +12045,15 @@ (zero_extend:DI (match_operand:SI 1 "GOT_memory_operand" "Bg"))) (match_operand 2)))] - "TARGET_X32" + "TARGET_X32 && Pmode == SImode" + "* return ix86_output_call_insn (insn, operands[1]);" + [(set_attr "type" "callv")]) + +(define_insn "*call_value_got_x32_long" + [(set (match_operand 0) + (call (mem:QI (match_operand:DI 1 "GOT_memory_operand" "Bg")) + (match_operand 2)))] + "TARGET_X32 && Pmode == DImode" "* return ix86_output_call_insn (insn, operands[1]);" [(set_attr "type" "callv")]) diff --git a/gcc/testsuite/gcc.target/i386/pr66232-10.c b/gcc/testsuite/gcc.target/i386/pr66232-10.c new file mode 100644 index 0000000..c4e9157 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr66232-10.c @@ -0,0 +1,13 @@ +/* { dg-do compile { target *-*-linux* } } */ +/* { dg-require-effective-target maybe_x32 } */ +/* { dg-options "-O2 -mx32 -fpic -fno-plt -maddress-mode=long" } */ + +extern void bar (void); + +void +foo (void) +{ + bar (); +} + +/* { dg-final { scan-assembler "jmp\[ \t\]*.bar@GOTPCREL" } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr66232-11.c b/gcc/testsuite/gcc.target/i386/pr66232-11.c new file mode 100644 index 0000000..05794af --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr66232-11.c @@ -0,0 +1,14 @@ +/* { dg-do compile { target *-*-linux* } } */ +/* { dg-require-effective-target maybe_x32 } */ +/* { dg-options "-O2 -mx32 -fpic -fno-plt -maddress-mode=long" } */ + +extern void bar (void); + +int +foo (void) +{ + bar (); + return 0; +} + +/* { dg-final { scan-assembler "call\[ \t\]*.bar@GOTPCREL" } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr66232-12.c b/gcc/testsuite/gcc.target/i386/pr66232-12.c new file mode 100644 index 0000000..313b9e4 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr66232-12.c @@ -0,0 +1,13 @@ +/* { dg-do compile { target *-*-linux* } } */ +/* { dg-require-effective-target maybe_x32 } */ +/* { dg-options "-O2 -mx32 -fpic -fno-plt -maddress-mode=long" } */ + +extern int bar (void); + +int +foo (void) +{ + return bar (); +} + +/* { dg-final { scan-assembler "jmp\[ \t\]*.bar@GOTPCREL" } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr66232-13.c b/gcc/testsuite/gcc.target/i386/pr66232-13.c new file mode 100644 index 0000000..50a12cf --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr66232-13.c @@ -0,0 +1,13 @@ +/* { dg-do compile { target *-*-linux* } } */ +/* { dg-require-effective-target maybe_x32 } */ +/* { dg-options "-O2 -mx32 -fpic -fno-plt -maddress-mode=long" } */ + +extern int bar (void); + +int +foo (void) +{ + return bar () + 1; +} + +/* { dg-final { scan-assembler "call\[ \t\]*.bar@GOTPCREL" } } */ -- 2.5.0