public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r13-4683] i386: Fix up *concat*_{5,6,7} patterns [PR108044]
@ 2022-12-13 21:17 Jakub Jelinek
  0 siblings, 0 replies; only message in thread
From: Jakub Jelinek @ 2022-12-13 21:17 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:37c2d99f3f569350ebc0de43c10374b90086b832

commit r13-4683-g37c2d99f3f569350ebc0de43c10374b90086b832
Author: Jakub Jelinek <jakub@redhat.com>
Date:   Tue Dec 13 22:16:34 2022 +0100

    i386: Fix up *concat*_{5,6,7} patterns [PR108044]
    
    The following patch fixes 2 issues with the *concat<half><mode>3_5 and
    *concat<mode><dwi>3_{6,7} patterns.
    One is that if the destination is memory rather than register, then
    we can't use movabsq and so can't support all the possible immediates.
    I see 3 possibilities to fix that.  One would be to use
    x86_64_hilo_int_operand predicate instead of const_scalar_int_operand
    and thus not match it at all during combine in such cases, but that
    unnecessarily pessimizes also the case when it is loaded into register
    where we can use movabsq.
    Another one is what is implemented in the patch, use Wd constraint
    for the integer on 64-bit if destination is memory and n otherwise.
    Yet another option would be to add match_scratch to the pattern and use
    it with =X constraints except for the =o case for 64-bit non-Wd where it
    would give a single DImode register (rather than 2).
    
    Another thing is that if one half of the constant is
    ix86_endbr_immediate_operand, then for -fcf-protection=branch we
    force those constants into memory and that might not work properly
    with -fpic.  So we should refuse to match with such constants.
    OT, seems for movabsq we don't check that and happily allow the endbr
    pattern in the immediate.
    
    2022-12-13  Jakub Jelinek  <jakub@redhat.com>
    
            PR target/108044
            * config/i386/i386.md (*concat<half><mode>3_5, *concat<mode><dwi>3_6,
            *concat<mode><dwi>3_7): Split alternative with =ro output constraint
            into =r,o,o and use Wd input constraint for the last alternative which
            is enabled for TARGET_64BIT.  Reject ix86_endbr_immediate_operand
            in the input constant.
    
            * gcc.target/i386/pr108044-1.c: New test.
            * gcc.target/i386/pr108044-2.c: New test.
            * gcc.target/i386/pr108044-3.c: New test.
            * gcc.target/i386/pr108044-4.c: New test.

Diff:
---
 gcc/config/i386/i386.md                    | 47 ++++++++++++++++++++----------
 gcc/testsuite/gcc.target/i386/pr108044-1.c | 33 +++++++++++++++++++++
 gcc/testsuite/gcc.target/i386/pr108044-2.c | 21 +++++++++++++
 gcc/testsuite/gcc.target/i386/pr108044-3.c | 33 +++++++++++++++++++++
 gcc/testsuite/gcc.target/i386/pr108044-4.c | 21 +++++++++++++
 5 files changed, 140 insertions(+), 15 deletions(-)

diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index 04a5d634021..06267529245 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -11470,11 +11470,11 @@
 })
 
 (define_insn_and_split "*concat<half><mode>3_5"
-  [(set (match_operand:DWI 0 "nonimmediate_operand" "=ro")
+  [(set (match_operand:DWI 0 "nonimmediate_operand" "=r,o,o")
 	(any_or_plus:DWI
-	  (ashift:DWI (match_operand:DWI 1 "register_operand" "r")
+	  (ashift:DWI (match_operand:DWI 1 "register_operand" "r,r,r")
 		      (match_operand:DWI 2 "const_int_operand"))
-	  (match_operand:DWI 3 "const_scalar_int_operand")))]
+	  (match_operand:DWI 3 "const_scalar_int_operand" "n,n,Wd")))]
   "INTVAL (operands[2]) == <MODE_SIZE> * BITS_PER_UNIT / 2
    && (<MODE>mode == DImode
        ? CONST_INT_P (operands[3])
@@ -11482,7 +11482,12 @@
        : CONST_INT_P (operands[3])
        ? INTVAL (operands[3]) >= 0
        : CONST_WIDE_INT_NUNITS (operands[3]) == 2
-	 && CONST_WIDE_INT_ELT (operands[3], 1) == 0)"
+	 && CONST_WIDE_INT_ELT (operands[3], 1) == 0)
+   && !(CONST_INT_P (operands[3])
+	? ix86_endbr_immediate_operand (operands[3], VOIDmode)
+	: ix86_endbr_immediate_operand (GEN_INT (CONST_WIDE_INT_ELT (operands[3],
+								     0)),
+					VOIDmode))"
   "#"
   "&& reload_completed"
   [(clobber (const_int 0))]
