middle-end/106053 - fold_sign_changed_comparison and large bools
The following fixes a latent issue in the match.pd variant of fold_sign_changed_comparison which replaces an unsigned integer comparison with a signed boolean comparison of the same precision despite the fact that we treat BOOLEAN_TYPEs as only having two valid values. 2022-06-28 Richard Biener <rguenther@suse.de> PR middle-end/106053 * match.pd ((T)a == (T)b): Avoid folding away sign changes in a comparison if we'd truncate to a boolean. * gcc.target/i386/pr106053.c: New testcase.
This commit is contained in:
parent
6835baee71
commit
a3ca1fc5f4
2 changed files with 43 additions and 1 deletions
|
@ -5542,7 +5542,12 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
|
|||
&& (TYPE_UNSIGNED (TREE_TYPE (@00)) == TYPE_UNSIGNED (TREE_TYPE (@0))
|
||||
|| cmp == NE_EXPR
|
||||
|| cmp == EQ_EXPR)
|
||||
&& !POINTER_TYPE_P (TREE_TYPE (@00)))
|
||||
&& !POINTER_TYPE_P (TREE_TYPE (@00))
|
||||
/* (int)bool:32 != (int)uint is not the same as
|
||||
bool:32 != (bool:32)uint since boolean types only have two valid
|
||||
values independent of their precision. */
|
||||
&& (TREE_CODE (TREE_TYPE (@00)) != BOOLEAN_TYPE
|
||||
|| TREE_CODE (TREE_TYPE (@10)) == BOOLEAN_TYPE))
|
||||
/* ??? The special-casing of INTEGER_CST conversion was in the original
|
||||
code and here to avoid a spurious overflow flag on the resulting
|
||||
constant which fold_convert produces. */
|
||||
|
|
37
gcc/testsuite/gcc.target/i386/pr106053.c
Normal file
37
gcc/testsuite/gcc.target/i386/pr106053.c
Normal file
|
@ -0,0 +1,37 @@
|
|||
/* { dg-do run { target lp64 } } */
|
||||
/* { dg-options "-O -fno-tree-fre -w -mno-avx" } */
|
||||
|
||||
typedef unsigned __attribute__((__vector_size__ (32))) v256u8;
|
||||
typedef unsigned __attribute__((__vector_size__ (64))) v512u8;
|
||||
typedef unsigned short u16;
|
||||
typedef unsigned int u32;
|
||||
typedef unsigned long long u64;
|
||||
typedef unsigned long __attribute__((__vector_size__ (64))) v512u64;
|
||||
typedef unsigned __int128 __attribute__((__vector_size__ (32))) v256u128;
|
||||
unsigned u;
|
||||
v512u64 foo0_v512u64_0;
|
||||
|
||||
static inline v256u8
|
||||
foo (u32 u32_0, u64 u64_0, v256u128 v256u128_0)
|
||||
{
|
||||
int o = __builtin_add_overflow_p (u64_0, 0, 0);
|
||||
v512u64 v512u64_1 =
|
||||
foo0_v512u64_0 & (u32) __builtin_sub_overflow_p (0, o, 0);
|
||||
u64_0 |= u;
|
||||
v256u128 v256u128_2 = u64_0 < v256u128_0;
|
||||
v256u128 v256u128_3 = -v256u128_2 == u64_0 * u32_0;
|
||||
v256u8 v256u8_r = ((union {
|
||||
v512u8 a; v256u8 b[2];
|
||||
}) (v512u8) v512u64_1).b[0] + (v256u8) v256u128_3;
|
||||
return v256u8_r;
|
||||
}
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
v256u8 x = foo (3095179400, 23725760132, (v256u128) { 2, 2 });
|
||||
for (unsigned i = 0; i < sizeof (x) / sizeof (x[0]); i++)
|
||||
if (x[i])
|
||||
__builtin_abort ();
|
||||
return 0;
|
||||
}
|
Loading…
Add table
Reference in a new issue