aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorUros Bizjak <ubizjak@gmail.com>2025-08-06 20:06:42 +0200
committerUros Bizjak <ubizjak@gmail.com>2025-08-07 00:08:46 +0200
commit84476b4c88465f09c3ec1a52fdf0df1a76364988 (patch)
tree756cc76fe8381c17315771c5779630dff8e722f6 /gcc
parent01a523943c0a9b297726289d7333a5217b1d4d31 (diff)
downloadgcc-84476b4c88465f09c3ec1a52fdf0df1a76364988.zip
gcc-84476b4c88465f09c3ec1a52fdf0df1a76364988.tar.gz
gcc-84476b4c88465f09c3ec1a52fdf0df1a76364988.tar.bz2
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.sandiford@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.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/config/i386/i386.md14
-rw-r--r--gcc/config/i386/predicates.md6
2 files changed, 12 insertions, 8 deletions
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index 2b0dd66..6686f10 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 0f31090..175798c 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"))