i386: Fix mode of ZERO_EXTRACT RTXes, remove ext_register_operand predicate.

The mode of ZERO_EXTRACT RTX should match the mode of its LOC register
operand.  The mode should be HI, SI or DImode to enable combine to synthesize
extractions from HImode and DImode operands, in addition to existing SImode.
Further, these changes tighten allowed modes for extv, extzv and insv
named patterns and finally enable removal of ext_register_operand
special predicate.

2020-18-06  Uroš Bizjak  <ubizjak@gmail.com>

gcc/ChangeLog:

	* config/i386/i386.md (*cmpqi_ext<mode>_1): Use SWI248 mode
	iterator instead of SImode for ZERO_EXTRACT RTX.  Use SWI248
	mode iterator for the first operand of ZERO_EXTRACT RTX.
	Change ext_register_operand predicate to register_operand.
	Rename from *cmpqi_ext_1.
	(*cmpqi_ext<mode>_2): Ditto.  Rename from *cmpqi_ext_2.
	(*cmpqi_ext<mode>_3): Ditto.  Rename from *cmpqi_ext_3.
	(*cmpqi_ext<mode>_4): Ditto.  Rename from *cmpqi_ext_4.
	(cmpi_ext_3): Use HImode instead of SImode for ZERO_EXTRACT RTX.
	(*extv<mode>): Use SWI24 mode iterator for the first operand
	of ZERO_EXTRACT RTX.  Change ext_register_operand predicate
	to register_operand.
	(*extzv<mode>): Use SWI248 mode iterator for the first operand
	of ZERO_EXTRACT RTX.  Change ext_register_operand predicate
	to register_operand.
	(*extzvqi): Use SWI248 mode iterator instead of SImode for
	ZERO_EXTRACT RTX.  Use SWI248 mode iterator for the first operand
	of ZERO_EXTRACT RTX.  Change ext_register_operand predicate to
	register_operand.
	(*extzvqi_mem_rex64 and corresponding peephole2):  Use SWI248 mode
	iterator instead of SImode for ZERO_EXTRACT RTX.  Use SWI248
	mode iterator for the first operand of ZERO_EXTRACT RTX.
	Change ext_register_operand predicate to register_operand.
	(@insv<mode>_1): Use SWI248 mode iterator for the first operand
	of ZERO_EXTRACT RTX.  Change ext_register_operand predicate to
	register_operand.
	(*insvqi_1): Use SWI248 mode iterator instead of SImode
	for ZERO_EXTRACT RTX.  Use SWI248 mode iterator for the
	first operand of ZERO_EXTRACT RTX.  Change ext_register_operand
	predicate to register_operand.
	(*insvqi_2): Ditto.
	(*insvqi_3): Ditto.
	(*insvqi_1_mem_rex64 and corresponding peephole2):  Use SWI248 mode
	iterator instead of SImode for ZERO_EXTRACT RTX.  Use SWI248
	mode iterator for the first operand of ZERO_EXTRACT RTX.
	Change ext_register_operand predicate to register_operand.
	(addqi_ext_1): New expander.
	(*addqi_ext<mode>_1): Use SWI248 mode iterator instead of SImode
	for ZERO_EXTRACT RTX.  Use SWI248 mode iterator for the first
	operand of ZERO_EXTRACT RTX.  Change ext_register_operand predicate
	to register_operand.  Rename from *addqi_ext_1.
	(*addqi_ext<mode>_2): Ditto. Rename from *addqi_ext_2.
	(divmodqi4): Use HImode instead of SImode for ZERO_EXTRACT RTX.
	(udivmodqi4): Ditto.
	(testqi_ext_1): Use HImode instead of SImode for ZERO_EXTRACT RTX.
	(*testqi_ext<mode>_1): Use SWI248 mode iterator instead of SImode
	for ZERO_EXTRACT RTX.  Use SWI248 mode iterator for the first
	operand of ZERO_EXTRACT RTX.  Change ext_register_operand predicate
	to register_operand.  Rename from *testqi_ext_1.
	(*testqi_ext<mode>_2): Ditto.  Rename from *testqi_ext_2.
	(andqi_ext_1): New expander.
	(*andqi_ext<mode>_1): Use SWI248 mode iterator instead of SImode
	for ZERO_EXTRACT RTX.  Use SWI248 mode iterator for the first
	operand of ZERO_EXTRACT RTX.  Change ext_register_operand predicate
	to register_operand.  Rename from andqi_ext_1.
	(*andqi_ext<mode>_1_cc): Ditto.  Rename from *andqi_ext_1_cc.
	(*andqi_ext<mode>_2): Ditto.  Rename from *andqi_ext_2.
	(*<code>qi_ext<mode>_1): Ditto.  Rename from *<code>qi_ext_1.
	(*<code>qi_ext<mode>_2): Ditto.  Rename from *<code>qi_ext_2.
	(xorqi_ext_1_cc): Use HImode instead of SImode for ZERO_EXTRACT RTX.
	(*xorqi_ext<mode>_1_cc):  Use SWI248 mode iterator instead of SImode
	for ZERO_EXTRACT RTX.  Use SWI248 mode iterator for the first
	operand of ZERO_EXTRACT RTX.  Change ext_register_operand predicate
	to register_operand.  Rename from *xorqi_ext_1_cc.
	* config/i386/i386-expand.c (ix86_split_idivmod): Emit ZERO_EXTRACT
	in mode, matching its first operand.
	(promote_duplicated_reg): Update for renamed insv<mode>_1.
	* config/i386/predicates.md (ext_register_operand): Remove predicate.

