On Tue, Jan 18, 2022 at 11:25:38AM -0500, Jason Merrill wrote:
Can you please comment on https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86369#c1
then?
Done.
Thanks.
About the rest of the patch, I thought I had seen richi comment on IRC (but
can't find the comment now) that these cases where we could give a constant
answer but decide not to because of C++ rules should be handled in the front
end rather than generic code, which makes sense to me; that is, use
folding_initializer only for giving more constant results, not for giving
fewer constant results. Maybe add another flag for limiting constant
results if we think it's significantly easier to recognize these cases in
fold?
I'm afraid avoiding the match.pd & fold-const code here would be a lot of
work.
The match.pd code looks like:
(for cmp (simple_comparison)
(simplify
(cmp (convert1?@2 addr@0) (convert2? addr@1))
(with
{
poly_int64 off0, off1;
tree base0, base1;
int equal = address_compare (cmp, TREE_TYPE (@2), @0, @1, base0, base1,
off0, off1, GENERIC);
}
(if (equal == 1)
(switch
(if (cmp == EQ_EXPR && (known_eq (off0, off1) || known_ne (off0, off1)))
{ constant_boolean_node (known_eq (off0, off1), type); })
(if (cmp == NE_EXPR && (known_eq (off0, off1) || known_ne (off0, off1)))
{ constant_boolean_node (known_ne (off0, off1), type); })
(if (cmp == LT_EXPR && (known_lt (off0, off1) || known_ge (off0, off1)))
{ constant_boolean_node (known_lt (off0, off1), type); })
(if (cmp == LE_EXPR && (known_le (off0, off1) || known_gt (off0, off1)))
{ constant_boolean_node (known_le (off0, off1), type); })
(if (cmp == GE_EXPR && (known_ge (off0, off1) || known_lt (off0, off1)))
{ constant_boolean_node (known_ge (off0, off1), type); })
(if (cmp == GT_EXPR && (known_gt (off0, off1) || known_le (off0, off1)))
{ constant_boolean_node (known_gt (off0, off1), type); }))
(if (equal == 0)
(switch
(if (cmp == EQ_EXPR)
{ constant_boolean_node (false, type); })
(if (cmp == NE_EXPR)
{ constant_boolean_node (true, type); })))))))
and
(for minmax (min max)
cmp (lt gt)
(simplify
(minmax (convert1?@2 addr@0) (convert2?@3 addr@1))
(with
{
poly_int64 off0, off1;
tree base0, base1;
int equal = address_compare (cmp, TREE_TYPE (@2), @0, @1, base0, base1,
off0, off1, GENERIC);
}
(if (equal == 1)
(if (minmax == MIN_EXPR)
(if (known_le (off0, off1))
@2
(if (known_gt (off0, off1))
@3))
(if (known_ge (off0, off1))
@2
(if (known_lt (off0, off1))
@3)))))))
and address_compare is a fairly large routine and uses equal_address_to
which is another quite large routine and we'd need to redo big chunks
of that code in constexpr.c.
Not using match.pd and fold-const.cc at all during constexpr evaluation
(except perhaps for folding of builtins) seems like a nice ultimate goal
(we would only optimize what we are required to and nothing else, at least
in the strict modes), but I'm afraid it would take several years to implement.
Having another flag next to folding_initialize that would be used in
fold-const.c in the meantime looks fine to me, any suggestion on how to call
it?