[Bug bootstrap/114985] [15 regression] internal compiler error: in discriminator_fail during stage2
aldyh at gcc dot gnu.org
gcc-bugzilla@gcc.gnu.org
Wed May 8 16:34:43 GMT 2024
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114985
Aldy Hernandez <aldyh at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
Ever confirmed|0 |1
Last reconfirmed| |2024-05-08
Status|UNCONFIRMED |NEW
CC| |amacleod at redhat dot com,
| |hubicka at gcc dot gnu.org,
| |jamborm at gcc dot gnu.org
--- Comment #4 from Aldy Hernandez <aldyh at gcc dot gnu.org> ---
Confirmed.
Here is some background on tracking discriminator failures.
The sanity check in the range_op dispatch code has noticed that it has an
unsupported pointer range combination. This is the sanity check:
bool
range_op_handler::fold_range (vrange &r, tree type,
const vrange &lh,
const vrange &rh,
relation_trio rel) const
...
...
if (has_pointer_operand_p (r, lh, rh)
&& !m_operator->pointers_handled_p (DISPATCH_FOLD_RANGE,
dispatch_kind (r, lh, rh)))
discriminator_fail (r, lh, rh);
The above code fails if the operator cannot handle the pointer combo it was
passed, and the operator at hand is op_equal:
(gdb) p *this
$11 = {m_operator = 0x1463a590 <op_equal>}
What's being attempted is a <POINTER> = <POINTER> == <POINTER> as per the
somewhat cryptic error:
DISCRIMINATOR FAIL. Dispatch ====> RO_PPP <====
This is because for operator_equal::fold_range(), we only handle INTEGER =
POINTER OP_EQUAL POINTER. That is, the result must be an integer:
bool
operator_equal::pointers_handled_p (range_op_dispatch_type type,
unsigned dispatch) const
{
switch (type)
{
case DISPATCH_FOLD_RANGE:
return dispatch == RO_IPP;
...
...
}
This all comes from ipa_value_range_from_jfunc() which is trying to calculate
the equality of two pointer ranges and store the result in a pointer. I
believe this is incorrect, as the result of equality should be a
boolean_type_node, or at least an integer.
This is where IPA is trying to call fold_range with the invalid combo:
Value_Range op_res (vr_type);
Value_Range res (vr_type);
tree op = ipa_get_jf_pass_through_operand (jfunc);
Value_Range op_vr (TREE_TYPE (op));
range_op_handler handler (operation);
ipa_range_set_and_normalize (op_vr, op);
if (!handler
|| !op_res.supports_type_p (vr_type)
=> || !handler.fold_range (op_res, vr_type, srcvr, op_vr))
op_res.set_varying (vr_type);
It is trying to call fold_range() with EQ_EXPR for two pointer operands, but
storing the result in a pointer:
(gdb) p operation
$18 = EQ_EXPR
(gdb) p debug(srcvr)
[prange] union tree_node * * [0, +INF] MASK 0xfffffffffffffff8 VALUE 0x0
$14 = void
(gdb) p debug(op_vr)
[prange] union tree_node * * [0, 0] MASK 0x0 VALUE 0x0
$15 = void
IMO op_res should have an integer type, but it is a pointer:
(gdb) p debug_generic_stmt(vr_type)
union tree_node * *
...causing op_res to be a pointer:
(gdb) p debug(op_res)
[prange] UNDEFINED
If <POINTER> = <POINTER> OP_EQUAL <POINTER> is valid gimple, then we should
change operator_equal::fold_range() to accept all pointer operands. If not,
then we need to change the IPA pass.
I would appreciate if an IL expert could opine here.
More information about the Gcc-bugs
mailing list