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 PM, Gabriel Paubert <paubert@iram.es> wrote:
> 
> On Fri, Aug 18, 2017 at 10:29:04AM +1200, Michael Clark 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);
>> 	}
>> 
>> riscv asm:
>> 
>> 	sx5(int):
>> 	  slliw a0,a0,3
>> 	  slliw a0,a0,24
>> 	  sraiw a0,a0,24
>> 	  sraiw a0,a0,3
>> 	  ret
>> 
>> hand coded riscv asm
>> 
>> 	sx5(int):
>> 	  slliw a0,a0,27
>> 	  sraiw a0,a0,27
>> 	  ret
>> 
>> x86 asm:
>> 
>> 	sx5(int):
>> 	  lea eax, [0+rdi*8]
>> 	  sar al, 3
>> 	  movsx eax, al
>> 	  ret
>> 
>> hand coded x86 asm (no worse because the sar depends on the lea)
>> 
>> 	sx5(int):
>> 	  shl edi, 27
>> 	  sar edi, 27
>> 	  movsx eax, dl
> 
> Huh? dl is not a subreg of edi!
> 
> s/edi/edx/ and it may work.
> 
> dil can also be used, but only on 64 bit.

Sorry I meant dil on x86-64. I was sure that it was possible to extend into another register. I have not done much i386 asm so I am unaware of the constraints. Can the source and dest registers for movsx not differ on i386? I thought they could.

In any case, the plot thickens…

I believe we have bugs on both RISC-V and Aarch64.

I found that it at least appears like it is transitioning to a char or short as the break is at 24 and 16 depending on the width, and values over 16 work as one would expect.

Here is an updated test program: https://cx.rv8.io/g/M9ewNf

	template <typename T, unsigned B>
	inline T signextend(const T x)
	{
	  struct {T x:B;} s;
	  return s.x = x;
	}

	int sx3(int x) { return signextend<signed int,3>(x); }
	int sx5(int x) { return signextend<signed int,5>(x); }
	int sx11(int x) { return signextend<signed int,11>(x); }
	int sx14(int x) { return signextend<signed int,14>(x); }
	int sx19(int x) { return signextend<signed int,19>(x); }

I filed a bug on riscv-gcc but I think it is target independent code given there appears to be an issue on Aarch64. AFAICT, Aarch64 should generate a single sbfx for all of the test functions.

- https://github.com/riscv/riscv-gcc/issues/89

Should I file a bug on GCC bugzilla given it looks to be target independent?

On RISC-V, the codegen is much more obviously wrong, but essentially the same thing is happening on Aarch64 but there is only one additional instruction instead of two.

	sx3(int):
	  slliw a0,a0,5
	  slliw a0,a0,24
	  sraiw a0,a0,24
	  sraiw a0,a0,5
	  ret
	sx5(int):
	  slliw a0,a0,3
	  slliw a0,a0,24
	  sraiw a0,a0,24
	  sraiw a0,a0,3
	  ret
	sx11(int):
	  slliw a0,a0,5
	  slliw a0,a0,16
	  sraiw a0,a0,16
	  sraiw a0,a0,5
	  ret
	sx14(int):
	  slliw a0,a0,2
	  slliw a0,a0,16
	  sraiw a0,a0,16
	  sraiw a0,a0,2
	  ret
	sx19(int):
	  slliw a0,a0,13
	  sraiw a0,a0,13
	  ret



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