diff options
author | 2010-12-26 05:31:07 +0000 | |
---|---|---|
committer | 2010-12-26 05:31:07 +0000 | |
commit | 2fac5534ec0c389ca580044b4eed52f4b6c6b635 (patch) | |
tree | 21da3a93d10c94d83d7011bf8901ac8f88ea7534 /4.5.2 | |
parent | Add upstream patch for bug #346845. (diff) | |
download | gcc-patches-2fac5534ec0c389ca580044b4eed52f4b6c6b635.tar.gz gcc-patches-2fac5534ec0c389ca580044b4eed52f4b6c6b635.tar.bz2 gcc-patches-2fac5534ec0c389ca580044b4eed52f4b6c6b635.zip |
Add upstream patch for bug #349113.
Diffstat (limited to '4.5.2')
-rw-r--r-- | 4.5.2/gentoo/60_all_4.5.2_pr46915_hppa-wrong-code.patch | 185 | ||||
-rw-r--r-- | 4.5.2/gentoo/README.history | 1 |
2 files changed, 186 insertions, 0 deletions
diff --git a/4.5.2/gentoo/60_all_4.5.2_pr46915_hppa-wrong-code.patch b/4.5.2/gentoo/60_all_4.5.2_pr46915_hppa-wrong-code.patch new file mode 100644 index 0000000..979de43 --- /dev/null +++ b/4.5.2/gentoo/60_all_4.5.2_pr46915_hppa-wrong-code.patch @@ -0,0 +1,185 @@ +[HPPA] Wrong code is generated for conditional branch followed by zero length asm + +http://gcc.gnu.org/PR46915 +https://bugs.gentoo.org/349113 + +--- gcc/config/pa/pa.c ++++ gcc/config/pa/pa.c +@@ -6097,37 +6097,94 @@ + } + + /* Return TRUE if INSN, a jump insn, has an unfilled delay slot and +- it branches to the next real instruction. Otherwise, return FALSE. */ ++ it branches into the delay slot. Otherwise, return FALSE. */ + + static bool + branch_to_delay_slot_p (rtx insn) + { ++ rtx jump_insn; ++ + if (dbr_sequence_length ()) + return FALSE; + +- return next_real_insn (JUMP_LABEL (insn)) == next_real_insn (insn); ++ jump_insn = next_active_insn (JUMP_LABEL (insn)); ++ while (insn) ++ { ++ insn = next_active_insn (insn); ++ if (jump_insn == insn) ++ return TRUE; ++ ++ /* We can't rely on the length of asms. So, we return FALSE when ++ the branch is followed by an asm. */ ++ if (!insn ++ || GET_CODE (PATTERN (insn)) == ASM_INPUT ++ || extract_asm_operands (PATTERN (insn)) != NULL_RTX ++ || get_attr_length (insn) > 0) ++ break; ++ } ++ ++ return FALSE; + } + +-/* Return TRUE if INSN, a jump insn, needs a nop in its delay slot. ++/* Return TRUE if INSN, a forward jump insn, needs a nop in its delay slot. + + This occurs when INSN has an unfilled delay slot and is followed +- by an ASM_INPUT. Disaster can occur if the ASM_INPUT is empty and +- the jump branches into the delay slot. So, we add a nop in the delay +- slot just to be safe. This messes up our instruction count, but we +- don't know how big the ASM_INPUT insn is anyway. */ ++ by an asm. Disaster can occur if the asm is empty and the jump ++ branches into the delay slot. So, we add a nop in the delay slot ++ when this occurs. */ + + static bool + branch_needs_nop_p (rtx insn) + { +- rtx next_insn; ++ rtx jump_insn; + + if (dbr_sequence_length ()) + return FALSE; + +- next_insn = next_real_insn (insn); +- return GET_CODE (PATTERN (next_insn)) == ASM_INPUT; ++ jump_insn = next_active_insn (JUMP_LABEL (insn)); ++ while (insn) ++ { ++ insn = next_active_insn (insn); ++ if (!insn || jump_insn == insn) ++ return TRUE; ++ ++ if (!(GET_CODE (PATTERN (insn)) == ASM_INPUT ++ || extract_asm_operands (PATTERN (insn)) != NULL_RTX) ++ && get_attr_length (insn) > 0) ++ break; ++ } ++ ++ return FALSE; + } + ++/* Return TRUE if INSN, a forward jump insn, can use nullification ++ to skip the following instruction. This avoids an extra cycle due ++ to a mis-predicted branch when we fall through. */ ++ ++static bool ++use_skip_p (rtx insn) ++{ ++ rtx jump_insn = next_active_insn (JUMP_LABEL (insn)); ++ ++ while (insn) ++ { ++ insn = next_active_insn (insn); ++ ++ /* We can't rely on the length of asms, so we can't skip asms. */ ++ if (!insn ++ || GET_CODE (PATTERN (insn)) == ASM_INPUT ++ || extract_asm_operands (PATTERN (insn)) != NULL_RTX) ++ break; ++ if (get_attr_length (insn) == 4 ++ && jump_insn == next_active_insn (insn)) ++ return TRUE; ++ if (get_attr_length (insn) > 0) ++ break; ++ } ++ ++ return FALSE; ++} ++ + /* This routine handles all the normal conditional branch sequences we + might need to generate. It handles compare immediate vs compare + register, nullification of delay slots, varying length branches, +@@ -6139,7 +6196,7 @@ + output_cbranch (rtx *operands, int negated, rtx insn) + { + static char buf[100]; +- int useskip = 0; ++ bool useskip; + int nullify = INSN_ANNULLED_BRANCH_P (insn); + int length = get_attr_length (insn); + int xdelay; +@@ -6177,12 +6234,7 @@ + /* A forward branch over a single nullified insn can be done with a + comclr instruction. This avoids a single cycle penalty due to + mis-predicted branch if we fall through (branch not taken). */ +- if (length == 4 +- && next_real_insn (insn) != 0 +- && get_attr_length (next_real_insn (insn)) == 4 +- && JUMP_LABEL (insn) == next_nonnote_insn (next_real_insn (insn)) +- && nullify) +- useskip = 1; ++ useskip = (length == 4 && nullify) ? use_skip_p (insn) : FALSE; + + switch (length) + { +@@ -6470,7 +6522,7 @@ + output_bb (rtx *operands ATTRIBUTE_UNUSED, int negated, rtx insn, int which) + { + static char buf[100]; +- int useskip = 0; ++ bool useskip; + int nullify = INSN_ANNULLED_BRANCH_P (insn); + int length = get_attr_length (insn); + int xdelay; +@@ -6496,14 +6548,8 @@ + /* A forward branch over a single nullified insn can be done with a + extrs instruction. This avoids a single cycle penalty due to + mis-predicted branch if we fall through (branch not taken). */ ++ useskip = (length == 4 && nullify) ? use_skip_p (insn) : FALSE; + +- if (length == 4 +- && next_real_insn (insn) != 0 +- && get_attr_length (next_real_insn (insn)) == 4 +- && JUMP_LABEL (insn) == next_nonnote_insn (next_real_insn (insn)) +- && nullify) +- useskip = 1; +- + switch (length) + { + +@@ -6661,7 +6707,7 @@ + output_bvb (rtx *operands ATTRIBUTE_UNUSED, int negated, rtx insn, int which) + { + static char buf[100]; +- int useskip = 0; ++ bool useskip; + int nullify = INSN_ANNULLED_BRANCH_P (insn); + int length = get_attr_length (insn); + int xdelay; +@@ -6687,14 +6733,8 @@ + /* A forward branch over a single nullified insn can be done with a + extrs instruction. This avoids a single cycle penalty due to + mis-predicted branch if we fall through (branch not taken). */ ++ useskip = (length == 4 && nullify) ? use_skip_p (insn) : FALSE; + +- if (length == 4 +- && next_real_insn (insn) != 0 +- && get_attr_length (next_real_insn (insn)) == 4 +- && JUMP_LABEL (insn) == next_nonnote_insn (next_real_insn (insn)) +- && nullify) +- useskip = 1; +- + switch (length) + { + diff --git a/4.5.2/gentoo/README.history b/4.5.2/gentoo/README.history index ca8c45a..9f5bd60 100644 --- a/4.5.2/gentoo/README.history +++ b/4.5.2/gentoo/README.history @@ -14,6 +14,7 @@ + 47_all_arm-unbreak-armv4t.patch + 51_all_gcc-3.4-libiberty-pic.patch + 53_all_gcc4-superh-default-multilib.patch + + 60_all_4.5.2_pr46915_hppa-wrong-code.patch + 61_all_gcc4-ia64-noteGNUstack.patch + 74_all_sh-pr24836.patch + 91_all_gcc-fbsdshared-spec.patch |