@@ -11491,16 +11496,17 @@
   split_double_concat (<MODE>mode, operands[0], op3,
 		       gen_lowpart (<HALF>mode, operands[1]));
   DONE;
-})
+}
+  [(set_attr "isa" "*,nox64,x64")])
 
 (define_insn_and_split "*concat<mode><dwi>3_6"
-  [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
+  [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o,o,r")
 	(any_or_plus:<DWI>
 	  (ashift:<DWI>
 	    (zero_extend:<DWI>
-	      (match_operand:DWIH 1 "nonimmediate_operand" "r,m"))
+	      (match_operand:DWIH 1 "nonimmediate_operand" "r,r,r,m"))
 	    (match_operand:<DWI> 2 "const_int_operand"))
-	  (match_operand:<DWI> 3 "const_scalar_int_operand")))]
+	  (match_operand:<DWI> 3 "const_scalar_int_operand" "n,n,Wd,n")))]
   "INTVAL (operands[2]) == <MODE_SIZE> * BITS_PER_UNIT
    && (<DWI>mode == DImode
        ? CONST_INT_P (operands[3])
@@ -11508,7 +11514,12 @@
        : CONST_INT_P (operands[3])
        ? INTVAL (operands[3]) >= 0
        : CONST_WIDE_INT_NUNITS (operands[3]) == 2
-	 && CONST_WIDE_INT_ELT (operands[3], 1) == 0)"
+	 && CONST_WIDE_INT_ELT (operands[3], 1) == 0)
+   && !(CONST_INT_P (operands[3])
+	? ix86_endbr_immediate_operand (operands[3], VOIDmode)
+	: ix86_endbr_immediate_operand (GEN_INT (CONST_WIDE_INT_ELT (operands[3],
+								     0)),
+					VOIDmode))"
   "#"
   "&& reload_completed"
   [(clobber (const_int 0))]
@@ -11516,20 +11527,25 @@
   rtx op3 = simplify_subreg (<MODE>mode, operands[3], <DWI>mode, 0);
   split_double_concat (<DWI>mode, operands[0], op3, operands[1]);
   DONE;
-})
+}
+  [(set_attr "isa" "*,nox64,x64,*")])
 
 (define_insn_and_split "*concat<mode><dwi>3_7"
-  [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
+  [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o,o,r")
 	(any_or_plus:<DWI>
 	  (zero_extend:<DWI>
-	    (match_operand:DWIH 1 "nonimmediate_operand" "r,m"))
-	  (match_operand:<DWI> 2 "const_scalar_int_operand")))]
+	    (match_operand:DWIH 1 "nonimmediate_operand" "r,r,r,m"))
+	  (match_operand:<DWI> 2 "const_scalar_int_operand" "n,n,Wd,n")))]
   "<DWI>mode == DImode
    ? CONST_INT_P (operands[2])
      && (UINTVAL (operands[2]) & GET_MODE_MASK (SImode)) == 0
+     && !ix86_endbr_immediate_operand (operands[2], VOIDmode)
    : CONST_WIDE_INT_P (operands[2])
      && CONST_WIDE_INT_NUNITS (operands[2]) == 2
-     && CONST_WIDE_INT_ELT (operands[2], 0) == 0"
+     && CONST_WIDE_INT_ELT (operands[2], 0) == 0
+     && !ix86_endbr_immediate_operand (GEN_INT (CONST_WIDE_INT_ELT (operands[2],
+								    1)),
+				       VOIDmode)"
   "#"
   "&& reload_completed"
   [(clobber (const_int 0))]
@@ -11541,7 +11557,8 @@
     op2 = gen_int_mode (CONST_WIDE_INT_ELT (operands[2], 1), <MODE>mode);
   split_double_concat (<DWI>mode, operands[0], operands[1], op2);
   DONE;
