Commit 44cd6810 by Wei Guozhi Committed by Wei Guozhi

re PR target/53447 (missed optimization of 64bit ALU operation with small constant)

	PR target/53447
	* config/arm/arm-protos.h (const_ok_for_dimode_op): New prototype.
	* config/arm/arm.c (const_ok_for_dimode_op): New function.
	* config/arm/constraints.md (Dd): New constraint.
	* config/arm/predicates.md (arm_adddi_operand): New predicate.
	* config/arm/arm.md (adddi3): Extend it to handle constants.
	(arm_adddi3): Likewise.
	(addsi3_carryin_<optab>): Extend it to handle sbc case.
	(addsi3_carryin_alt2_<optab>): Likewise.
	* config/arm/neon.md (adddi3_neon): Extend it to handle constants.

	* gcc.target/arm/pr53447-1.c: New testcase.
	* gcc.target/arm/pr53447-2.c: New testcase.
	* gcc.target/arm/pr53447-3.c: New testcase.
	* gcc.target/arm/pr53447-4.c: New testcase.

From-SVN: r189102
parent 9faeb493
2012-07-01 Wei Guozhi <carrot@google.com>
PR target/53447
* config/arm/arm-protos.h (const_ok_for_dimode_op): New prototype.
* config/arm/arm.c (const_ok_for_dimode_op): New function.
* config/arm/constraints.md (Dd): New constraint.
* config/arm/predicates.md (arm_adddi_operand): New predicate.
* config/arm/arm.md (adddi3): Extend it to handle constants.
(arm_adddi3): Likewise.
(addsi3_carryin_<optab>): Extend it to handle sbc case.
(addsi3_carryin_alt2_<optab>): Likewise.
* config/arm/neon.md (adddi3_neon): Extend it to handle constants.
2012-06-30 Nathan Sidwell <nathan@acm.org> 2012-06-30 Nathan Sidwell <nathan@acm.org>
* coverage.c (bbg_file_stamp): New. * coverage.c (bbg_file_stamp): New.
......
...@@ -50,6 +50,7 @@ extern int arm_hard_regno_mode_ok (unsigned int, enum machine_mode); ...@@ -50,6 +50,7 @@ extern int arm_hard_regno_mode_ok (unsigned int, enum machine_mode);
extern bool arm_modes_tieable_p (enum machine_mode, enum machine_mode); extern bool arm_modes_tieable_p (enum machine_mode, enum machine_mode);
extern int const_ok_for_arm (HOST_WIDE_INT); extern int const_ok_for_arm (HOST_WIDE_INT);
extern int const_ok_for_op (HOST_WIDE_INT, enum rtx_code); extern int const_ok_for_op (HOST_WIDE_INT, enum rtx_code);
extern int const_ok_for_dimode_op (HOST_WIDE_INT, enum rtx_code);
extern int arm_split_constant (RTX_CODE, enum machine_mode, rtx, extern int arm_split_constant (RTX_CODE, enum machine_mode, rtx,
HOST_WIDE_INT, rtx, rtx, int); HOST_WIDE_INT, rtx, rtx, int);
extern RTX_CODE arm_canonicalize_comparison (RTX_CODE, rtx *, rtx *); extern RTX_CODE arm_canonicalize_comparison (RTX_CODE, rtx *, rtx *);
......
...@@ -2507,6 +2507,28 @@ const_ok_for_op (HOST_WIDE_INT i, enum rtx_code code) ...@@ -2507,6 +2507,28 @@ const_ok_for_op (HOST_WIDE_INT i, enum rtx_code code)
} }
} }
/* Return true if I is a valid di mode constant for the operation CODE. */
int
const_ok_for_dimode_op (HOST_WIDE_INT i, enum rtx_code code)
{
HOST_WIDE_INT hi_val = (i >> 32) & 0xFFFFFFFF;
HOST_WIDE_INT lo_val = i & 0xFFFFFFFF;
rtx hi = GEN_INT (hi_val);
rtx lo = GEN_INT (lo_val);
if (TARGET_THUMB1)
return 0;
switch (code)
{
case PLUS:
return arm_not_operand (hi, SImode) && arm_add_operand (lo, SImode);
default:
return 0;
}
}
/* Emit a sequence of insns to handle a large constant. /* Emit a sequence of insns to handle a large constant.
CODE is the code of the operation required, it can be any of SET, PLUS, CODE is the code of the operation required, it can be any of SET, PLUS,
IOR, AND, XOR, MINUS; IOR, AND, XOR, MINUS;
......
...@@ -604,7 +604,7 @@ ...@@ -604,7 +604,7 @@
[(parallel [(parallel
[(set (match_operand:DI 0 "s_register_operand" "") [(set (match_operand:DI 0 "s_register_operand" "")
(plus:DI (match_operand:DI 1 "s_register_operand" "") (plus:DI (match_operand:DI 1 "s_register_operand" "")
(match_operand:DI 2 "s_register_operand" ""))) (match_operand:DI 2 "arm_adddi_operand" "")))
(clobber (reg:CC CC_REGNUM))])] (clobber (reg:CC CC_REGNUM))])]
"TARGET_EITHER" "TARGET_EITHER"
" "
...@@ -630,9 +630,9 @@ ...@@ -630,9 +630,9 @@
) )
(define_insn_and_split "*arm_adddi3" (define_insn_and_split "*arm_adddi3"
[(set (match_operand:DI 0 "s_register_operand" "=&r,&r") [(set (match_operand:DI 0 "s_register_operand" "=&r,&r,&r,&r,&r")
(plus:DI (match_operand:DI 1 "s_register_operand" "%0, 0") (plus:DI (match_operand:DI 1 "s_register_operand" "%0, 0, r, 0, r")
(match_operand:DI 2 "s_register_operand" "r, 0"))) (match_operand:DI 2 "arm_adddi_operand" "r, 0, r, Dd, Dd")))
(clobber (reg:CC CC_REGNUM))] (clobber (reg:CC CC_REGNUM))]
"TARGET_32BIT && !TARGET_NEON" "TARGET_32BIT && !TARGET_NEON"
"#" "#"
...@@ -650,7 +650,7 @@ ...@@ -650,7 +650,7 @@
operands[0] = gen_lowpart (SImode, operands[0]); operands[0] = gen_lowpart (SImode, operands[0]);
operands[4] = gen_highpart (SImode, operands[1]); operands[4] = gen_highpart (SImode, operands[1]);
operands[1] = gen_lowpart (SImode, operands[1]); operands[1] = gen_lowpart (SImode, operands[1]);
operands[5] = gen_highpart (SImode, operands[2]); operands[5] = gen_highpart_mode (SImode, DImode, operands[2]);
operands[2] = gen_lowpart (SImode, operands[2]); operands[2] = gen_lowpart (SImode, operands[2]);
}" }"
[(set_attr "conds" "clob") [(set_attr "conds" "clob")
...@@ -1001,22 +1001,26 @@ ...@@ -1001,22 +1001,26 @@
) )
(define_insn "*addsi3_carryin_<optab>" (define_insn "*addsi3_carryin_<optab>"
[(set (match_operand:SI 0 "s_register_operand" "=r") [(set (match_operand:SI 0 "s_register_operand" "=r,r")
(plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%r") (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%r,r")
(match_operand:SI 2 "arm_rhs_operand" "rI")) (match_operand:SI 2 "arm_not_operand" "rI,K"))
(LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))] (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))]
"TARGET_32BIT" "TARGET_32BIT"
"adc%?\\t%0, %1, %2" "@
adc%?\\t%0, %1, %2
sbc%?\\t%0, %1, #%B2"
[(set_attr "conds" "use")] [(set_attr "conds" "use")]
) )
(define_insn "*addsi3_carryin_alt2_<optab>" (define_insn "*addsi3_carryin_alt2_<optab>"
[(set (match_operand:SI 0 "s_register_operand" "=r") [(set (match_operand:SI 0 "s_register_operand" "=r,r")
(plus:SI (plus:SI (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0)) (plus:SI (plus:SI (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))
(match_operand:SI 1 "s_register_operand" "%r")) (match_operand:SI 1 "s_register_operand" "%r,r"))
(match_operand:SI 2 "arm_rhs_operand" "rI")))] (match_operand:SI 2 "arm_rhs_operand" "rI,K")))]
"TARGET_32BIT" "TARGET_32BIT"
"adc%?\\t%0, %1, %2" "@
adc%?\\t%0, %1, %2
sbc%?\\t%0, %1, #%B2"
[(set_attr "conds" "use")] [(set_attr "conds" "use")]
) )
......
...@@ -31,7 +31,7 @@ ...@@ -31,7 +31,7 @@
;; 'H' was previously used for FPA. ;; 'H' was previously used for FPA.
;; The following multi-letter normal constraints have been used: ;; The following multi-letter normal constraints have been used:
;; in ARM/Thumb-2 state: Da, Db, Dc, Dn, Dl, DL, Dv, Dy, Di, Dt, Dz ;; in ARM/Thumb-2 state: Da, Db, Dc, Dd, Dn, Dl, DL, Dv, Dy, Di, Dt, Dz
;; in Thumb-1 state: Pa, Pb, Pc, Pd, Pe ;; in Thumb-1 state: Pa, Pb, Pc, Pd, Pe
;; in Thumb-2 state: Pj, PJ, Ps, Pt, Pu, Pv, Pw, Px, Py ;; in Thumb-2 state: Pj, PJ, Ps, Pt, Pu, Pv, Pw, Px, Py
...@@ -242,6 +242,12 @@ ...@@ -242,6 +242,12 @@
(match_test "TARGET_32BIT && arm_const_double_inline_cost (op) == 4 (match_test "TARGET_32BIT && arm_const_double_inline_cost (op) == 4
&& !(optimize_size || arm_ld_sched)"))) && !(optimize_size || arm_ld_sched)")))
(define_constraint "Dd"
"@internal
In ARM/Thumb-2 state a const_int that can be used by insn adddi."
(and (match_code "const_int")
(match_test "TARGET_32BIT && const_ok_for_dimode_op (ival, PLUS)")))
(define_constraint "Di" (define_constraint "Di"
"@internal "@internal
In ARM/Thumb-2 state a const_int or const_double where both the high In ARM/Thumb-2 state a const_int or const_double where both the high
......
...@@ -587,9 +587,9 @@ ...@@ -587,9 +587,9 @@
) )
(define_insn "adddi3_neon" (define_insn "adddi3_neon"
[(set (match_operand:DI 0 "s_register_operand" "=w,?&r,?&r,?w") [(set (match_operand:DI 0 "s_register_operand" "=w,?&r,?&r,?w,?&r,?&r,?&r")
(plus:DI (match_operand:DI 1 "s_register_operand" "%w,0,0,w") (plus:DI (match_operand:DI 1 "s_register_operand" "%w,0,0,w,r,0,r")
(match_operand:DI 2 "s_register_operand" "w,r,0,w"))) (match_operand:DI 2 "arm_adddi_operand" "w,r,0,w,r,Dd,Dd")))
(clobber (reg:CC CC_REGNUM))] (clobber (reg:CC CC_REGNUM))]
"TARGET_NEON" "TARGET_NEON"
{ {
...@@ -599,13 +599,16 @@ ...@@ -599,13 +599,16 @@
case 3: return "vadd.i64\t%P0, %P1, %P2"; case 3: return "vadd.i64\t%P0, %P1, %P2";
case 1: return "#"; case 1: return "#";
case 2: return "#"; case 2: return "#";
case 4: return "#";
case 5: return "#";
case 6: return "#";
default: gcc_unreachable (); default: gcc_unreachable ();
} }
} }
[(set_attr "neon_type" "neon_int_1,*,*,neon_int_1") [(set_attr "neon_type" "neon_int_1,*,*,neon_int_1,*,*,*")
(set_attr "conds" "*,clob,clob,*") (set_attr "conds" "*,clob,clob,*,clob,clob,clob")
(set_attr "length" "*,8,8,*") (set_attr "length" "*,8,8,*,8,8,8")
(set_attr "arch" "nota8,*,*,onlya8")] (set_attr "arch" "nota8,*,*,onlya8,*,*,*")]
) )
(define_insn "*sub<mode>3_neon" (define_insn "*sub<mode>3_neon"
......
...@@ -141,6 +141,11 @@ ...@@ -141,6 +141,11 @@
(ior (match_operand 0 "arm_rhs_operand") (ior (match_operand 0 "arm_rhs_operand")
(match_operand 0 "arm_neg_immediate_operand"))) (match_operand 0 "arm_neg_immediate_operand")))
(define_predicate "arm_adddi_operand"
(ior (match_operand 0 "s_register_operand")
(and (match_code "const_int")
(match_test "const_ok_for_dimode_op (INTVAL (op), PLUS)"))))
(define_predicate "arm_addimm_operand" (define_predicate "arm_addimm_operand"
(ior (match_operand 0 "arm_immediate_operand") (ior (match_operand 0 "arm_immediate_operand")
(match_operand 0 "arm_neg_immediate_operand"))) (match_operand 0 "arm_neg_immediate_operand")))
......
2012-07-01 Wei Guozhi <carrot@google.com>
PR target/53447
* gcc.target/arm/pr53447-1.c: New testcase.
* gcc.target/arm/pr53447-2.c: New testcase.
* gcc.target/arm/pr53447-3.c: New testcase.
* gcc.target/arm/pr53447-4.c: New testcase.
2012-06-29 Richard Guenther <rguenther@suse.de> 2012-06-29 Richard Guenther <rguenther@suse.de>
PR tree-optimization/47061 PR tree-optimization/47061
......
/* { dg-options "-O2" } */
/* { dg-require-effective-target arm32 } */
/* { dg-final { scan-assembler-not "mov" } } */
void t0p(long long * p)
{
*p += 0x100000001;
}
/* { dg-options "-O2" } */
/* { dg-require-effective-target arm32 } */
/* { dg-final { scan-assembler-not "mov" } } */
void t0p(long long * p)
{
*p -= 0x100000008;
}
/* { dg-options "-O2" } */
/* { dg-require-effective-target arm32 } */
/* { dg-final { scan-assembler-not "mov" } } */
void t0p(long long * p)
{
*p +=0x1fffffff8;
}
/* { dg-options "-O2" } */
/* { dg-require-effective-target arm32 } */
/* { dg-final { scan-assembler-not "mov" } } */
void t0p(long long * p)
{
*p -=0x1fffffff8;
}
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