This is the mail archive of the gcc@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: Bit-field struct member sign extension pattern results in redundant


> On 18 Aug 2017, at 10:41 AM, Andrew Pinski <pinskia@gmail.com> wrote:
> 
> On Thu, Aug 17, 2017 at 3:29 PM, Michael Clark <michaeljclark@mac.com> wrote:
>> Sorry I had to send again as my Apple mailer is munging emails. I’ve disabled RTF.
>> 
>> 
>> This one is quite interesting:
>> 
>> - https://cx.rv8.io/g/WXWMTG
>> 
>> It’s another target independent bug. x86 is using some LEA followed by SAR trick with a 3 bit shift. Surely SHL 27, SAR 27 would suffice. In any case RISC-V seems like a nice target to try to fix this codegen for, as its less risk than attempting a fix in x86 ;-)
>> 
>> - https://github.com/riscv/riscv-gcc/issues/89
>> 
>> code:
>> 
>>        template <typename T, unsigned B>
>>        inline T signextend(const T x)
>>        {
>>        struct {T x:B;} s;
>>        return s.x = x;
>>        }
>> 
>>        int sx5(int x) {
>>                return signextend<signed int,5>(x);
>>        }
> 
> on AARCH64 I get:
>        sbfiz   w0, w0, 3, 5
>        asr     w0, w0, 3
>        ret

So it is a bug on arm too? and can be done with one sbfiz instruction? (assuming I’m understand sbfiz from my first reading) e.g.

	sbfiz   w0, w0, 0, 2
        ret

> Which is:
> (insn 7 6 8 2 (set (reg:SI 80)
>        (sign_extend:SI (ashift:QI (reg:QI 0 x0 [ x+3 ])
>                (const_int 3 [0x3])))) t.cc:5 557 {*extendsi_ashlqi}
>     (expr_list:REG_DEAD (reg:SI 0 x0 [ x ])
>        (nil)))
> 
> (insn 14 9 17 2 (set (reg/i:SI 0 x0)
>        (ashiftrt:SI (reg:SI 80)
>            (const_int 3 [0x3]))) t.cc:10 530 {*aarch64_ashr_sisd_or_int_si3}
>     (expr_list:REG_DEAD (reg:SI 80)
>        (nil)))
> 
> What I suspect is we get a QImode register in there and that is what
> is happening to both x86 and riscv.

Curious. Thanks.

I still need to learn more about gcc pattern matching and lowering.

I actually have this exact code pattern using a struct member to do arbitrary width sign extend as it’s the first method for arbitrary bit width extension, in Google and on the Stanford Bit Twiddling Hacks page. I understand i’m better off changing my pattern to an explicit shift left and shift right, given I’m now aware this is unambiguously the optimal lowering for ISAs with 1 cycle shifters and no field extract instructions, however given others are likely to stumble on the Stanford page, I wouldn’t be surprised if i’m not the only one using this pattern:

- https://graphics.stanford.edu/~seander/bithacks.html#FixedSignExtend

The x86 sequence is kind of trick and it’s no better off in instruction count by using two shifts. I’m also annoyed that BZHI in BMI2 is an arbitrary width zero extend versus a bit extend. I’d like a BEXT-like instruction that copies a bit at offset n, but given it is only two instruction saving it should also do a right shift so it can be used for signed and unsigned field extract (with a bit copy or bit zero operand bit).

Thanks,
Michael.


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