This patch tweaks i386.md to ensure that it is AOP-safe, i.e. can recognize
shld and shrd instructions when expressed in RTL using either PLUS, IOR or
XOR. This is a pre-requisite to fixing PR tree-optimization/108477.
This patch has been tested on x86_64-pc-linux-gnu with make bootstrap
and make -k check, both with and without --target_board=unix{-m32}
with no new failures. Ok for mainline?
To double check the approach used, I've also bootstrap and regression
tested a variant using aop_pref_plus that prefers PLUS in the gen_insn
functions, also with no new failures.
2026-09-30 Roger Sayle <[email protected]>
gcc/ChangeLog
* config/i386/i386.md (aop_pref_ior): New code attribute to
produce "*" for XOR/PLUS.
(x86_64_shld<nf_name>): Use any_or_plus and aop_pref_ior.
(x86_64_shld_ndd<nf_name>): Likewise.
(x86_64_shld_1<nf_name>): Likewise.
(x86_64_shld_ndd_1<nf_name>): Likewise.
(*x86_64_shld_shrd_1_nozext_nf): Use any_or_plus.
(*x86_64_shld_shrd_1_nozext): Likewise.
(*x86_64_shld_2): Likewise.
(*x86_64_shld_ndd_2): Likewise.
(x86_shld<nf_name>): Use any_or_plus and aop_pref_ior.
(x86_shld_1<nf_name>): Likewise.
(x86_shld_ndd_1<nf_name>): Likewise.
(*x86_shld_shrd_1_nozext_nf): Use any_or_plus.
(*x86_shld_shrd_1_nozext): Likewise.
(*x86_shld_2): Likewise.
(*x86_shld_ndd_2): Likewise.
(x86_64_shrd<nf_name>): Use any_or_plus and aop_pref_ior.
(x86_64_shrd_ndd<nf_name>): Likewise.
(x86_64_shrd_1<nf_name>): Likewise.
(x86_64_shrd_ndd_1<nf_name>): Likewise.
(*x86_64_shrd_shld_1_nozext_nf): Use any_or_plus.
(*x86_64_shrd_shld_1_nozext): Likewise.
(*x86_64_shrd_2): Likewise.
(*x86_64_shrd_ndd_2): Likewise.
(x86_shrd<nf_name>): Use any_or_plus and aop_pref_ior.
(x86_shrd_ndd<nf_name>): Likewise.
(x86_shrd_1<nf_name>): Likewise.
(x86_shrd_ndd_1<nf_name>): Likewise.
(*x86_shrd_shld_1_nozext_nf): Use any_or_plus.
(*x86_shrd_shld_1_nozext): Likewise.
(*x86_shrd_2): Likewise.
(*x86_shrd_ndd_2): Likewise.
Thanks in advance,
Roger
--
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index 9888644ed91..a02a0b9fdaa 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -3761,6 +3761,8 @@
(set_attr "mode" "QI")])
(define_code_iterator any_or_plus [plus ior xor])
+;; any_or_plus preferred prefix.
+(define_code_attr aop_pref_ior [(ior "") (xor "*") (plus "*")])
(define_insn_and_split "*insvti_highpart_1"
[(set (match_operand:TI 0 "nonimmediate_operand" "=ro,r,r,&r")
@@ -16372,9 +16374,10 @@
(symbol_ref "TARGET_ENABLE_NDD_MEM")]
(symbol_ref "true")))])
-(define_insn "x86_64_shld<nf_name>"
+(define_insn "<aop_pref_ior>x86_64_shld<nf_name>"
[(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
- (ior:DI (ashift:DI (match_dup 0)
+ (any_or_plus:DI
+ (ashift:DI (match_dup 0)
(and:QI (match_operand:QI 2 "nonmemory_operand" "Jc")
(const_int 63)))
(subreg:DI
@@ -16393,9 +16396,10 @@
(set_attr "amdfam10_decode" "vector")
(set_attr "bdver1_decode" "vector")])
-(define_insn "x86_64_shld_ndd<nf_name>"
+(define_insn "<aop_pref_ior>x86_64_shld_ndd<nf_name>"
[(set (match_operand:DI 0 "register_operand" "=r,r")
- (ior:DI (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "r,m")
+ (any_or_plus:DI
+ (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "r,m")
(and:QI (match_operand:QI 3 "nonmemory_operand" "Jc,Jc")
(const_int 63)))
(subreg:DI
@@ -16414,9 +16418,10 @@
(set_attr "has_nf" "1")
(set_attr "mode" "DI")])
-(define_insn "x86_64_shld_1<nf_name>"
+(define_insn "<aop_pref_ior>x86_64_shld_1<nf_name>"
[(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
- (ior:DI (ashift:DI (match_dup 0)
+ (any_or_plus:DI
+ (ashift:DI (match_dup 0)
(match_operand:QI 2 "const_0_to_63_operand"))
(subreg:DI
(lshiftrt:TI
@@ -16436,9 +16441,10 @@
(set_attr "amdfam10_decode" "vector")
(set_attr "bdver1_decode" "vector")])
-(define_insn "x86_64_shld_ndd_1<nf_name>"
+(define_insn "<aop_pref_ior>x86_64_shld_ndd_1<nf_name>"
[(set (match_operand:DI 0 "register_operand" "=r,r")
- (ior:DI (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "r,m")
+ (any_or_plus:DI
+ (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "r,m")
(match_operand:QI 3 "const_0_to_63_operand"))
(subreg:DI
(lshiftrt:TI
@@ -16460,8 +16466,9 @@
(define_insn_and_split "*x86_64_shld_shrd_1_nozext_nf"
[(set (match_operand:DI 0 "nonimmediate_operand")
- (ior:DI (ashift:DI (match_operand:DI 4 "nonimmediate_operand")
- (match_operand:QI 2 "const_0_to_63_operand"))
+ (any_or_plus:DI
+ (ashift:DI (match_operand:DI 4 "nonimmediate_operand")
+ (match_operand:QI 2 "const_0_to_63_operand"))
(lshiftrt:DI
(match_operand:DI 1 "nonimmediate_operand")
(match_operand:QI 3 "const_0_to_63_operand"))))]
@@ -16515,8 +16522,9 @@
(define_insn_and_split "*x86_64_shld_shrd_1_nozext"
[(set (match_operand:DI 0 "nonimmediate_operand")
- (ior:DI (ashift:DI (match_operand:DI 4 "nonimmediate_operand")
- (match_operand:QI 2 "const_0_to_63_operand"))
+ (any_or_plus:DI
+ (ashift:DI (match_operand:DI 4 "nonimmediate_operand")
+ (match_operand:QI 2 "const_0_to_63_operand"))
(lshiftrt:DI
(match_operand:DI 1 "nonimmediate_operand")
(match_operand:QI 3 "const_0_to_63_operand"))))
@@ -16569,7 +16577,8 @@
(define_insn_and_split "*x86_64_shld_2"
[(set (match_operand:DI 0 "nonimmediate_operand")
- (ior:DI (ashift:DI (match_dup 0)
+ (any_or_plus:DI
+ (ashift:DI (match_dup 0)
(match_operand:QI 2 "nonmemory_operand"))
(lshiftrt:DI (match_operand:DI 1 "register_operand")
(minus:QI (const_int 64) (match_dup 2)))))
@@ -16590,7 +16599,8 @@
(define_insn_and_split "*x86_64_shld_ndd_2"
[(set (match_operand:DI 0 "register_operand")
- (ior:DI (ashift:DI (match_operand:DI 1 "nonimmediate_operand")
+ (any_or_plus:DI
+ (ashift:DI (match_operand:DI 1 "nonimmediate_operand")
(match_operand:QI 3 "nonmemory_operand"))
(lshiftrt:DI (match_operand:DI 2 "register_operand")
(minus:QI (const_int 64) (match_dup 3)))))
@@ -16610,9 +16620,10 @@
(const_int 63)))) 0)))
(clobber (reg:CC FLAGS_REG))])])
-(define_insn "x86_shld<nf_name>"
+(define_insn "<aop_pref_ior>x86_shld<nf_name>"
[(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
- (ior:SI (ashift:SI (match_dup 0)
+ (any_or_plus:SI
+ (ashift:SI (match_dup 0)
(and:QI (match_operand:QI 2 "nonmemory_operand" "Ic")
(const_int 31)))
(subreg:SI
@@ -16632,9 +16643,10 @@
(set_attr "amdfam10_decode" "vector")
(set_attr "bdver1_decode" "vector")])
-(define_insn "x86_shld_ndd<nf_name>"
+(define_insn "<aop_pref_ior>x86_shld_ndd<nf_name>"
[(set (match_operand:SI 0 "nonimmediate_operand" "=r,r")
- (ior:SI (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "r,m")
+ (any_or_plus:SI
+ (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "r,m")
(and:QI (match_operand:QI 3 "nonmemory_operand" "Ic,Ic")
(const_int 31)))
(subreg:SI
@@ -16654,9 +16666,10 @@
(set_attr "mode" "SI")])
-(define_insn "x86_shld_1<nf_name>"
+(define_insn "<aop_pref_ior>x86_shld_1<nf_name>"
[(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
- (ior:SI (ashift:SI (match_dup 0)
+ (any_or_plus:SI
+ (ashift:SI (match_dup 0)
(match_operand:QI 2 "const_0_to_31_operand"))
(subreg:SI
(lshiftrt:DI
@@ -16676,9 +16689,10 @@
(set_attr "amdfam10_decode" "vector")
(set_attr "bdver1_decode" "vector")])
-(define_insn "x86_shld_ndd_1<nf_name>"
+(define_insn "<aop_pref_ior>x86_shld_ndd_1<nf_name>"
[(set (match_operand:SI 0 "register_operand" "=r,r")
- (ior:SI (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "r,m")
+ (any_or_plus:SI
+ (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "r,m")
(match_operand:QI 3 "const_0_to_31_operand"))
(subreg:SI
(lshiftrt:DI
@@ -16700,8 +16714,9 @@
(define_insn_and_split "*x86_shld_shrd_1_nozext_nf"
[(set (match_operand:SI 0 "nonimmediate_operand")
- (ior:SI (ashift:SI (match_operand:SI 4 "nonimmediate_operand")
- (match_operand:QI 2 "const_0_to_31_operand"))
+ (any_or_plus:SI
+ (ashift:SI (match_operand:SI 4 "nonimmediate_operand")
+ (match_operand:QI 2 "const_0_to_31_operand"))
(lshiftrt:SI
(match_operand:SI 1 "nonimmediate_operand")
(match_operand:QI 3 "const_0_to_31_operand"))))]
@@ -16755,7 +16770,8 @@
(define_insn_and_split "*x86_shld_shrd_1_nozext"
[(set (match_operand:SI 0 "nonimmediate_operand")
- (ior:SI (ashift:SI (match_operand:SI 4 "nonimmediate_operand")
+ (any_or_plus:SI
+ (ashift:SI (match_operand:SI 4 "nonimmediate_operand")
(match_operand:QI 2 "const_0_to_31_operand"))
(lshiftrt:SI
(match_operand:SI 1 "nonimmediate_operand")
@@ -16808,7 +16824,8 @@
(define_insn_and_split "*x86_shld_2"
[(set (match_operand:SI 0 "nonimmediate_operand")
- (ior:SI (ashift:SI (match_dup 0)
+ (any_or_plus:SI
+ (ashift:SI (match_dup 0)
(match_operand:QI 2 "nonmemory_operand"))
(lshiftrt:SI (match_operand:SI 1 "register_operand")
(minus:QI (const_int 32) (match_dup 2)))))
@@ -16829,7 +16846,8 @@
(define_insn_and_split "*x86_shld_ndd_2"
[(set (match_operand:SI 0 "register_operand")
- (ior:SI (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
+ (any_or_plus:SI
+ (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
(match_operand:QI 3 "nonmemory_operand"))
(lshiftrt:SI (match_operand:SI 2 "register_operand")
(minus:QI (const_int 32) (match_dup 3)))))
@@ -17728,9 +17746,10 @@
}
[(set_attr "has_nf" "1")])
-(define_insn "x86_64_shrd<nf_name>"
+(define_insn "<aop_pref_ior>x86_64_shrd<nf_name>"
[(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
- (ior:DI (lshiftrt:DI (match_dup 0)
+ (any_or_plus:DI
+ (lshiftrt:DI (match_dup 0)
(and:QI (match_operand:QI 2 "nonmemory_operand" "Jc")
(const_int 63)))
(subreg:DI
@@ -17749,9 +17768,10 @@
(set_attr "amdfam10_decode" "vector")
(set_attr "bdver1_decode" "vector")])
-(define_insn "x86_64_shrd_ndd<nf_name>"
+(define_insn "<aop_pref_ior>x86_64_shrd_ndd<nf_name>"
[(set (match_operand:DI 0 "register_operand" "=r,r")
- (ior:DI (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "r,m")
+ (any_or_plus:DI
+ (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "r,m")
(and:QI (match_operand:QI 3 "nonmemory_operand" "Jc,Jc")
(const_int 63)))
(subreg:DI
@@ -17770,9 +17790,10 @@
(set_attr "has_nf" "1")
(set_attr "mode" "DI")])
-(define_insn "x86_64_shrd_1<nf_name>"
+(define_insn "<aop_pref_ior>x86_64_shrd_1<nf_name>"
[(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
- (ior:DI (lshiftrt:DI (match_dup 0)
+ (any_or_plus:DI
+ (lshiftrt:DI (match_dup 0)
(match_operand:QI 2 "const_0_to_63_operand"))
(subreg:DI
(ashift:TI
@@ -17792,9 +17813,10 @@
(set_attr "amdfam10_decode" "vector")
(set_attr "bdver1_decode" "vector")])
-(define_insn "x86_64_shrd_ndd_1<nf_name>"
+(define_insn "<aop_pref_ior>x86_64_shrd_ndd_1<nf_name>"
[(set (match_operand:DI 0 "register_operand" "=r,r")
- (ior:DI (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "r,m")
+ (any_or_plus:DI
+ (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "r,m")
(match_operand:QI 3 "const_0_to_63_operand"))
(subreg:DI
(ashift:TI
@@ -17816,7 +17838,8 @@
(define_insn_and_split "*x86_64_shrd_shld_1_nozext_nf"
[(set (match_operand:DI 0 "nonimmediate_operand")
- (ior:DI (lshiftrt:DI (match_operand:DI 4 "nonimmediate_operand")
+ (any_or_plus:DI
+ (lshiftrt:DI (match_operand:DI 4 "nonimmediate_operand")
(match_operand:QI 2 "const_0_to_63_operand"))
(ashift:DI
(match_operand:DI 1 "nonimmediate_operand")
@@ -17871,7 +17894,8 @@
(define_insn_and_split "*x86_64_shrd_shld_1_nozext"
[(set (match_operand:DI 0 "nonimmediate_operand")
- (ior:DI (lshiftrt:DI (match_operand:DI 4 "nonimmediate_operand")
+ (any_or_plus:DI
+ (lshiftrt:DI (match_operand:DI 4 "nonimmediate_operand")
(match_operand:QI 2 "const_0_to_63_operand"))
(ashift:DI
(match_operand:DI 1 "nonimmediate_operand")
@@ -17925,7 +17949,8 @@
(define_insn_and_split "*x86_64_shrd_2"
[(set (match_operand:DI 0 "nonimmediate_operand")
- (ior:DI (lshiftrt:DI (match_dup 0)
+ (any_or_plus:DI
+ (lshiftrt:DI (match_dup 0)
(match_operand:QI 2 "nonmemory_operand"))
(ashift:DI (match_operand:DI 1 "register_operand")
(minus:QI (const_int 64) (match_dup 2)))))
@@ -17946,7 +17971,8 @@
(define_insn_and_split "*x86_64_shrd_ndd_2"
[(set (match_operand:DI 0 "register_operand")
- (ior:DI (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand")
+ (any_or_plus:DI
+ (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand")
(match_operand:QI 3 "nonmemory_operand"))
(ashift:DI (match_operand:DI 2 "register_operand")
(minus:QI (const_int 64) (match_dup 2)))))
@@ -17966,9 +17992,10 @@
(const_int 63)))) 0)))
(clobber (reg:CC FLAGS_REG))])])
-(define_insn "x86_shrd<nf_name>"
+(define_insn "<aop_pref_ior>x86_shrd<nf_name>"
[(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
- (ior:SI (lshiftrt:SI (match_dup 0)
+ (any_or_plus:SI
+ (lshiftrt:SI (match_dup 0)
(and:QI (match_operand:QI 2 "nonmemory_operand" "Ic")
(const_int 31)))
(subreg:SI
@@ -17988,9 +18015,10 @@
(set_attr "amdfam10_decode" "vector")
(set_attr "bdver1_decode" "vector")])
-(define_insn "x86_shrd_ndd<nf_name>"
+(define_insn "<aop_pref_ior>x86_shrd_ndd<nf_name>"
[(set (match_operand:SI 0 "register_operand" "=r,r")
- (ior:SI (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "r,m")
+ (any_or_plus:SI
+ (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "r,m")
(and:QI (match_operand:QI 3 "nonmemory_operand" "Ic,Ic")
(const_int 31)))
(subreg:SI
@@ -18009,9 +18037,10 @@
(set_attr "has_nf" "1")
(set_attr "mode" "SI")])
-(define_insn "x86_shrd_1<nf_name>"
+(define_insn "<aop_pref_ior>x86_shrd_1<nf_name>"
[(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
- (ior:SI (lshiftrt:SI (match_dup 0)
+ (any_or_plus:SI
+ (lshiftrt:SI (match_dup 0)
(match_operand:QI 2 "const_0_to_31_operand"))
(subreg:SI
(ashift:DI
@@ -18031,9 +18060,10 @@
(set_attr "amdfam10_decode" "vector")
(set_attr "bdver1_decode" "vector")])
-(define_insn "x86_shrd_ndd_1<nf_name>"
+(define_insn "<aop_pref_ior>x86_shrd_ndd_1<nf_name>"
[(set (match_operand:SI 0 "register_operand" "=r,r")
- (ior:SI (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "r,m")
+ (any_or_plus:SI
+ (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "r,m")
(match_operand:QI 3 "const_0_to_31_operand"))
(subreg:SI
(ashift:DI
@@ -18055,8 +18085,9 @@
(define_insn_and_split "*x86_shrd_shld_1_nozext_nf"
[(set (match_operand:SI 0 "nonimmediate_operand")
- (ior:SI (lshiftrt:SI (match_operand:SI 4 "nonimmediate_operand")
- (match_operand:QI 2 "const_0_to_31_operand"))
+ (any_or_plus:SI
+ (lshiftrt:SI (match_operand:SI 4 "nonimmediate_operand")
+ (match_operand:QI 2 "const_0_to_31_operand"))
(ashift:SI
(match_operand:SI 1 "nonimmediate_operand")
(match_operand:QI 3 "const_0_to_31_operand"))))]
@@ -18110,8 +18141,9 @@
(define_insn_and_split "*x86_shrd_shld_1_nozext"
[(set (match_operand:SI 0 "nonimmediate_operand")
- (ior:SI (lshiftrt:SI (match_operand:SI 4 "nonimmediate_operand")
- (match_operand:QI 2 "const_0_to_31_operand"))
+ (any_or_plus:SI
+ (lshiftrt:SI (match_operand:SI 4 "nonimmediate_operand")
+ (match_operand:QI 2 "const_0_to_31_operand"))
(ashift:SI
(match_operand:SI 1 "nonimmediate_operand")
(match_operand:QI 3 "const_0_to_31_operand"))))
@@ -18163,7 +18195,8 @@
(define_insn_and_split "*x86_shrd_2"
[(set (match_operand:SI 0 "nonimmediate_operand")
- (ior:SI (lshiftrt:SI (match_dup 0)
+ (any_or_plus:SI
+ (lshiftrt:SI (match_dup 0)
(match_operand:QI 2 "nonmemory_operand"))
(ashift:SI (match_operand:SI 1 "register_operand")
(minus:QI (const_int 32) (match_dup 2)))))
@@ -18184,7 +18217,8 @@
(define_insn_and_split "*x86_shrd_ndd_2"
[(set (match_operand:SI 0 "register_operand")
- (ior:SI (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand")
+ (any_or_plus:SI
+ (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand")
(match_operand:QI 3 "nonmemory_operand"))
(ashift:SI (match_operand:SI 2 "register_operand")
(minus:QI (const_int 32) (match_dup 3)))))