[gcc r13-9022] i386: Fix up __builtin_ia32_b{extr{, i}_u{32, 64}, zhi_{s, d}i} folding [PR116287]

Jakub Jelinek jakub@gcc.gnu.org
Fri Sep 13 14:08:17 GMT 2024


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

commit r13-9022-ge5839cad7886c0277c111d96cc99c400f6f36b9d
Author: Jakub Jelinek <jakub@redhat.com>
Date:   Fri Aug 9 14:32:51 2024 +0200

    i386: Fix up __builtin_ia32_b{extr{,i}_u{32,64},zhi_{s,d}i} folding [PR116287]
    
    The GENERIC folding of these builtins have cases where it folds to a
    constant regardless of the value of the first operand.  If so, we need
    to use omit_one_operand to avoid throwing away side-effects in the first
    operand if any.  The cases which verify the first argument is INTEGER_CST
    don't need that, INTEGER_CST doesn't have side-effects.
    
    2024-08-09  Jakub Jelinek  <jakub@redhat.com>
    
            PR target/116287
            * config/i386/i386.cc (ix86_fold_builtin) <case IX86_BUILTIN_BEXTR32>:
            When folding into zero without checking whether first argument is
            constant, use omit_one_operand.
            (ix86_fold_builtin) <case IX86_BUILTIN_BZHI32>: Likewise.
    
            * gcc.target/i386/bmi-pr116287.c: New test.
            * gcc.target/i386/bmi2-pr116287.c: New test.
            * gcc.target/i386/tbm-pr116287.c: New test.
    
    (cherry picked from commit 6e7088dbe3bf87108a89558ffb7df36df3469206)

Diff:
---
 gcc/config/i386/i386.cc                       | 12 +++++++----
 gcc/testsuite/gcc.target/i386/bmi-pr116287.c  | 28 ++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/i386/bmi2-pr116287.c | 24 ++++++++++++++++++++++
 gcc/testsuite/gcc.target/i386/tbm-pr116287.c  | 29 +++++++++++++++++++++++++++
 4 files changed, 89 insertions(+), 4 deletions(-)

diff --git a/gcc/config/i386/i386.cc b/gcc/config/i386/i386.cc
index a90351ca9c2c..85aa68175aa3 100644
--- a/gcc/config/i386/i386.cc
+++ b/gcc/config/i386/i386.cc
@@ -18054,9 +18054,11 @@ ix86_fold_builtin (tree fndecl, int n_args,
 	      unsigned int prec = TYPE_PRECISION (TREE_TYPE (args[0]));
 	      unsigned int start = tree_to_uhwi (args[1]);
 	      unsigned int len = (start & 0xff00) >> 8;
+	      tree lhs_type = TREE_TYPE (TREE_TYPE (fndecl));
 	      start &= 0xff;
 	      if (start >= prec || len == 0)
-		res = 0;
+		return omit_one_operand (lhs_type, build_zero_cst (lhs_type),
+					 args[0]);
 	      else if (!tree_fits_uhwi_p (args[0]))
 		break;
 	      else
@@ -18065,7 +18067,7 @@ ix86_fold_builtin (tree fndecl, int n_args,
 		len = prec;
 	      if (len < HOST_BITS_PER_WIDE_INT)
 		res &= (HOST_WIDE_INT_1U << len) - 1;
-	      return build_int_cstu (TREE_TYPE (TREE_TYPE (fndecl)), res);
+	      return build_int_cstu (lhs_type, res);
 	    }
 	  break;
 
@@ -18075,15 +18077,17 @@ ix86_fold_builtin (tree fndecl, int n_args,
 	  if (tree_fits_uhwi_p (args[1]))
 	    {
 	      unsigned int idx = tree_to_uhwi (args[1]) & 0xff;
+	      tree lhs_type = TREE_TYPE (TREE_TYPE (fndecl));
 	      if (idx >= TYPE_PRECISION (TREE_TYPE (args[0])))
 		return args[0];
 	      if (idx == 0)
-		return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), 0);
+		return omit_one_operand (lhs_type, build_zero_cst (lhs_type),
+					 args[0]);
 	      if (!tree_fits_uhwi_p (args[0]))
 		break;
 	      unsigned HOST_WIDE_INT res = tree_to_uhwi (args[0]);
 	      res &= ~(HOST_WIDE_INT_M1U << idx);
-	      return build_int_cstu (TREE_TYPE (TREE_TYPE (fndecl)), res);
+	      return build_int_cstu (lhs_type, res);
 	    }
 	  break;
 