gcc/testsuite/ChangeLog:

	* gcc.target/i386/pr78904-1a.c: New test.
	* gcc.target/i386/pr78904-1b.c: Ditto.
	* gcc.target/i386/pr78904-2a.c: Ditto.
	* gcc.target/i386/pr78904-2b.c: Ditto.
	* gcc.target/i386/pr78904-3a.c: Ditto.
	* gcc.target/i386/pr78904-3b.c: Ditto.
	* gcc.target/i386/pr78904-4a.c: Ditto.
	* gcc.target/i386/pr78904-4b.c: Ditto.
	* gcc.target/i386/pr78904-5a.c: Ditto.
	* gcc.target/i386/pr78904-5b.c: Ditto.
	* gcc.target/i386/pr78904-6a.c: Ditto.
	* gcc.target/i386/pr78904-6b.c: Ditto.
	* gcc.target/i386/pr78967-1a.c: Ditto.
	* gcc.target/i386/pr78967-1b.c: Ditto.
	* gcc.target/i386/pr78967-2a.c: Ditto.
	* gcc.target/i386/pr78967-2b.c: Ditto.
This commit is contained in:
Uros Bizjak 2020-06-18 20:12:48 +02:00
parent 5acc654e38
commit e95395926a
19 changed files with 764 additions and 220 deletions

View file