-})
+}
+  [(set_attr "isa" "*,nox64,x64,*")])
 \f
 ;; Negation instructions
 
diff --git a/gcc/testsuite/gcc.target/i386/pr108044-1.c b/gcc/testsuite/gcc.target/i386/pr108044-1.c
new file mode 100644
index 00000000000..3fd32bc5bb1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr108044-1.c
@@ -0,0 +1,33 @@
+/* PR target/108044 */
+/* { dg-do compile { target int128 } } */
+/* { dg-options "-O2" } */
+
+static inline unsigned __int128
+foo (unsigned long long x, unsigned long long y)
+{
+  return ((unsigned __int128) x << 64) | y;
+}
+
+void
+bar (unsigned __int128 *p, unsigned long long x)
+{
+  p[0] = foo (x, 0xdeadbeefcafebabeULL);
+}
+
+void
+baz (unsigned __int128 *p, unsigned long long x)
+{
+  p[0] = foo (0xdeadbeefcafebabeULL, x);
+}
+
+void
+qux (unsigned __int128 *p, unsigned long long x)
+{
+  p[0] = foo (x, 0xffffffffcafebabeULL);
+}
+
+void
+corge (unsigned __int128 *p, unsigned long long x)
+{
+  p[0] = foo (0xffffffffcafebabeULL, x);
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr108044-2.c b/gcc/testsuite/gcc.target/i386/pr108044-2.c
new file mode 100644
index 00000000000..0adb0dddf7a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr108044-2.c
@@ -0,0 +1,21 @@
+/* PR target/108044 */
+/* { dg-do compile { target ia32 } } */
+/* { dg-options "-O2" } */
+
+static inline unsigned long long
+foo (unsigned int x, unsigned int y)
+{
+  return ((unsigned long long) x << 32) | y;
+}
+
+void
+bar (unsigned long long *p, unsigned int x)
+{
+  p[0] = foo (x, 0xcafebabeU);
+}
+
+void
+baz (unsigned long long *p, unsigned int x)
+{
+  p[0] = foo (0xcafebabeU, x);
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr108044-3.c b/gcc/testsuite/gcc.target/i386/pr108044-3.c
new file mode 100644
index 00000000000..70ba9f2f570
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr108044-3.c
@@ -0,0 +1,33 @@
+/* PR target/108044 */
+/* { dg-do compile { target int128 } } */
+/* { dg-options "-O2 -fcf-protection=branch" } */
+
+static inline unsigned __int128
+foo (unsigned long long x, unsigned long long y)
+{
+  return ((unsigned __int128) x << 64) | y;
+}
+
+unsigned __int128
+bar (unsigned long long x)
+{
+  return foo (x, 0xfa1e0ff3ULL);
+}
+
+unsigned __int128
+baz (unsigned long long x)
+{
+  return foo (0xfa1e0ff3ULL, x);
+}
+
+unsigned __int128
+qux (unsigned long long x)
+{
+  return foo (x, 0xffbafa1e0ff3abdeULL);
+}
+
+unsigned __int128
+corge (unsigned long long x)
+{
+  return foo (0xffbafa1e0ff3abdeULL, x);
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr108044-4.c b/gcc/testsuite/gcc.target/i386/pr108044-4.c
new file mode 100644
index 00000000000..4880e249319
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr108044-4.c
@@ -0,0 +1,21 @@
+/* PR target/108044 */
+/* { dg-do compile { target ia32 } } */
+/* { dg-options "-O2 -fcf-protection=branch" } */
+
+static inline unsigned long long
+foo (unsigned int x, unsigned int y)
+{
+  return ((unsigned long long) x << 32) | y;
+}
+
+unsigned long long
+bar (unsigned int x)
+{
+  return foo (x, 0xfa1e0ff3U);
+}
+
+unsigned long long
+baz (unsigned int x)
+{
+  return foo (0xfa1e0ff3U, x);
+}

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

only message in thread, other threads:[~2022-12-13 21:17 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-12-13 21:17 [gcc r13-4683] i386: Fix up *concat*_{5,6,7} patterns [PR108044] Jakub Jelinek

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).