Skip to content
Snippets Groups Projects
Commit 6e7088db authored by Jakub Jelinek's avatar Jakub Jelinek Committed by Jakub Jelinek
Browse files

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.
parent b5a09a68
No related branches found
No related tags found
No related merge requests found
......@@ -18549,9 +18549,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
......@@ -18560,7 +18562,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;
 
......@@ -18570,15 +18572,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;
 
......
/* 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
}
/* 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
}
/* 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
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment