My recent patch to add scalar integer simplification unit tests to simplify_rtx_c_tests identified two "trivial" corner cases that could be improved in simplify-rtx.c. I don't believe that either case can currently be triggered from GCC current front-end/back-end combinations, but hopefully the reviewer agrees these changes are simple/safe enough.
Although it makes no sense to ever see a BImode ROTATE, the current ordering of transformations in simplify_binary_operation_1 converts (rotate:bi (reg:bi) 0) to (rotatert:bi (reg:bi) 1), which then doesn't get simplified away. Rather than teach the middle-end that any hypothetical ROTATE or ROTATERT of a BImode value is a no-op, a more realistic invariant is that any rotate by const0_rtx is already canonical. Optimizing "parity of parity" matches the tree constant folding transformation pending review. Alas, the only mentions of PARITY in GCC's official backend machine descriptions are in expanders, so the middle-end's RTL optimizers never see a PARITY to simplify. A test can be added to test_scalar_int_ops once that patch is reviewed/approved. This patch has been tested with "make bootstrap" and "make -k check" on x86_64-pc-linux-gnu with no regressions. 2020-06-19 Roger Sayle <ro...@nextmovesoftware.com> * simplify-rtx.c (simplify_unary_operation_1): Simplify (parity (parity x)) as (parity x), i.e. PARITY is idempotent. (simplify_binary_operation_1): Don't canonicalize rotations by zero bits, these get simplified away. Thanks in advance, Roger -- Roger Sayle NextMove Software Cambridge, UK
diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c index 28c2dc6..b856b02 100644 --- a/gcc/simplify-rtx.c +++ b/gcc/simplify-rtx.c @@ -1391,6 +1391,10 @@ simplify_unary_operation_1 (enum rtx_code code, machine_mode mode, rtx op) GET_MODE (XEXP (op, 0))); break; + case PARITY: + /* (parity (parity x)) -> parity (x). */ + return op; + default: break; } @@ -3649,7 +3653,8 @@ simplify_binary_operation_1 (enum rtx_code code, machine_mode mode, if (CONST_INT_P (trueop1) && IN_RANGE (INTVAL (trueop1), GET_MODE_UNIT_PRECISION (mode) / 2 + (code == ROTATE), - GET_MODE_UNIT_PRECISION (mode) - 1)) + GET_MODE_UNIT_PRECISION (mode) - 1) + && trueop1 != CONST0_RTX (mode)) { int new_amount = GET_MODE_UNIT_PRECISION (mode) - INTVAL (trueop1); rtx new_amount_rtx = gen_int_shift_amount (mode, new_amount);