diff options
author | Zhenqiang Chen <zhenqiang.chen@arm.com> | 2014-12-12 05:51:19 +0000 |
---|---|---|
committer | Zhenqiang Chen <zqchen@gcc.gnu.org> | 2014-12-12 05:51:19 +0000 |
commit | 0a6aa4763eedb8b1a5383b3d9a0cc9d8ec043e4a (patch) | |
tree | d2258ae3f54efa0239da9d1d2ef4d9f2385d2c2e /gcc | |
parent | e8c8ffa90081e97f664e73f58518a95f695aaca3 (diff) | |
download | gcc-0a6aa4763eedb8b1a5383b3d9a0cc9d8ec043e4a.zip gcc-0a6aa4763eedb8b1a5383b3d9a0cc9d8ec043e4a.tar.gz gcc-0a6aa4763eedb8b1a5383b3d9a0cc9d8ec043e4a.tar.bz2 |
re PR rtl-optimization/63917 (r217646 caused many failures)
2014-12-12 Zhenqiang Chen <zhenqiang.chen@arm.com>
PR rtl-optimization/63917
* ifcvt.c (cc_in_cond): New function.
(end_ifcvt_sequence): Make sure new generated insns do not clobber CC.
(noce_process_if_block, check_cond_move_block): Check CC references.
testsuite/ChangeLog:
2014-12-12 Zhenqiang Chen <zhenqiang.chen@arm.com>
* gcc.dg/pr64007.c: New test.
From-SVN: r218658
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/ifcvt.c | 30 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/pr64007.c | 50 |
4 files changed, 90 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 7478b0f..d9a4bde 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2014-12-12 Zhenqiang Chen <zhenqiang.chen@arm.com> + + PR rtl-optimization/63917 + * ifcvt.c (cc_in_cond): New function. + (end_ifcvt_sequence): Make sure new generated insns do not clobber CC. + (noce_process_if_block, check_cond_move_block): Check CC references. + 2014-12-11 Andrew Pinski <apinski@cavium.com> * config/aarch64/aarch64-protos.h (tune_params): Add align field. diff --git a/gcc/ifcvt.c b/gcc/ifcvt.c index f7a9224..f0159c1 100644 --- a/gcc/ifcvt.c +++ b/gcc/ifcvt.c @@ -1016,6 +1016,18 @@ noce_emit_move_insn (rtx x, rtx y) 0, 0, outmode, y); } +/* Return the CC reg if it is used in COND. */ + +static rtx +cc_in_cond (rtx cond) +{ + if (HAVE_cbranchcc4 && cond + && GET_MODE_CLASS (GET_MODE (XEXP (cond, 0))) == MODE_CC) + return XEXP (cond, 0); + + return NULL_RTX; +} + /* Return sequence of instructions generated by if conversion. This function calls end_sequence() to end the current stream, ensures that are instructions are unshared, recognizable non-jump insns. @@ -1026,6 +1038,7 @@ end_ifcvt_sequence (struct noce_if_info *if_info) { rtx_insn *insn; rtx_insn *seq = get_insns (); + rtx cc = cc_in_cond (if_info->cond); set_used_flags (if_info->x); set_used_flags (if_info->cond); @@ -1040,7 +1053,9 @@ end_ifcvt_sequence (struct noce_if_info *if_info) allows proper placement of required clobbers. */ for (insn = seq; insn; insn = NEXT_INSN (insn)) if (JUMP_P (insn) - || recog_memoized (insn) == -1) + || recog_memoized (insn) == -1 + /* Make sure new generated code does not clobber CC. */ + || (cc && set_of (cc, insn))) return NULL; return seq; @@ -2544,6 +2559,7 @@ noce_process_if_block (struct noce_if_info *if_info) rtx_insn *insn_a, *insn_b; rtx set_a, set_b; rtx orig_x, x, a, b; + rtx cc; /* We're looking for patterns of the form @@ -2655,6 +2671,13 @@ noce_process_if_block (struct noce_if_info *if_info) if_info->a = a; if_info->b = b; + /* Skip it if the instruction to be moved might clobber CC. */ + cc = cc_in_cond (cond); + if (cc + && (set_of (cc, insn_a) + || (insn_b && set_of (cc, insn_b)))) + return FALSE; + /* Try optimizations in some approximation of a useful order. */ /* ??? Should first look to see if X is live incoming at all. If it isn't, we don't need anything but an unconditional set. */ @@ -2811,6 +2834,7 @@ check_cond_move_block (basic_block bb, rtx cond) { rtx_insn *insn; + rtx cc = cc_in_cond (cond); /* We can only handle simple jumps at the end of the basic block. It is almost impossible to update the CFG otherwise. */ @@ -2868,6 +2892,10 @@ check_cond_move_block (basic_block bb, && modified_between_p (src, insn, NEXT_INSN (BB_END (bb)))) return FALSE; + /* Skip it if the instruction to be moved might clobber CC. */ + if (cc && set_of (cc, insn)) + return FALSE; + vals->put (dest, src); regs->safe_push (dest); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 1c06df0..fc4869f 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2014-12-12 Zhenqiang Chen <zhenqiang.chen@arm.com> + + * gcc.dg/pr64007.c: New test. + 2014-12-12 Bin Cheng <bin.cheng@arm.com> * gcc.target/aarch64/ldp_stp_2.c: Make test less vulnerable. diff --git a/gcc/testsuite/gcc.dg/pr64007.c b/gcc/testsuite/gcc.dg/pr64007.c new file mode 100644 index 0000000..cb0e50f --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr64007.c @@ -0,0 +1,50 @@ +/* { dg-options " -O3 " } */ +/* { dg-do run } */ + +#include <assert.h> + +int d, i; + +struct S +{ + int f0; +} *b, c, e, h, **g = &b; + +static struct S *f = &e; + +int +fn1 (int p) +{ + int a = 0; + return a || p < 0 || p >= 2 || 1 >> p; +} + +int +main () +{ + int k = 1, l, *m = &c.f0; + + for (;;) + { + l = fn1 (i); + *m = k && i; + if (l) + { + int n[1] = {0}; + } + break; + } + + *g = &h; + + assert (b); + + if (d) + (*m)--; + d = (f != 0) | (i >= 0); + + if (c.f0 != 0) + __builtin_abort (); + + return 0; +} |