re PR tree-optimization/93098 (ICE with negative shifter)
PR tree-optimization/93098 * match.pd (popcount): For shift amounts, use integer_onep or wi::to_widest () == cst instead of tree_to_uhwi () == cst tests. Make sure that precision is power of two larger than or equal to 16. Ensure shift is never negative. Use HOST_WIDE_INT_UC macro instead of ULL suffixed constants. Formatting fixes. * gcc.c-torture/compile/pr93098.c: New test. From-SVN: r279809
This commit is contained in:
parent
b3b13bf186
commit
2efa10d528
37056
gcc/ChangeLog
37056
gcc/ChangeLog
File diff suppressed because it is too large
Load Diff
37052
gcc/ChangeLog-2019
Normal file
37052
gcc/ChangeLog-2019
Normal file
File diff suppressed because it is too large
Load Diff
79
gcc/match.pd
79
gcc/match.pd
@ -5786,43 +5786,50 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
|
||||
return (x * 0x01010101) >> 24;
|
||||
} */
|
||||
(simplify
|
||||
(rshift
|
||||
(mult
|
||||
(bit_and
|
||||
(plus:c
|
||||
(rshift @8 INTEGER_CST@5)
|
||||
(plus:c@8
|
||||
(bit_and @6 INTEGER_CST@7)
|
||||
(bit_and
|
||||
(rshift
|
||||
(minus@6
|
||||
@0
|
||||
(bit_and
|
||||
(rshift @0 INTEGER_CST@4)
|
||||
INTEGER_CST@11))
|
||||
INTEGER_CST@10)
|
||||
INTEGER_CST@9)))
|
||||
INTEGER_CST@3)
|
||||
INTEGER_CST@2)
|
||||
INTEGER_CST@1)
|
||||
(rshift
|
||||
(mult
|
||||
(bit_and
|
||||
(plus:c
|
||||
(rshift @8 INTEGER_CST@5)
|
||||
(plus:c@8
|
||||
(bit_and @6 INTEGER_CST@7)
|
||||
(bit_and
|
||||
(rshift
|
||||
(minus@6 @0
|
||||
(bit_and (rshift @0 INTEGER_CST@4) INTEGER_CST@11))
|
||||
INTEGER_CST@10)
|
||||
INTEGER_CST@9)))
|
||||
INTEGER_CST@3)
|
||||
INTEGER_CST@2)
|
||||
INTEGER_CST@1)
|
||||
/* Check constants and optab. */
|
||||
(with
|
||||
{
|
||||
unsigned prec = TYPE_PRECISION (type);
|
||||
int shift = 64 - prec;
|
||||
const unsigned HOST_WIDE_INT c1 = 0x0101010101010101ULL >> shift,
|
||||
c2 = 0x0F0F0F0F0F0F0F0FULL >> shift,
|
||||
c3 = 0x3333333333333333ULL >> shift,
|
||||
c4 = 0x5555555555555555ULL >> shift;
|
||||
}
|
||||
(if (prec <= 64 && TYPE_UNSIGNED (type) && tree_to_uhwi (@4) == 1
|
||||
&& tree_to_uhwi (@10) == 2 && tree_to_uhwi (@5) == 4
|
||||
&& tree_to_uhwi (@1) == prec - 8 && tree_to_uhwi (@2) == c1
|
||||
&& tree_to_uhwi (@3) == c2 && tree_to_uhwi (@9) == c3
|
||||
&& tree_to_uhwi (@7) == c3 && tree_to_uhwi (@11) == c4
|
||||
&& direct_internal_fn_supported_p (IFN_POPCOUNT, type,
|
||||
OPTIMIZE_FOR_BOTH))
|
||||
(convert (IFN_POPCOUNT:type @0)))))
|
||||
(with { unsigned prec = TYPE_PRECISION (type);
|
||||
int shift = (64 - prec) & 63;
|
||||
unsigned HOST_WIDE_INT c1
|
||||
= HOST_WIDE_INT_UC (0x0101010101010101) >> shift;
|
||||
unsigned HOST_WIDE_INT c2
|
||||
= HOST_WIDE_INT_UC (0x0F0F0F0F0F0F0F0F) >> shift;
|
||||
unsigned HOST_WIDE_INT c3
|
||||
= HOST_WIDE_INT_UC (0x3333333333333333) >> shift;
|
||||
unsigned HOST_WIDE_INT c4
|
||||
= HOST_WIDE_INT_UC (0x5555555555555555) >> shift;
|
||||
}
|
||||
(if (prec >= 16
|
||||
&& prec <= 64
|
||||
&& pow2p_hwi (prec)
|
||||
&& TYPE_UNSIGNED (type)
|
||||
&& integer_onep (@4)
|
||||
&& wi::to_widest (@10) == 2
|
||||
&& wi::to_widest (@5) == 4
|
||||
&& wi::to_widest (@1) == prec - 8
|
||||
&& tree_to_uhwi (@2) == c1
|
||||
&& tree_to_uhwi (@3) == c2
|
||||
&& tree_to_uhwi (@9) == c3
|
||||
&& tree_to_uhwi (@7) == c3
|
||||
&& tree_to_uhwi (@11) == c4
|
||||
&& direct_internal_fn_supported_p (IFN_POPCOUNT, type,
|
||||
OPTIMIZE_FOR_BOTH))
|
||||
(convert (IFN_POPCOUNT:type @0)))))
|
||||
#endif
|
||||
|
||||
/* Simplify:
|
||||
|
19185
gcc/testsuite/ChangeLog
19185
gcc/testsuite/ChangeLog
File diff suppressed because it is too large
Load Diff
19187
gcc/testsuite/ChangeLog-2019
Normal file
19187
gcc/testsuite/ChangeLog-2019
Normal file
File diff suppressed because it is too large
Load Diff
37
gcc/testsuite/gcc.c-torture/compile/pr93098.c
Normal file
37
gcc/testsuite/gcc.c-torture/compile/pr93098.c
Normal file
@ -0,0 +1,37 @@
|
||||
/* PR tree-optimization/93098 */
|
||||
|
||||
int
|
||||
foo (unsigned long long x)
|
||||
{
|
||||
x -= (x >> -1) & 0x5555555555555555ULL;
|
||||
x = (x & 0x3333333333333333ULL) + ((x >> 2) & 0x3333333333333333ULL);
|
||||
x = (x + (x >> 4)) & 0x0f0f0f0f0f0f0f0fULL;
|
||||
return (x * 0x0101010101010101ULL) >> 56;
|
||||
}
|
||||
|
||||
int
|
||||
bar (unsigned long long x)
|
||||
{
|
||||
x -= (x >> 1) & 0x5555555555555555ULL;
|
||||
x = (x & 0x3333333333333333ULL) + ((x >> -2) & 0x3333333333333333ULL);
|
||||
x = (x + (x >> 4)) & 0x0f0f0f0f0f0f0f0fULL;
|
||||
return (x * 0x0101010101010101ULL) >> 56;
|
||||
}
|
||||
|
||||
int
|
||||
baz (unsigned long long x)
|
||||
{
|
||||
x -= (x >> 1) & 0x5555555555555555ULL;
|
||||
x = (x & 0x3333333333333333ULL) + ((x >> 2) & 0x3333333333333333ULL);
|
||||
x = (x + (x >> -4)) & 0x0f0f0f0f0f0f0f0fULL;
|
||||
return (x * 0x0101010101010101ULL) >> 56;
|
||||
}
|
||||
|
||||
int
|
||||
qux (unsigned long long x)
|
||||
{
|
||||
x -= (x >> 1) & 0x5555555555555555ULL;
|
||||
x = (x & 0x3333333333333333ULL) + ((x >> 2) & 0x3333333333333333ULL);
|
||||
x = (x + (x >> 4)) & 0x0f0f0f0f0f0f0f0fULL;
|
||||
return (x * 0x0101010101010101ULL) >> -56;
|
||||
}
|
Loading…
Reference in New Issue
Block a user