diff options
author | Andrew Pinski <apinski@marvell.com> | 2023-08-02 15:54:20 -0700 |
---|---|---|
committer | Andrew Pinski <apinski@marvell.com> | 2023-08-02 19:32:04 -0700 |
commit | ff36932e4d6638e475d5c343c3032728f9925d3f (patch) | |
tree | edecd8aae1d6d6fd5d8e88777ee3d07bf67004fd | |
parent | 1b53748c61a8b6489ca9a56a25037131335d3cc6 (diff) | |
download | gcc-ff36932e4d6638e475d5c343c3032728f9925d3f.zip gcc-ff36932e4d6638e475d5c343c3032728f9925d3f.tar.gz gcc-ff36932e4d6638e475d5c343c3032728f9925d3f.tar.bz2 |
Fix `~X & X` and `~X | X` patterns
As Jakub noticed in https://gcc.gnu.org/pipermail/gcc-patches/2023-August/626039.html
what I did was not totally correct because sometimes chosing the wrong type.
So to get back to what the original code but keeping around the use of bitwise_inverted_equal_p,
we just need to check if the types of the two catupures are the same type.
Also adds a testcase for the problem Jakub found.
Committed as obvious after a bootstrap and test.
gcc/ChangeLog:
* match.pd (`~X & X`): Check that the types match.
(`~x | x`, `~x ^ x`): Likewise.
gcc/testsuite/ChangeLog:
* gcc.c-torture/execute/20230802-1.c: New test.
-rw-r--r-- | gcc/match.pd | 6 | ||||
-rw-r--r-- | gcc/testsuite/gcc.c-torture/execute/20230802-1.c | 68 |
2 files changed, 72 insertions, 2 deletions
diff --git a/gcc/match.pd b/gcc/match.pd index c62f205..53e622b 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -1158,7 +1158,8 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) /* Simplify ~X & X as zero. */ (simplify (bit_and (convert? @0) (convert? @1)) - (if (bitwise_inverted_equal_p (@0, @1)) + (if (types_match (TREE_TYPE (@0), TREE_TYPE (@1)) + && bitwise_inverted_equal_p (@0, @1)) { build_zero_cst (type); })) /* PR71636: Transform x & ((1U << b) - 1) -> x & ~(~0U << b); */ @@ -1397,7 +1398,8 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (for op (bit_ior bit_xor) (simplify (op (convert? @0) (convert? @1)) - (if (bitwise_inverted_equal_p (@0, @1)) + (if (types_match (TREE_TYPE (@0), TREE_TYPE (@1)) + && bitwise_inverted_equal_p (@0, @1)) (convert { build_all_ones_cst (TREE_TYPE (@0)); })))) /* x ^ x -> 0 */ diff --git a/gcc/testsuite/gcc.c-torture/execute/20230802-1.c b/gcc/testsuite/gcc.c-torture/execute/20230802-1.c new file mode 100644 index 0000000..8802ffa --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/20230802-1.c @@ -0,0 +1,68 @@ +/* We used to simplify these incorrectly. */ +__attribute__((noipa)) +long long +foo (unsigned int x) +{ + int y = x; + y = ~y; + return ((long long) x) & y; +} + +__attribute__((noipa)) +long long +foo_v (volatile unsigned int x) +{ + volatile int y = x; + y = ~y; + return ((long long) x) & y; +} + +__attribute__((noipa)) +long long +bar (unsigned int x) +{ + int y = x; + y = ~y; + return ((long long) x) ^ y; +} + +__attribute__((noipa)) +long long +bar_v (volatile unsigned int x) +{ + volatile int y = x; + y = ~y; + return ((long long) x) ^ y; +} + +__attribute__((noipa)) +long long +baz (unsigned int x) +{ + int y = x; + y = ~y; + return y ^ ((long long) x); +} + +__attribute__((noipa)) +long long +baz_v (volatile unsigned int x) +{ + volatile int y = x; + y = ~y; + return y ^ ((long long) x); +} + + +int main() +{ + for(int t = -1; t <= 1; t++) + { + if (foo(t) != foo_v(t)) + __builtin_abort (); + if (bar(t) != bar_v(t)) + __builtin_abort (); + if (baz(t) != baz_v(t)) + __builtin_abort (); + } +} |