diff --git a/gcc/testsuite/gcc.target/i386/bmi-pr116287.c b/gcc/testsuite/gcc.target/i386/bmi-pr116287.c
new file mode 100644
index 000000000000..2212cb458d26
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/bmi-pr116287.c
@@ -0,0 +1,28 @@
+/* PR target/116287 */
+/* { dg-do run { target bmi } } */
+/* { dg-options "-O2 -mbmi" } */
+
+#include <x86intrin.h>
+
+#include "bmi-check.h"
+
+static void
+bmi_test ()
+{
+  unsigned int a = 0;
+  if (__builtin_ia32_bextr_u32 (a++, 0) != 0)
+    abort ();
+  if (__builtin_ia32_bextr_u32 (a++, 0x120) != 0)
+    abort ();
+  if (a != 2)
+    abort ();
+#ifdef __x86_64__
+  unsigned long long b = 0;
+  if (__builtin_ia32_bextr_u64 (b++, 0) != 0)
+    abort ();
+  if (__builtin_ia32_bextr_u64 (b++, 0x140) != 0)
+    abort ();
+  if (b != 2)
+    abort ();
+#endif
+}
diff --git a/gcc/testsuite/gcc.target/i386/bmi2-pr116287.c b/gcc/testsuite/gcc.target/i386/bmi2-pr116287.c
new file mode 100644
index 000000000000..51c939c39f62
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/bmi2-pr116287.c
@@ -0,0 +1,24 @@
+/* PR target/116287 */
+/* { dg-do run { target bmi2 } } */
+/* { dg-options "-O2 -mbmi2" } */
+
+#include <x86intrin.h>
+
+#include "bmi2-check.h"
+
+static void
+bmi2_test ()
+{
+  unsigned int a = 0;
+  if (__builtin_ia32_bzhi_si (a++, 0) != 0)
+    abort ();
+  if (a != 1)
+    abort ();
+#ifdef __x86_64__
+  unsigned long long b = 0;
+  if (__builtin_ia32_bzhi_di (b++, 0) != 0)
+    abort ();
+  if (b != 1)
+    abort ();
+#endif
+}
diff --git a/gcc/testsuite/gcc.target/i386/tbm-pr116287.c b/gcc/testsuite/gcc.target/i386/tbm-pr116287.c
new file mode 100644
index 000000000000..a229d8bb416c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/tbm-pr116287.c
@@ -0,0 +1,29 @@
+/* PR target/116287 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -mtbm -fdump-tree-optimized" } */
+/* { dg-final { scan-tree-dump-not "link_error \\\(\\\);" "optimized" } } */
+
+#include <x86intrin.h>
+
+extern void link_error (void);
+
+void
+tbm_test ()
+{
+  unsigned int a = 0;
+  if (__builtin_ia32_bextri_u32 (a++, 0) != 0)
+    link_error ();
+  if (__builtin_ia32_bextri_u32 (a++, 0x120) != 0)
+    link_error ();
+  if (a != 2)
+    link_error ();
+#ifdef __x86_64__
+  unsigned long long b = 0;
+  if (__builtin_ia32_bextr_u64 (b++, 0) != 0)
+    link_error ();
+  if (__builtin_ia32_bextr_u64 (b++, 0x140) != 0)
+    link_error ();
+  if (b != 2)
+    link_error ();
+#endif
+}


More information about the Gcc-cvs mailing list