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