The odd patterns for rldic and rldicr that require an insn predicate that examines both the shift count and the mask, must be costed at a point where both count and mask are available.
Also tidies the mode passed to a couple of predicates. * config/rs6000/rs6000.c (rs6000_rtx_costs): Pass mode to reg_or_add_cint_operand and reg_or_sub_cint_operand. Handle rldic and rldicr insns under AND. diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 5f42192..a4a72f3 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -30681,9 +30681,9 @@ rs6000_rtx_costs (rtx x, machine_mode mode, int outer_code, return true; } else if ((outer_code == PLUS - && reg_or_add_cint_operand (x, VOIDmode)) + && reg_or_add_cint_operand (x, mode)) || (outer_code == MINUS - && reg_or_sub_cint_operand (x, VOIDmode)) + && reg_or_sub_cint_operand (x, mode)) || ((outer_code == SET || outer_code == IOR || outer_code == XOR) @@ -30801,7 +30801,6 @@ rs6000_rtx_costs (rtx x, machine_mode mode, int outer_code, } /* FALLTHRU */ - case AND: case CLZ: case IOR: case XOR: @@ -30809,6 +30808,24 @@ rs6000_rtx_costs (rtx x, machine_mode mode, int outer_code, *total = COSTS_N_INSNS (1); return false; + case AND: + *total = COSTS_N_INSNS (1); + if (mode == DImode) + { + rtx op0 = XEXP (x, 0); + if ((GET_CODE (op0) == ASHIFT || GET_CODE (op0) == ROTATE) + && CONST_INT_P (XEXP (op0, 1))) + { + rtx op1 = XEXP (x, 1); + if (includes_rldic_lshift_p (XEXP (op0, 1), op1)) + return true; + if (GET_CODE (op0) == ASHIFT + && includes_rldicr_lshift_p (XEXP (op0, 1), op1)) + return true; + } + } + return false; + case ASHIFT: case ASHIFTRT: case LSHIFTRT: -- Alan Modra Australia Development Lab, IBM