From: Kyrylo Tkachov Date: Fri, 7 Jun 2013 13:35:54 +0000 (+0000) Subject: re PR target/56315 (ARM: Improve use of 64-bit constants in logical operations) X-Git-Tag: releases/gcc-4.9.0~5498 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=79678d044b8830a93b9323e14b54eca48a6f457e;p=thirdparty%2Fgcc.git re PR target/56315 (ARM: Improve use of 64-bit constants in logical operations) gcc/ 2013-06-07 Kyrylo Tkachov PR target/56315 * config/arm/arm.md (*xordi3_insn): Change to insn_and_split. (xordi3): Change operand 2 constraint to arm_xordi_operand. * config/arm/arm.c (const_ok_for_dimode_op): Handle XOR. * config/arm/constraints.md (Dg): New constraint. * config/arm/neon.md (xordi3_neon): Remove. (neon_veor): Generate xordi3 instead of xordi3_neon. * config/arm/predicates.md (arm_xordi_operand): New predicate. gcc/testsuite 2013-06-07 Kyrylo Tkachov PR target/56315 * gcc.target/arm/xordi3-opt.c: New test. From-SVN: r199814 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 0c66239556a6..39775f966f6a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +2013-06-07 Kyrylo Tkachov + + PR target/56315 + * config/arm/arm.md (*xordi3_insn): Change to insn_and_split. + (xordi3): Change operand 2 constraint to arm_xordi_operand. + * config/arm/arm.c (const_ok_for_dimode_op): Handle XOR. + * config/arm/constraints.md (Dg): New constraint. + * config/arm/neon.md (xordi3_neon): Remove. + (neon_veor): Generate xordi3 instead of xordi3_neon. + * config/arm/predicates.md (arm_xordi_operand): New predicate. + 2013-06-07 Kyrylo Tkachov * config/arm/arm.md (anddi3_insn): Remove duplicate alternatives. diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index 033e8bf0f3c5..6fc307e7709b 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -2687,6 +2687,7 @@ const_ok_for_dimode_op (HOST_WIDE_INT i, enum rtx_code code) { case AND: case IOR: + case XOR: return (const_ok_for_op (hi_val, code) || hi_val == 0xFFFFFFFF) && (const_ok_for_op (lo_val, code) || lo_val == 0xFFFFFFFF); case PLUS: diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md index dc62caa56694..3f0e021f3ed0 100644 --- a/gcc/config/arm/arm.md +++ b/gcc/config/arm/arm.md @@ -3181,19 +3181,49 @@ (define_expand "xordi3" [(set (match_operand:DI 0 "s_register_operand" "") (xor:DI (match_operand:DI 1 "s_register_operand" "") - (match_operand:DI 2 "s_register_operand" "")))] + (match_operand:DI 2 "arm_xordi_operand" "")))] "TARGET_32BIT" "" ) -(define_insn "*xordi3_insn" - [(set (match_operand:DI 0 "s_register_operand" "=&r,&r") - (xor:DI (match_operand:DI 1 "s_register_operand" "%0,r") - (match_operand:DI 2 "s_register_operand" "r,r")))] - "TARGET_32BIT && !TARGET_IWMMXT && !TARGET_NEON" - "#" - [(set_attr "length" "8") - (set_attr "predicable" "yes")] +(define_insn_and_split "*xordi3_insn" + [(set (match_operand:DI 0 "s_register_operand" "=w,&r,&r,&r,&r,?w") + (xor:DI (match_operand:DI 1 "s_register_operand" "w ,%0,r ,0 ,r ,w") + (match_operand:DI 2 "arm_xordi_operand" "w ,r ,r ,Dg,Dg,w")))] + "TARGET_32BIT && !TARGET_IWMMXT" +{ + switch (which_alternative) + { + case 1: + case 2: + case 3: + case 4: /* fall through */ + return "#"; + case 0: /* fall through */ + case 5: return "veor\t%P0, %P1, %P2"; + default: gcc_unreachable (); + } +} + "TARGET_32BIT && !TARGET_IWMMXT && reload_completed + && !(IS_VFP_REGNUM (REGNO (operands[0])))" + [(set (match_dup 3) (match_dup 4)) + (set (match_dup 5) (match_dup 6))] + " + { + operands[3] = gen_lowpart (SImode, operands[0]); + operands[5] = gen_highpart (SImode, operands[0]); + + operands[4] = simplify_gen_binary (XOR, SImode, + gen_lowpart (SImode, operands[1]), + gen_lowpart (SImode, operands[2])); + operands[6] = simplify_gen_binary (XOR, SImode, + gen_highpart (SImode, operands[1]), + gen_highpart_mode (SImode, DImode, operands[2])); + + }" + [(set_attr "length" "*,8,8,8,8,*") + (set_attr "neon_type" "neon_int_1,*,*,*,*,neon_int_1") + (set_attr "arch" "neon_for_64bits,*,*,*,*,avoid_neon_for_64bits")] ) (define_insn "*xordi_zesidi_di" diff --git a/gcc/config/arm/constraints.md b/gcc/config/arm/constraints.md index 53cbff6421b6..7cd8e31c97f4 100644 --- a/gcc/config/arm/constraints.md +++ b/gcc/config/arm/constraints.md @@ -266,6 +266,12 @@ (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 diff --git a/gcc/config/arm/neon.md b/gcc/config/arm/neon.md index 1697008531e1..e814df0d264b 100644 --- a/gcc/config/arm/neon.md +++ b/gcc/config/arm/neon.md @@ -782,21 +782,6 @@ [(set_attr "neon_type" "neon_int_1")] ) -(define_insn "xordi3_neon" - [(set (match_operand:DI 0 "s_register_operand" "=w,?&r,?&r,?w") - (xor:DI (match_operand:DI 1 "s_register_operand" "%w,0,r,w") - (match_operand:DI 2 "s_register_operand" "w,r,r,w")))] - "TARGET_NEON" - "@ - veor\t%P0, %P1, %P2 - # - # - veor\t%P0, %P1, %P2" - [(set_attr "neon_type" "neon_int_1,*,*,neon_int_1") - (set_attr "length" "*,8,8,*") - (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits")] -) - (define_insn "one_cmpl2" [(set (match_operand:VDQ 0 "s_register_operand" "=w") (not:VDQ (match_operand:VDQ 1 "s_register_operand" "w")))] @@ -5605,7 +5590,7 @@ (match_operand:SI 3 "immediate_operand" "")] "TARGET_NEON" { - emit_insn (gen_xor3 (operands[0], operands[1], operands[2])); + emit_insn (gen_xor3 (operands[0], operands[1], operands[2])); DONE; }) diff --git a/gcc/config/arm/predicates.md b/gcc/config/arm/predicates.md index 3cec56901934..d169cb270356 100644 --- a/gcc/config/arm/predicates.md +++ b/gcc/config/arm/predicates.md @@ -179,6 +179,11 @@ (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") diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index b39ac889448a..9c2ff38c1115 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2013-06-07 Kyrylo Tkachov + + PR target/56315 + * gcc.target/arm/xordi3-opt.c: New test. + 2013-06-07 Rainer Orth * gcc.dg/debug/dwarf2/discriminator.c: Fix wording. diff --git a/gcc/testsuite/gcc.target/arm/xordi3-opt.c b/gcc/testsuite/gcc.target/arm/xordi3-opt.c new file mode 100644 index 000000000000..7e031c3af2cd --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/xordi3-opt.c @@ -0,0 +1,9 @@ +/* { dg-do compile } */ +/* { dg-options "-O1" } */ + +unsigned long long xor64 (unsigned long long input) +{ + return input ^ 0x200000004ULL; +} + +/* { dg-final { scan-assembler-not "mov\[\\t \]+.+,\[\\t \]*.+" } } */