-
- Downloads
LoongArch: Expand some SImode operations through "si3_extend" instructions if TARGET_64BIT
We already had "si3_extend" insns and we hoped the fwprop or combine passes can use them to remove unnecessary sign extensions. But this does not always work: for cases like x << 1 | y, the compiler tends to do (sign_extend:DI (ior:SI (ashift:SI (reg:SI $r4) (const_int 1)) (reg:SI $r5))) instead of (ior:DI (sign_extend:DI (ashift:SI (reg:SI $r4) (const_int 1))) (sign_extend:DI (reg:SI $r5))) So we cannot match the ashlsi3_extend instruction here and we get: slli.w $r4,$r4,1 or $r4,$r5,$r4 slli.w $r4,$r4,0 # <= redundant jr $r1 To eliminate this redundant extension we need to turn SImode shift etc. to DImode "si3_extend" operations earlier, when we expand the SImode operation. We are already doing this for addition, now do it for shifts, rotates, substract, multiplication, division, and modulo as well. The bytepick.w definition for TARGET_64BIT needs to be adjusted so it won't be undone by the shift expanding. gcc/ChangeLog: * config/loongarch/loongarch.md (optab): Add (rotatert "rotr"). (<optab:any_shift><mode>3, <optab:any_div><mode>3, sub<mode>3, rotr<mode>3, mul<mode>3): Add a "*" to the insn name so we can redefine the names with define_expand. (*<optab:any_shift>si3_extend): Remove "*" so we can use them in expanders. (*subsi3_extended, *mulsi3_extended): Likewise, also remove the trailing "ed" for consistency. (*<optab:any_div>si3_extended): Add mode for sign_extend to prevent an ICE using it in expanders. (shift_w, arith_w): New define_code_iterator. (<optab:any_w><mode>3): New define_expand. Expand with <optab:any_w>si3_extend for SImode if TARGET_64BIT. (<optab:arith_w><mode>3): Likewise. (mul<mode>3): Expand to mulsi3_extended for SImode if TARGET_64BIT and ISA_HAS_DIV32. (<optab:any_div><mode>3): Expand to <optab:any_div>si3_extended for SImode if TARGET_64BIT. (rotl<mode>3): Expand to rotrsi3_extend for SImode if TARGET_64BIT. (bytepick_w_<bytepick_imm>): Add mode for lshiftrt and ashift. (bitsize, bytepick_imm, bytepick_w_ashift_amount): New define_mode_attr. (bytepick_w_<bytepick_imm>_extend): Adjust for the RTL change caused by 32-bit shift expanding. Now bytepick_imm only covers 2 and 3, separate one remaining case to ... (bytepick_w_1_extend): ... here, new define_insn. gcc/testsuite/ChangeLog: * gcc.target/loongarch/bitwise_extend.c: New test.
Loading
Please register or sign in to comment