https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82524
--- Comment #9 from Jakub Jelinek <jakub at gcc dot gnu.org> --- (In reply to Uroš Bizjak from comment #7) > (In reply to Jakub Jelinek from comment #6) > > (insn 66 37 38 2 (set (reg:SI 0 ax [159]) > > (reg:SI 3 bx [159])) "pr82545.c":27 82 {*movsi_internal} > > (nil)) > > (insn 38 66 39 2 (parallel [ > > (set (zero_extract:SI (reg:SI 0 ax [159]) > > (const_int 8 [0x8]) > > (const_int 8 [0x8])) > > (subreg:SI (plus:QI (subreg:QI (zero_extract:SI (reg:SI 0 ax > > [159]) > > (const_int 8 [0x8]) > > (const_int 8 [0x8])) 0) > > (subreg:QI (zero_extract:SI (reg:SI 1 dx [163]) > > (const_int 8 [0x8]) > > (const_int 8 [0x8])) 0)) 0)) > > (clobber (reg:CC 17 flags)) > > ]) "pr82545.c":27 235 {*addqi_ext_2} > > (nil)) > > Do we need "+Q" instead of "=Q" on LHS zero_extract patterns? That said, yes, I think it should use +Q. As expected, if I fix those, then LRA ICEs, because it really has no way to reload that: --- gcc/config/i386/i386.md.jj 2017-10-12 14:05:15.000000000 +0200 +++ gcc/config/i386/i386.md 2017-10-12 15:45:25.001188884 +0200 @@ -6264,7 +6264,7 @@ (set_attr "mode" "<MODE>")]) (define_insn "addqi_ext_1" - [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q") + [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q") (const_int 8) (const_int 8)) (subreg:SI @@ -6300,7 +6300,7 @@ (set_attr "mode" "QI")]) (define_insn "*addqi_ext_2" - [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") + [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q") (const_int 8) (const_int 8)) (subreg:SI @@ -8998,7 +8998,7 @@ (set_attr "mode" "QI")]) (define_insn "andqi_ext_1" - [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q") + [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q") (const_int 8) (const_int 8)) (subreg:SI @@ -9027,7 +9027,7 @@ (const_int 8)) 0) (match_operand:QI 2 "general_operand" "QnBc,m")) (const_int 0))) - (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q") + (set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q") (const_int 8) (const_int 8)) (subreg:SI @@ -9044,7 +9044,7 @@ (set_attr "mode" "QI")]) (define_insn "*andqi_ext_2" - [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") + [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q") (const_int 8) (const_int 8)) (subreg:SI @@ -9431,7 +9431,7 @@ (set_attr "mode" "<MODE>")]) (define_insn "*<code>qi_ext_1" - [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q") + [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q") (const_int 8) (const_int 8)) (subreg:SI @@ -9449,7 +9449,7 @@ (set_attr "mode" "QI")]) (define_insn "*<code>qi_ext_2" - [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") + [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q") (const_int 8) (const_int 8)) (subreg:SI @@ -9552,7 +9552,7 @@ (const_int 8)) 0) (match_operand:QI 2 "general_operand" "QnBc,m")) (const_int 0))) - (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q") + (set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q") (const_int 8) (const_int 8)) (subreg:SI I think for the non-commutative inputs, we could as well just replace the match_operand 1 with match_dup 0. For the commutative case, we need to verify one of the operands is rtx_equal_p.