Skip to content

Commit 6e7088d

Browse files
committed
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 <[email protected]> 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.
1 parent b5a09a6 commit 6e7088d

File tree

4 files changed

+89
-4
lines changed

4 files changed

+89
-4
lines changed

gcc/config/i386/i386.cc

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18549,9 +18549,11 @@ ix86_fold_builtin (tree fndecl, int n_args,
1854918549
unsigned int prec = TYPE_PRECISION (TREE_TYPE (args[0]));
1855018550
unsigned int start = tree_to_uhwi (args[1]);
1855118551
unsigned int len = (start & 0xff00) >> 8;
18552+
tree lhs_type = TREE_TYPE (TREE_TYPE (fndecl));
1855218553
start &= 0xff;
1855318554
if (start >= prec || len == 0)
18554-
res = 0;
18555+
return omit_one_operand (lhs_type, build_zero_cst (lhs_type),
18556+
args[0]);
1855518557
else if (!tree_fits_uhwi_p (args[0]))
1855618558
break;
1855718559
else
@@ -18560,7 +18562,7 @@ ix86_fold_builtin (tree fndecl, int n_args,
1856018562
len = prec;
1856118563
if (len < HOST_BITS_PER_WIDE_INT)
1856218564
res &= (HOST_WIDE_INT_1U << len) - 1;
18563-
return build_int_cstu (TREE_TYPE (TREE_TYPE (fndecl)), res);
18565+
return build_int_cstu (lhs_type, res);
1856418566
}
1856518567
break;
1856618568

@@ -18570,15 +18572,17 @@ ix86_fold_builtin (tree fndecl, int n_args,
1857018572
if (tree_fits_uhwi_p (args[1]))
1857118573
{
1857218574
unsigned int idx = tree_to_uhwi (args[1]) & 0xff;
18575+
tree lhs_type = TREE_TYPE (TREE_TYPE (fndecl));
1857318576
if (idx >= TYPE_PRECISION (TREE_TYPE (args[0])))
1857418577
return args[0];
1857518578
if (idx == 0)
18576-
return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), 0);
18579+
return omit_one_operand (lhs_type, build_zero_cst (lhs_type),
18580+
args[0]);
1857718581
if (!tree_fits_uhwi_p (args[0]))
1857818582
break;
1857918583
unsigned HOST_WIDE_INT res = tree_to_uhwi (args[0]);
1858018584
res &= ~(HOST_WIDE_INT_M1U << idx);
18581-
return build_int_cstu (TREE_TYPE (TREE_TYPE (fndecl)), res);
18585+
return build_int_cstu (lhs_type, res);
1858218586
}
1858318587
break;
1858418588

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/* PR target/116287 */
2+
/* { dg-do run { target bmi } } */
3+
/* { dg-options "-O2 -mbmi" } */
4+
5+
#include <x86intrin.h>
6+
7+
#include "bmi-check.h"
8+
9+
static void
10+
bmi_test ()
11+
{
12+
unsigned int a = 0;
13+
if (__builtin_ia32_bextr_u32 (a++, 0) != 0)
14+
abort ();
15+
if (__builtin_ia32_bextr_u32 (a++, 0x120) != 0)
16+
abort ();
17+
if (a != 2)
18+
abort ();
19+
#ifdef __x86_64__
20+
unsigned long long b = 0;
21+
if (__builtin_ia32_bextr_u64 (b++, 0) != 0)
22+
abort ();
23+
if (__builtin_ia32_bextr_u64 (b++, 0x140) != 0)
24+
abort ();
25+
if (b != 2)
26+
abort ();
27+
#endif
28+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/* PR target/116287 */
2+
/* { dg-do run { target bmi2 } } */
3+
/* { dg-options "-O2 -mbmi2" } */
4+
5+
#include <x86intrin.h>
6+
7+
#include "bmi2-check.h"
8+
9+
static void
10+
bmi2_test ()
11+
{
12+
unsigned int a = 0;
13+
if (__builtin_ia32_bzhi_si (a++, 0) != 0)
14+
abort ();
15+
if (a != 1)
16+
abort ();
17+
#ifdef __x86_64__
18+
unsigned long long b = 0;
19+
if (__builtin_ia32_bzhi_di (b++, 0) != 0)
20+
abort ();
21+
if (b != 1)
22+
abort ();
23+
#endif
24+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/* PR target/116287 */
2+
/* { dg-do compile } */
3+
/* { dg-options "-O2 -mtbm -fdump-tree-optimized" } */
4+
/* { dg-final { scan-tree-dump-not "link_error \\\(\\\);" "optimized" } } */
5+
6+
#include <x86intrin.h>
7+
8+
extern void link_error (void);
9+
10+
void
11+
tbm_test ()
12+
{
13+
unsigned int a = 0;
14+
if (__builtin_ia32_bextri_u32 (a++, 0) != 0)
15+
link_error ();
16+
if (__builtin_ia32_bextri_u32 (a++, 0x120) != 0)
17+
link_error ();
18+
if (a != 2)
19+
link_error ();
20+
#ifdef __x86_64__
21+
unsigned long long b = 0;
22+
if (__builtin_ia32_bextr_u64 (b++, 0) != 0)
23+
link_error ();
24+
if (__builtin_ia32_bextr_u64 (b++, 0x140) != 0)
25+
link_error ();
26+
if (b != 2)
27+
link_error ();
28+
#endif
29+
}

0 commit comments

Comments
 (0)