https://gcc.gnu.org/g:e0700fbe35286d31fe64782b255c8d2caec673dc

commit r15-1401-ge0700fbe35286d31fe64782b255c8d2caec673dc
Author: Richard Sandiford <richard.sandif...@arm.com>
Date:   Tue Jun 18 12:22:32 2024 +0100

    Add force_highpart_subreg
    
    This patch adds a force_highpart_subreg to go along with the
    recently added force_lowpart_subreg.
    
    gcc/
            * explow.h (force_highpart_subreg): Declare.
            * explow.cc (force_highpart_subreg): New function.
            * builtins.cc (expand_builtin_issignaling): Use it.
            * expmed.cc (emit_store_flag_1): Likewise.

Diff:
---
 gcc/builtins.cc | 15 ++++-----------
 gcc/explow.cc   | 14 ++++++++++++++
 gcc/explow.h    |  1 +
 gcc/expmed.cc   |  4 +---
 4 files changed, 20 insertions(+), 14 deletions(-)

diff --git a/gcc/builtins.cc b/gcc/builtins.cc
index bde517b639e8..d467d1697b45 100644
--- a/gcc/builtins.cc
+++ b/gcc/builtins.cc
@@ -2835,9 +2835,7 @@ expand_builtin_issignaling (tree exp, rtx target)
             it is, working on the DImode high part is usually better.  */
          if (!MEM_P (temp))
            {
-             if (rtx t = simplify_gen_subreg (imode, temp, fmode,
-                                              subreg_highpart_offset (imode,
-                                                                      fmode)))
+             if (rtx t = force_highpart_subreg (imode, temp, fmode))
                hi = t;
              else
                {
@@ -2845,9 +2843,7 @@ expand_builtin_issignaling (tree exp, rtx target)
                  if (int_mode_for_mode (fmode).exists (&imode2))
                    {
                      rtx temp2 = gen_lowpart (imode2, temp);
-                     poly_uint64 off = subreg_highpart_offset (imode, imode2);
-                     if (rtx t = simplify_gen_subreg (imode, temp2,
-                                                      imode2, off))
+                     if (rtx t = force_highpart_subreg (imode, temp2, imode2))
                        hi = t;
                    }
                }
@@ -2938,8 +2934,7 @@ expand_builtin_issignaling (tree exp, rtx target)
           it is, working on DImode parts is usually better.  */
        if (!MEM_P (temp))
          {
-           hi = simplify_gen_subreg (imode, temp, fmode,
-                                     subreg_highpart_offset (imode, fmode));
+           hi = force_highpart_subreg (imode, temp, fmode);
            lo = force_lowpart_subreg (imode, temp, fmode);
            if (!hi || !lo)
              {
@@ -2947,9 +2942,7 @@ expand_builtin_issignaling (tree exp, rtx target)
                if (int_mode_for_mode (fmode).exists (&imode2))
                  {
                    rtx temp2 = gen_lowpart (imode2, temp);
-                   hi = simplify_gen_subreg (imode, temp2, imode2,
-                                             subreg_highpart_offset (imode,
-                                                                     imode2));
+                   hi = force_highpart_subreg (imode, temp2, imode2);
                    lo = force_lowpart_subreg (imode, temp2, imode2);
                  }
              }
diff --git a/gcc/explow.cc b/gcc/explow.cc
index 2a91cf76ea62..b4a0df89bc36 100644
--- a/gcc/explow.cc
+++ b/gcc/explow.cc
@@ -778,6 +778,20 @@ force_lowpart_subreg (machine_mode outermode, rtx op,
   return force_subreg (outermode, op, innermode, byte);
 }
 
+/* Try to return an rvalue expression for the OUTERMODE highpart of OP,
+   which has mode INNERMODE.  Allow OP to be forced into a new register
+   if necessary.
+
+   Return null on failure.  */
+
+rtx
+force_highpart_subreg (machine_mode outermode, rtx op,
+                      machine_mode innermode)
+{
+  auto byte = subreg_highpart_offset (outermode, innermode);
+  return force_subreg (outermode, op, innermode, byte);
+}
+
 /* If X is a memory ref, copy its contents to a new temp reg and return
    that reg.  Otherwise, return X.  */
 
diff --git a/gcc/explow.h b/gcc/explow.h
index dd654649b068..de89e9e2933e 100644
--- a/gcc/explow.h
+++ b/gcc/explow.h
@@ -44,6 +44,7 @@ extern rtx force_reg (machine_mode, rtx);
 
 extern rtx force_subreg (machine_mode, rtx, machine_mode, poly_uint64);
 extern rtx force_lowpart_subreg (machine_mode, rtx, machine_mode);
+extern rtx force_highpart_subreg (machine_mode, rtx, machine_mode);
 
 /* Return given rtx, copied into a new temp reg if it was in memory.  */
 extern rtx force_not_mem (rtx);
diff --git a/gcc/expmed.cc b/gcc/expmed.cc
index 1f68e7be721d..3b9475f5aa0b 100644
--- a/gcc/expmed.cc
+++ b/gcc/expmed.cc
@@ -5784,9 +5784,7 @@ emit_store_flag_1 (rtx target, enum rtx_code code, rtx 
op0, rtx op1,
          rtx op0h;
 
          /* If testing the sign bit, can just test on high word.  */
-         op0h = simplify_gen_subreg (word_mode, op0, int_mode,
-                                     subreg_highpart_offset (word_mode,
-                                                             int_mode));
+         op0h = force_highpart_subreg (word_mode, op0, int_mode);
          tem = emit_store_flag (NULL_RTX, code, op0h, op1, word_mode,
                                 unsignedp, normalizep);
        }

Reply via email to