I made a thinko in r214080. That patch makes the "andi." pattern not match for insns that can match "rlwinm", and also makes "rlwinm." not match insns that can match "andi." (and similar for "andis." and "rldicl" etc.) This ensures we always choose the cheapest instruction.
However, the splitter for "andi." does not take this into account, and generates a clobber always, leading to unrecognisable instructions. This patch fixes it. Okay if it survives bootstrap+regcheck? Segher 2014-09-05 Segher Boessenkool <seg...@kernel.crashing.org> PR target/63187 * config/rs6000/rs6000.md (*and<mode>3_imm_dot, *and<mode>3_imm_dot2): Do not allow any_mask_operand for operands[2]. (*and<mode>3_imm_mask_dot, *and<mode>3_imm_mask_dot2): New. --- gcc/config/rs6000/rs6000.md | 56 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 54 insertions(+), 2 deletions(-) diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index 8f3549e..2df8e41 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -2736,7 +2736,8 @@ (define_insn_and_split "*and<mode>3_imm_dot" (clobber (match_scratch:GPR 0 "=r,r")) (clobber (match_scratch:CC 4 "=X,x"))] "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff) - && rs6000_gen_cell_microcode" + && rs6000_gen_cell_microcode + && !any_mask_operand (operands[2], <MODE>mode)" "@ andi%e2. %0,%1,%u2 #" @@ -2763,7 +2764,8 @@ (define_insn_and_split "*and<mode>3_imm_dot2" (match_dup 2))) (clobber (match_scratch:CC 4 "=X,x"))] "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff) - && rs6000_gen_cell_microcode" + && rs6000_gen_cell_microcode + && !any_mask_operand (operands[2], <MODE>mode)" "@ andi%e2. %0,%1,%u2 #" @@ -2780,6 +2782,56 @@ (define_insn_and_split "*and<mode>3_imm_dot2" (set_attr "dot" "yes") (set_attr "length" "4,8")]) +(define_insn_and_split "*and<mode>3_imm_mask_dot" + [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y") + (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r") + (match_operand:GPR 2 "logical_const_operand" "n,n")) + (const_int 0))) + (clobber (match_scratch:GPR 0 "=r,r"))] + "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff) + && rs6000_gen_cell_microcode + && any_mask_operand (operands[2], <MODE>mode)" + "@ + andi%e2. %0,%1,%u2 + #" + "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" + [(set (match_dup 0) + (and:GPR (match_dup 1) + (match_dup 2))) + (set (match_dup 3) + (compare:CC (match_dup 0) + (const_int 0)))] + "" + [(set_attr "type" "logical") + (set_attr "dot" "yes") + (set_attr "length" "4,8")]) + +(define_insn_and_split "*and<mode>3_imm_mask_dot2" + [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y") + (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r") + (match_operand:GPR 2 "logical_const_operand" "n,n")) + (const_int 0))) + (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") + (and:GPR (match_dup 1) + (match_dup 2)))] + "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff) + && rs6000_gen_cell_microcode + && any_mask_operand (operands[2], <MODE>mode)" + "@ + andi%e2. %0,%1,%u2 + #" + "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" + [(set (match_dup 0) + (and:GPR (match_dup 1) + (match_dup 2))) + (set (match_dup 3) + (compare:CC (match_dup 0) + (const_int 0)))] + "" + [(set_attr "type" "logical") + (set_attr "dot" "yes") + (set_attr "length" "4,8")]) + (define_insn "*and<mode>3_mask" [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") -- 1.8.1.4