From: Jakub Jelinek Date: Fri, 2 Mar 2018 09:16:50 +0000 (+0100) Subject: re PR rtl-optimization/84614 (wrong code with u16->u128 extension at aarch64 -fno... X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=ec2d71214f90e21675a5abbe5b532273f7b11ded;p=gcc.git re PR rtl-optimization/84614 (wrong code with u16->u128 extension at aarch64 -fno-split-wide-types -g3 --param=max-combine-insns=3) PR target/84614 * rtl.h (prev_real_nondebug_insn, next_real_nondebug_insn): New prototypes. * emit-rtl.c (next_real_insn, prev_real_insn): Fix up function comments. (next_real_nondebug_insn, prev_real_nondebug_insn): New functions. * cfgcleanup.c (try_head_merge_bb): Use prev_real_nondebug_insn instead of a loop around prev_real_insn. * combine.c (move_deaths): Use prev_real_nondebug_insn instead of prev_real_insn. * gcc.dg/pr84614.c: New test. From-SVN: r258129 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index bb32cf440e2..09cae39cc27 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,16 @@ 2018-03-02 Jakub Jelinek + PR target/84614 + * rtl.h (prev_real_nondebug_insn, next_real_nondebug_insn): New + prototypes. + * emit-rtl.c (next_real_insn, prev_real_insn): Fix up function + comments. + (next_real_nondebug_insn, prev_real_nondebug_insn): New functions. + * cfgcleanup.c (try_head_merge_bb): Use prev_real_nondebug_insn + instead of a loop around prev_real_insn. + * combine.c (move_deaths): Use prev_real_nondebug_insn instead of + prev_real_insn. + PR inline-asm/84625 * config/i386/i386.c (ix86_print_operand): Use conditional output_operand_lossage instead of gcc_assert if CONST_VECTOR is not diff --git a/gcc/cfgcleanup.c b/gcc/cfgcleanup.c index 6892d806e53..4f721537eb2 100644 --- a/gcc/cfgcleanup.c +++ b/gcc/cfgcleanup.c @@ -2448,9 +2448,7 @@ try_head_merge_bb (basic_block bb) max_match--; if (max_match == 0) return false; - do - e0_last_head = prev_real_insn (e0_last_head); - while (DEBUG_INSN_P (e0_last_head)); + e0_last_head = prev_real_nondebug_insn (e0_last_head); } if (max_match == 0) diff --git a/gcc/combine.c b/gcc/combine.c index 6b761c609ae..ddea5b18fe0 100644 --- a/gcc/combine.c +++ b/gcc/combine.c @@ -13923,7 +13923,7 @@ move_deaths (rtx x, rtx maybe_kill_insn, int from_luid, rtx_insn *to_insn, FROM_LUID and TO_INSN. If so, find it. This is PR83304. */ if (!where_dead || DF_INSN_LUID (where_dead) >= DF_INSN_LUID (to_insn)) { - rtx_insn *insn = prev_real_insn (to_insn); + rtx_insn *insn = prev_real_nondebug_insn (to_insn); while (insn && BLOCK_FOR_INSN (insn) == BLOCK_FOR_INSN (to_insn) && DF_INSN_LUID (insn) >= from_luid) @@ -13935,7 +13935,7 @@ move_deaths (rtx x, rtx maybe_kill_insn, int from_luid, rtx_insn *to_insn, break; } - insn = prev_real_insn (insn); + insn = prev_real_nondebug_insn (insn); } } diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c index dd8fec3f349..4dce18df041 100644 --- a/gcc/emit-rtl.c +++ b/gcc/emit-rtl.c @@ -3597,7 +3597,7 @@ prev_nonnote_nondebug_insn_bb (rtx_insn *insn) return insn; } -/* Return the next INSN, CALL_INSN or JUMP_INSN after INSN; +/* Return the next INSN, CALL_INSN, JUMP_INSN or DEBUG_INSN after INSN; or 0, if there is none. This routine does not look inside SEQUENCEs. */ @@ -3616,7 +3616,7 @@ next_real_insn (rtx uncast_insn) return insn; } -/* Return the last INSN, CALL_INSN or JUMP_INSN before INSN; +/* Return the last INSN, CALL_INSN, JUMP_INSN or DEBUG_INSN before INSN; or 0, if there is none. This routine does not look inside SEQUENCEs. */ @@ -3633,6 +3633,42 @@ prev_real_insn (rtx_insn *insn) return insn; } +/* Return the next INSN, CALL_INSN or JUMP_INSN after INSN; + or 0, if there is none. This routine does not look inside + SEQUENCEs. */ + +rtx_insn * +next_real_nondebug_insn (rtx uncast_insn) +{ + rtx_insn *insn = safe_as_a (uncast_insn); + + while (insn) + { + insn = NEXT_INSN (insn); + if (insn == 0 || NONDEBUG_INSN_P (insn)) + break; + } + + return insn; +} + +/* Return the last INSN, CALL_INSN or JUMP_INSN before INSN; + or 0, if there is none. This routine does not look inside + SEQUENCEs. */ + +rtx_insn * +prev_real_nondebug_insn (rtx_insn *insn) +{ + while (insn) + { + insn = PREV_INSN (insn); + if (insn == 0 || NONDEBUG_INSN_P (insn)) + break; + } + + return insn; +} + /* Return the last CALL_INSN in the current list, or 0 if there is none. This routine does not look inside SEQUENCEs. */ diff --git a/gcc/rtl.h b/gcc/rtl.h index c9dd7dd959f..f31b4ade9d3 100644 --- a/gcc/rtl.h +++ b/gcc/rtl.h @@ -3277,6 +3277,8 @@ extern rtx_insn *next_nonnote_nondebug_insn (rtx_insn *); extern rtx_insn *next_nonnote_nondebug_insn_bb (rtx_insn *); extern rtx_insn *prev_real_insn (rtx_insn *); extern rtx_insn *next_real_insn (rtx); +extern rtx_insn *prev_real_nondebug_insn (rtx_insn *); +extern rtx_insn *next_real_nondebug_insn (rtx); extern rtx_insn *prev_active_insn (rtx_insn *); extern rtx_insn *next_active_insn (rtx_insn *); extern int active_insn_p (const rtx_insn *); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index b035c357dbe..cb19be5925b 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,8 @@ 2018-03-02 Jakub Jelinek + PR target/84614 + * gcc.dg/pr84614.c: New test. + PR inline-asm/84625 * gcc.target/i386/pr84625.c: New test. diff --git a/gcc/testsuite/gcc.dg/pr84614.c b/gcc/testsuite/gcc.dg/pr84614.c new file mode 100644 index 00000000000..98af26ba4e5 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr84614.c @@ -0,0 +1,28 @@ +/* PR target/84614 */ +/* { dg-do run { target int128 } } */ +/* { dg-options "-Og -fno-split-wide-types -fno-tree-coalesce-vars -g --param=max-combine-insns=3 -fcompare-debug" } */ + +unsigned __int128 a; + +unsigned __int128 +b (unsigned short c, unsigned int d) +{ + unsigned long long e; + __builtin_sub_overflow (0, d, &e); + e >>= c; + c ^= 65535; + d ^= 824; + return c + a + d + e; +} + +int +main () +{ + unsigned __int128 x = b (0, 9); + if (__SIZEOF_INT__ * __CHAR_BIT__ == 32 + && __SIZEOF_LONG_LONG__ * __CHAR_BIT__ == 64 + && __SIZEOF_INT128__ * __CHAR_BIT__ == 128 + && x != (((unsigned __int128) 1 << 64) | 0x10327)) + __builtin_abort (); + return 0; +}