The following patch fixes https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92796
The patch was successfully bootstrapped and tested on x86-64. Committed as r279204
Index: ChangeLog =================================================================== --- ChangeLog (revision 279200) +++ ChangeLog (working copy) @@ -1,3 +1,18 @@ +2019-12-10 Vladimir Makarov <vmaka...@redhat.com> + + PR rtl-optimization/92796 + * lra-int.h (lra_risky_transformations_p): Rename to + check_and_force_assignment_correctness_p. + * lra-assigns.c: Ditto. + (lra_assign): Reset check_and_force_assignment_correctness_p. + * lra-constraints.c (lra_risky_transformations_p): Rename to + check_and_force_assignment_correctness_p. + (lra_constraints): Set up check_and_force_assignment_correctness_p + only for the 1st sub-pass. + * lra-eliminations.c (process_insn_for_elimination): Set up + check_and_force_assignment_correctness_p if the insn chnaged its + code. + 2019-12-10 Jakub Jelinek <ja...@redhat.com> PR rtl-optimization/92882 Index: lra-assigns.c =================================================================== --- lra-assigns.c (revision 278608) +++ lra-assigns.c (working copy) @@ -1131,7 +1131,7 @@ static int *sorted_pseudos; /* The constraints pass is allowed to create equivalences between pseudos that make the current allocation "incorrect" (in the sense that pseudos are assigned to hard registers from their own conflict - sets). The global variable lra_risky_transformations_p says + sets). The global variable check_and_force_assignment_correctness_p says whether this might have happened. Process pseudos assigned to hard registers (less frequently used @@ -1152,7 +1152,7 @@ setup_live_pseudos_and_spill_after_risky bitmap_iterator bi; int max_regno = max_reg_num (); - if (! lra_risky_transformations_p) + if (! check_and_force_assignment_correctness_p) { for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++) if (reg_renumber[i] >= 0 && lra_reg_info[i].nrefs > 0) @@ -1690,6 +1690,8 @@ lra_assign (bool &fails_p) internal_error ("maximum number of LRA assignment passes is achieved (%d)", LRA_MAX_ASSIGNMENT_ITERATION_NUMBER); + /* Reset the assignment correctness flag: */ + check_and_force_assignment_correctness_p = false; return no_spills_p; } Index: lra-constraints.c =================================================================== --- lra-constraints.c (revision 278608) +++ lra-constraints.c (working copy) @@ -4665,11 +4665,14 @@ loc_equivalence_callback (rtx loc, const /* The current iteration number of this LRA pass. */ int lra_constraint_iter; -/* True if we substituted equiv which needs checking register - allocation correctness because the equivalent value contains - allocatable hard registers or when we restore multi-register - pseudo. */ -bool lra_risky_transformations_p; +/* True if we should during assignment sub-pass check assignment + correctness for all pseudos and spill some of them to correct + conflicts. It can be necessary when we substitute equiv which + needs checking register allocation correctness because the + equivalent value contains allocatable hard registers, or when we + restore multi-register pseudo, or when we change the insn code and + its operand became INOUT operand when it was IN one before. */ +bool check_and_force_assignment_correctness_p; /* Return true if REGNO is referenced in more than one block. */ static bool @@ -4811,14 +4814,14 @@ lra_constraints (bool first_p) changed_p = false; if (pic_offset_table_rtx && REGNO (pic_offset_table_rtx) >= FIRST_PSEUDO_REGISTER) - lra_risky_transformations_p = true; - else + check_and_force_assignment_correctness_p = true; + else if (first_p) /* On the first iteration we should check IRA assignment correctness. In rare cases, the assignments can be wrong as early clobbers operands are ignored in IRA or usages of paradoxical sub-registers are not taken into account by IRA. */ - lra_risky_transformations_p = first_p; + check_and_force_assignment_correctness_p = true; new_insn_uid_start = get_max_uid (); new_regno_start = first_p ? lra_constraint_new_regno_start : max_reg_num (); /* Mark used hard regs for target stack size calulations. */ @@ -4994,7 +4997,7 @@ lra_constraints (bool first_p) dump_insn_slim (lra_dump_file, curr_insn); } if (contains_reg_p (x, true, false)) - lra_risky_transformations_p = true; + check_and_force_assignment_correctness_p = true; lra_set_insn_deleted (curr_insn); continue; } @@ -5507,7 +5510,7 @@ need_for_split_p (HARD_REG_SET potential /* Don't split call clobbered hard regs living through calls, otherwise we might have a check problem in the assign sub-pass as in the most cases (exception is a - situation when lra_risky_transformations_p value is + situation when check_and_force_assignment_correctness_p value is true) the assign pass assumes that all pseudos living through calls are assigned to call saved hard regs. */ && (regno >= FIRST_PSEUDO_REGISTER @@ -5799,7 +5802,7 @@ split_reg (bool before_p, int original_r sub-register levels, LRA do this on pseudos level right now and this discrepancy may create allocation conflicts after splitting. */ - lra_risky_transformations_p = true; + check_and_force_assignment_correctness_p = true; if (lra_dump_file != NULL) fprintf (lra_dump_file, " ))))))))))))))))))))))))))))))))))))))))))))))))\n"); @@ -6561,7 +6564,7 @@ inherit_in_ebb (rtx_insn *head, rtx_insn before_p, curr_insn, max_uid)) { if (reg->subreg_p) - lra_risky_transformations_p = true; + check_and_force_assignment_correctness_p = true; change_p = true; /* Invalidate. */ usage_insns[src_regno].check = 0; Index: lra-eliminations.c =================================================================== --- lra-eliminations.c (revision 278608) +++ lra-eliminations.c (working copy) @@ -1311,6 +1311,11 @@ process_insn_for_elimination (rtx_insn * if (icode >= 0 && icode != INSN_CODE (insn)) { + if (INSN_CODE (insn) >= 0) + /* Insn code is changed. It may change its operand type + from IN to INOUT. Inform the subsequent assignment + subpass about this situation. */ + check_and_force_assignment_correctness_p = true; INSN_CODE (insn) = icode; lra_update_insn_recog_data (insn); } Index: lra-int.h =================================================================== --- lra-int.h (revision 278413) +++ lra-int.h (working copy) @@ -337,7 +337,7 @@ extern void lra_init_equiv (void); extern int lra_constraint_offset (int, machine_mode); extern int lra_constraint_iter; -extern bool lra_risky_transformations_p; +extern bool check_and_force_assignment_correctness_p; extern int lra_inheritance_iter; extern int lra_undo_inheritance_iter; extern bool lra_constrain_insn (rtx_insn *); Index: testsuite/ChangeLog =================================================================== --- testsuite/ChangeLog (revision 279200) +++ testsuite/ChangeLog (working copy) @@ -1,3 +1,8 @@ +2019-12-10 Vladimir Makarov <vmaka...@redhat.com> + + PR rtl-optimization/92796 + * gcc.target/powerpc/pr92796.c: New test. + 2019-12-10 Jakub Jelinek <ja...@redhat.com> PR rtl-optimization/92882 Index: testsuite/gcc.target/powerpc/pr92796.c =================================================================== --- testsuite/gcc.target/powerpc/pr92796.c (nonexistent) +++ testsuite/gcc.target/powerpc/pr92796.c (working copy) @@ -0,0 +1,21 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fstack-protector-strong -mcpu=power8" } */ + +typedef union +{ + __ieee128 a; + int b; +} c; + +__ieee128 +d (__ieee128 x) +{ + __ieee128 g; + c h; + h.a = x; + g = h.b & 5; + h.b = g; + if (g) + return x - x; + return h.a; +}