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"))

Reply via email to