Re: [PATCH 3/6] ccmp: Reject chains without an explicit comparison [PR109832]
Andrea Pinski <[email protected]>
| Newsgroups | gmane.comp.gcc.patches |
|---|---|
| Message-ID | <CALvbMcD6qwjAaKyjHcz5PjfWF4-xG=k+VByvmTnxrzuHxqLV+Q@mail.gmail.com> |
On Mon, Aug 10, 2026 at 6:23 AM <[email protected]> wrote: > > From: Kyrylo Tkachov <[email protected]> > > The conditional-compare expander accepts a plain boolean as a comparison > against zero. This is useful when a chain also contains an explicit > comparison. It is harmful when every leaf is a boolean. For example: > > _Bool > f (_Bool x, _Bool y) > { > return x || y; > } > > AArch64 emitted: > > and w1, w1, 255 > tst w0, 255 > ccmp w1, 0, 0, eq > cset w0, ne > > After this patch it emits one bitwise operation: > > orr w0, w0, w1 > > Require at least one explicit comparison in a conditional-compare tree. > Mixed boolean and comparison chains remain accepted. > > Bootstrapped and tested on aarch64-none-linux-gnu. > Ok for trunk? > Thanks, > Kyrill > > gcc/ > > PR middle-end/109832 > * ccmp.cc (ccmp_tree_has_comparison_p): New function. > (expand_ccmp_expr): Reject an all-boolean tree. > > gcc/testsuite/ > > PR middle-end/109832 > * gcc.target/aarch64/ccmp_7.c: New test. > > Signed-off-by: Kyrylo Tkachov <[email protected]> > --- > gcc/ccmp.cc | 24 ++++++++++++ > gcc/testsuite/gcc.target/aarch64/ccmp_7.c | 46 +++++++++++++++++++++++ > 2 files changed, 70 insertions(+) > create mode 100644 gcc/testsuite/gcc.target/aarch64/ccmp_7.c > > diff --git a/gcc/ccmp.cc b/gcc/ccmp.cc > index 1c540f641b2..9f7670bf58e 100644 > --- a/gcc/ccmp.cc > +++ b/gcc/ccmp.cc > @@ -93,6 +93,25 @@ ccmp_tree_comparison_p (tree t, basic_block bb) > > typedef hash_map<tree, bool> ccmp_uniform_cache; > > +/* Return true if AND/IOR tree T contains a comparison in BB. */ > + > +static bool > +ccmp_tree_has_comparison_p (tree t, basic_block bb) > +{ > + gimple *g = get_gimple_for_ssa_name (t); > + if (!g || !is_gimple_assign (g)) > + return false; > + > + tree_code code = gimple_assign_rhs_code (g); > + if (TREE_CODE_CLASS (code) == tcc_comparison) > + return gimple_bb (g) == bb; > + if (code != BIT_AND_EXPR && code != BIT_IOR_EXPR) > + return false; > + > + return (ccmp_tree_has_comparison_p (gimple_assign_rhs1 (g), bb) > + || ccmp_tree_has_comparison_p (gimple_assign_rhs2 (g), bb)); Is there a way to do this non recursive (and not with a work list)? I think it might be a good idea to move ccmp away from expand into say isel. We already don't really want to depend on TER and your above code does not even use ter. > +} > + > /* Return true if T is a CODE tree in BB whose leaves are comparisons. > CACHE records results for logical SSA definitions. */ > > @@ -368,6 +387,11 @@ expand_ccmp_expr (gimple *g, machine_mode mode) > if (!ccmp_candidate_p (g, cache, true)) > return NULL_RTX; > > + basic_block bb = gimple_bb (g); > + if (!ccmp_tree_has_comparison_p (gimple_assign_rhs1 (g), bb) > + && !ccmp_tree_has_comparison_p (gimple_assign_rhs2 (g), bb)) > + return NULL_RTX; > + > last = get_last_insn (); > > rtx_insn *prep_seq = NULL, *gen_seq = NULL; > diff --git a/gcc/testsuite/gcc.target/aarch64/ccmp_7.c b/gcc/testsuite/gcc.target/aarch64/ccmp_7.c > new file mode 100644 > index 00000000000..29e269b854e > --- /dev/null > +++ b/gcc/testsuite/gcc.target/aarch64/ccmp_7.c > @@ -0,0 +1,46 @@ > +/* { dg-do compile } */ > +/* { dg-options "-O2" } */ > +/* PR middle-end/109832 */ > + > +/* A conditional compare folds a comparison into the flags. When the operands > + are plain booleans there is no comparison to fold and the bitwise operation > + is cheaper, so no conditional compare should be formed. */ > + > +_Bool > +bool_ior (_Bool x, _Bool y) > +{ > + return x || y; > +} > + > +_Bool > +bool_and (_Bool x, _Bool y) > +{ > + return x && y; > +} > + > +extern _Bool t (void); > + > +_Bool > +bool_call_ior (void) > +{ > + _Bool x = t (); > + _Bool y = t (); > + return x | y; > +} > + > +_Bool > +bool_ior_tree (_Bool a, _Bool b, _Bool c, _Bool d) > +{ > + return (a | b) | (c | d); > +} > + > +/* One explicit comparison is enough to keep each chain profitable. */ > + > +int > +bool_and_cmp_tree (_Bool a, _Bool b, _Bool c, int x, int y) > +{ > + return ((a & b) & c) & (x < y); > +} > + > +/* { dg-final { scan-assembler-times {\tccmp\t} 3 } } */ > +/* { dg-final { scan-assembler-times {\torr\t} 5 } } */ > -- > 2.50.1 (Apple Git-155) >