Discussion:
[4.8 & 4.9] Backport of r211885
Felix Yang
2014-10-08 15:00:24 UTC
Permalink
The enclosed patch for 4.8 & 4.9 branch is a backport of r211885 from trunk.

The only change is to use:

for (def_rec = DF_INSN_INFO_DEFS (insn_info); *def_rec; def_rec++)

other than the new FOR_EACH_INSN_INFO_DEF interface.

Bootstrapped on x86_64-SUSE-Linux for both branches. OK to apply?


Index: gcc/loop-invariant.c
===================================================================
--- gcc/loop-invariant.c (revision 216001)
+++ gcc/loop-invariant.c (working copy)
@@ -839,6 +839,41 @@ check_dependencies (rtx insn, bitmap depends_on)
return true;
}

+/* Pre-check candidate DEST to skip the one which can not make a valid insn
+ during move_invariant_reg. SIMPLE is to skip HARD_REGISTER. */
+
+static bool
+pre_check_invariant_p (bool simple, rtx dest)
+{
+ if (simple && REG_P (dest) && DF_REG_DEF_COUNT (REGNO (dest)) > 1)
+ {
+ df_ref use;
+ rtx ref;
+ unsigned int i = REGNO (dest);
+ struct df_insn_info *insn_info;
+ df_ref *def_rec;
+
+ for (use = DF_REG_USE_CHAIN (i); use; use = DF_REF_NEXT_REG (use))
+ {
+ ref = DF_REF_INSN (use);
+ insn_info = DF_INSN_INFO_GET (ref);
+
+ for (def_rec = DF_INSN_INFO_DEFS (insn_info); *def_rec; def_rec++)
+ if (DF_REF_REGNO (*def_rec) == i)
+ {
+ /* Multi definitions at this stage, most likely are due to
+ instruction constraints, which requires both read and write
+ on the same register. Since move_invariant_reg is not
+ powerful enough to handle such cases, just ignore the INV
+ and leave the chance to others. */
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+
/* Finds invariant in INSN. ALWAYS_REACHED is true if the insn is always
executed. ALWAYS_EXECUTED is true if the insn is always executed,
unless the program ends due to a function call. */
@@ -869,6 +904,7 @@ find_invariant_insn (rtx insn, bool always_reached
simple = false;

if (!may_assign_reg_p (SET_DEST (set))
+ || !pre_check_invariant_p (simple, dest)
|| !check_maybe_invariant (SET_SRC (set)))
return;


Cheers,
Felix
Yangfei (Felix)
2014-10-09 08:50:07 UTC
Permalink
PING?
Post by Felix Yang
The enclosed patch for 4.8 & 4.9 branch is a backport of r211885 from trunk.
for (def_rec = DF_INSN_INFO_DEFS (insn_info); *def_rec; def_rec++)
other than the new FOR_EACH_INSN_INFO_DEF interface.
Bootstrapped on x86_64-SUSE-Linux for both branches. OK to apply?
Index: gcc/loop-invariant.c
================================================================
===
--- gcc/loop-invariant.c (revision 216001)
+++ gcc/loop-invariant.c (working copy)
@@ -839,6 +839,41 @@ check_dependencies (rtx insn, bitmap depends_on)
return true;
}
+/* Pre-check candidate DEST to skip the one which can not make a valid insn
+ during move_invariant_reg. SIMPLE is to skip HARD_REGISTER. */
+
+static bool
+pre_check_invariant_p (bool simple, rtx dest) {
+ if (simple && REG_P (dest) && DF_REG_DEF_COUNT (REGNO (dest)) > 1)
+ {
+ df_ref use;
+ rtx ref;
+ unsigned int i = REGNO (dest);
+ struct df_insn_info *insn_info;
+ df_ref *def_rec;
+
+ for (use = DF_REG_USE_CHAIN (i); use; use = DF_REF_NEXT_REG (use))
+ {
+ ref = DF_REF_INSN (use);
+ insn_info = DF_INSN_INFO_GET (ref);
+
+ for (def_rec = DF_INSN_INFO_DEFS (insn_info); *def_rec; def_rec++)
+ if (DF_REF_REGNO (*def_rec) == i)
+ {
+ /* Multi definitions at this stage, most likely are due to
+ instruction constraints, which requires both read and write
+ on the same register. Since move_invariant_reg is not
+ powerful enough to handle such cases, just ignore the INV
+ and leave the chance to others. */
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+
/* Finds invariant in INSN. ALWAYS_REACHED is true if the insn is always
executed. ALWAYS_EXECUTED is true if the insn is always executed,
@@ find_invariant_insn (rtx insn, bool always_reached
simple = false;
if (!may_assign_reg_p (SET_DEST (set))
+ || !pre_check_invariant_p (simple, dest)
|| !check_maybe_invariant (SET_SRC (set)))
return;
Jakub Jelinek
2014-10-09 08:53:53 UTC
Permalink
Post by Felix Yang
The enclosed patch for 4.8 & 4.9 branch is a backport of r211885 from trunk.
for (def_rec = DF_INSN_INFO_DEFS (insn_info); *def_rec; def_rec++)
other than the new FOR_EACH_INSN_INFO_DEF interface.
Bootstrapped on x86_64-SUSE-Linux for both branches. OK to apply?
ChangeLog entry is missing, plus description why do you want to backport it.
If it fixes a bug on the branches, it would be better to have a bugzilla
PR for that, and definitely a testcase.
Post by Felix Yang
--- gcc/loop-invariant.c (revision 216001)
+++ gcc/loop-invariant.c (working copy)
@@ -839,6 +839,41 @@ check_dependencies (rtx insn, bitmap depends_on)
return true;
}
+/* Pre-check candidate DEST to skip the one which can not make a valid insn
+ during move_invariant_reg. SIMPLE is to skip HARD_REGISTER. */
+
+static bool
+pre_check_invariant_p (bool simple, rtx dest)
+{
+ if (simple && REG_P (dest) && DF_REG_DEF_COUNT (REGNO (dest)) > 1)
+ {
+ df_ref use;
+ rtx ref;
+ unsigned int i = REGNO (dest);
+ struct df_insn_info *insn_info;
+ df_ref *def_rec;
+
+ for (use = DF_REG_USE_CHAIN (i); use; use = DF_REF_NEXT_REG (use))
+ {
+ ref = DF_REF_INSN (use);
+ insn_info = DF_INSN_INFO_GET (ref);
+
+ for (def_rec = DF_INSN_INFO_DEFS (insn_info); *def_rec; def_rec++)
+ if (DF_REF_REGNO (*def_rec) == i)
+ {
+ /* Multi definitions at this stage, most likely are due to
+ instruction constraints, which requires both read and write
+ on the same register. Since move_invariant_reg is not
+ powerful enough to handle such cases, just ignore the INV
+ and leave the chance to others. */
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+
/* Finds invariant in INSN. ALWAYS_REACHED is true if the insn is always
executed. ALWAYS_EXECUTED is true if the insn is always executed,
unless the program ends due to a function call. */
@@ -869,6 +904,7 @@ find_invariant_insn (rtx insn, bool always_reached
simple = false;
if (!may_assign_reg_p (SET_DEST (set))
+ || !pre_check_invariant_p (simple, dest)
|| !check_maybe_invariant (SET_SRC (set)))
return;
Cheers,
Felix
Jakub
Yangfei (Felix)
2014-10-09 09:04:49 UTC
Permalink
Post by Jakub Jelinek
Post by Felix Yang
The enclosed patch for 4.8 & 4.9 branch is a backport of r211885 from trunk.
for (def_rec = DF_INSN_INFO_DEFS (insn_info); *def_rec; def_rec++)
other than the new FOR_EACH_INSN_INFO_DEF interface.
Bootstrapped on x86_64-SUSE-Linux for both branches. OK to apply?
ChangeLog entry is missing, plus description why do you want to backport it.
If it fixes a bug on the branches, it would be better to have a bugzilla PR for that,
and definitely a testcase.
Yeah, I will add a ChangeLog entry for this patch when it is committed.
I encountered the same issue when working on my local customized 4.8/4.9 branches. Not reproduceable with the official 4.8/4.9 branches.
I thinks it's just an enhancement for the loop invariant pass to make it more versatile. It's better that 4.8/4.9 branches
Jakub Jelinek
2014-10-09 09:07:29 UTC
Permalink
Post by Yangfei (Felix)
Post by Jakub Jelinek
Post by Felix Yang
The enclosed patch for 4.8 & 4.9 branch is a backport of r211885 from trunk.
for (def_rec = DF_INSN_INFO_DEFS (insn_info); *def_rec; def_rec++)
other than the new FOR_EACH_INSN_INFO_DEF interface.
Bootstrapped on x86_64-SUSE-Linux for both branches. OK to apply?
ChangeLog entry is missing, plus description why do you want to backport it.
If it fixes a bug on the branches, it would be better to have a bugzilla PR for that,
and definitely a testcase.
Yeah, I will add a ChangeLog entry for this patch when it is committed.
I encountered the same issue when working on my local customized 4.8/4.9 branches. Not reproduceable with the official 4.8/4.9 branches.
I thinks it's just an enhancement for the loop invariant pass to make it more versatile. It's better that 4.8/4.9 branches also inlcude this enhancement.
OK?
If it is just an enhancement, then those generally are not backported to
release branches (exceptions possible of course, but there needs to be a
strong reason). Each pass has some risk of breaking something, exposing
previously only latent bugs in later passes etc.

Jakub
Yangfei (Felix)
2014-10-09 09:17:55 UTC
Permalink
Post by Felix Yang
Post by Yangfei (Felix)
Post by Jakub Jelinek
Post by Felix Yang
The enclosed patch for 4.8 & 4.9 branch is a backport of r211885 from
trunk.
Post by Yangfei (Felix)
Post by Jakub Jelinek
Post by Felix Yang
for (def_rec = DF_INSN_INFO_DEFS (insn_info); *def_rec; def_rec++)
other than the new FOR_EACH_INSN_INFO_DEF interface.
Bootstrapped on x86_64-SUSE-Linux for both branches. OK to apply?
ChangeLog entry is missing, plus description why do you want to backport
it.
Post by Yangfei (Felix)
Post by Jakub Jelinek
If it fixes a bug on the branches, it would be better to have a
bugzilla PR for that, and definitely a testcase.
Yeah, I will add a ChangeLog entry for this patch when it is committed.
I encountered the same issue when working on my local customized 4.8/4.9
branches. Not reproduceable with the official 4.8/4.9 branches.
Post by Yangfei (Felix)
I thinks it's just an enhancement for the loop invariant pass to make it more
versatile. It's better that 4.8/4.9 branches also inlcude this enhancement.
Post by Yangfei (Felix)
OK?
If it is just an enhancement, then those generally are not backported to release
branches (exceptions possible of course, but there needs to be a strong reason).
Each pass has some risk of breaking something, exposing previously only latent
bugs in later passes etc.
Jakub
We can treat it as bugfix, as we got incorrect code when it triggers.
It just happens so rare
Yangfei (Felix)
2014-10-09 09:35:50 UTC
Permalink
Post by Jakub Jelinek
Post by Felix Yang
Post by Yangfei (Felix)
Post by Jakub Jelinek
Post by Felix Yang
The enclosed patch for 4.8 & 4.9 branch is a backport of r211885
from
trunk.
Post by Yangfei (Felix)
Post by Jakub Jelinek
Post by Felix Yang
for (def_rec = DF_INSN_INFO_DEFS (insn_info); *def_rec; def_rec++)
other than the new FOR_EACH_INSN_INFO_DEF interface.
Bootstrapped on x86_64-SUSE-Linux for both branches. OK to apply?
ChangeLog entry is missing, plus description why do you want to
backport
it.
Post by Yangfei (Felix)
Post by Jakub Jelinek
If it fixes a bug on the branches, it would be better to have a
bugzilla PR for that, and definitely a testcase.
Yeah, I will add a ChangeLog entry for this patch when it is committed.
I encountered the same issue when working on my local customized
4.8/4.9
branches. Not reproduceable with the official 4.8/4.9 branches.
Post by Yangfei (Felix)
I thinks it's just an enhancement for the loop invariant pass to
make it more
versatile. It's better that 4.8/4.9 branches also inlcude this enhancement.
Post by Yangfei (Felix)
OK?
If it is just an enhancement, then those generally are not backported
to release branches (exceptions possible of course, but there needs to be a
strong reason).
Post by Felix Yang
Each pass has some risk of breaking something, exposing previously
only latent bugs in later passes etc.
Jakub
We can treat it as bugfix, as we got incorrect code when it triggers.
It just happens so rarely. Does it worth backporting?
And the patch fix this bug by making the loop invariant pass more conservative.
I didn't find a PR or testcase o
Richard Biener
2014-10-09 10:41:15 UTC
Permalink
Post by Yangfei (Felix)
Post by Jakub Jelinek
Post by Felix Yang
Post by Yangfei (Felix)
Post by Jakub Jelinek
Post by Felix Yang
The enclosed patch for 4.8 & 4.9 branch is a backport of r211885
from
trunk.
Post by Yangfei (Felix)
Post by Jakub Jelinek
Post by Felix Yang
for (def_rec = DF_INSN_INFO_DEFS (insn_info); *def_rec; def_rec++)
other than the new FOR_EACH_INSN_INFO_DEF interface.
Bootstrapped on x86_64-SUSE-Linux for both branches. OK to apply?
ChangeLog entry is missing, plus description why do you want to
backport
it.
Post by Yangfei (Felix)
Post by Jakub Jelinek
If it fixes a bug on the branches, it would be better to have a
bugzilla PR for that, and definitely a testcase.
Yeah, I will add a ChangeLog entry for this patch when it is committed.
I encountered the same issue when working on my local customized
4.8/4.9
branches. Not reproduceable with the official 4.8/4.9 branches.
Post by Yangfei (Felix)
I thinks it's just an enhancement for the loop invariant pass to
make it more
versatile. It's better that 4.8/4.9 branches also inlcude this enhancement.
Post by Yangfei (Felix)
OK?
If it is just an enhancement, then those generally are not backported
to release branches (exceptions possible of course, but there needs to be a
strong reason).
Post by Felix Yang
Each pass has some risk of breaking something, exposing previously
only latent bugs in later passes etc.
Jakub
We can treat it as bugfix, as we got incorrect code when it triggers.
It just happens so rarely. Does it worth backporting?
And the patch fix this bug by making the loop invariant pass more conservative.
I didn't find a PR or testcase on trunk for this patch either.
We at least want a testcase for the "we got incorrect code when it triggers".

Richard.
Felix Yang
2014-10-09 11:04:54 UTC
Permalink
The issue is that I cannot reproduce it on the official released branches.
It happens on my local GCC branch (with a new port).
Let's see if the original author of the patch has an testcase.
Zhenqiang, do you have one that can reproduce this bug with the
official 4.8/4.9 branches?
Thanks.
Cheers,
Felix


On Thu, Oct 9, 2014 at 6:41 PM, Richard Biener
Post by Richard Biener
Post by Yangfei (Felix)
Post by Jakub Jelinek
Post by Felix Yang
Post by Yangfei (Felix)
Post by Jakub Jelinek
Post by Felix Yang
The enclosed patch for 4.8 & 4.9 branch is a backport of r211885
from
trunk.
Post by Yangfei (Felix)
Post by Jakub Jelinek
Post by Felix Yang
for (def_rec = DF_INSN_INFO_DEFS (insn_info); *def_rec; def_rec++)
other than the new FOR_EACH_INSN_INFO_DEF interface.
Bootstrapped on x86_64-SUSE-Linux for both branches. OK to apply?
ChangeLog entry is missing, plus description why do you want to
backport
it.
Post by Yangfei (Felix)
Post by Jakub Jelinek
If it fixes a bug on the branches, it would be better to have a
bugzilla PR for that, and definitely a testcase.
Yeah, I will add a ChangeLog entry for this patch when it is committed.
I encountered the same issue when working on my local customized
4.8/4.9
branches. Not reproduceable with the official 4.8/4.9 branches.
Post by Yangfei (Felix)
I thinks it's just an enhancement for the loop invariant pass to
make it more
versatile. It's better that 4.8/4.9 branches also inlcude this enhancement.
Post by Yangfei (Felix)
OK?
If it is just an enhancement, then those generally are not backported
to release branches (exceptions possible of course, but there needs to be a
strong reason).
Post by Felix Yang
Each pass has some risk of breaking something, exposing previously
only latent bugs in later passes etc.
Jakub
We can treat it as bugfix, as we got incorrect code when it triggers.
It just happens so rarely. Does it worth backporting?
And the patch fix this bug by making the loop invariant pass more conservative.
I didn't find a PR or testcase on trunk for this patch either.
We at least want a testcase for the "we got incorrect code when it triggers".
Richard.
Loading...