Commit cdfc0e86 by Wilco Dijkstra Committed by Wilco Dijkstra

[ARM] Cleanup logical DImode operations

Cleanup the logical DImode operations since the current implementation is way
too complicated.  Thumb-1, Thumb-2, VFP/Neon and iwMMXt all work differently,
resulting in a bewildering number of expansions, patterns and splits across
several md files.  All this complexity is counterproductive and results in
inefficient code.

A much simpler approach is to split these operations early in the expander
so that optimizations and register allocation are applied on the 32-bit halves.
Codegeneration is unchanged on Thumb-1 and Arm/Thumb-2 without Neon or iwMMXt
(which already expand these instructions early).  With Neon these changes save
~1000 instructions from the PR77308 testcase, mostly by significantly reducing
register pressure and spilling.

Bootstrap OK on arm-none-linux-gnueabihf --with-cpu=cortex-a57

    gcc/
	* config/arm/arm.md (split and/eor/ior): Remove Neon check.
	(split not): Add DImode not splitter.
	(anddi3): Remove pattern.
	(anddi3_insn): Likewise.
	(anddi_zesidi_di): Likewise.
	(anddi_sesdi_di): Likewise.
	(anddi_notdi_di): Likewise.
	(anddi_notzesidi_di): Likewise.
	(anddi_notsesidi_di): Likewise.
	(iordi3): Likewise.
	(iordi3_insn): Likewise.
	(iordi_zesidi_di): Likewise.
	(iordi_sesidi_di): Likewise.
	(xordi3): Likewise.
	(xordi3_insn): Likewise.
	(xordi_sesidi_di): Likewise.
	(xordi_zesidi_di): Likewise.
	(one_cmpldi2): Likewise.
	(one_cmpldi2_insn): Likewise.
	* config/arm/constraints.md: Remove De, Df, Dg constraints.
	* config/arm/iwmmxt.md (iwmmxt_iordi3): Remove general register
	alternative.
	(iwmmxt_xordi3): Likewise.
	(iwmmxt_anddi3): Likewise.
	* config/arm/neon.md (orndi3_neon): Remove pattern.
	(anddi_notdi_di): Likewise.
	* config/arm/predicates.md (arm_anddi_operand_neon): Remove.
	(arm_iordi_operand_neon): Likewise.
	(arm_xordi_operand_neon): Likewise.
	* config/arm/thumb2.md(iordi_notdi_di): Remove pattern.
	(iordi_notzesidi_di): Likewise.
	(iordi_notdi_zesidi): Likewise.
	(iordi_notsesidi_di): Likewise.

