This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] Fix simplify_shift_const_1 once more (PR rtl-optimization/70429)


On Tue, Mar 29, 2016 at 11:47:57AM -0600, Jeff Law wrote:
> >>>2016-03-29  Jakub Jelinek  <jakub@redhat.com>
> >>>
> >>>	PR rtl-optimization/70429
> >>>	* combine.c (simplify_shift_const_1): For ASHIFTRT don't optimize
> >>>	(cst1 >> count) >> cst2 into (cst1 >> cst2) >> count if
> >>>	mode != result_mode.
> >>>
> >>>	* gcc.c-torture/execute/pr70429.c: New test.
> >>But isn't the point of this code that cst1 >> cst2 turns into a compile time
> >>constant just leaving one runtime shift of the result by count?
> >
> >But with the mode change then you are changing
> >(cst1 >> count) >> cst2
> >into
> >((((cst1 >> cst2) >> count) << (bitsz - cst2)) >> (bitsz - cst))
> Why can't we sign extend cst1 >> cst2 at compile time and use a ASHIFTRT for
> the >> count shift?   Even if we've got a mode change to deal with, we can
> generate the constant in whatever mode we want.

I don't understand how you could do that.
In the original source there is a variable shift count first, then narrowing
cast, then further arithmetic shift by constant.
So sure, you can shift the cst1 by cst2, but which bit you want to sign
extend on depends on the count value, only known at runtime.

Consider the testcase I've posted in the patch:
__attribute__((noinline, noclone)) int
foo (int a)
{
  return (int) (0x14ff6e2207db5d1fLL >> a) >> 4;
}

if a is 1, 0x14ff6e2207db5d1fLL >> a is
0xa7fb71103edae8f
and bit 31 of this is 0, so in the end you get
0x03edae8f >> 4
If a is 2, 0x14ff6e2207db5d1fLL >> a is
0x53fdb8881f6d747
and bit 31 of this is 1, so in the end you get
0xffffffff81f6d747 >> 4
Now, if you want to shift by 4 first, you have cst1 >> cst2
0x14ff6e2207db5d1LL, but you need to sign extend this, but which bit
from depends on count (and the difference between bitsizes of mode and
result_mode).

	Jakub


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]