Rotate instructions do not need to mask the third operand. For example, RV64 the following code: unsigned long foo1(unsigned long rs1, unsigned long rs2) { long shamt = rs2 & (64 - 1); return (rs1 << shamt) | (rs1 >> ((64 - shamt) & (64 - 1))); } Compiles to: foo1: andi a1,a1,63 rol a0,a0,a1 ret This patch removes unnecessary masking. Besides, I have merged masking insns for shifts that were written before. gcc/ChangeLog: * config/riscv/riscv.md (*3_mask): New pattern, combined from ... (*si3_mask, *di3_mask): Here. (*3_mask_1): New pattern, combined from ... (*si3_mask_1, *di3_mask_1): Here. * config/riscv/bitmanip.md (*3_mask): New pattern. (*si3_sext_mask): Likewise. * config/riscv/iterators.md (shiftm1): Generalize to handle more masking constants. (bitmanip_rotate): New iterator. (bitmanip_optab): Add rotates. * config/riscv/predicates.md (const_si_mask_operand): Renamed from const31_operand. Generalize to handle more mask constants. (const_di_mask_operand): Similarly. gcc/testsuite/ChangeLog: * testsuite/gcc.target/riscv/shift-and-2.c: Fixed test * testsuite/gcc.target/riscv/zbb-rol-ror-01.c: New test * testsuite/gcc.target/riscv/zbb-rol-ror-02.c: New test * testsuite/gcc.target/riscv/zbb-rol-ror-03.c: New test * testsuite/gcc.target/riscv/zbb-rol-ror-04.c: New test * testsuite/gcc.target/riscv/zbb-rol-ror-05.c: New test * testsuite/gcc.target/riscv/zbb-rol-ror-06.c: New test * testsuite/gcc.target/riscv/zbb-rol-ror-07.c: New test -- With the best regards Jivan Hakobyan