On 2015.01.14 at 17:10 +0000, Robert Suchanek wrote:
> Here is the revised patch that would handle the other cases as per Richard's
> comments.
>
> I slightly modified Matthew's proposed patch and used split_const
> instead of get_related_value. AFAICS, the canonical form would always have
> the 'plus' expression.
>
> The offset on the high part is most likely not important as the code
> generation
> has to guarantee that the low part represents the true address in the case
> where the high and lo_sum are directly related.
>
> Regards,
> Robert
>
> gcc/
> * simplify-rtx.c (simplify_replace_fn_rtx): Simplify (lo_sum
> (high x) y) to y if x and y have the same base.
>
> gcc/testsuite/
> * gcc.c-torture/compile/20150108.c: New test.
>
> diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c
> index 04af01e..df86f8b 100644
> --- a/gcc/simplify-rtx.c
> +++ b/gcc/simplify-rtx.c
> @@ -499,9 +499,15 @@ simplify_replace_fn_rtx (rtx x, const_rtx old_rtx,
> op0 = simplify_replace_fn_rtx (XEXP (x, 0), old_rtx, fn, data);
> op1 = simplify_replace_fn_rtx (XEXP (x, 1), old_rtx, fn, data);
>
> - /* (lo_sum (high x) x) -> x */
> - if (GET_CODE (op0) == HIGH && rtx_equal_p (XEXP (op0, 0), op1))
> - return op1;
> + /* (lo_sum (high x) y) -> y where x and y have the same base. */
> + if (GET_CODE (op0) == HIGH)
> + {
> + rtx base0, base1, offset0, offset1;
> + split_const (XEXP (op0, 0), &base0, &offset0);
> + split_const (op1, &base1, &offset1);
> + if (rtx_equal_p (base0, base1))
> + return op1;
> + }
>
> if (op0 == XEXP (x, 0) && op1 == XEXP (x, 1))
> return x;
> diff --git a/gcc/testsuite/gcc.c-torture/compile/20150108.c
> b/gcc/testsuite/gcc.c-torture/compile/20150108.c
> new file mode 100644
> index 0000000..15c53e3
> --- /dev/null
> +++ b/gcc/testsuite/gcc.c-torture/compile/20150108.c
> @@ -0,0 +1,23 @@
> +long long a[10];
> +long long b, c, d, k, m, n, o, p, q, r, s, t, u, v, w;
> +int e, f, g, h, i, j, l, x;
> +
> +int fn1 () {
> + for (; x; x++)
> + if (x & 1)
> + s = h | g;
> + else
> + s = f | e;
> + l = ~0;
> + m = 1 | k;
> + n = i;
> + o = j;
> + p = f | e;
> + q = h | g;
> + w = d | c | a[1];
> + t = c;
> + v = b | c;
> + u = v;
> + r = b | a[4];
> + return e;
> +
There is a missing } in the testcase.
--
Markus