rotatert with imm emits an unnecessary load if imm > __riscv_xlen/2
marcfedorow opened this issue · 1 comments
marcfedorow commented
gcc/simplify-rtx.c has such statement:
#if defined(HAVE_rotate) && defined(HAVE_rotatert)
if (CONST_INT_P (trueop1)
&& IN_RANGE (INTVAL (trueop1),
GET_MODE_UNIT_PRECISION (mode) / 2 + (code == ROTATE),
GET_MODE_UNIT_PRECISION (mode) - 1))
{
int new_amount = GET_MODE_UNIT_PRECISION (mode) - INTVAL (trueop1);
rtx new_amount_rtx = gen_int_shift_amount (mode, new_amount);
return simplify_gen_binary (code == ROTATE ? ROTATERT : ROTATE,
mode, op0, new_amount_rtx);
}
#endif
Thus gcc emits li reg2, 15; rol reg1, reg2;
instead of rori reg1, 17
on RV32.
This may fix it:
(define_expand "riscv_rolw"
[(match_operand:SI 0 "register_operand" "=r")
(match_operand:SI 1 "register_operand" "r")
(match_operand:SI 2 "register_operand" "r")]
"TARGET_64BIT && (TARGET_ZBB || TARGET_ZBKB)"
{
emit_insn (gen_rotl64si3 (operands[0], operands[1], operands[2]));
DONE;
})
(define_insn "rotlsi3"
[(set (match_operand:SI 0 "register_operand" "=r,r")
(rotate:SI (match_operand:SI 1 "register_operand" "r,r")
(match_operand:QI 2 "arith_operand" "r,I")))]
"!TARGET_64BIT && (TARGET_ZBB || TARGET_ZBKB)"
"@
rol\t%0,%1,%2
rori\t%0,%1,32-%2"
[(set_attr "type" "bitmanip")])
(define_insn "rotl64si3"
[(set (match_operand:SI 0 "register_operand" "=r,r")
(rotate:SI (match_operand:SI 1 "register_operand" "r,r")
(match_operand:QI 2 "arith_operand" "r,I")))]
"TARGET_64BIT && (TARGET_ZBB || TARGET_ZBKB)"
"@
rolw\t%0,%1,%2
roriw\t%0,%1,32-%2"
[(set_attr "type" "bitmanip")])
(define_insn "rotldi3"
[(set (match_operand:DI 0 "register_operand" "=r,r")
(rotate:DI (match_operand:DI 1 "register_operand" "r,r")
(match_operand:QI 2 "arith_operand" "r,I")))]
"TARGET_64BIT && (TARGET_ZBB || TARGET_ZBKB)"
"@
rol\t%0,%1,%2
rori\t%0,%1,64-%2"
[(set_attr "type" "bitmanip")])
(define_insn "rotlsi3_sext"
[(set (match_operand:DI 0 "register_operand" "=r,r")
(sign_extend:DI (rotate:SI (match_operand:SI 1 "register_operand" "r,r")
(match_operand:QI 2 "arith_operand" "r,I"))))]
"TARGET_64BIT && (TARGET_ZBB || TARGET_ZBKB)"
"@
rolw\t%0,%1,%2
roriw\t%0,%1,%2"
[(set_attr "type" "bitmanip")])
cmuellner commented
Thanks for reporting this issue.
Please, note that this bug tracker is not meant to track RISC-V-related backend issues in GCC.
Please report to GCC's bugzilla (https://gcc.gnu.org/bugzilla/).
Also, note that a patch to address this has been posted recently on gcc-patches:
https://gcc.gnu.org/pipermail/gcc-patches/2021-November/584143.html