@ -1179,9 +1179,8 @@ ix86_split_idivmod (machine_mode mode, rtx operands[],
JUMP_LABEL (insn) = qimode_label;
/* Generate original signed/unsigned divimod. */
div = gen_divmod4_1 (operands[0], operands[1],
operands[2], operands[3]);
emit_insn (div);
emit_insn (gen_divmod4_1 (operands[0], operands[1],
operands[2], operands[3]));
/* Branch to the end. */
emit_jump_insn (gen_jump (end_label));
@ -1215,18 +1214,10 @@ ix86_split_idivmod (machine_mode mode, rtx operands[],
}
/* Extract remainder from AH. */
tmp1 = gen_rtx_ZERO_EXTRACT (GET_MODE (operands[1]),
tmp0, GEN_INT (8), GEN_INT (8));
if (REG_P (operands[1]))
insn = emit_move_insn (operands[1], tmp1);
else
{
/* Need a new scratch register since the old one has result
of 8bit divide. */
scratch = gen_reg_rtx (GET_MODE (operands[1]));
emit_move_insn (scratch, tmp1);
insn = emit_move_insn (operands[1], scratch);
}
scratch = gen_lowpart (GET_MODE (operands[1]), scratch);
tmp1 = gen_rtx_ZERO_EXTRACT (GET_MODE (operands[1]), scratch,
GEN_INT (8), GEN_INT (8));
insn = emit_move_insn (operands[1], tmp1);
set_unique_reg_note (insn, REG_EQUAL, mod);
/* Zero extend quotient from AL. */
@ -7060,10 +7051,7 @@ promote_duplicated_reg (machine_mode mode, rtx val)
rtx reg = convert_modes (mode, QImode, val, true);
if (!TARGET_PARTIAL_REG_STALL)
if (mode == SImode)
emit_insn (gen_insvsi_1 (reg, reg));
else
emit_insn (gen_insvdi_1 (reg, reg));
emit_insn (gen_insv_1 (mode, reg, reg));
else
{
tmp = expand_simple_binop (mode, ASHIFT, reg, GEN_INT (8),

View file

@ -1355,13 +1355,13 @@
[(set_attr "type" "icmp")
(set_attr "mode" "<MODE>")])
(define_insn "*cmpqi_ext_1"
(define_insn "*cmpqi_ext<mode>_1"
[(set (reg FLAGS_REG)
(compare
(match_operand:QI 0 "nonimmediate_operand" "QBc,m")
(subreg:QI
(zero_extract:SI
(match_operand 1 "ext_register_operand" "Q,Q")
(zero_extract:SWI248
(match_operand:SWI248 1 "register_operand" "Q,Q")
(const_int 8)
(const_int 8)) 0)))]
"ix86_match_ccmode (insn, CCmode)"
@ -1370,12 +1370,12 @@
(set_attr "type" "icmp")
(set_attr "mode" "QI")])
(define_insn "*cmpqi_ext_2"
(define_insn "*cmpqi_ext<mode>_2"
[(set (reg FLAGS_REG)
(compare
(subreg:QI
(zero_extract:SI
(match_operand 0 "ext_register_operand" "Q")
(zero_extract:SWI248
(match_operand:SWI248 0 "register_operand" "Q")
(const_int 8)
(const_int 8)) 0)
(match_operand:QI 1 "const0_operand")))]
@ -1389,18 +1389,18 @@
[(set (reg:CC FLAGS_REG)
(compare:CC
(subreg:QI
(zero_extract:SI
(match_operand 0 "ext_register_operand")
(zero_extract:HI
(match_operand:HI 0 "register_operand")
(const_int 8)
(const_int 8)) 0)
(match_operand:QI 1 "const_int_operand")))])
(define_insn "*cmpqi_ext_3"
(define_insn "*cmpqi_ext<mode>_3"
[(set (reg FLAGS_REG)
(compare
(subreg:QI
(zero_extract:SI
(match_operand 0 "ext_register_operand" "Q,Q")
(zero_extract:SWI248
(match_operand:SWI248 0 "register_operand" "Q,Q")
(const_int 8)
(const_int 8)) 0)
(match_operand:QI 1 "general_operand" "QnBc,m")))]
@ -1410,17 +1410,17 @@
(set_attr "type" "icmp")
(set_attr "mode" "QI")])
(define_insn "*cmpqi_ext_4"
(define_insn "*cmpqi_ext<mode>_4"
[(set (reg FLAGS_REG)
(compare
(subreg:QI
(zero_extract:SI
(match_operand 0 "ext_register_operand" "Q")
(zero_extract:SWI248
(match_operand:SWI248 0 "register_operand" "Q")
(const_int 8)
(const_int 8)) 0)
(subreg:QI
(zero_extract:SI
(match_operand 1 "ext_register_operand" "Q")
(zero_extract:SWI248
(match_operand:SWI248 1 "register_operand" "Q")
(const_int 8)
(const_int 8)) 0)))]
"ix86_match_ccmode (insn, CCmode)"
@ -2775,7 +2775,7 @@
(define_insn "*extv<mode>"
[(set (match_operand:SWI24 0 "register_operand" "=R")
(sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
(sign_extract:SWI24 (match_operand:SWI24 1 "register_operand" "Q")
(const_int 8)
(const_int 8)))]
""
@ -2807,9 +2807,10 @@
(define_insn "*extzvqi_mem_rex64"
[(set (match_operand:QI 0 "norex_memory_operand" "=Bn")
(subreg:QI
(zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
(const_int 8)
(const_int 8)) 0))]
(zero_extract:SWI248
(match_operand:SWI248 1 "register_operand" "Q")
(const_int 8)
(const_int 8)) 0))]
"TARGET_64BIT && reload_completed"
"mov{b}\t{%h1, %0|%0, %h1}"
[(set_attr "type" "imov")
@ -2817,7 +2818,7 @@
(define_insn "*extzv<mode>"
[(set (match_operand:SWI248 0 "register_operand" "=R")
(zero_extract:SWI248 (match_operand 1 "ext_register_operand" "Q")
(zero_extract:SWI248 (match_operand:SWI248 1 "register_operand" "Q")
(const_int 8)
(const_int 8)))]
""
@ -2828,9 +2829,10 @@
(define_insn "*extzvqi"
[(set (match_operand:QI 0 "nonimmediate_operand" "=QBc,?R,m")
(subreg:QI
(zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q,Q")
(const_int 8)
(const_int 8)) 0))]
(zero_extract:SWI248
(match_operand:SWI248 1 "register_operand" "Q,Q,Q")
(const_int 8)
(const_int 8)) 0))]
""
{
switch (get_attr_type (insn))
@ -2856,17 +2858,17 @@
(define_peephole2
[(set (match_operand:QI 0 "register_operand")
(subreg:QI
(zero_extract:SI (match_operand 1 "ext_register_operand")
(const_int 8)
(const_int 8)) 0))
(zero_extract:SWI248 (match_operand:SWI248 1 "register_operand")
(const_int 8)
(const_int 8)) 0))
(set (match_operand:QI 2 "norex_memory_operand") (match_dup 0))]
"TARGET_64BIT
&& peep2_reg_dead_p (2, operands[0])"
[(set (match_dup 2)
(subreg:QI
(zero_extract:SI (match_dup 1)
(const_int 8)
(const_int 8)) 0))])
(zero_extract:SWI248 (match_dup 1)
(const_int 8)
(const_int 8)) 0))])
(define_expand "insv<mode>"
[(set (zero_extract:SWI248 (match_operand:SWI248 0 "register_operand")
@ -2892,7 +2894,7 @@
else
dst = operands[0];
emit_insn (gen_insv<mode>_1 (dst, operands[3]));
emit_insn (gen_insv_1 (<MODE>mode, dst, operands[3]));
/* Fix up the destination if needed. */
if (dst != operands[0])
@ -2902,20 +2904,22 @@
})
(define_insn "*insvqi_1_mem_rex64"
[(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
(const_int 8)
(const_int 8))
(subreg:SI
[(set (zero_extract:SWI248
(match_operand:SWI248 0 "register_operand" "+Q")
(const_int 8)
(const_int 8))
(subreg:SWI248
(match_operand:QI 1 "norex_memory_operand" "Bn") 0))]
"TARGET_64BIT && reload_completed"
"mov{b}\t{%1, %h0|%h0, %1}"
[(set_attr "type" "imov")
(set_attr "mode" "QI")])
(define_insn "insv<mode>_1"
[(set (zero_extract:SWI248 (match_operand 0 "ext_register_operand" "+Q,Q")
(const_int 8)
(const_int 8))
(define_insn "@insv<mode>_1"
[(set (zero_extract:SWI248
(match_operand:SWI248 0 "register_operand" "+Q,Q")
(const_int 8)
(const_int 8))
(match_operand:SWI248 1 "general_operand" "QnBc,m"))]
""
{
@ -2928,10 +2932,11 @@
(set_attr "mode" "QI")])
(define_insn "*insvqi_1"
[(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
(const_int 8)
(const_int 8))
(subreg:SI
[(set (zero_extract:SWI248
(match_operand:SWI248 0 "register_operand" "+Q,Q")
(const_int 8)
(const_int 8))
(subreg:SWI248
(match_operand:QI 1 "general_operand" "QnBc,m") 0))]
""
"mov{b}\t{%1, %h0|%h0, %1}"
@ -2942,37 +2947,41 @@
(define_peephole2
[(set (match_operand:QI 0 "register_operand")
(match_operand:QI 1 "norex_memory_operand"))
(set (zero_extract:SI (match_operand 2 "ext_register_operand")
(const_int 8)
(const_int 8))
(subreg:SI (match_dup 0) 0))]
(set (zero_extract:SWI248 (match_operand:SWI248 2 "register_operand")
(const_int 8)
(const_int 8))
(subreg:SWI248 (match_dup 0) 0))]
"TARGET_64BIT
&& peep2_reg_dead_p (2, operands[0])"
[(set (zero_extract:SI (match_dup 2)
(const_int 8)
(const_int 8))
(subreg:SI (match_dup 1) 0))])
[(set (zero_extract:SWI248 (match_dup 2)
(const_int 8)
(const_int 8))
(subreg:SWI248 (match_dup 1) 0))])
(define_code_iterator any_extract [sign_extract zero_extract])
(define_insn "*insvqi_2"
[(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
(const_int 8)
(const_int 8))
(any_extract:SI (match_operand 1 "ext_register_operand" "Q")
(const_int 8)
(const_int 8)))]
[(set (zero_extract:SWI248
(match_operand:SWI248 0 "register_operand" "+Q")
(const_int 8)
(const_int 8))
(any_extract:SWI248
(match_operand:SWI248 1 "register_operand" "Q")
(const_int 8)
(const_int 8)))]
""
"mov{b}\t{%h1, %h0|%h0, %h1}"
[(set_attr "type" "imov")
(set_attr "mode" "QI")])
(define_insn "*insvqi_3"
[(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
(const_int 8)
(const_int 8))
(any_shiftrt:SI (match_operand:SI 1 "register_operand" "Q")
(const_int 8)))]
[(set (zero_extract:SWI248
(match_operand:SWI248 0 "register_operand" "+Q")
(const_int 8)
(const_int 8))
(any_shiftrt:SWI248
(match_operand:SWI248 1 "register_operand" "Q")
(const_int 8)))]
""
"mov{b}\t{%h1, %h0|%h0, %h1}"
[(set_attr "type" "imov")
@ -5835,16 +5844,32 @@
(const_string "*")))
(set_attr "mode" "<MODE>")])
(define_insn "addqi_ext_1"
[(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
(const_int 8)
(const_int 8))
(subreg:SI
(define_expand "addqi_ext_1"
[(parallel
[(set (zero_extract:HI (match_operand:HI 0 "register_operand")
(const_int 8)
(const_int 8))
(subreg:HI
(plus:QI
(subreg:QI
(zero_extract:HI (match_operand:HI 1 "register_operand")
(const_int 8)
(const_int 8)) 0)
(match_operand:QI 2 "const_int_operand")) 0))
(clobber (reg:CC FLAGS_REG))])])
(define_insn "*addqi_ext<mode>_1"
[(set (zero_extract:SWI248
(match_operand:SWI248 0 "register_operand" "+Q,Q")
(const_int 8)
(const_int 8))
(subreg:SWI248
(plus:QI
(subreg:QI
(zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
(const_int 8)
(const_int 8)) 0)
(zero_extract:SWI248
(match_operand:SWI248 1 "register_operand" "0,0")
(const_int 8)
(const_int 8)) 0)
(match_operand:QI 2 "general_operand" "QnBc,m")) 0))
(clobber (reg:CC FLAGS_REG))]
"/* FIXME: without this LRA can't reload this pattern, see PR82524. */
@ -5872,20 +5897,23 @@
(const_string "alu")))
(set_attr "mode" "QI")])
(define_insn "*addqi_ext_2"
[(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
(const_int 8)
(const_int 8))
(subreg:SI
(define_insn "*addqi_ext<mode>_2"
[(set (zero_extract:SWI248
(match_operand:SWI248 0 "register_operand" "+Q")
(const_int 8)
(const_int 8))
(subreg:SWI248
(plus:QI
(subreg:QI
(zero_extract:SI (match_operand 1 "ext_register_operand" "%0")
(const_int 8)
(const_int 8)) 0)
(zero_extract:SWI248
(match_operand:SWI248 1 "register_operand" "%0")
(const_int 8)
(const_int 8)) 0)
(subreg:QI
(zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
(const_int 8)
(const_int 8)) 0)) 0))
(zero_extract:SWI248
(match_operand:SWI248 2 "register_operand" "Q")
(const_int 8)
(const_int 8)) 0)) 0))
(clobber (reg:CC FLAGS_REG))]
"/* FIXME: without this LRA can't reload this pattern, see PR82524. */
rtx_equal_p (operands[0], operands[1])
@ -8556,8 +8584,8 @@
emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
/* Extract remainder from AH. */
tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
tmp1 = lowpart_subreg (QImode, tmp1, SImode);
tmp1 = gen_rtx_ZERO_EXTRACT (HImode, tmp0, GEN_INT (8), GEN_INT (8));
tmp1 = lowpart_subreg (QImode, tmp1, HImode);
rtx_insn *insn = emit_move_insn (operands[3], tmp1);
mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
@ -8593,8 +8621,8 @@
emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
/* Extract remainder from AH. */
tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
tmp1 = lowpart_subreg (QImode, tmp1, SImode);
tmp1 = gen_rtx_ZERO_EXTRACT (HImode, tmp0, GEN_INT (8), GEN_INT (8));
tmp1 = lowpart_subreg (QImode, tmp1, HImode);
rtx_insn *insn = emit_move_insn (operands[3], tmp1);
mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
@ -8740,20 +8768,22 @@
(compare:CCNO
(and:QI
(subreg:QI
(zero_extract:SI (match_operand 0 "ext_register_operand")
(const_int 8)
(const_int 8)) 0)
(match_operand 1 "const_int_operand"))
(zero_extract:HI
(match_operand:HI 0 "register_operand")
(const_int 8)
(const_int 8)) 0)
(match_operand:QI 1 "const_int_operand"))
(const_int 0)))])
(define_insn "*testqi_ext_1"
(define_insn "*testqi_ext<mode>_1"
[(set (reg FLAGS_REG)
(compare
(and:QI
(subreg:QI
(zero_extract:SI (match_operand 0 "ext_register_operand" "Q,Q")
(const_int 8)
(const_int 8)) 0)
(zero_extract:SWI248
(match_operand:SWI248 0 "register_operand" "Q,Q")
(const_int 8)
(const_int 8)) 0)
(match_operand:QI 1 "general_operand" "QnBc,m"))
(const_int 0)))]
"ix86_match_ccmode (insn, CCNOmode)"
@ -8762,18 +8792,20 @@
(set_attr "type" "test")
(set_attr "mode" "QI")])
(define_insn "*testqi_ext_2"
(define_insn "*testqi_ext<mode>_2"
[(set (reg FLAGS_REG)
(compare
(and:QI
(subreg:QI
(zero_extract:SI (match_operand 0 "ext_register_operand" "Q")
(const_int 8)
(const_int 8)) 0)
(zero_extract:SWI248
(match_operand:SWI248 0 "register_operand" "Q")
(const_int 8)
(const_int 8)) 0)
(subreg:QI
(zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
(const_int 8)
(const_int 8)) 0))
(zero_extract:SWI248
(match_operand:SWI248 1 "register_operand" "Q")
(const_int 8)
(const_int 8)) 0))
(const_int 0)))]
"ix86_match_ccmode (insn, CCNOmode)"
"test{b}\t{%h1, %h0|%h0, %h1}"
@ -9312,16 +9344,32 @@
[(set_attr "type" "alu")
(set_attr "mode" "<MODE>")])
(define_insn "andqi_ext_1"
[(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
(const_int 8)
(const_int 8))
(subreg:SI
(define_expand "andqi_ext_1"
[(parallel
[(set (zero_extract:HI (match_operand:HI 0 "register_operand")
(const_int 8)
(const_int 8))
(subreg:HI
(and:QI
(subreg:QI
(zero_extract:HI (match_operand:HI 1 "register_operand")
(const_int 8)
(const_int 8)) 0)
(match_operand:QI 2 "const_int_operand")) 0))
(clobber (reg:CC FLAGS_REG))])])
(define_insn "*andqi_ext<mode>_1"
[(set (zero_extract:SWI248
(match_operand:SWI248 0 "register_operand" "+Q,Q")
(const_int 8)
(const_int 8))
(subreg:SWI248
(and:QI
(subreg:QI
(zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
(const_int 8)
(const_int 8)) 0)
(zero_extract:SWI248
(match_operand:SWI248 1 "register_operand" "0,0")
(const_int 8)
(const_int 8)) 0)
(match_operand:QI 2 "general_operand" "QnBc,m")) 0))
(clobber (reg:CC FLAGS_REG))]
"/* FIXME: without this LRA can't reload this pattern, see PR82524. */
@ -9333,25 +9381,28 @@
;; Generated by peephole translating test to and. This shows up
;; often in fp comparisons.
(define_insn "*andqi_ext_1_cc"
(define_insn "*andqi_ext<mode>_1_cc"
[(set (reg FLAGS_REG)
(compare
(and:QI
(subreg:QI
(zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
(const_int 8)
(const_int 8)) 0)
(zero_extract:SWI248
(match_operand:SWI248 1 "register_operand" "0,0")
(const_int 8)
(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")
(const_int 8)
(const_int 8))
(subreg:SI
(set (zero_extract:SWI248
(match_operand:SWI248 0 "register_operand" "+Q,Q")
(const_int 8)
(const_int 8))
(subreg:SWI248
(and:QI
(subreg:QI
(zero_extract:SI (match_dup 1)
(const_int 8)
(const_int 8)) 0)
(zero_extract:SWI248
(match_dup 1)
(const_int 8)
(const_int 8)) 0)
(match_dup 2)) 0))]
"ix86_match_ccmode (insn, CCNOmode)
/* FIXME: without this LRA can't reload this pattern, see PR82524. */
@ -9361,20 +9412,23 @@
(set_attr "type" "alu")
(set_attr "mode" "QI")])
(define_insn "*andqi_ext_2"
[(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
(const_int 8)
(const_int 8))
(subreg:SI
(define_insn "*andqi_ext<mode>_2"
[(set (zero_extract:SWI248
(match_operand:SWI248 0 "register_operand" "+Q")
(const_int 8)
(const_int 8))
(subreg:SWI248
(and:QI
(subreg:QI
(zero_extract:SI (match_operand 1 "ext_register_operand" "%0")
(const_int 8)
(const_int 8)) 0)
(zero_extract:SWI248
(match_operand:SWI248 1 "register_operand" "%0")
(const_int 8)
(const_int 8)) 0)
(subreg:QI
(zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
(const_int 8)
(const_int 8)) 0)) 0))
(zero_extract:SWI248
(match_operand:SWI248 2 "register_operand" "Q")
(const_int 8)
(const_int 8)) 0)) 0))
(clobber (reg:CC FLAGS_REG))]
"/* FIXME: without this LRA can't reload this pattern, see PR82524. */
rtx_equal_p (operands[0], operands[1])
@ -9743,16 +9797,18 @@
[(set_attr "type" "alu")
(set_attr "mode" "<MODE>")])
(define_insn "*<code>qi_ext_1"
[(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
(const_int 8)
(const_int 8))
(subreg:SI
(define_insn "*<code>qi_ext<mode>_1"
[(set (zero_extract:SWI248
(match_operand:SWI248 0 "register_operand" "+Q,Q")
(const_int 8)
(const_int 8))
(subreg:SWI248
(any_or:QI
(subreg:QI
(zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
(const_int 8)
(const_int 8)) 0)
(zero_extract:SWI248
(match_operand:SWI248 1 "register_operand" "0,0")
(const_int 8)
(const_int 8)) 0)
(match_operand:QI 2 "general_operand" "QnBc,m")) 0))
(clobber (reg:CC FLAGS_REG))]
"(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
@ -9763,20 +9819,23 @@
(set_attr "type" "alu")
(set_attr "mode" "QI")])
(define_insn "*<code>qi_ext_2"
[(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
(const_int 8)
(const_int 8))
(subreg:SI
(define_insn "*<code>qi_ext<mode>_2"
[(set (zero_extract:SWI248
(match_operand:SWI248 0 "register_operand" "+Q")
(const_int 8)
(const_int 8))
(subreg:SWI248
(any_or:QI
(subreg:QI
(zero_extract:SI (match_operand 1 "ext_register_operand" "%0")
(const_int 8)
(const_int 8)) 0)
(zero_extract:SWI248
(match_operand:SWI248 1 "register_operand" "%0")
(const_int 8)
(const_int 8)) 0)
(subreg:QI
(zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
(const_int 8)
(const_int 8)) 0)) 0))
(zero_extract:SWI248
(match_operand:SWI248 2 "register_operand" "Q")
(const_int 8)
(const_int 8)) 0)) 0))
(clobber (reg:CC FLAGS_REG))]
"(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
/* FIXME: without this LRA can't reload this pattern, see PR82524. */
@ -9839,46 +9898,49 @@
})
(define_expand "xorqi_ext_1_cc"
[(parallel [
(set (reg:CCNO FLAGS_REG)
(compare:CCNO
(xor:QI
(subreg:QI
(zero_extract:SI (match_operand 1 "ext_register_operand")
(const_int 8)
(const_int 8)) 0)
(match_operand 2 "const_int_operand"))
(const_int 0)))
(set (zero_extract:SI (match_operand 0 "ext_register_operand")
(const_int 8)
(const_int 8))
(subreg:SI
(xor:QI
(subreg:QI
(zero_extract:SI (match_dup 1)
(const_int 8)
(const_int 8)) 0)
(match_dup 2)) 0))])])
[(parallel
[(set (reg:CCNO FLAGS_REG)
(compare:CCNO
(xor:QI
(subreg:QI
(zero_extract:HI (match_operand:HI 1 "register_operand")
(const_int 8)
(const_int 8)) 0)
(match_operand:QI 2 "const_int_operand"))
(const_int 0)))
(set (zero_extract:HI (match_operand:HI 0 "register_operand")
(const_int 8)
(const_int 8))
(subreg:HI
(xor:QI
(subreg:QI
(zero_extract:HI (match_dup 1)
(const_int 8)
(const_int 8)) 0)
(match_dup 2)) 0))])])
(define_insn "*xorqi_ext_1_cc"
(define_insn "*xorqi_ext<mode>_1_cc"
[(set (reg FLAGS_REG)
(compare
(xor:QI
(subreg:QI
(zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
(const_int 8)
(const_int 8)) 0)
(zero_extract:SWI248
(match_operand:SWI248 1 "register_operand" "0,0")
(const_int 8)
(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")
(const_int 8)
(const_int 8))
(subreg:SI
(set (zero_extract:SWI248
(match_operand:SWI248 0 "register_operand" "+Q,Q")
(const_int 8)
(const_int 8))
(subreg:SWI248
(xor:QI
(subreg:QI
(zero_extract:SI (match_dup 1)
(const_int 8)
(const_int 8)) 0)
(zero_extract:SWI248
(match_dup 1)
(const_int 8)
(const_int 8)) 0)
(match_dup 2)) 0))]
"ix86_match_ccmode (insn, CCNOmode)
/* FIXME: without this LRA can't reload this pattern, see PR82524. */
@ -19409,9 +19471,9 @@
(match_operator 1 "compare_operator"
[(and:QI
(subreg:QI
(zero_extract:SI (match_operand 2 "QIreg_operand")
(const_int 8)
(const_int 8)) 0)
(zero_extract:SWI248 (match_operand:SWI248 2 "QIreg_operand")
(const_int 8)
(const_int 8)) 0)
(match_operand 3 "const_int_operand"))
(const_int 0)]))]
"! TARGET_PARTIAL_REG_STALL
@ -19423,20 +19485,20 @@
(match_op_dup 1
[(and:QI
(subreg:QI
(zero_extract:SI (match_dup 2)
(const_int 8)
(const_int 8)) 0)
(zero_extract:SWI248 (match_dup 2)
(const_int 8)
(const_int 8)) 0)
(match_dup 3))
(const_int 0)]))
(set (zero_extract:SI (match_dup 2)
(const_int 8)
(const_int 8))
(subreg:SI
(set (zero_extract:SWI248 (match_dup 2)
(const_int 8)
(const_int 8))
(subreg:SWI248
(and:QI
(subreg:QI
(zero_extract:SI (match_dup 2)
(const_int 8)
(const_int 8)) 0)
(zero_extract:SWI248 (match_dup 2)
(const_int 8)
(const_int 8)) 0)
(match_dup 3)) 0))])])
;; Don't do logical operations with memory inputs.

View file

@ -87,14 +87,6 @@
(and (match_code "reg")
(match_test "REGNO (op) == FLAGS_REG")))
;; Match a DI, SI or HImode register for a zero_extract.
(define_special_predicate "ext_register_operand"
(and (match_operand 0 "register_operand")
(ior (and (match_test "TARGET_64BIT")
(match_test "GET_MODE (op) == DImode"))
(match_test "GET_MODE (op) == SImode")
(match_test "GET_MODE (op) == HImode"))))
;; Match a DI, SI, HI or QImode nonimmediate_operand.
(define_special_predicate "int_nonimmediate_operand"
(and (match_operand 0 "nonimmediate_operand")

View file

@ -0,0 +1,47 @@
/* PR target/78904 */
/* { dg-do compile } */
/* { dg-options "-O2 -masm=att" } */
/* { dg-final { scan-assembler-not "movzbl" } } */
/* { dg-final { scan-assembler-not "movb" } } */
struct S1
{
unsigned char pad1;
unsigned char val;
};
struct S1 test_and (struct S1 a, struct S1 b)
{
a.val &= b.val;
return a;
}
/* { dg-final { scan-assembler "\[ \t\]andb" } } */
struct S1 test_or (struct S1 a, struct S1 b)
{
a.val |= b.val;
return a;
}
/* { dg-final { scan-assembler "\[ \t\]orb" } } */
struct S1 test_xor (struct S1 a, struct S1 b)
{
a.val ^= b.val;
return a;
}
/* { dg-final { scan-assembler "\[ \t\]xorb" } } */
struct S1 test_add (struct S1 a, struct S1 b)
{
a.val += b.val;
return a;
}
/* { dg-final { scan-assembler "\[ \t\]addb" } } */

View file

@ -0,0 +1,49 @@
/* PR target/78904 */
/* { dg-do compile { target { ! ia32 } } } */
/* { dg-options "-O2 -masm=att" } */
/* { dg-final { scan-assembler-not "movzbl" } } */
/* { dg-final { scan-assembler-not "movb" } } */
struct S1
{
unsigned char pad1;
unsigned char val;
unsigned short pad2;
unsigned int pad3;
};
struct S1 test_and (struct S1 a, struct S1 b)
{
a.val &= b.val;
return a;
}
/* { dg-final { scan-assembler "\[ \t\]andb" } } */
struct S1 test_or (struct S1 a, struct S1 b)
{
a.val |= b.val;
return a;
}
/* { dg-final { scan-assembler "\[ \t\]orb" } } */
struct S1 test_xor (struct S1 a, struct S1 b)
{
a.val ^= b.val;
return a;
}
/* { dg-final { scan-assembler "\[ \t\]xorb" } } */
struct S1 test_add (struct S1 a, struct S1 b)
{
a.val += b.val;
return a;
}
/* { dg-final { scan-assembler "\[ \t\]addb" } } */

View file

@ -0,0 +1,48 @@
/* PR target/78904 */
/* { dg-do compile } */
/* { dg-require-effective-target nonpic } */
/* { dg-options "-O2 -masm=att" } */
struct S1
{
unsigned char pad1;
unsigned char val;
};
extern struct S1 t;
struct S1 test_and (struct S1 a)
{
a.val &= t.val;
return a;
}
/* { dg-final { scan-assembler "\[ \t\]andb\[ \t\]+t\[^\n\r]*, %.h" } } */
struct S1 test_or (struct S1 a)
{
a.val |= t.val;
return a;
}
/* { dg-final { scan-assembler "\[ \t\]orb\[ \t\]+t\[^\n\r]*, %.h" } } */
struct S1 test_xor (struct S1 a)
{
a.val ^= t.val;
return a;
}
/* { dg-final { scan-assembler "\[ \t\]xorb\[ \t\]+t\[^\n\r]*, %.h" } } */
struct S1 test_add (struct S1 a)
{
a.val += t.val;
return a;
}
/* { dg-final { scan-assembler "\[ \t\]addb\[ \t\]+t\[^\n\r]*, %.h" } } */

View file

@ -0,0 +1,50 @@
/* PR target/78904 */
/* { dg-do compile { target { ! ia32 } } } */
/* { dg-require-effective-target nonpic } */
/* { dg-options "-O2 -masm=att" } */
struct S1
{
unsigned char pad1;
unsigned char val;
unsigned short pad2;
unsigned int pad3;
};
extern struct S1 t;
struct S1 test_and (struct S1 a)
{
a.val &= t.val;
return a;
}
/* { dg-final { scan-assembler "\[ \t\]andb\[ \t\]+t\[^\n\r]*, %.h" } } */
struct S1 test_or (struct S1 a)
{
a.val |= t.val;
return a;
}
/* { dg-final { scan-assembler "\[ \t\]orb\[ \t\]+t\[^\n\r]*, %.h" } } */
struct S1 test_xor (struct S1 a)
{
a.val ^= t.val;
return a;
}
/* { dg-final { scan-assembler "\[ \t\]xorb\[ \t\]+t\[^\n\r]*, %.h" } } */
struct S1 test_add (struct S1 a)
{
a.val += t.val;
return a;
}
/* { dg-final { scan-assembler "\[ \t\]addb\[ \t\]+t\[^\n\r]*, %.h" } } */

View file

@ -0,0 +1,42 @@
/* PR target/78904 */
/* { dg-do assemble } */
/* { dg-options "-O2" } */
typedef __SIZE_TYPE__ size_t;
struct S1
{
unsigned char pad1;
unsigned char val;
unsigned short pad2;
};
extern struct S1 t[256];
struct S1 test_and (struct S1 a, size_t i)
{
a.val &= t[i].val;
return a;
}
struct S1 test_or (struct S1 a, size_t i)
{
a.val |= t[i].val;
return a;
}
struct S1 test_xor (struct S1 a, size_t i)
{
a.val ^= t[i].val;
return a;
}
struct S1 test_add (struct S1 a, size_t i)
{
a.val += t[i].val;
return a;
}

View file

@ -0,0 +1,43 @@
/* PR target/78904 */
/* { dg-do assemble { target { ! ia32 } } } */
/* { dg-options "-O2" } */
typedef __SIZE_TYPE__ size_t;
struct S1
{
unsigned char pad1;
unsigned char val;
unsigned short pad2;
unsigned int pad3;
};
extern struct S1 t[256];
struct S1 test_and (struct S1 a, size_t i)
{
a.val &= t[i].val;
return a;
}
struct S1 test_or (struct S1 a, size_t i)
{
a.val |= t[i].val;
return a;
}
struct S1 test_xor (struct S1 a, size_t i)
{
a.val ^= t[i].val;
return a;
}
struct S1 test_add (struct S1 a, size_t i)
{
a.val += t[i].val;
return a;
}

View file

@ -0,0 +1,21 @@
/* PR target/78904 */
/* { dg-do compile } */
/* { dg-require-effective-target nonpic } */
/* { dg-options "-O2 -masm=att" } */
typedef __SIZE_TYPE__ size_t;
struct S1
{
unsigned char pad1;
unsigned char val;
};
extern unsigned char t[256];
void foo (struct S1 a, size_t i)
{
t[i] = a.val;
}
/* { dg-final { scan-assembler "\[ \t\]movb\[\t \]+%.h, t" } } */

View file

@ -0,0 +1,23 @@
/* PR target/78904 */
/* { dg-do compile { target { ! ia32 } } } */
/* { dg-require-effective-target nonpic } */
/* { dg-options "-O2 -masm=att" } */
typedef __SIZE_TYPE__ size_t;
struct S1
{
unsigned char pad1;
unsigned char val;
unsigned short pad2;
unsigned int pad3;
};
extern unsigned char t[256];
void foo (struct S1 a, size_t i)
{
t[i] = a.val;
}
/* { dg-final { scan-assembler "\[ \t\]movb\[\t \]+%.h, t" } } */

View file

@ -0,0 +1,21 @@
/* PR target/78904 */
/* { dg-do assemble { target { ! ia32 } } } */
/* { dg-options "-O2" } */
typedef __SIZE_TYPE__ size_t;
struct S1
{
unsigned char pad1;
unsigned char val;
};
extern unsigned char t[256];
void foo (struct S1 a, size_t i)
{
register size_t _i __asm ("r10") = i;
asm volatile ("" : "+r" (_i));
t[_i] = a.val;
}

View file

@ -0,0 +1,23 @@
/* PR target/78904 */
/* { dg-do assemble { target { ! ia32 } } } */
/* { dg-options "-O2" } */
typedef __SIZE_TYPE__ size_t;
struct S1
{
unsigned char pad1;
unsigned char val;
unsigned short pad2;
unsigned int pad3;
};
extern unsigned char t[256];
void foo (struct S1 a, size_t i)
{
register size_t _i __asm ("r10") = i;
asm volatile ("" : "+r" (_i));
t[_i] = a.val;
}

View file

@ -0,0 +1,21 @@
/* PR target/78904 */
/* { dg-do compile } */
/* { dg-require-effective-target nonpic } */
/* { dg-options "-O2 -masm=att" } */
typedef __SIZE_TYPE__ size_t;
struct S1
{
char pad1;
char val;
};
extern char t[256];
void foo (struct S1 a, size_t i)
{
t[i] = a.val;
}
/* { dg-final { scan-assembler "\[ \t\]movb\[\t \]*%.h, t" } } */

View file

@ -0,0 +1,23 @@
/* PR target/78904 */
/* { dg-do compile { target { ! ia32 } } } */
/* { dg-require-effective-target nonpic } */
/* { dg-options "-O2 -masm=att" } */
typedef __SIZE_TYPE__ size_t;
struct S1
{
char pad1;
char val;
short pad2;
int pad3;
};
extern char t[256];
void foo (struct S1 a, size_t i)
{
t[i] = a.val;
}
/* { dg-final { scan-assembler "\[ \t\]movb\[\t \]*%.h, t" } } */

View file

@ -0,0 +1,20 @@
/* PR target/78967 */
/* { dg-do compile } */
/* { dg-options "-O2 -masm=att" } */
/* { dg-additional-options "-mregparm=3" { target ia32 } } */
/* { dg-final { scan-assembler-not "movzbl" } } */
struct S1
{
unsigned char pad1;
unsigned char val;
};
struct S1 foo (struct S1 a, struct S1 b)
{
a.val = b.val;
return a;
}
/* { dg-final { scan-assembler "\[ \t\]movb\[ \t\]+%.h, %.h" } } */

View file

@ -0,0 +1,21 @@
/* PR target/78967 */
/* { dg-do compile { target { ! ia32 } } } */
/* { dg-options "-O2 -masm=att" } */
/* { dg-final { scan-assembler-not "movzbl" } } */
struct S1
{
unsigned char pad1;
unsigned char val;
unsigned short pad2;
unsigned int pad3;
};
struct S1 foo (struct S1 a, struct S1 b)
{
a.val = b.val;
return a;
}
/* { dg-final { scan-assembler "\[ \t\]movb\[ \t\]+%.h, %.h" } } */

View file

@ -0,0 +1,24 @@
/* PR target/78967 */
/* { dg-do compile } */
/* { dg-options "-O2 -masm=att" } */
/* { dg-require-effective-target nonpic } */
/* { dg-final { scan-assembler-not "movzbl" } } */
typedef __SIZE_TYPE__ size_t;
struct S1
{
unsigned char pad1;
unsigned char val;
};
extern unsigned char t[256];
struct S1 foo (struct S1 a, size_t i)
{
a.val = t[i];
return a;
}
/* { dg-final { scan-assembler "\[ \t\]movb\[ \t\]+t\[^\n\r]*, %.h" } } */

View file

@ -0,0 +1,26 @@
/* PR target/78967 */
/* { dg-do compile { target { ! ia32 } } } */
/* { dg-options "-O2 -masm=att" } */
/* { dg-require-effective-target nonpic } */
/* { dg-final { scan-assembler-not "movzbl" } } */
typedef __SIZE_TYPE__ size_t;
struct S1
{
unsigned char pad1;
unsigned char val;
unsigned short pad2;
unsigned int pad3;
};
extern unsigned char t[256];
struct S1 foo (struct S1 a, size_t i)
{
a.val = t[i];
return a;
}
/* { dg-final { scan-assembler "\[ \t\]movb\[ \t\]+t\[^\n\r]*, %.h" } } */