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

Reply via email to