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

Jeff Law law@redhat.com
Wed Mar 30 19:26:00 GMT 2016


On 03/29/2016 12:03 PM, Jakub Jelinek wrote:
> 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).
Ah, I see.  I should have looked at your test.  It's the variable shift 
that's defines the sign bit that we're using for the conversion.   Hence 
we can't know its value at compile-time.

Jeff



More information about the Gcc-patches mailing list