public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [committed] Fix fr30-elf newlib build failure with late-combine
@ 2024-06-25 17:25 Jeff Law
  0 siblings, 0 replies; only message in thread
From: Jeff Law @ 2024-06-25 17:25 UTC (permalink / raw)
  To: gcc-patches

[-- Attachment #1: Type: text/plain, Size: 909 bytes --]

So the late combine work has exposed a latent bug in the fr30 port.

The fr30 "call" instruction is pc-relative with a *very* limited range, 
12 bits to be precise.


With such a limited range its hard to see how we could ever consistently 
use it in the compiler, with the possible exception of self-recursion. 
Code generation seemed to be using indirect forms pretty consistently, 
though the RTL would allow direct calls.

With late-combine some of those indirects would be optimized into direct 
calls.  This naturally led to out of range scenarios.

With the fr30 port slated for removal unless it gets updated to use LRA 
and the fundamental problems using direct calls, I took the shortest 
path to keep things working -- namely forcing all calls to be indirect.

Tested in my tester with no regressions (and fixes the newlib build 
failure with late-combine enabled).    Pushed to the trunk.

Jeff



[-- Attachment #2: P --]
[-- Type: text/plain, Size: 4609 bytes --]

commit 7c28228cda274484b78611ea4c5cbe4ce08f512e
Author: Jeff Law <jlaw@ventanamicro.com>
Date:   Tue Jun 25 11:22:01 2024 -0600

    [committed] Fix fr30-elf newlib build failure with late-combine
    
    So the late combine work has exposed a latent bug in the fr30 port.
    
    The fr30 "call" instruction is pc-relative with a *very* limited range, 12 bits
    to be precise.
    
    With such a limited range its hard to see how we could ever consistently use it
    in the compiler, with the possible exception of self-recursion.  Even for a
    call to a locally binding function -ffunction-sections and linker placement of
    functions may separate the caller/callee.  Code generation seemed to be using
    indirect forms pretty consistently, though the RTL would allow direct calls.
    
    With late-combine some of those indirects would be optimized into direct calls.
    This naturally led to out of range scenarios.
    
    With the fr30 port slated for removal unless it gets updated to use LRA and the
    fundamental problems using direct calls, I took the shortest path to keep
    things working -- namely forcing all calls to be indirect.
    
    Tested in my tester with no regressions (and fixes the newlib build failure
    with late-combine enabled).    Pushed to the trunk.
    
    gcc/
            * config/fr30/constraints.md (Q): Remove unused constraint.
            * config/fr30/predicates.md (call_operand): Remove unused predicate.
            * config/fr30/fr30.md (call, vall_value): Turn into expanders and
            force the call address into a register.
            (*call, *call_value): Adjust to only allow indirect calls.  Adjust
            output template accordingly.

diff --git a/gcc/config/fr30/constraints.md b/gcc/config/fr30/constraints.md
index e4e2be1bfd9..1beee7cc3a2 100644
--- a/gcc/config/fr30/constraints.md
+++ b/gcc/config/fr30/constraints.md
@@ -63,9 +63,3 @@ (define_constraint "P"
   "An integer in the range -256 to 255."
   (and (match_code "const_int")
        (match_test "IN_RANGE (ival, -256, 255)")))
-
-;; Extra constraints.
-(define_constraint "Q"
-  "@internal"
-  (and (match_code "mem")
-       (match_code "symbol_ref" "0")))
diff --git a/gcc/config/fr30/fr30.md b/gcc/config/fr30/fr30.md
index ecde60b455d..04f6d909054 100644
--- a/gcc/config/fr30/fr30.md
+++ b/gcc/config/fr30/fr30.md
@@ -1079,12 +1079,19 @@ (define_insn "*branch_false"
 ;; `SImode', except it is normally a `const_int'); operand 2 is the number of
 ;; registers used as operands.
 
-(define_insn "call"
-  [(call (match_operand 0 "call_operand" "Qm")
+(define_expand "call"
+  [(parallel [(call (mem:QI (match_operand:SI  0 "register_operand" "r"))
+                    (match_operand 1 ""             "g"))
+              (clobber (reg:SI 17))])]
+  ""
+  " { operands[0] = force_reg (SImode, XEXP (operands[0], 0)); } ")
+
+(define_insn "*call"
+  [(call (mem:QI (match_operand:SI 0 "register_operand" "r"))
 	 (match_operand 1 ""             "g"))
    (clobber (reg:SI 17))]
   ""
-  "call%#\\t%0"
+  "call%#\\t@%0"
   [(set_attr "delay_type" "delayed")]
 )
 
@@ -1094,14 +1101,21 @@ (define_insn "call"
 ;; increased by one).
 
 ;; Subroutines that return `BLKmode' objects use the `call' insn.
+(define_expand "call_value"
+  [(parallel [(set (match_operand 0 "register_operand"  "=r")
+                   (call (mem:QI (match_operand:SI 1 "register_operand" "r"))
+                         (match_operand 2 ""             "g")))
+              (clobber (reg:SI 17))])]
+  ""
+  " { operands[1] = force_reg (SImode, XEXP (operands[1], 0)); } ")
 
-(define_insn "call_value"
+(define_insn "*call_value"
   [(set (match_operand 0 "register_operand"  "=r")
-	(call (match_operand 1 "call_operand" "Qm")
+	(call (mem:QI (match_operand:SI 1 "register_operand" "r"))
 	      (match_operand 2 ""             "g")))
    (clobber (reg:SI 17))]
   ""
-  "call%#\\t%1"
+  "call%#\\t@%1"
   [(set_attr "delay_type" "delayed")]
 )
 
diff --git a/gcc/config/fr30/predicates.md b/gcc/config/fr30/predicates.md
index f67c6097430..2f87a4c81b2 100644
--- a/gcc/config/fr30/predicates.md
+++ b/gcc/config/fr30/predicates.md
@@ -51,16 +51,6 @@ (define_predicate "low_register_operand"
      && REGNO (op) <= 7);
 })
 
-;; Returns true if OP is suitable for use in a CALL insn.
-
-(define_predicate "call_operand"
-  (match_code "mem")
-{
-  return (GET_CODE (op) == MEM
-	  && (GET_CODE (XEXP (op, 0)) == SYMBOL_REF
-	      || GET_CODE (XEXP (op, 0)) == REG));
-})
-
 ;; Returns TRUE if OP is a valid operand of a DImode operation.
 
 (define_predicate "di_operand"

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2024-06-25 17:25 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-06-25 17:25 [committed] Fix fr30-elf newlib build failure with late-combine Jeff Law

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).