diff mbox

PATCH: PR target/66232: -fPIC -fno-plt -mx32 fails to generate indirect branch via GOT

Message ID 20151217164950.GA24079@intel.com
State New
Headers show

Commit Message

H.J. Lu Dec. 17, 2015, 4:49 p.m. UTC
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 mbox

Patch

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" } } */