From-SVN: r274823
parent 203ef022
2019-08-22 Wilco Dijkstra <wdijkstr@arm.com>
* config/arm/arm.md (split and/eor/ior): Remove Neon check.
(split not): Add DImode not splitter.
(anddi3): Remove pattern.
(anddi3_insn): Likewise.
(anddi_zesidi_di): Likewise.
(anddi_sesdi_di): Likewise.
(anddi_notdi_di): Likewise.
(anddi_notzesidi_di): Likewise.
(anddi_notsesidi_di): Likewise.
(iordi3): Likewise.
(iordi3_insn): Likewise.
(iordi_zesidi_di): Likewise.
(iordi_sesidi_di): Likewise.
(xordi3): Likewise.
(xordi3_insn): Likewise.
(xordi_sesidi_di): Likewise.
(xordi_zesidi_di): Likewise.
(one_cmpldi2): Likewise.
(one_cmpldi2_insn): Likewise.
* config/arm/constraints.md: Remove De, Df, Dg constraints.
* config/arm/iwmmxt.md (iwmmxt_iordi3): Remove general register
alternative.
(iwmmxt_xordi3): Likewise.
(iwmmxt_anddi3): Likewise.
* config/arm/neon.md (orndi3_neon): Remove pattern.
(anddi_notdi_di): Likewise.
* config/arm/predicates.md (arm_anddi_operand_neon): Remove.
(arm_iordi_operand_neon): Likewise.
(arm_xordi_operand_neon): Likewise.
* config/arm/thumb2.md(iordi_notdi_di): Remove pattern.
(iordi_notzesidi_di): Likewise.
(iordi_notdi_zesidi): Likewise.
(iordi_notsesidi_di): Likewise.
2019-08-22 Richard Earnshaw <rearnsha@arm.com>
* config/arm/arm.md (iorsi3_compare0): Add alternative for 16-bit thumb
......
......@@ -273,24 +273,6 @@
(and (match_code "const_int")
(match_test "TARGET_32BIT && const_ok_for_dimode_op (ival, PLUS)")))
(define_constraint "De"
"@internal
In ARM/Thumb-2 state a const_int that can be used by insn anddi."
(and (match_code "const_int")
(match_test "TARGET_32BIT && const_ok_for_dimode_op (ival, AND)")))
(define_constraint "Df"
"@internal
In ARM/Thumb-2 state a const_int that can be used by insn iordi."
(and (match_code "const_int")
(match_test "TARGET_32BIT && const_ok_for_dimode_op (ival, IOR)")))
(define_constraint "Dg"
"@internal
In ARM/Thumb-2 state a const_int that can be used by insn xordi."
(and (match_code "const_int")
(match_test "TARGET_32BIT && const_ok_for_dimode_op (ival, XOR)")))
(define_constraint "Di"
"@internal
In ARM/Thumb-2 state a const_int or const_double where both the high
......
......@@ -55,45 +55,36 @@
)
(define_insn "iwmmxt_iordi3"
[(set (match_operand:DI 0 "register_operand" "=y,?&r,?&r")
(ior:DI (match_operand:DI 1 "register_operand" "%y,0,r")
(match_operand:DI 2 "register_operand" "y,r,r")))]
[(set (match_operand:DI 0 "register_operand" "=y")
(ior:DI (match_operand:DI 1 "register_operand" "%y")
(match_operand:DI 2 "register_operand" "y")))]
"TARGET_REALLY_IWMMXT"
"@
wor%?\\t%0, %1, %2
#
#"
"wor%?\\t%0, %1, %2"
[(set_attr "predicable" "yes")
(set_attr "length" "4,8,8")
(set_attr "type" "wmmx_wor,*,*")]
(set_attr "length" "4")
(set_attr "type" "wmmx_wor")]
)
(define_insn "iwmmxt_xordi3"
[(set (match_operand:DI 0 "register_operand" "=y,?&r,?&r")
(xor:DI (match_operand:DI 1 "register_operand" "%y,0,r")
(match_operand:DI 2 "register_operand" "y,r,r")))]
[(set (match_operand:DI 0 "register_operand" "=y")
(xor:DI (match_operand:DI 1 "register_operand" "%y")
(match_operand:DI 2 "register_operand" "y")))]
"TARGET_REALLY_IWMMXT"
"@
wxor%?\\t%0, %1, %2
#
#"
"wxor%?\\t%0, %1, %2"
[(set_attr "predicable" "yes")
(set_attr "length" "4,8,8")
(set_attr "type" "wmmx_wxor,*,*")]
(set_attr "length" "4")
(set_attr "type" "wmmx_wxor")]
)
(define_insn "iwmmxt_anddi3"
[(set (match_operand:DI 0 "register_operand" "=y,?&r,?&r")
(and:DI (match_operand:DI 1 "register_operand" "%y,0,r")
(match_operand:DI 2 "register_operand" "y,r,r")))]
[(set (match_operand:DI 0 "register_operand" "=y")
(and:DI (match_operand:DI 1 "register_operand" "%y")
(match_operand:DI 2 "register_operand" "y")))]
"TARGET_REALLY_IWMMXT"
"@
wand%?\\t%0, %1, %2
#
#"
"wand%?\\t%0, %1, %2"
[(set_attr "predicable" "yes")
(set_attr "length" "4,8,8")
(set_attr "type" "wmmx_wand,*,*")]
(set_attr "length" "4")
(set_attr "type" "wmmx_wand")]
)
(define_insn "iwmmxt_nanddi3"
......
......@@ -838,46 +838,6 @@
[(set_attr "type" "neon_logic<q>")]
)
;; TODO: investigate whether we should disable
;; this and bicdi3_neon for the A8 in line with the other
;; changes above.
(define_insn_and_split "orndi3_neon"
[(set (match_operand:DI 0 "s_register_operand" "=w,?&r,?&r,?&r")
(ior:DI (not:DI (match_operand:DI 2 "s_register_operand" "w,0,0,r"))
(match_operand:DI 1 "s_register_operand" "w,r,r,0")))]
"TARGET_NEON"
"@
vorn\t%P0, %P1, %P2
#
#
#"
"reload_completed &&
(TARGET_NEON && !(IS_VFP_REGNUM (REGNO (operands[0]))))"
[(set (match_dup 0) (ior:SI (not:SI (match_dup 2)) (match_dup 1)))
(set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5)))]
"
{
if (TARGET_THUMB2)
{
operands[3] = gen_highpart (SImode, operands[0]);
operands[0] = gen_lowpart (SImode, operands[0]);
operands[4] = gen_highpart (SImode, operands[2]);
operands[2] = gen_lowpart (SImode, operands[2]);
operands[5] = gen_highpart (SImode, operands[1]);
operands[1] = gen_lowpart (SImode, operands[1]);
}
else
{
emit_insn (gen_one_cmpldi2 (operands[0], operands[2]));
emit_insn (gen_iordi3 (operands[0], operands[1], operands[0]));
DONE;
}
}"
[(set_attr "type" "neon_logic,multiple,multiple,multiple")
(set_attr "length" "*,16,8,8")
(set_attr "arch" "any,a,t2,t2")]
)
(define_insn "bic<mode>3_neon"
[(set (match_operand:VDQ 0 "s_register_operand" "=w")
(and:VDQ (not:VDQ (match_operand:VDQ 2 "s_register_operand" "w"))
......@@ -887,20 +847,6 @@
[(set_attr "type" "neon_logic<q>")]
)
;; Compare to *anddi_notdi_di.
(define_insn "bicdi3_neon"
[(set (match_operand:DI 0 "s_register_operand" "=w,?&r,?&r")
(and:DI (not:DI (match_operand:DI 2 "s_register_operand" "w,r,0"))
(match_operand:DI 1 "s_register_operand" "w,0,r")))]
"TARGET_NEON"
"@
vbic\t%P0, %P1, %P2
#
#"
[(set_attr "type" "neon_logic,multiple,multiple")
(set_attr "length" "*,8,8")]
)
(define_insn "xor<mode>3"
[(set (match_operand:VDQ 0 "s_register_operand" "=w")
(xor:VDQ (match_operand:VDQ 1 "s_register_operand" "w")
......
......@@ -201,23 +201,6 @@
(ior (match_operand 0 "arm_rhs_operand")
(match_operand 0 "arm_neg_immediate_operand")))
(define_predicate "arm_anddi_operand_neon"
(ior (match_operand 0 "s_register_operand")
(and (match_code "const_int")
(match_test "const_ok_for_dimode_op (INTVAL (op), AND)"))
(match_operand 0 "neon_inv_logic_op2")))
(define_predicate "arm_iordi_operand_neon"
(ior (match_operand 0 "s_register_operand")
(and (match_code "const_int")
(match_test "const_ok_for_dimode_op (INTVAL (op), IOR)"))
(match_operand 0 "neon_logic_op2")))
(define_predicate "arm_xordi_operand"
(ior (match_operand 0 "s_register_operand")
(and (match_code "const_int")
(match_test "const_ok_for_dimode_op (INTVAL (op), XOR)"))))
(define_predicate "arm_adddi_operand"
(ior (match_operand 0 "s_register_operand")
(and (match_code "const_int")
......
......@@ -1476,103 +1476,6 @@
(set_attr "type" "alu_sreg")]
)
; Constants for op 2 will never be given to these patterns.
(define_insn_and_split "*iordi_notdi_di"
[(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
(ior:DI (not:DI (match_operand:DI 1 "s_register_operand" "0,r"))
(match_operand:DI 2 "s_register_operand" "r,0")))]
"TARGET_THUMB2"
"#"
"TARGET_THUMB2 && reload_completed"
[(set (match_dup 0) (ior:SI (not:SI (match_dup 1)) (match_dup 2)))
(set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5)))]
"
{
operands[3] = gen_highpart (SImode, operands[0]);
operands[0] = gen_lowpart (SImode, operands[0]);
operands[4] = gen_highpart (SImode, operands[1]);
operands[1] = gen_lowpart (SImode, operands[1]);
operands[5] = gen_highpart (SImode, operands[2]);
operands[2] = gen_lowpart (SImode, operands[2]);
}"
[(set_attr "length" "8")
(set_attr "predicable" "yes")
(set_attr "predicable_short_it" "no")
(set_attr "type" "multiple")]
)
(define_insn_and_split "*iordi_notzesidi_di"
[(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
(ior:DI (not:DI (zero_extend:DI
(match_operand:SI 2 "s_register_operand" "r,r")))
(match_operand:DI 1 "s_register_operand" "0,?r")))]
"TARGET_THUMB2"
"#"
; (not (zero_extend...)) means operand0 will always be 0xffffffff
"TARGET_THUMB2 && reload_completed"
[(set (match_dup 0) (ior:SI (not:SI (match_dup 2)) (match_dup 1)))
(set (match_dup 3) (const_int -1))]
"
{
operands[3] = gen_highpart (SImode, operands[0]);
operands[0] = gen_lowpart (SImode, operands[0]);
operands[1] = gen_lowpart (SImode, operands[1]);
}"
[(set_attr "length" "4,8")
(set_attr "predicable" "yes")
(set_attr "predicable_short_it" "no")
(set_attr "type" "multiple")]
)
(define_insn_and_split "*iordi_notdi_zesidi"
[(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
(ior:DI (not:DI (match_operand:DI 2 "s_register_operand" "0,?r"))
(zero_extend:DI
(match_operand:SI 1 "s_register_operand" "r,r"))))]
"TARGET_THUMB2"
"#"
"TARGET_THUMB2 && reload_completed"
[(set (match_dup 0) (ior:SI (not:SI (match_dup 2)) (match_dup 1)))
(set (match_dup 3) (not:SI (match_dup 4)))]
"
{
operands[3] = gen_highpart (SImode, operands[0]);
operands[0] = gen_lowpart (SImode, operands[0]);
operands[1] = gen_lowpart (SImode, operands[1]);
operands[4] = gen_highpart (SImode, operands[2]);
operands[2] = gen_lowpart (SImode, operands[2]);
}"
[(set_attr "length" "8")
(set_attr "predicable" "yes")
(set_attr "predicable_short_it" "no")
(set_attr "type" "multiple")]
)
(define_insn_and_split "*iordi_notsesidi_di"
[(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
(ior:DI (not:DI (sign_extend:DI
(match_operand:SI 2 "s_register_operand" "r,r")))
(match_operand:DI 1 "s_register_operand" "0,r")))]
"TARGET_THUMB2"
"#"
"TARGET_THUMB2 && reload_completed"
[(set (match_dup 0) (ior:SI (not:SI (match_dup 2)) (match_dup 1)))
(set (match_dup 3) (ior:SI (not:SI
(ashiftrt:SI (match_dup 2) (const_int 31)))
(match_dup 4)))]
"
{
operands[3] = gen_highpart (SImode, operands[0]);
operands[0] = gen_lowpart (SImode, operands[0]);
operands[4] = gen_highpart (SImode, operands[1]);
operands[1] = gen_lowpart (SImode, operands[1]);
}"
[(set_attr "length" "8")
(set_attr "predicable" "yes")
(set_attr "predicable_short_it" "no")
(set_attr "type" "multiple")]
)
(define_insn "*orsi_notsi_si"
[(set (match_operand:SI 0 "s_register_operand" "=r")
(ior:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment