aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorKyrylo Tkachov <kyrylo.tkachov@arm.com>2013-05-31 09:29:41 +0000
committerKyrylo Tkachov <ktkachov@gcc.gnu.org>2013-05-31 09:29:41 +0000
commitb6af05a9b34eab3b8aafa34b54adbec2c70a304f (patch)
tree4bb66cfa14474b935cb3c2212d06af921d6c1f24 /gcc
parentf800c166104121e785d57933fe1412101b0496d0 (diff)
downloadgcc-b6af05a9b34eab3b8aafa34b54adbec2c70a304f.zip
gcc-b6af05a9b34eab3b8aafa34b54adbec2c70a304f.tar.gz
gcc-b6af05a9b34eab3b8aafa34b54adbec2c70a304f.tar.bz2
re PR target/56315 (ARM: Improve use of 64-bit constants in logical operations)
gcc/ 2013-05-31 Kyrylo Tkachov <kyrylo.tkachov@arm.com> 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<mode>): 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 <kyrylo.tkachov@arm.com> PR target/56315 * gcc.target/arm/iordi3-opt.c: New test. From-SVN: r199527
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog12
-rw-r--r--gcc/config/arm/arm.c1
-rw-r--r--gcc/config/arm/arm.md49
-rw-r--r--gcc/config/arm/neon.md25
-rw-r--r--gcc/config/arm/predicates.md28
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.target/arm/iordi3-opt.c9
7 files changed, 86 insertions, 43 deletions
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 <kyrylo.tkachov@arm.com>
+
+ 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<mode>): 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 <rguenther@suse.de>
PR tree-optimization/57478
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index 55a5123..42f52c70 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_ior<mode>3<V_suf64> (operands[0], operands[1], operands[2]));
+ emit_insn (gen_ior<mode>3 (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 <kyrylo.tkachov@arm.com>
+
+ PR target/56315
+ * gcc.target/arm/iordi3-opt.c: New test.
+
2013-05-31 Janus Weil <janus@gcc.gnu.org>
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 \]*.+" } } */