diff mbox series

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

Message ID ZrXFZe3BfMXUF8mF@tucnak
State New
Headers show
Series i386: Fix up __builtin_ia32_b{extr{,i}_u{32,64},zhi_{s,d}i} folding [PR116287] | expand

Commit Message

Jakub Jelinek Aug. 9, 2024, 7:29 a.m. UTC
Hi!

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.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

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.


	Jakub

Comments

Uros Bizjak Aug. 9, 2024, 11:08 a.m. UTC | #1
On Fri, Aug 9, 2024 at 9:29 AM Jakub Jelinek <jakub@redhat.com> wrote:
>
> Hi!
>
> 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.
>
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
>
> 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.

Rubberstamp OK.

Thanks,
Uros.

>
> --- gcc/config/i386/i386.cc.jj  2024-08-01 14:33:28.172801480 +0200
> +++ gcc/config/i386/i386.cc     2024-08-08 12:55:12.780696418 +0200
> @@ -18549,9 +18549,11 @@ ix86_fold_builtin (tree fndecl, int n_ar
>               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
> @@ -18560,7 +18562,7 @@ ix86_fold_builtin (tree fndecl, int n_ar
>                 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;
>
> @@ -18570,15 +18572,17 @@ ix86_fold_builtin (tree fndecl, int n_ar
>           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;
>
> --- gcc/testsuite/gcc.target/i386/bmi-pr116287.c.jj     2024-08-08 13:14:25.566827913 +0200
> +++ gcc/testsuite/gcc.target/i386/bmi-pr116287.c        2024-08-08 13:21:32.718312216 +0200
> @@ -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
> +}
> --- gcc/testsuite/gcc.target/i386/bmi2-pr116287.c.jj    2024-08-08 13:22:55.263246127 +0200
> +++ gcc/testsuite/gcc.target/i386/bmi2-pr116287.c       2024-08-08 13:30:44.851181267 +0200
> @@ -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
> +}
> --- gcc/testsuite/gcc.target/i386/tbm-pr116287.c.jj     2024-08-08 13:14:48.453532722 +0200
> +++ gcc/testsuite/gcc.target/i386/tbm-pr116287.c        2024-08-08 13:22:36.940482770 +0200
> @@ -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
> +}
>
>         Jakub
>
diff mbox series

Patch

--- gcc/config/i386/i386.cc.jj	2024-08-01 14:33:28.172801480 +0200
+++ gcc/config/i386/i386.cc	2024-08-08 12:55:12.780696418 +0200
@@ -18549,9 +18549,11 @@  ix86_fold_builtin (tree fndecl, int n_ar
 	      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
@@ -18560,7 +18562,7 @@  ix86_fold_builtin (tree fndecl, int n_ar
 		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;
 
@@ -18570,15 +18572,17 @@  ix86_fold_builtin (tree fndecl, int n_ar
 	  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;
 
--- gcc/testsuite/gcc.target/i386/bmi-pr116287.c.jj	2024-08-08 13:14:25.566827913 +0200
+++ gcc/testsuite/gcc.target/i386/bmi-pr116287.c	2024-08-08 13:21:32.718312216 +0200
@@ -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
+}
--- gcc/testsuite/gcc.target/i386/bmi2-pr116287.c.jj	2024-08-08 13:22:55.263246127 +0200
+++ gcc/testsuite/gcc.target/i386/bmi2-pr116287.c	2024-08-08 13:30:44.851181267 +0200
@@ -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
+}
--- gcc/testsuite/gcc.target/i386/tbm-pr116287.c.jj	2024-08-08 13:14:48.453532722 +0200
+++ gcc/testsuite/gcc.target/i386/tbm-pr116287.c	2024-08-08 13:22:36.940482770 +0200
@@ -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
+}