We didn't have patterns yet for rl[wd]imi insns that do a rotate by 0. This fixes it. Tested on powerpc64-linux {-m32,-m64}. With a further patch (to generic code) now all my rl*imi tests works (I still need to make those tests usable in the GCC testsuite, they currently take hours to run).
Is this okay for trunk? Segher 2016-11-21 Segher Boessenkool <seg...@kernel.crashing.org> PR target/68803 * config/rs6000/rs6000.md (*rotlsi3_insert_5, *rotldi3_insert_6, *rotldi3_insert_7): New define_insns. --- gcc/config/rs6000/rs6000.md | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index a779f5c..52f07e8 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -3853,6 +3853,50 @@ (define_insn "*rotl<mode>3_insert_4" } [(set_attr "type" "insert")]) +(define_insn "*rotlsi3_insert_5" + [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r") + (ior:SI (and:SI (match_operand:SI 1 "gpc_reg_operand" "0,r") + (match_operand:SI 2 "const_int_operand" "n,n")) + (and:SI (match_operand:SI 3 "gpc_reg_operand" "r,0") + (match_operand:SI 4 "const_int_operand" "n,n"))))] + "rs6000_is_valid_mask (operands[2], NULL, NULL, SImode) + && UINTVAL (operands[2]) != 0 && UINTVAL (operands[4]) != 0 + && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0" + "@ + rlwimi %0,%3,0,%4 + rlwimi %0,%1,0,%2" + [(set_attr "type" "insert")]) + +(define_insn "*rotldi3_insert_6" + [(set (match_operand:DI 0 "gpc_reg_operand" "=r") + (ior:DI (and:DI (match_operand:DI 1 "gpc_reg_operand" "0") + (match_operand:DI 2 "const_int_operand" "n")) + (and:DI (match_operand:DI 3 "gpc_reg_operand" "r") + (match_operand:DI 4 "const_int_operand" "n"))))] + "exact_log2 (-UINTVAL (operands[2])) > 0 + && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0" +{ + operands[5] = GEN_INT (64 - exact_log2 (-UINTVAL (operands[2]))); + return "rldimi %0,%3,0,%5"; +} + [(set_attr "type" "insert") + (set_attr "size" "64")]) + +(define_insn "*rotldi3_insert_7" + [(set (match_operand:DI 0 "gpc_reg_operand" "=r") + (ior:DI (and:DI (match_operand:DI 3 "gpc_reg_operand" "r") + (match_operand:DI 4 "const_int_operand" "n")) + (and:DI (match_operand:DI 1 "gpc_reg_operand" "0") + (match_operand:DI 2 "const_int_operand" "n"))))] + "exact_log2 (-UINTVAL (operands[2])) > 0 + && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0" +{ + operands[5] = GEN_INT (64 - exact_log2 (-UINTVAL (operands[2]))); + return "rldimi %0,%3,0,%5"; +} + [(set_attr "type" "insert") + (set_attr "size" "64")]) + ; This handles the important case of multiple-precision shifts. There is ; no canonicalization rule for ASHIFT vs. LSHIFTRT, so two patterns. -- 1.9.3