diff mbox

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

Message ID CAFULd4auNTic56yVSvVp4OP52ddCObR5-zj3dSUf64CDtr831Q@mail.gmail.com
State New
Headers show

Commit Message

Uros Bizjak May 21, 2015, 6:19 p.m. UTC
On Thu, May 21, 2015 at 7:01 PM, H.J. Lu <hjl.tools@gmail.com> wrote:

> Here is the updated patch.  It limited memory operand to
> GOT slot only.  It used a single pattern to cover both call
> and sibcall since only GOT slot is allowed.
>
> OK for master if there is no regression?
>
> Thanks.
>
>
> --
> H.J.
> ---
> X32 doesn't support indirect branch via 32-bit memory slot since
> indirect branch will load 64-bit address from 64-bit memory slot.
> Since x32 GOT slot is 64-bit, we should allow indirect branch via GOT
> slot for x32.
>
> gcc/
>
> PR target/66232
> * config/i386/constraints.md (Bg): Add a constraint for x32
> call and sibcall memory operand.
> * config/i386/i386.md (*call_got_x32): New pattern.
> (*call_value_got_x32): Likewise.
> * config/i386/predicates.md (x32_call_got_memory_operand): New
> predicate.
> (x32_call_insn_got_operand): Likewise.
>
> gcc/testsuite/
>
> PR target/66232
> * gcc.target/i386/pr66232-1.c: New test.
> * gcc.target/i386/pr66232-2.c: Likewise.
> * gcc.target/i386/pr66232-3.c: Likewise.
> * gcc.target/i386/pr66232-4.c: Likewise.
> * gcc.target/i386/pr66232-5.c: Likewise.

The above predicate is not needed, all insns are protected by TARGET_X32.

 ;; Match exactly zero.
 (define_predicate "const0_operand"
diff mbox

Patch

diff --git a/gcc/config/i386/constraints.md b/gcc/config/i386/constraints.md
index 2271bd1..4ec9821 100644
--- a/gcc/config/i386/constraints.md
+++ b/gcc/config/i386/constraints.md
@@ -146,10 +146,16 @@ 
  "@internal Lower SSE register when avoiding REX prefix and all SSE
registers otherwise.")

 ;; We use the B prefix to denote any number of internal operands:
+;;  g  Call and sibcall memory operand, valid for TARGET_X32
 ;;  s  Sibcall memory operand, not valid for TARGET_X32
 ;;  w  Call memory operand, not valid for TARGET_X32
 ;;  z  Constant call address operand.

+(define_constraint "Bg"
+  "@internal Call/sibcall GOT memory operand for x32."
+  (and (match_test "TARGET_X32")
+       (match_operand 0 "x32_call_got_memory_operand")))

No need for TARGET_X32, when all insn patterns are protected by it.
And the predicate is not x32 specific. And not call specific, so
"@internal GOT memory operand". Please use "GOT_memory_operand"
predicate, see below.

 (define_constraint "Bs"
   "@internal Sibcall memory operand."
   (and (not (match_test "TARGET_X32"))
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index aefca43..158a3ed 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -11659,6 +11659,15 @@ 
   "* return ix86_output_call_insn (insn, operands[0]);"
   [(set_attr "type" "call")])

+;; This covers both call and sibcall since only GOT slot is allowed.
+(define_insn "*call_got_x32"
+  [(call (mem:QI (zero_extend:DI
+           (match_operand:SI 0 "x32_call_insn_got_operand" "Bg")))
+     (match_operand 1))]
+  "TARGET_X32"
+  "* return ix86_output_call_insn (insn, operands[0]);"
+  [(set_attr "type" "call")])

"GOT_memory_operand" in the above pattern and all other call patterns.

 (define_insn "*sibcall"
   [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "UBsBz"))
      (match_operand 1))]
@@ -11825,6 +11834,17 @@ 
   "* return ix86_output_call_insn (insn, operands[1]);"
   [(set_attr "type" "callv")])

+;; This covers both call and sibcall since only GOT slot is allowed.
+(define_insn "*call_value_got_x32"
+  [(set (match_operand 0)
+    (call (mem:QI
+        (zero_extend:DI
+          (match_operand:SI 1 "x32_call_insn_got_operand" "Bg")))
+          (match_operand 2)))]
+  "TARGET_X32"
+  "* return ix86_output_call_insn (insn, operands[1]);"
+  [(set_attr "type" "callv")])
+
 (define_insn "*sibcall_value"
   [(set (match_operand 0)
     (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "UBsBz"))
diff --git a/gcc/config/i386/predicates.md b/gcc/config/i386/predicates.md
index 26dd3e1..166893e 100644
--- a/gcc/config/i386/predicates.md
+++ b/gcc/config/i386/predicates.md
@@ -606,6 +606,20 @@ 
        (and (not (match_test "TARGET_X32"))
         (match_operand 0 "sibcall_memory_operand"))))

+;; Return true if OP is a GOT memory operand that can be used in x32 calls
+;; and sibcalls.
+(define_predicate "x32_call_got_memory_operand"
+  (and (match_operand 0 "memory_operand")
+       (match_test "CONSTANT_P (XEXP (op, 0))")
+       (match_test "GET_CODE (XEXP (XEXP (op, 0), 0)) == UNSPEC")
+       (match_test "XINT (XEXP (XEXP (op, 0), 0), 1) == UNSPEC_GOTPCREL")))

There is nothing x32 specific, it is just a GOT memory operand, so
let's name it "GOT_memory_operand".

+;; Test for a valid operand for an x32 call/sibcall instruction via
+;; memory.  Only the 64-bit GOT slot is allowed.
+(define_special_predicate "x32_call_insn_got_operand"
+  (and (match_test "TARGET_X32")
+       (match_operand 0 "x32_call_got_memory_operand")))