Skip to content

Commit 2cc729c

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. (cherry picked from commit 6e7088d)
1 parent f4269a9 commit 2cc729c

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
@@ -17937,9 +17937,11 @@ ix86_fold_builtin (tree fndecl, int n_args,
1793717937
unsigned int prec = TYPE_PRECISION (TREE_TYPE (args[0]));
1793817938
unsigned int start = tree_to_uhwi (args[1]);
1793917939
unsigned int len = (start & 0xff00) >> 8;
17940+
tree lhs_type = TREE_TYPE (TREE_TYPE (fndecl));
1794017941
start &= 0xff;
1794117942
if (start >= prec || len == 0)
17942-
res = 0;
17943+
return omit_one_operand (lhs_type, build_zero_cst (lhs_type),
17944+
args[0]);
1794317945
else if (!tree_fits_uhwi_p (args[0]))
1794417946
break;
1794517947
else
@@ -17948,7 +17950,7 @@ ix86_fold_builtin (tree fndecl, int n_args,
1794817950
len = prec;
1794917951
if (len < HOST_BITS_PER_WIDE_INT)
1795017952
res &= (HOST_WIDE_INT_1U << len) - 1;
17951-
return build_int_cstu (TREE_TYPE (TREE_TYPE (fndecl)), res);
17953+
return build_int_cstu (lhs_type, res);
1795217954
}
1795317955
break;
1795417956

@@ -17958,15 +17960,17 @@ ix86_fold_builtin (tree fndecl, int n_args,
1795817960
if (tree_fits_uhwi_p (args[1]))
1795917961
{
1796017962
unsigned int idx = tree_to_uhwi (args[1]) & 0xff;
17963+
tree lhs_type = TREE_TYPE (TREE_TYPE (fndecl));
1796117964
if (idx >= TYPE_PRECISION (TREE_TYPE (args[0])))
1796217965
return args[0];
1796317966
if (idx == 0)
17964-
return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), 0);
17967+
return omit_one_operand (lhs_type, build_zero_cst (lhs_type),
17968+
args[0]);
1796517969
if (!tree_fits_uhwi_p (args[0]))
1796617970
break;
1796717971
unsigned HOST_WIDE_INT res = tree_to_uhwi (args[0]);
1796817972
res &= ~(HOST_WIDE_INT_M1U << idx);
17969-
return build_int_cstu (TREE_TYPE (TREE_TYPE (fndecl)), res);
17973+
return build_int_cstu (lhs_type, res);
1797017974
}
1797117975
break;
1797217976

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)