diff options
author | Natanael Copa <ncopa@alpinelinux.org> | 2010-09-28 11:55:35 +0000 |
---|---|---|
committer | Natanael Copa <ncopa@alpinelinux.org> | 2010-09-28 11:55:35 +0000 |
commit | 3f2e52f3c70d5d48fe46d5a163261f52bd67d437 (patch) | |
tree | 61daa4274a0319771a81030ee055a148673c7ce7 /main/gcc/50_all_pr45312-kernel-miscompile.patch | |
parent | 88fc2b618030ea5e180892038ed42405cdb52566 (diff) | |
download | aports-3f2e52f3c70d5d48fe46d5a163261f52bd67d437.tar.bz2 aports-3f2e52f3c70d5d48fe46d5a163261f52bd67d437.tar.xz |
main/gcc: upgrade to 4.5.1
fixes #438
Diffstat (limited to 'main/gcc/50_all_pr45312-kernel-miscompile.patch')
-rw-r--r-- | main/gcc/50_all_pr45312-kernel-miscompile.patch | 181 |
1 files changed, 181 insertions, 0 deletions
diff --git a/main/gcc/50_all_pr45312-kernel-miscompile.patch b/main/gcc/50_all_pr45312-kernel-miscompile.patch new file mode 100644 index 0000000000..b9b1a7d7f0 --- /dev/null +++ b/main/gcc/50_all_pr45312-kernel-miscompile.patch @@ -0,0 +1,181 @@ +GCC 4.4.4 miscompiles the Linux kernel +http://gcc.gnu.org/PR45312 +https://bugzilla.kernel.org/show_bug.cgi?id=16612 +https://bugs.gentoo.org/334269 + +--- a/gcc/reload1.c ++++ b/gcc/reload1.c +@@ -431,7 +431,6 @@ static void failed_reload (rtx, int); + static int set_reload_reg (int, int); + static void choose_reload_regs_init (struct insn_chain *, rtx *); + static void choose_reload_regs (struct insn_chain *); +-static void merge_assigned_reloads (rtx); + static void emit_input_reload_insns (struct insn_chain *, struct reload *, + rtx, int); + static void emit_output_reload_insns (struct insn_chain *, struct reload *, +@@ -4215,12 +4214,6 @@ reload_as_needed (int live_known) + Record the choices of reload reg in reload_reg_rtx. */ + choose_reload_regs (chain); + +- /* Merge any reloads that we didn't combine for fear of +- increasing the number of spill registers needed but now +- discover can be safely merged. */ +- if (SMALL_REGISTER_CLASSES) +- merge_assigned_reloads (insn); +- + /* Generate the insns to reload operands into or out of + their reload regs. */ + emit_reload_insns (chain); +@@ -6598,152 +6591,6 @@ deallocate_reload_reg (int r) + reload_spill_index[r] = -1; + } + +-/* If SMALL_REGISTER_CLASSES is nonzero, we may not have merged two +- reloads of the same item for fear that we might not have enough reload +- registers. However, normally they will get the same reload register +- and hence actually need not be loaded twice. +- +- Here we check for the most common case of this phenomenon: when we have +- a number of reloads for the same object, each of which were allocated +- the same reload_reg_rtx, that reload_reg_rtx is not used for any other +- reload, and is not modified in the insn itself. If we find such, +- merge all the reloads and set the resulting reload to RELOAD_OTHER. +- This will not increase the number of spill registers needed and will +- prevent redundant code. */ +- +-static void +-merge_assigned_reloads (rtx insn) +-{ +- int i, j; +- +- /* Scan all the reloads looking for ones that only load values and +- are not already RELOAD_OTHER and ones whose reload_reg_rtx are +- assigned and not modified by INSN. */ +- +- for (i = 0; i < n_reloads; i++) +- { +- int conflicting_input = 0; +- int max_input_address_opnum = -1; +- int min_conflicting_input_opnum = MAX_RECOG_OPERANDS; +- +- if (rld[i].in == 0 || rld[i].when_needed == RELOAD_OTHER +- || rld[i].out != 0 || rld[i].reg_rtx == 0 +- || reg_set_p (rld[i].reg_rtx, insn)) +- continue; +- +- /* Look at all other reloads. Ensure that the only use of this +- reload_reg_rtx is in a reload that just loads the same value +- as we do. Note that any secondary reloads must be of the identical +- class since the values, modes, and result registers are the +- same, so we need not do anything with any secondary reloads. */ +- +- for (j = 0; j < n_reloads; j++) +- { +- if (i == j || rld[j].reg_rtx == 0 +- || ! reg_overlap_mentioned_p (rld[j].reg_rtx, +- rld[i].reg_rtx)) +- continue; +- +- if (rld[j].when_needed == RELOAD_FOR_INPUT_ADDRESS +- && rld[j].opnum > max_input_address_opnum) +- max_input_address_opnum = rld[j].opnum; +- +- /* If the reload regs aren't exactly the same (e.g, different modes) +- or if the values are different, we can't merge this reload. +- But if it is an input reload, we might still merge +- RELOAD_FOR_INPUT_ADDRESS and RELOAD_FOR_OTHER_ADDRESS reloads. */ +- +- if (! rtx_equal_p (rld[i].reg_rtx, rld[j].reg_rtx) +- || rld[j].out != 0 || rld[j].in == 0 +- || ! rtx_equal_p (rld[i].in, rld[j].in)) +- { +- if (rld[j].when_needed != RELOAD_FOR_INPUT +- || ((rld[i].when_needed != RELOAD_FOR_INPUT_ADDRESS +- || rld[i].opnum > rld[j].opnum) +- && rld[i].when_needed != RELOAD_FOR_OTHER_ADDRESS)) +- break; +- conflicting_input = 1; +- if (min_conflicting_input_opnum > rld[j].opnum) +- min_conflicting_input_opnum = rld[j].opnum; +- } +- } +- +- /* If all is OK, merge the reloads. Only set this to RELOAD_OTHER if +- we, in fact, found any matching reloads. */ +- +- if (j == n_reloads +- && max_input_address_opnum <= min_conflicting_input_opnum) +- { +- gcc_assert (rld[i].when_needed != RELOAD_FOR_OUTPUT); +- +- for (j = 0; j < n_reloads; j++) +- if (i != j && rld[j].reg_rtx != 0 +- && rtx_equal_p (rld[i].reg_rtx, rld[j].reg_rtx) +- && (! conflicting_input +- || rld[j].when_needed == RELOAD_FOR_INPUT_ADDRESS +- || rld[j].when_needed == RELOAD_FOR_OTHER_ADDRESS)) +- { +- rld[i].when_needed = RELOAD_OTHER; +- rld[j].in = 0; +- reload_spill_index[j] = -1; +- transfer_replacements (i, j); +- } +- +- /* If this is now RELOAD_OTHER, look for any reloads that +- load parts of this operand and set them to +- RELOAD_FOR_OTHER_ADDRESS if they were for inputs, +- RELOAD_OTHER for outputs. Note that this test is +- equivalent to looking for reloads for this operand +- number. +- +- We must take special care with RELOAD_FOR_OUTPUT_ADDRESS; +- it may share registers with a RELOAD_FOR_INPUT, so we can +- not change it to RELOAD_FOR_OTHER_ADDRESS. We should +- never need to, since we do not modify RELOAD_FOR_OUTPUT. +- +- It is possible that the RELOAD_FOR_OPERAND_ADDRESS +- instruction is assigned the same register as the earlier +- RELOAD_FOR_OTHER_ADDRESS instruction. Merging these two +- instructions will cause the RELOAD_FOR_OTHER_ADDRESS +- instruction to be deleted later on. */ +- +- if (rld[i].when_needed == RELOAD_OTHER) +- for (j = 0; j < n_reloads; j++) +- if (rld[j].in != 0 +- && rld[j].when_needed != RELOAD_OTHER +- && rld[j].when_needed != RELOAD_FOR_OTHER_ADDRESS +- && rld[j].when_needed != RELOAD_FOR_OUTPUT_ADDRESS +- && rld[j].when_needed != RELOAD_FOR_OPERAND_ADDRESS +- && (! conflicting_input +- || rld[j].when_needed == RELOAD_FOR_INPUT_ADDRESS +- || rld[j].when_needed == RELOAD_FOR_INPADDR_ADDRESS) +- && reg_overlap_mentioned_for_reload_p (rld[j].in, +- rld[i].in)) +- { +- int k; +- +- rld[j].when_needed +- = ((rld[j].when_needed == RELOAD_FOR_INPUT_ADDRESS +- || rld[j].when_needed == RELOAD_FOR_INPADDR_ADDRESS) +- ? RELOAD_FOR_OTHER_ADDRESS : RELOAD_OTHER); +- +- /* Check to see if we accidentally converted two +- reloads that use the same reload register with +- different inputs to the same type. If so, the +- resulting code won't work. */ +- if (rld[j].reg_rtx) +- for (k = 0; k < j; k++) +- gcc_assert (rld[k].in == 0 || rld[k].reg_rtx == 0 +- || rld[k].when_needed != rld[j].when_needed +- || !rtx_equal_p (rld[k].reg_rtx, +- rld[j].reg_rtx) +- || rtx_equal_p (rld[k].in, +- rld[j].in)); +- } +- } +- } +-} +- + /* These arrays are filled by emit_reload_insns and its subroutines. */ + static rtx input_reload_insns[MAX_RECOG_OPERANDS]; + static rtx other_input_address_reload_insns = 0; |