+ (lit0 != 0) + (lit1 != 0)
+ (minus_lit0 != 0) + (minus_lit1 != 0)) > 2)
{
+ int var0_origin = (var0 != 0) + 2 * (var1 != 0);
+ int minus_var0_origin
+ = (minus_var0 != 0) + 2 * (minus_var1 != 0);
+ int con0_origin = (con0 != 0) + 2 * (con1 != 0);
+ int minus_con0_origin
+ = (minus_con0 != 0) + 2 * (minus_con1 != 0);
+ int lit0_origin = (lit0 != 0) + 2 * (lit1 != 0);
+ int minus_lit0_origin
+ = (minus_lit0 != 0) + 2 * (minus_lit1 != 0);
var0 = associate_trees (loc, var0, var1, code, atype);
minus_var0 = associate_trees (loc, minus_var0, minus_var1,
code, atype);
if (minus_var0 && var0)
{
+ var0_origin |= minus_var0_origin;
var0 = associate_trees (loc, var0, minus_var0,
MINUS_EXPR, atype);
minus_var0 = 0;
+ minus_var0_origin = 0;
}
if (minus_con0 && con0)
{
+ con0_origin |= minus_con0_origin;
con0 = associate_trees (loc, con0, minus_con0,
MINUS_EXPR, atype);
minus_con0 = 0;
+ minus_con0_origin = 0;
}
/* Preserve the MINUS_EXPR if the negative part of the literal is
/* But avoid ending up with only negated parts. */
&& (var0 || con0))
{
+ minus_lit0_origin |= lit0_origin;
minus_lit0 = associate_trees (loc, minus_lit0, lit0,
MINUS_EXPR, atype);
lit0 = 0;
+ lit0_origin = 0;
}
else
{
+ lit0_origin |= minus_lit0_origin;
lit0 = associate_trees (loc, lit0, minus_lit0,
MINUS_EXPR, atype);
minus_lit0 = 0;
+ minus_lit0_origin = 0;
}
}
return NULL_TREE;
/* Eliminate lit0 and minus_lit0 to con0 and minus_con0. */
+ con0_origin |= lit0_origin;
con0 = associate_trees (loc, con0, lit0, code, atype);
- lit0 = 0;
+ minus_con0_origin |= minus_lit0_origin;
minus_con0 = associate_trees (loc, minus_con0, minus_lit0,
code, atype);
- minus_lit0 = 0;
/* Eliminate minus_con0. */
if (minus_con0)
{
if (con0)
- con0 = associate_trees (loc, con0, minus_con0,
- MINUS_EXPR, atype);
+ {
+ con0_origin |= minus_con0_origin;
+ con0 = associate_trees (loc, con0, minus_con0,
+ MINUS_EXPR, atype);
+ }
else if (var0)
- var0 = associate_trees (loc, var0, minus_con0,
- MINUS_EXPR, atype);
+ {
+ var0_origin |= minus_con0_origin;
+ var0 = associate_trees (loc, var0, minus_con0,
+ MINUS_EXPR, atype);
+ }
else
gcc_unreachable ();
- minus_con0 = 0;
}
/* Eliminate minus_var0. */
if (minus_var0)
{
if (con0)
- con0 = associate_trees (loc, con0, minus_var0,
- MINUS_EXPR, atype);
+ {
+ con0_origin |= minus_var0_origin;
+ con0 = associate_trees (loc, con0, minus_var0,
+ MINUS_EXPR, atype);
+ }
else
gcc_unreachable ();
- minus_var0 = 0;
}
+ /* Reassociate only if there has been any actual association
+ between subtrees from op0 and subtrees from op1 in at
+ least one of the operands, otherwise we risk infinite
+ recursion. See PR114084. */
+ if (var0_origin != 3 && con0_origin != 3)
+ return NULL_TREE;
+
return
fold_convert_loc (loc, type, associate_trees (loc, var0, con0,
code, atype));