[gcc r15-6253] warn-access: Fix up matching_alloc_calls_p [PR118024]
https://gcc.gnu.org/g:9537ca5ad9bc23d7e9c446b4a7cbb98f63bddb6a commit r15-6253-g9537ca5ad9bc23d7e9c446b4a7cbb98f63bddb6a Author: Jakub Jelinek Date: Sat Dec 14 11:27:20 2024 +0100 warn-access: Fix up matching_alloc_calls_p [PR118024] The following testcase ICEs because of a bug in matching_alloc_calls_p. The loop was apparently meant to be walking the two attribute chains in lock-step, but doesn't really do that. If the first lookup_attribute returns non-NULL, the second one is not done, so rmats in that case can be some random unrelated attribute rather than "malloc" attribute; the body assumes even rmats if non-NULL is "malloc" attribute and relies on its argument to be a "malloc" argument and if it is some other attribute with incompatible attribute, it just crashes. Now, fixing that in the obvious way, instead of doing (amats = lookup_attribute ("malloc", amats)) || (rmats = lookup_attribute ("malloc", rmats)) in the condition do ((amats = lookup_attribute ("malloc", amats)), (rmats = lookup_attribute ("malloc", rmats)), (amats || rmats)) fixes the testcase but regresses Wmismatched-dealloc-{2,3}.c tests. The problem is that walking the attribute lists in a lock-step is obviously a very bad idea, there is no requirement that the same deallocators are present in the same order on both decls, e.g. there could be an extra malloc attribute without argument in just one of the lists, or the order of say free/realloc could be swapped, etc. We don't generally document nor enforce any particular ordering of attributes (even when for some attributes we just handle the first one rather than all). So, this patch instead simply splits it into two loops, the first one walks alloc_decl attributes, the second one walks dealloc_decl attributes. If the malloc attribute argument is a built-in, that doesn't change anything, and otherwise we have the chance to populate the whole common_deallocs hash_set in the first loop and then can check it in the second one (and don't need to use more expensive add method on it, can just check contains there). Not to mention that it also fixes the case when the function would incorrectly return true if there wasn't a common deallocator between the two, but dealloc_decl had 2 malloc attributes with the same deallocator. 2024-12-14 Jakub Jelinek PR middle-end/118024 * gimple-ssa-warn-access.cc (matching_alloc_calls_p): Walk malloc attributes of alloc_decl and dealloc_decl in separate loops rather than in lock-step. Use common_deallocs.contains rather than common_deallocs.add in the second loop. * gcc.dg/pr118024.c: New test. Diff: --- gcc/gimple-ssa-warn-access.cc | 85 - gcc/testsuite/gcc.dg/pr118024.c | 15 2 files changed, 56 insertions(+), 44 deletions(-) diff --git a/gcc/gimple-ssa-warn-access.cc b/gcc/gimple-ssa-warn-access.cc index 12c9ddb292dd..820f23825254 100644 --- a/gcc/gimple-ssa-warn-access.cc +++ b/gcc/gimple-ssa-warn-access.cc @@ -1935,52 +1935,49 @@ matching_alloc_calls_p (tree alloc_decl, tree dealloc_decl) headers. With AMATS set to the Allocator's Malloc ATtributes, and RMATS set to Reallocator's Malloc ATtributes... */ - for (tree amats = DECL_ATTRIBUTES (alloc_decl), -rmats = DECL_ATTRIBUTES (dealloc_decl); - (amats = lookup_attribute ("malloc", amats)) -|| (rmats = lookup_attribute ("malloc", rmats)); - amats = amats ? TREE_CHAIN (amats) : NULL_TREE, -rmats = rmats ? TREE_CHAIN (rmats) : NULL_TREE) -{ - if (tree args = amats ? TREE_VALUE (amats) : NULL_TREE) - if (tree adealloc = TREE_VALUE (args)) - { - if (DECL_P (adealloc) - && fndecl_built_in_p (adealloc, BUILT_IN_NORMAL)) - { - built_in_function fncode = DECL_FUNCTION_CODE (adealloc); - if (fncode == BUILT_IN_FREE || fncode == BUILT_IN_REALLOC) - { - if (realloc_kind == alloc_kind_t::builtin) - return true; - alloc_dealloc_kind = alloc_kind_t::builtin; - } - continue; - } - - common_deallocs.add (adealloc); - } + for (tree amats = DECL_ATTRIBUTES (alloc_decl); + (amats = lookup_attribute ("malloc", amats)); + amats = amats ? TREE_CHAIN (amats) : NULL_TREE) +if (tree args = amats ? TREE_VALUE (amats) : NULL_TREE) + if (tree adealloc = TREE_VALUE (args)) + { + if (DECL_P (adealloc) + && fndecl_built_in_p (adealloc, BUILT_IN_NORMAL)) + { + built_in_function fncode = DECL_FUNCTION_CODE (adealloc); + if (fncode == BUILT_IN_FREE || fncode == BUILT_IN_REALLOC)
[gcc r15-6254] gimple-fold: Fix the recent ifcombine optimization for _BitInt [PR118023]
https://gcc.gnu.org/g:7f4e85a954d24cc30bf85f4040fcd204bd5e23fd commit r15-6254-g7f4e85a954d24cc30bf85f4040fcd204bd5e23fd Author: Jakub Jelinek Date: Sat Dec 14 11:28:25 2024 +0100 gimple-fold: Fix the recent ifcombine optimization for _BitInt [PR118023] The BIT_FIELD_REF verifier has: if (INTEGRAL_TYPE_P (TREE_TYPE (op)) && !type_has_mode_precision_p (TREE_TYPE (op))) { error ("%qs of non-mode-precision operand", code_name); return true; } check among other things, so one can't extract something out of say _BitInt(63) or _BitInt(4096). The new ifcombine optimization happily creates such BIT_FIELD_REFs and ICEs during their verification. The following patch fixes that by rejecting those in decode_field_reference. 2024-12-14 Jakub Jelinek PR tree-optimization/118023 * gimple-fold.cc (decode_field_reference): Return NULL_TREE if inner has non-type_has_mode_precision_p integral type. * gcc.dg/bitint-119.c: New test. Diff: --- gcc/gimple-fold.cc| 4 +++- gcc/testsuite/gcc.dg/bitint-119.c | 11 +++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/gcc/gimple-fold.cc b/gcc/gimple-fold.cc index e1b4b65dd662..6c11654a2c65 100644 --- a/gcc/gimple-fold.cc +++ b/gcc/gimple-fold.cc @@ -7643,7 +7643,9 @@ decode_field_reference (tree *pexp, HOST_WIDE_INT *pbitsize, /* Reject out-of-bound accesses (PR79731). */ || (! AGGREGATE_TYPE_P (TREE_TYPE (inner)) && compare_tree_int (TYPE_SIZE (TREE_TYPE (inner)), - bp + bs) < 0)) + bp + bs) < 0) + || (INTEGRAL_TYPE_P (TREE_TYPE (inner)) + && !type_has_mode_precision_p (TREE_TYPE (inner return NULL_TREE; *pbitsize = bs; diff --git a/gcc/testsuite/gcc.dg/bitint-119.c b/gcc/testsuite/gcc.dg/bitint-119.c new file mode 100644 index ..8283d50b3a68 --- /dev/null +++ b/gcc/testsuite/gcc.dg/bitint-119.c @@ -0,0 +1,11 @@ +/* PR tree-optimization/118023 */ +/* { dg-do compile { target bitint } } */ +/* { dg-options "-O2" } */ + +_BitInt(63) b; + +int +foo (void) +{ + return !*(_Complex char *) &b; +}
[gcc r15-6255] doc: Fix typos for --enable-host-pie docs in install.texi
https://gcc.gnu.org/g:a7df4961d171ef071bd0972335d6f116d420eb13 commit r15-6255-ga7df4961d171ef071bd0972335d6f116d420eb13 Author: Heiko Eißfeldt Date: Sat Dec 14 12:31:58 2024 + doc: Fix typos for --enable-host-pie docs in install.texi gcc/ChangeLog: * doc/install.texi (Configuration): Fix typos in documentation for --enable-host-pie. Diff: --- gcc/doc/install.texi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gcc/doc/install.texi b/gcc/doc/install.texi index feabf4cbe20b..9109c172039c 100644 --- a/gcc/doc/install.texi +++ b/gcc/doc/install.texi @@ -1119,7 +1119,7 @@ yielding a slightly slower compiler (but faster than at random addresses each time they are executed, therefore provide additional protection against Return Oriented Programming (ROP) attacks. -@option{--enable-host-pie}) may be used with @option{--enable-host-shared}), +@option{--enable-host-pie} may be used with @option{--enable-host-shared}, in which case @option{-fPIC} is used when compiling, and @option{-pie} when linking.
[gcc r14-11089] [PATCH] PR modula2/117120: case ch with a nul char constant causes ICE
https://gcc.gnu.org/g:cfe21668f3a7a0f07fa1e79ef2561a107a09a67d commit r14-11089-gcfe21668f3a7a0f07fa1e79ef2561a107a09a67d Author: Gaius Mulley Date: Sat Dec 14 11:46:57 2024 + [PATCH] PR modula2/117120: case ch with a nul char constant causes ICE This patch fixes the ICE caused when a case clause contains a character constant ''. The fix was to walk the caselist and convert any 0 length string into a char constant of value 0. gcc/m2/ChangeLog: PR modula2/117120 * gm2-compiler/M2CaseList.mod (CaseBoundsResolved): Rewrite. (ConvertNulStr2NulChar): New procedure function. (NulStr2NulChar): Ditto. (GetCaseExpression): Ditto. (OverlappingCaseBound): Rewrite. * gm2-compiler/M2GCCDeclare.mod (CheckResolveSubrange): Allow '' to be used as the subrange low limit. * gm2-compiler/M2GenGCC.mod (FoldConvert): Rewrite. (PopKindTree): Ditto. (BuildHighFromString): Reformat. * gm2-compiler/SymbolTable.mod (PushConstString): Add test for length 0 and PushChar (nul). gcc/testsuite/ChangeLog: PR modula2/117120 * gm2/pim/pass/forloopnulchar.mod: New test. * gm2/pim/pass/nulcharcase.mod: New test. * gm2/pim/pass/nulcharvar.mod: New test. (cherry picked from commit e0ab8816ea53e2a343f7e945f4718172bff5ce95) Signed-off-by: Gaius Mulley Diff: --- gcc/m2/gm2-compiler/M2CaseList.mod| 150 +- gcc/m2/gm2-compiler/M2GCCDeclare.mod | 4 +- gcc/m2/gm2-compiler/M2GenGCC.mod | 130 +++--- gcc/m2/gm2-compiler/SymbolTable.mod | 8 +- gcc/testsuite/gm2/pim/pass/forloopnulchar.mod | 8 ++ gcc/testsuite/gm2/pim/pass/nulcharcase.mod| 16 +++ gcc/testsuite/gm2/pim/pass/nulcharvar.mod | 7 ++ 7 files changed, 231 insertions(+), 92 deletions(-) diff --git a/gcc/m2/gm2-compiler/M2CaseList.mod b/gcc/m2/gm2-compiler/M2CaseList.mod index 7a889bd5d8bf..7fcfe1b40722 100644 --- a/gcc/m2/gm2-compiler/M2CaseList.mod +++ b/gcc/m2/gm2-compiler/M2CaseList.mod @@ -27,10 +27,10 @@ FROM M2GCCDeclare IMPORT TryDeclareConstant, GetTypeMin, GetTypeMax ; FROM M2MetaError IMPORT MetaError1, MetaError2, MetaErrorT0, MetaErrorT1, MetaErrorT2, MetaErrorT3, MetaErrorT4, MetaErrorStringT0, MetaErrorString1 ; FROM M2Error IMPORT InternalError ; FROM M2Range IMPORT OverlapsRange, IsEqual, IsGreater ; -FROM M2ALU IMPORT PushIntegerTree, PopIntegerTree, Addn, Sub, PushInt ; +FROM M2ALU IMPORT PushIntegerTree, PopIntegerTree, Addn, Sub, PushInt, PushCard ; FROM Indexing IMPORT Index, InitIndex, PutIndice, GetIndice, ForeachIndiceInIndexDo, HighIndice ; FROM Lists IMPORT InitList, IncludeItemIntoList, RemoveItemFromList, NoOfItemsInList, GetItemFromList ; -FROM NameKey IMPORT KeyToCharStar ; +FROM NameKey IMPORT NulName, KeyToCharStar ; FROM SymbolConversion IMPORT GccKnowsAbout, Mod2Gcc, AddModGcc ; FROM DynamicStrings IMPORT InitString, InitStringCharStar, InitStringChar, ConCat, Mark, KillString ; FROM gcctypes IMPORT tree ; @@ -44,7 +44,8 @@ FROM NumberIO IMPORT WriteCard ; FROM SymbolTable IMPORT NulSym, IsConst, IsFieldVarient, IsRecord, IsRecordField, GetVarientTag, GetType, ForeachLocalSymDo, GetSymName, IsEnumeration, SkipType, NoOfElements, GetNth, -IsSubrange ; +IsSubrange, MakeConstLit, IsConstString, GetStringLength, MakeConstVar, PutConst, +PopValue ; TYPE RangePair = POINTER TO RECORD @@ -64,6 +65,7 @@ TYPE END ; CaseDescriptor = POINTER TO RECORD + resolved : BOOLEAN ; elseClause : BOOLEAN ; elseField: CARDINAL ; record : CARDINAL ; @@ -110,6 +112,7 @@ BEGIN InternalError ('out of memory error') ELSE WITH c^ DO + resolved := FALSE ; elseClause := FALSE ; elseField := NulSym ; record := rec ; @@ -244,7 +247,30 @@ END GetVariantTagType ; PROCEDURE CaseBoundsResolved (tokenno: CARDINAL; c: CARDINAL) : BOOLEAN ; VAR - resolved: BOOLEAN ; + p: CaseDescriptor ; +BEGIN + p := GetIndice (caseArray, c) ; + IF p^.resolved + THEN + RETURN TRUE + ELSE + IF CheckCaseBoundsResolved (tokenno, c) + THEN + ConvertNulStr2NulChar (tokenno, c) ; + RETURN TRUE + ELSE + RETURN FALSE + END + END +END CaseBoundsResolved ; + + +(* + CheckCaseBoundsResolved - return TRUE if all constants in the case list c are known to GCC. +*) + +PROCEDURE CheckCaseBoundsResolved (tokenno: CARDINAL; c: CARDINAL) : BOOLEAN ; +VAR p : CaseDescriptor ; q : CaseList ; r : RangePair ; @@ -327,7 +353,62 @@ BEGIN END
[gcc r15-6252] opts: Use OPTION_SET_P instead of magic value 2 for -fshort-enums default [PR118011]
https://gcc.gnu.org/g:18f0b7d5f370c47633837e935f8a6e1b8616b56b commit r15-6252-g18f0b7d5f370c47633837e935f8a6e1b8616b56b Author: Jakub Jelinek Date: Sat Dec 14 11:25:08 2024 +0100 opts: Use OPTION_SET_P instead of magic value 2 for -fshort-enums default [PR118011] The magic values for default (usually -1 or sometimes 2) for some options are from times we haven't global_options_set, I think we should eventually get rid of all of those. The PR is about gcc -Q --help=optimizers reporting -fshort-enums as [enabled] when it is disabled. For this the following patch is just partial fix; with explicit gcc -Q --help=optimizers -fshort-enums or gcc -Q --help=optimizers -fno-short-enums it already worked correctly before, with this patch it will report even with just gcc -Q --help=optimizers correct value on most targets, except 32-bit arm with some options or defaults, so I think it is a step in the right direction. But, as I wrote in the PR, process_options isn't done before --help= and even shouldn't be in its current form where it warns on some option combinations or errors or emits sorry on others, so I think ideally process_options should have some bool argument whether it is done for --help= purposes or not, if yes, not emit warnings and just adjust the options, otherwise do what it currently does. 2024-12-14 Jakub Jelinek PR c/118011 gcc/ * opts.cc (init_options_struct): Don't set opts->x_flag_short_enums to 2. * toplev.cc (process_options): Test !OPTION_SET_P (flag_short_enums) rather than flag_short_enums == 2. gcc/ada/ * gcc-interface/misc.cc (gnat_post_options): Test !OPTION_SET_P (flag_short_enums) rather than flag_short_enums == 2. Diff: --- gcc/ada/gcc-interface/misc.cc | 2 +- gcc/opts.cc | 3 --- gcc/toplev.cc | 2 +- 3 files changed, 2 insertions(+), 5 deletions(-) diff --git a/gcc/ada/gcc-interface/misc.cc b/gcc/ada/gcc-interface/misc.cc index c7c735e57639..d3f8ffa8692c 100644 --- a/gcc/ada/gcc-interface/misc.cc +++ b/gcc/ada/gcc-interface/misc.cc @@ -283,7 +283,7 @@ gnat_post_options (const char **pfilename ATTRIBUTE_UNUSED) /* Unfortunately the post_options hook is called before the value of flag_short_enums is autodetected, if need be. Mimic the process for our private flag_short_enums. */ - if (flag_short_enums == 2) + if (!OPTION_SET_P (flag_short_enums)) flag_short_enums = targetm.default_short_enums (); return false; diff --git a/gcc/opts.cc b/gcc/opts.cc index 9909d4a4fc50..fa64bb7734a9 100644 --- a/gcc/opts.cc +++ b/gcc/opts.cc @@ -444,9 +444,6 @@ init_options_struct (struct gcc_options *opts, struct gcc_options *opts_set) /* Initialize whether `char' is signed. */ opts->x_flag_signed_char = DEFAULT_SIGNED_CHAR; - /* Set this to a special "uninitialized" value. The actual default - is set after target options have been processed. */ - opts->x_flag_short_enums = 2; /* Initialize target_flags before default_options_optimization so the latter can modify it. */ diff --git a/gcc/toplev.cc b/gcc/toplev.cc index 370d7f39f218..5f19ebb5cf2a 100644 --- a/gcc/toplev.cc +++ b/gcc/toplev.cc @@ -1300,7 +1300,7 @@ process_options () flag_section_anchors = 0; } - if (flag_short_enums == 2) + if (!OPTION_SET_P (flag_short_enums)) flag_short_enums = targetm.default_short_enums (); /* Set aux_base_name if not already set. */
[gcc r15-6256] bpf: fix build adding new required arg to RESOLVE_OVERLOADED_BUILTIN
https://gcc.gnu.org/g:6866547e2421cc40606c13c2c3621a3d9121e893 commit r15-6256-g6866547e2421cc40606c13c2c3621a3d9121e893 Author: Jose E. Marchesi Date: Sat Dec 14 19:15:34 2024 +0100 bpf: fix build adding new required arg to RESOLVE_OVERLOADED_BUILTIN gcc/ChangeLog * config/bpf/bpf.cc (bpf_resolve_overloaded_builtin): Add argument `complain'. Diff: --- gcc/config/bpf/bpf.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gcc/config/bpf/bpf.cc b/gcc/config/bpf/bpf.cc index fd913ecdb655..9a927e3a6ff1 100644 --- a/gcc/config/bpf/bpf.cc +++ b/gcc/config/bpf/bpf.cc @@ -1084,7 +1084,8 @@ bpf_expand_builtin (tree exp, rtx target ATTRIBUTE_UNUSED, #define TARGET_EXPAND_BUILTIN bpf_expand_builtin static tree -bpf_resolve_overloaded_builtin (location_t loc, tree fndecl, void *arglist) +bpf_resolve_overloaded_builtin (location_t loc, tree fndecl, void *arglist, + bool complain ATTRIBUTE_UNUSED) { int code = DECL_MD_FUNCTION_CODE (fndecl); if (code > BPF_CORE_BUILTINS_MARKER)
[gcc r15-6258] libbacktrace: don't use ZSTD_CLEVEL_DEFAULT
https://gcc.gnu.org/g:3e343ef7f0ac0eb9e526b4f6d3bf3f69be3f0684 commit r15-6258-g3e343ef7f0ac0eb9e526b4f6d3bf3f69be3f0684 Author: Ian Lance Taylor Date: Sat Dec 14 14:32:11 2024 -0800 libbacktrace: don't use ZSTD_CLEVEL_DEFAULT PR 117812 reports that testing GCC with zstd 1.3.4 fails because ZSTD_CLEVEL_DEFAULT is not defined, so avoid using it. PR libbacktrace/117812 * zstdtest.c (test_large): Use 3 rather than ZSTD_CLEVEL_DEFAULT Diff: --- libbacktrace/zstdtest.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/libbacktrace/zstdtest.c b/libbacktrace/zstdtest.c index b9552ab1b882..eb572a24e52f 100644 --- a/libbacktrace/zstdtest.c +++ b/libbacktrace/zstdtest.c @@ -379,8 +379,7 @@ test_large (struct backtrace_state *state ATTRIBUTE_UNUSED) } r = ZSTD_compress (compressed_buf, compressed_bufsize, -orig_buf, orig_bufsize, -ZSTD_CLEVEL_DEFAULT); +orig_buf, orig_bufsize, 3); if (ZSTD_isError (r)) { fprintf (stderr, "zstd compress failed: %s\n", ZSTD_getErrorName (r));
[gcc r15-6257] [PATCH v3] match.pd: Add pattern to simplify `(a - 1) & -a` to `0`
https://gcc.gnu.org/g:ad519f46194a7ab1671470a236c67ae17cb98ead commit r15-6257-gad519f46194a7ab1671470a236c67ae17cb98ead Author: Jovan Vukic Date: Sat Dec 14 14:47:35 2024 -0700 [PATCH v3] match.pd: Add pattern to simplify `(a - 1) & -a` to `0` Thank you for the feedback. I have made the minor changes that were requested. Additionally, I extracted the repetitive code into a reusable helper function, match_plus_neg_pattern, making the code much more readable. Furthermore, the logic, code, and tests remain the same as in version 2 of the patch. gcc/ChangeLog: * match.pd: New pattern. * simplify-rtx.cc (match_plus_neg_pattern): New helper function. (simplify_context::simplify_binary_operation_1): New code to handle (a - 1) & -a, (a - 1) | -a and (a - 1) ^ -a. gcc/testsuite/ChangeLog: * gcc.dg/tree-ssa/bitops-11.c: New test. Diff: --- gcc/match.pd | 16 gcc/simplify-rtx.cc | 41 +++ gcc/testsuite/gcc.dg/tree-ssa/bitops-11.c | 117 ++ 3 files changed, 174 insertions(+) diff --git a/gcc/match.pd b/gcc/match.pd index 4587658aa0a4..c43e51c96b7c 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -1472,6 +1472,22 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (bit_and:c @0 (bit_not (bit_xor:c @0 @1))) (bit_and @0 @1)) +/* Transform: + (a - 1) & -a -> 0. + (a - 1) | -a -> -1. + (a - 1) ^ -a -> -1. */ +(for bit_op (bit_ior bit_xor bit_and) + (simplify + (bit_op:c (plus @0 integer_minus_onep) (negate @0)) + (if (bit_op == BIT_AND_EXPR) +{ build_zero_cst (type); } +{ build_minus_one_cst (type); })) + (simplify + (bit_op:c (minus @0 integer_onep) (negate @0)) + (if (bit_op == BIT_AND_EXPR) +{ build_zero_cst (type); } +{ build_minus_one_cst (type); }))) + /* a & (a == b) --> a & b (boolean version of the above). */ (simplify (bit_and:c @0 (nop_convert? (eq:c @0 @1))) diff --git a/gcc/simplify-rtx.cc b/gcc/simplify-rtx.cc index 86b3f3319285..223a00959786 100644 --- a/gcc/simplify-rtx.cc +++ b/gcc/simplify-rtx.cc @@ -2941,6 +2941,35 @@ simplify_rotate_op (rtx op0, rtx op1, machine_mode mode) return NULL_RTX; } +/* Returns true if OP0 and OP1 match the pattern (OP (plus (A - 1)) (neg A)), + and the pattern can be simplified (there are no side effects). */ + +static bool +match_plus_neg_pattern (rtx op0, rtx op1, machine_mode mode) +{ + /* Remove SUBREG from OP0 and OP1, if needed. */ + if (GET_CODE (op0) == SUBREG + && GET_CODE (op1) == SUBREG + && subreg_lowpart_p (op0) + && subreg_lowpart_p (op1)) +{ + op0 = XEXP (op0, 0); + op1 = XEXP (op1, 0); +} + + /* Check for the pattern (OP (plus (A - 1)) (neg A)). */ + if (((GET_CODE (op1) == NEG + && GET_CODE (op0) == PLUS + && XEXP (op0, 1) == CONSTM1_RTX (mode)) + || (GET_CODE (op0) == NEG + && GET_CODE (op1) == PLUS + && XEXP (op1, 1) == CONSTM1_RTX (mode))) + && rtx_equal_p (XEXP (op0, 0), XEXP (op1, 0)) + && !side_effects_p (XEXP (op0, 0))) +return true; + return false; +} + /* Subroutine of simplify_binary_operation. Simplify a binary operation CODE with result mode MODE, operating on OP0 and OP1. If OP0 and/or OP1 are constant pool references, TRUEOP0 and TRUEOP1 represent the @@ -3553,6 +3582,10 @@ simplify_context::simplify_binary_operation_1 (rtx_code code, && GET_MODE_CLASS (mode) != MODE_CC) return CONSTM1_RTX (mode); + /* Convert (ior (plus (A - 1)) (neg A)) to -1. */ + if (match_plus_neg_pattern (op0, op1, mode)) + return CONSTM1_RTX (mode); + /* (ior A C) is C if all bits of A that might be nonzero are on in C. */ if (CONST_INT_P (op1) && HWI_COMPUTABLE_MODE_P (mode) @@ -3714,6 +3747,10 @@ simplify_context::simplify_binary_operation_1 (rtx_code code, & nonzero_bits (op1, mode)) == 0) return (simplify_gen_binary (IOR, mode, op0, op1)); + /* Convert (xor (plus (A - 1)) (neg A)) to -1. */ + if (match_plus_neg_pattern (op0, op1, mode)) + return CONSTM1_RTX (mode); + /* Convert (XOR (NOT x) (NOT y)) to (XOR x y). Also convert (XOR (NOT x) y) to (NOT (XOR x y)), similarly for (NOT y). */ @@ -3981,6 +4018,10 @@ simplify_context::simplify_binary_operation_1 (rtx_code code, && GET_MODE_CLASS (mode) != MODE_CC) return CONST0_RTX (mode); + /* Convert (and (plus (A - 1)) (neg A)) to 0. */ + if (match_plus_neg_pattern (op0, op1, mode)) + return CONST0_RTX (mode); + /* Transform (and (extend X) C) into (zero_extend (and X C)) if there are no nonzero bits of C outside of X's mode. */ if ((GET_CODE (op0) == SIGN_EXTEND diff --git a/gcc/testsuite/gcc.dg/tree-ssa/bitops-11.c b/gcc/testsuite/gcc.dg/tree-ssa/bitops-11.c new file mode 100644 inde