Skip to content

Commit

Permalink
Recognize ROL/ROR patterns
Browse files Browse the repository at this point in the history
  • Loading branch information
dstogov committed May 7, 2024
1 parent 48687e2 commit 005f7b5
Show file tree
Hide file tree
Showing 4 changed files with 129 additions and 0 deletions.
40 changes: 40 additions & 0 deletions ir_fold.h
Original file line number Diff line number Diff line change
Expand Up @@ -2838,6 +2838,46 @@ IR_FOLD(XOR(XOR, _))
IR_FOLD_NEXT;
}

/* ROL/ROR */
IR_FOLD(OR(SHL, SHR))
IR_FOLD(OR(SHR, SHL))
IR_FOLD(ADD(SHL, SHR))
IR_FOLD(ADD(SHR, SHL))
{
if (op1_insn->op1 == op2_insn->op1) {
if (IR_IS_CONST_REF(op1_insn->op2) && IR_IS_CONST_REF(op2_insn->op2)) {
if (ctx->ir_base[op1_insn->op2].val.u64 + ctx->ir_base[op2_insn->op2].val.u64 ==
ir_type_size[IR_OPT_TYPE(opt)] * 8) {
/* (x << c) | (x >> (32 - c)) -> ROL(x, c) */
op1 = op1_insn->op1;
op2 = op1_insn->op2;
opt = op1_insn->opt + 3; /* SHL -> ROL, SHR -> ROR */
IR_FOLD_RESTART;
}
} else if (ctx->ir_base[op2_insn->op2].op == IR_SUB
&& IR_IS_CONST_REF(ctx->ir_base[op2_insn->op2].op1)
&& ctx->ir_base[op2_insn->op2].op2 == op1_insn->op2
&& ctx->ir_base[ctx->ir_base[op2_insn->op2].op1].val.u64 == ir_type_size[IR_OPT_TYPE(opt)] * 8) {
/* (x << y) | (x >> (32 - y)) -> ROL(x, y) */
op1 = op1_insn->op1;
op2 = op1_insn->op2;
opt = op1_insn->opt + 3; /* SHL -> ROL, SHR -> ROR */
IR_FOLD_RESTART;
} else if (ctx->ir_base[op1_insn->op2].op == IR_SUB
&& IR_IS_CONST_REF(ctx->ir_base[op1_insn->op2].op1)
&& ctx->ir_base[op1_insn->op2].op2 == op2_insn->op2
&& ctx->ir_base[ctx->ir_base[op1_insn->op2].op1].val.u64 == ir_type_size[IR_OPT_TYPE(opt)] * 8) {
/* (x << (32 - y)) | (x >> y) -> ROR(x, y) */
op1 = op2_insn->op1;
op2 = op2_insn->op2;
opt = op2_insn->opt + 3; /* SHL -> ROL, SHR -> ROR */
IR_FOLD_RESTART;
}
}
IR_FOLD_NEXT;
}


/* Swap operands (move lower ref to op2) for better CSE */
IR_FOLD(ADD(_, _))
IR_FOLD(MUL(_, _))
Expand Down
30 changes: 30 additions & 0 deletions tests/combine_rol_ror_001.irt
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
--TEST--
001: Combine ROL/ROR
--ARGS--
-O2 --save
--CODE--
{
uintptr_t c_1 = 0;
bool c_2 = 0;
bool c_3 = 1;
int32_t c_4 = 32;
l_1 = START(l_12);
int32_t d_2 = PARAM(l_1, "x", 0);
int32_t d_3 = PARAM(l_1, "y", 1);
int32_t d_4 = SHL(d_2, d_3);
int32_t d_5 = SUB(c_4, d_3);
int32_t d_6 = SHR(d_2, d_5);
int32_t d_7 = OR(d_4, d_6);
l_12 = RETURN(l_1, d_7);
}
--EXPECT--
{
uintptr_t c_1 = 0;
bool c_2 = 0;
bool c_3 = 1;
l_1 = START(l_5);
int32_t d_2 = PARAM(l_1, "x", 0);
int32_t d_3 = PARAM(l_1, "y", 1);
int32_t d_4 = ROL(d_2, d_3);
l_5 = RETURN(l_1, d_4);
}
30 changes: 30 additions & 0 deletions tests/combine_rol_ror_002.irt
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
--TEST--
001: Combine ROL/ROR
--ARGS--
-O2 --save
--CODE--
{
uintptr_t c_1 = 0;
bool c_2 = 0;
bool c_3 = 1;
int32_t c_4 = 32;
l_1 = START(l_12);
int32_t d_2 = PARAM(l_1, "x", 0);
int32_t d_3 = PARAM(l_1, "y", 1);
int32_t d_4 = SUB(c_4, d_3);
int32_t d_5 = SHL(d_2, d_4);
int32_t d_6 = SHR(d_2, d_3);
int32_t d_7 = OR(d_5, d_6);
l_12 = RETURN(l_1, d_7);
}
--EXPECT--
{
uintptr_t c_1 = 0;
bool c_2 = 0;
bool c_3 = 1;
l_1 = START(l_5);
int32_t d_2 = PARAM(l_1, "x", 0);
int32_t d_3 = PARAM(l_1, "y", 1);
int32_t d_4 = ROR(d_2, d_3);
l_5 = RETURN(l_1, d_4);
}
29 changes: 29 additions & 0 deletions tests/combine_rol_ror_003.irt
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
--TEST--
001: Combine ROL/ROR
--ARGS--
-O2 --save
--CODE--
{
uintptr_t c_1 = 0;
bool c_2 = 0;
bool c_3 = 1;
int32_t c_4 = 12;
int32_t c_5 = 20;
l_1 = START(l_12);
int32_t d_2 = PARAM(l_1, "x", 0);
int32_t d_3 = SHL(d_2, c_4);
int32_t d_4 = SHR(d_2, c_5);
int32_t d_5 = OR(d_3, d_4);
l_12 = RETURN(l_1, d_5);
}
--EXPECT--
{
uintptr_t c_1 = 0;
bool c_2 = 0;
bool c_3 = 1;
int32_t c_4 = 12;
l_1 = START(l_4);
int32_t d_2 = PARAM(l_1, "x", 0);
int32_t d_3 = ROL(d_2, c_4);
l_4 = RETURN(l_1, d_3);
}

0 comments on commit 005f7b5

Please sign in to comment.