From: Kyrylo Tkachov Date: Fri, 31 May 2013 09:29:41 +0000 (+0000) Subject: re PR target/56315 (ARM: Improve use of 64-bit constants in logical operations) X-Git-Tag: upstream/12.2.0~69434 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=b6af05a9b34eab3b8aafa34b54adbec2c70a304f;p=platform%2Fupstream%2Fgcc.git re PR target/56315 (ARM: Improve use of 64-bit constants in logical operations) gcc/ 2013-05-31 Kyrylo Tkachov PR target/56315 * config/arm/arm.c (const_ok_for_dimode_op): Handle IOR. * config/arm/arm.md (*iordi3_insn): Change to insn_and_split. * config/arm/neon.md (iordi3_neon): Remove. (neon_vorr): Generate iordi3 instead of iordi3_neon. * config/arm/predicates.md (imm_for_neon_logic_operand): Move to earlier in the file. (neon_logic_op2): Likewise. (arm_iordi_operand_neon): New predicate. gcc/testsuite/ 2013-05-31 Kyrylo Tkachov PR target/56315 * gcc.target/arm/iordi3-opt.c: New test. From-SVN: r199527 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c3f08d8..ff9f38c 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,15 @@ +2013-05-31 Kyrylo Tkachov + + PR target/56315 + * config/arm/arm.c (const_ok_for_dimode_op): Handle IOR. + * config/arm/arm.md (*iordi3_insn): Change to insn_and_split. + * config/arm/neon.md (iordi3_neon): Remove. + (neon_vorr): Generate iordi3 instead of iordi3_neon. + * config/arm/predicates.md (imm_for_neon_logic_operand): + Move to earlier in the file. + (neon_logic_op2): Likewise. + (arm_iordi_operand_neon): New predicate. + 2013-05-31 Richard Biener PR tree-optimization/57478 diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index 55a5123..42f52c7 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -2677,6 +2677,7 @@ const_ok_for_dimode_op (HOST_WIDE_INT i, enum rtx_code code) switch (code) { case AND: + case IOR: 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 b7db361..466baa8 100644 --- a/gcc/config/arm/arm.md +++ b/gcc/config/arm/arm.md @@ -2997,14 +2997,47 @@ "" ) -(define_insn "*iordi3_insn" - [(set (match_operand:DI 0 "s_register_operand" "=&r,&r") - (ior: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 "*iordi3_insn" + [(set (match_operand:DI 0 "s_register_operand" "=w,w ,&r,&r,&r,&r,?w,?w") + (ior:DI (match_operand:DI 1 "s_register_operand" "%w,0 ,0 ,r ,0 ,r ,w ,0") + (match_operand:DI 2 "arm_iordi_operand_neon" "w ,Dl,r ,r ,De,De,w ,Dl")))] + "TARGET_32BIT && !TARGET_IWMMXT" + { + switch (which_alternative) + { + case 0: /* fall through */ + case 6: return "vorr\t%P0, %P1, %P2"; + case 1: /* fall through */ + case 7: return neon_output_logic_immediate ("vorr", &operands[2], + DImode, 0, VALID_NEON_QREG_MODE (DImode)); + case 2: + case 3: + case 4: + case 5: + return "#"; + 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 (IOR, SImode, + gen_lowpart (SImode, operands[1]), + gen_lowpart (SImode, operands[2])); + operands[6] = simplify_gen_binary (IOR, SImode, + gen_highpart (SImode, operands[1]), + gen_highpart_mode (SImode, DImode, operands[2])); + + }" + [(set_attr "neon_type" "neon_int_1,neon_int_1,*,*,*,*,neon_int_1,neon_int_1") + (set_attr "length" "*,*,8,8,8,8,8,8") + (set_attr "arch" "neon_for_64bits,neon_for_64bits,*,*,*,*,avoid_neon_for_64bits,avoid_neon_for_64bits")] ) (define_insn "*iordi_zesidi_di" diff --git a/gcc/config/arm/neon.md b/gcc/config/arm/neon.md index f91a6f7..1697008 100644 --- a/gcc/config/arm/neon.md +++ b/gcc/config/arm/neon.md @@ -679,29 +679,6 @@ [(set_attr "neon_type" "neon_int_1")] ) -(define_insn "iordi3_neon" - [(set (match_operand:DI 0 "s_register_operand" "=w,w,?&r,?&r,?w,?w") - (ior:DI (match_operand:DI 1 "s_register_operand" "%w,0,0,r,w,0") - (match_operand:DI 2 "neon_logic_op2" "w,Dl,r,r,w,Dl")))] - "TARGET_NEON" -{ - switch (which_alternative) - { - case 0: /* fall through */ - case 4: return "vorr\t%P0, %P1, %P2"; - case 1: /* fall through */ - case 5: return neon_output_logic_immediate ("vorr", &operands[2], - DImode, 0, VALID_NEON_QREG_MODE (DImode)); - case 2: return "#"; - case 3: return "#"; - default: gcc_unreachable (); - } -} - [(set_attr "neon_type" "neon_int_1,neon_int_1,*,*,neon_int_1,neon_int_1") - (set_attr "length" "*,*,8,8,*,*") - (set_attr "arch" "neon_for_64bits,neon_for_64bits,*,*,avoid_neon_for_64bits,avoid_neon_for_64bits")] -) - ;; The concrete forms of the Neon immediate-logic instructions are vbic and ;; vorr. We support the pseudo-instruction vand instead, because that ;; corresponds to the canonical form the middle-end expects to use for @@ -5617,7 +5594,7 @@ (match_operand:SI 3 "immediate_operand" "")] "TARGET_NEON" { - emit_insn (gen_ior3 (operands[0], operands[1], operands[2])); + emit_insn (gen_ior3 (operands[0], operands[1], operands[2])); DONE; }) diff --git a/gcc/config/arm/predicates.md b/gcc/config/arm/predicates.md index 92de9fe..3cec569 100644 --- a/gcc/config/arm/predicates.md +++ b/gcc/config/arm/predicates.md @@ -42,6 +42,17 @@ (ior (match_operand 0 "imm_for_neon_inv_logic_operand") (match_operand 0 "s_register_operand"))) +(define_predicate "imm_for_neon_logic_operand" + (match_code "const_vector") +{ + return (TARGET_NEON + && neon_immediate_valid_for_logic (op, mode, 0, NULL, NULL)); +}) + +(define_predicate "neon_logic_op2" + (ior (match_operand 0 "imm_for_neon_logic_operand") + (match_operand 0 "s_register_operand"))) + ;; Any hard register. (define_predicate "arm_hard_register_operand" (match_code "reg") @@ -162,6 +173,12 @@ (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_adddi_operand" (ior (match_operand 0 "s_register_operand") (and (match_code "const_int") @@ -535,17 +552,6 @@ (ior (match_operand 0 "s_register_operand") (match_operand 0 "imm_for_neon_rshift_operand"))) -(define_predicate "imm_for_neon_logic_operand" - (match_code "const_vector") -{ - return (TARGET_NEON - && neon_immediate_valid_for_logic (op, mode, 0, NULL, NULL)); -}) - -(define_predicate "neon_logic_op2" - (ior (match_operand 0 "imm_for_neon_logic_operand") - (match_operand 0 "s_register_operand"))) - ;; Predicates for named expanders that overlap multiple ISAs. (define_predicate "cmpdi_operand" diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index a46912e..fd4ebbb 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2013-05-31 Kyrylo Tkachov + + PR target/56315 + * gcc.target/arm/iordi3-opt.c: New test. + 2013-05-31 Janus Weil PR fortran/54190 diff --git a/gcc/testsuite/gcc.target/arm/iordi3-opt.c b/gcc/testsuite/gcc.target/arm/iordi3-opt.c new file mode 100644 index 0000000..b3f465b7 --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/iordi3-opt.c @@ -0,0 +1,9 @@ +/* { dg-do compile } */ +/* { dg-options "-O1" } */ + +unsigned long long or64 (unsigned long long input) +{ + return input | 0x200000004ULL; +} + +/* { dg-final { scan-assembler-not "mov\[\\t \]+.+,\[\\t \]*.+" } } */