On 07/08/2016 05:17 AM, Richard Biener wrote:
On Fri, 8 Jul 2016, Prathamesh Kulkarni wrote:
Hi Richard,
For the following test-case:
int f(int x, int y)
{
int ret;
if (x == y)
ret = x ^ y;
else
ret = 1;
return ret;
}
I was wondering if x ^ y should be folded to 0 since
it's guarded by condition x == y ?
optimized dump shows:
f (int x, int y)
{
int iftmp.0_1;
int iftmp.0_4;
<bb 2>:
if (x_2(D) == y_3(D))
goto <bb 3>;
else
goto <bb 4>;
<bb 3>:
iftmp.0_4 = x_2(D) ^ y_3(D);
<bb 4>:
# iftmp.0_1 = PHI <iftmp.0_4(3), 1(2)>
return iftmp.0_1;
}
The attached patch tries to fold for above case.
I am checking if op0 and op1 are equal using:
if (bitmap_intersect_p (vr1->equiv, vr2->equiv)
&& operand_equal_p (vr1->min, vr1->max)
&& operand_equal_p (vr2->min, vr2->max))
{ /* equal /* }
I suppose intersection would check if op0 and op1 have equivalent ranges,
and added operand_equal_p check to ensure that there is only one
element within the range. Does that look correct ?
Bootstrap+test in progress on x86_64-unknown-linux-gnu.
I think VRP is the wrong place to catch this and DOM should have but it
does
Optimizing block #3
1>>> STMT 1 = x_2(D) le_expr y_3(D)
1>>> STMT 1 = x_2(D) ge_expr y_3(D)
1>>> STMT 1 = x_2(D) eq_expr y_3(D)
1>>> STMT 0 = x_2(D) ne_expr y_3(D)
0>>> COPY x_2(D) = y_3(D)
0>>> COPY y_3(D) = x_2(D)
Optimizing statement ret_4 = x_2(D) ^ y_3(D);
Replaced 'x_2(D)' with variable 'y_3(D)'
Replaced 'y_3(D)' with variable 'x_2(D)'
Folded to: ret_4 = x_2(D) ^ y_3(D);
LKUP STMT ret_4 = x_2(D) bit_xor_expr y_3(D)
heh, registering both reqivalencies is obviously not going to help...
The 2nd equivalence is from doing
/* We already recorded that LHS = RHS, with canonicalization,
value chain following, etc.
We also want to record RHS = LHS, but without any
canonicalization
or value chain following. */
if (TREE_CODE (rhs) == SSA_NAME)
const_and_copies->record_const_or_copy_raw (rhs, lhs,
SSA_NAME_VALUE (rhs));
generally recording both is not helpful. Jeff? This seems to be
r233207 (fix for PR65917) which must have regressed this testcase.
The primary purpose of the const/copies table is to enable simple
const/copy propagation. So given a = b, we record that "a" can be
replaced with "b" and from then on we replace occurrences of "a" with
"b" -- ie, copy propagation.
We have a much lower priority goal of recording equivalences that arise
from conditionals such as if (a == b) and using those in const/copy
propagation. Given the structure of the table, we can record that a =
b or b = a. The problem is we've never come up with any good heuristics
for which of those two styles to record. Which you got was mostly a
function of canonicalization using SSA_NAME_VERSIONs.
As seen in 65917, sometimes that decision is wrong and can lead to
performance regressions. But it's really just luck of the draw whether
it gets optimized or not. And the test
65917 allows us to record both equivalences in the table. We do that by
bypassing all the checks/canonicalizations with a raw insertion method.
During DOM we can now lookup either form which allows us to fix the
regression in 65917.
It ought to be easy to fold x ^ y to zero when x == y (famous last
words). I'm sure I'll regret saying that when I go to look at how to
twiddle DOM appropriately.
jeff