https://gcc.gnu.org/g:84476b4c88465f09c3ec1a52fdf0df1a76364988
commit r16-3054-g84476b4c88465f09c3ec1a52fdf0df1a76364988 Author: Uros Bizjak <ubiz...@gmail.com> Date: Wed Aug 6 20:06:42 2025 +0200 i386: Fix invalid RTX mode in the unnamed rotate splitter. The following splitter from the commit r11-5747: (define_split [(set (match_operand:SWI 0 "register_operand") (any_rotate:SWI (match_operand:SWI 1 "const_int_operand") (subreg:QI (and (match_operand 2 "int248_register_operand") (match_operand 3 "const_int_operand")) 0)))] "(INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode) - 1)) == GET_MODE_BITSIZE (<MODE>mode) - 1" [(set (match_dup 4) (match_dup 1)) (set (match_dup 0) (any_rotate:SWI (match_dup 4) (subreg:QI (and:SI (match_dup 2) (match_dup 3)) 0)))] "operands[4] = gen_reg_rtx (<MODE>mode);") matches any mode of (and ...) on input, but hard-codes (and:SI ...) in the output. This causes an ICE if the incoming (and ...) is DImode rather than SImode. Co-developed-by: Richard Sandiford <richard.sandif...@arm.com> PR target/96226 gcc/ChangeLog: * config/i386/predicates.md (and_operator): New operator. * config/i386/i386.md (splitter after *<rotate_insn><mode>3_mask): Use and_operator to match AND RTX and use its mode in the split pattern. Diff: --- gcc/config/i386/i386.md | 14 +++++++------- gcc/config/i386/predicates.md | 6 +++++- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index 2b0dd66c68b6..6686f1070f9f 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -18298,17 +18298,17 @@ (any_rotate:SWI (match_operand:SWI 1 "const_int_operand") (subreg:QI - (and - (match_operand 2 "int248_register_operand") - (match_operand 3 "const_int_operand")) 0)))] + (match_operator 4 "and_operator" + [(match_operand 2 "int248_register_operand") + (match_operand 3 "const_int_operand")]) 0)))] "(INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode) - 1)) == GET_MODE_BITSIZE (<MODE>mode) - 1" - [(set (match_dup 4) (match_dup 1)) + [(set (match_dup 5) (match_dup 1)) (set (match_dup 0) - (any_rotate:SWI (match_dup 4) + (any_rotate:SWI (match_dup 5) (subreg:QI - (and:SI (match_dup 2) (match_dup 3)) 0)))] - "operands[4] = gen_reg_rtx (<MODE>mode);") + (match_op_dup 4 [(match_dup 2) (match_dup 3)]) 0)))] + "operands[5] = gen_reg_rtx (<MODE>mode);") (define_insn_and_split "*<insn><mode>3_mask_1" [(set (match_operand:SWI 0 "nonimmediate_operand") diff --git a/gcc/config/i386/predicates.md b/gcc/config/i386/predicates.md index 0f310902e7b4..175798cff69b 100644 --- a/gcc/config/i386/predicates.md +++ b/gcc/config/i386/predicates.md @@ -1714,10 +1714,14 @@ (define_predicate "div_operator" (match_code "div")) -;; Return true if this is a and, ior or xor operation. +;; Return true if this is an and, ior or xor operation. (define_predicate "logic_operator" (match_code "and,ior,xor")) +;; Return true if this is an and operation. +(define_predicate "and_operator" + (match_code "and")) + ;; Return true if this is a plus, minus, and, ior or xor operation. (define_predicate "plusminuslogic_operator" (match_code "plus,minus,and,ior,xor"))