[Bug rtl-optimization/66552] Missed optimization when shift amount is result of signed modulus
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66552 Jiu Fu Guo changed: What|Removed |Added Status|NEW |RESOLVED CC||guojiufu at gcc dot gnu.org Resolution|--- |FIXED --- Comment #16 from Jiu Fu Guo --- Just confirmed the fix is ready in the trunk.
[Bug rtl-optimization/66552] Missed optimization when shift amount is result of signed modulus
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66552 --- Comment #15 from CVS Commits --- The master branch has been updated by Jiu Fu Guo : https://gcc.gnu.org/g:222f312a773157f53396ba4cb287deb07f84cc34 commit r11-4033-g222f312a773157f53396ba4cb287deb07f84cc34 Author: guojiufu Date: Mon Oct 19 13:48:19 2020 +0800 [PATCH] fold x << (n % C) to x << (n & C-1) if C meets power2 This patch fixes PR66552 which is also as: https://gcc.gnu.org/pipermail/gcc-patches/2020-February/540930.html which requests to optimizes (x shift (n mod C)) to (x shift (n bit_and (C - 1))) when C is a constant and power of two. gcc/ChangeLog 2020-10-19 Li Jia He PR tree-optimization/66552 * match.pd (x << (n % C) -> x << (n & C-1)): New simplification. gcc/testsuite/ChangeLog 2020-10-19 Li Jia He PR tree-optimization/66552 * gcc.dg/pr66552.c: New testcase.
[Bug rtl-optimization/66552] Missed optimization when shift amount is result of signed modulus
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66552 Jakub Jelinek changed: What|Removed |Added CC||jakub at gcc dot gnu.org --- Comment #14 from Jakub Jelinek --- (In reply to Andrew Pinski from comment #8) > Some typos: > (simplify > (rshift @0 (mod @1 integer_pow2p@2)) > (rshift @0 (bit_and @1 (minus @2 { build_int_cst (TREE_TYPE (@2), 1); } > > This would be under the for: > (for mod (ceil_mod floor_mod round_mod trunc_mod) It should be also (for shift (lshift rshift) and use shift instead of rshift, because it applies to left shifts equally. Maube for rotates too, dunno if we consider the negative or out of bounds amounts UB or not for those, I bet they could be matched from expressions where it would be UB or where it wouldn't. Certainly if the @2 is the precision of the rotated value, it would be ok anyway (even if we don't consider int32 r>> -1 UB, it will still be the same thing as int32 r>> 31 (-1 & 31).
[Bug rtl-optimization/66552] Missed optimization when shift amount is result of signed modulus
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66552 --- Comment #13 from Li Jia He --- In this optimization we assume n is either positive or divisible by the nth power of 2. So the result of the % is non-negative. However, it is not reasonable for translating (a % 32)) to (a & 31). If a is signed int and value is -1, (a % 32) will get the follow result, (a % 32) = (-1 % 32) = -1. However, (a & 31) will get the follow result, (a & 31) = -1 & 31 = 31. This conversion is not reasonable at this time.
[Bug rtl-optimization/66552] Missed optimization when shift amount is result of signed modulus
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66552 --- Comment #12 from Segher Boessenkool --- Sure, but what makes shift amount special here? This works just fine in any other expression as well. That is, for unsigned n; for negative numbers modulo works differently: it returns 0 or negative, so it is either UB, or the masking works as expected. Is there not a better way to express that?
[Bug rtl-optimization/66552] Missed optimization when shift amount is result of signed modulus
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66552 --- Comment #11 from Li Jia He --- The reason is that it is the remainder of the nth power of 2. In x >> (n% 32), 32 is the fifth power of 2. The hexadecimal representation of 32 is 0x100. Taking the remainder of 0x100, the data range is 0 ~ 0xff. And the result is the same as x >> (n & 0xff).
[Bug rtl-optimization/66552] Missed optimization when shift amount is result of signed modulus
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66552 --- Comment #10 from Segher Boessenkool --- What makes shift amount special at all, for those gimple simplifications?
[Bug rtl-optimization/66552] Missed optimization when shift amount is result of signed modulus
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66552 --- Comment #9 from Li Jia He --- (In reply to Andrew Pinski from comment #8) > (In reply to Andrew Pinski from comment #7) > > (In reply to Andrew Pinski from comment #6) > > > (In reply to Li Jia He from comment #5) > > > > Could we consider doing this optimization on gimple? I use the following > > > > code on gimple to produce optimized results on powerpc64. > > > > > > It might make sense. But fold-const.c might not be the correct location; > > > match.pd might be a better place for it. > > > > Something like: > > (simplify > > (rshift @0 (mod @1 integer_pow2p@2)) > > (rshift @0 (bit_and @1 (minus @1 { build_int_cst (TREE_TYPE (@1), 1); } > > Some typos: > (simplify > (rshift @0 (mod @1 integer_pow2p@2)) > (rshift @0 (bit_and @1 (minus @2 { build_int_cst (TREE_TYPE (@2), 1); } > > This would be under the for: > (for mod (ceil_mod floor_mod round_mod trunc_mod) Thank you for your suggestions. Let's try it on gcc11 stage1 ^ _ ^.
[Bug rtl-optimization/66552] Missed optimization when shift amount is result of signed modulus
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66552 --- Comment #8 from Andrew Pinski --- (In reply to Andrew Pinski from comment #7) > (In reply to Andrew Pinski from comment #6) > > (In reply to Li Jia He from comment #5) > > > Could we consider doing this optimization on gimple? I use the following > > > code on gimple to produce optimized results on powerpc64. > > > > It might make sense. But fold-const.c might not be the correct location; > > match.pd might be a better place for it. > > Something like: > (simplify > (rshift @0 (mod @1 integer_pow2p@2)) > (rshift @0 (bit_and @1 (minus @1 { build_int_cst (TREE_TYPE (@1), 1); } Some typos: (simplify (rshift @0 (mod @1 integer_pow2p@2)) (rshift @0 (bit_and @1 (minus @2 { build_int_cst (TREE_TYPE (@2), 1); } This would be under the for: (for mod (ceil_mod floor_mod round_mod trunc_mod)
[Bug rtl-optimization/66552] Missed optimization when shift amount is result of signed modulus
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66552 --- Comment #7 from Andrew Pinski --- (In reply to Andrew Pinski from comment #6) > (In reply to Li Jia He from comment #5) > > Could we consider doing this optimization on gimple? I use the following > > code on gimple to produce optimized results on powerpc64. > > It might make sense. But fold-const.c might not be the correct location; > match.pd might be a better place for it. Something like: (simplify (rshift @0 (mod @1 integer_pow2p@2)) (rshift @0 (bit_and @1 (minus @1 { build_int_cst (TREE_TYPE (@1), 1); }
[Bug rtl-optimization/66552] Missed optimization when shift amount is result of signed modulus
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66552 --- Comment #6 from Andrew Pinski --- (In reply to Li Jia He from comment #5) > Could we consider doing this optimization on gimple? I use the following > code on gimple to produce optimized results on powerpc64. It might make sense. But fold-const.c might not be the correct location; match.pd might be a better place for it.
[Bug rtl-optimization/66552] Missed optimization when shift amount is result of signed modulus
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66552 Li Jia He changed: What|Removed |Added CC||helijia at gcc dot gnu.org --- Comment #5 from Li Jia He --- Could we consider doing this optimization on gimple? I use the following code on gimple to produce optimized results on powerpc64. diff --git a/gcc/fold-const.c b/gcc/fold-const.c index aefa91666e2..a40681b271f 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -11131,7 +11131,6 @@ fold_binary_loc (location_t loc, enum tree_code code, tree type, WARN_STRICT_OVERFLOW_MISC); return fold_convert_loc (loc, type, tem); } - return NULL_TREE; case CEIL_MOD_EXPR: @@ -11191,6 +11190,22 @@ fold_binary_loc (location_t loc, enum tree_code code, tree type, prec) == 0) return fold_convert_loc (loc, type, TREE_OPERAND (arg0, 0)); + if (code == RSHIFT_EXPR + && (TREE_CODE (arg1) == CEIL_MOD_EXPR + || TREE_CODE (arg1) == FLOOR_MOD_EXPR + || TREE_CODE (arg1) == ROUND_MOD_EXPR + || TREE_CODE (arg1) == TRUNC_MOD_EXPR) + && TREE_CODE (TREE_OPERAND (arg1, 1)) == INTEGER_CST + && integer_pow2p (TREE_OPERAND (arg1, 1))) +{ + tree arg10 = TREE_OPERAND (arg1, 0); + tree arg11 = TREE_OPERAND (arg1, 1); + return fold_build2_loc (loc, code, type, arg0, + fold_build2_loc (loc, BIT_AND_EXPR, TREE_TYPE(arg10), arg10, +fold_build2_loc (loc, MINUS_EXPR, TREE_TYPE(arg11), arg11, + build_one_cst(TREE_TYPE(arg11); +} + return NULL_TREE; case MIN_EXPR:
[Bug rtl-optimization/66552] Missed optimization when shift amount is result of signed modulus
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66552 --- Comment #4 from Segher Boessenkool --- Trunk does (both -m32 and -m64) srawi 9,4,5 addze 9,9 slwi 9,9,5 subf 4,9,4 srw 3,3,4 and rlwinm 4,4,0,27,31 srw 3,3,4 so the original problem is still there.
[Bug rtl-optimization/66552] Missed optimization when shift amount is result of signed modulus
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66552 --- Comment #3 from Martin Sebor msebor at gcc dot gnu.org --- (In reply to Segher Boessenkool from comment #2) I opened bug 66706.
[Bug rtl-optimization/66552] Missed optimization when shift amount is result of signed modulus
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66552 Segher Boessenkool segher at gcc dot gnu.org changed: What|Removed |Added Status|UNCONFIRMED |NEW Last reconfirmed||2015-06-30 CC||segher at gcc dot gnu.org Ever confirmed|0 |1 --- Comment #2 from Segher Boessenkool segher at gcc dot gnu.org --- Please file a separate bug for that last problem (it seems to be a combine problem; it has nothing to do with PR66217). You can assign it to me if you want. Confirmed, btw.