Hi! As mentioned in the PR, ix86_init_pic_reg for -mcmodel=large PIC creates invalid RTL. Shrink wrapping managed to work around it by unconditionally running find_many_sub_basic_blocks that has been invoked even when the prologue or split prologue actually didn't contain anything, but that isn't done anymore.
The problem is that we add a label into the sequence that we then insert on the single succ edge after ENTRY; but this insertion inserts the label after the NOTE_INSN_BLOCK_BEG, which is invalid, because labels should precede that. Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? 2017-09-01 Jakub Jelinek <ja...@redhat.com> PR target/81766 * config/i386/i386.c (ix86_init_large_pic_reg): Return label instead of void. (ix86_init_pic_reg): Remember label from ix86_init_large_pic_reg, if non-NULL and preceded by NOTE_INSN_BASIC_BLOCK, swap the note and label. * gcc.target/i386/pr81766.c: New test. --- gcc/config/i386/i386.c.jj 2017-08-07 18:50:10.000000000 +0200 +++ gcc/config/i386/i386.c 2017-08-08 16:01:41.917136120 +0200 @@ -8829,7 +8829,7 @@ ix86_use_pseudo_pic_reg (void) /* Initialize large model PIC register. */ -static void +static rtx_code_label * ix86_init_large_pic_reg (unsigned int tmp_regno) { rtx_code_label *label; @@ -8846,6 +8846,7 @@ ix86_init_large_pic_reg (unsigned int tm emit_insn (gen_set_got_offset_rex64 (tmp_reg, label)); emit_insn (ix86_gen_add3 (pic_offset_table_rtx, pic_offset_table_rtx, tmp_reg)); + return label; } /* Create and initialize PIC register if required. */ @@ -8854,6 +8855,7 @@ ix86_init_pic_reg (void) { edge entry_edge; rtx_insn *seq; + rtx_code_label *label = NULL; if (!ix86_use_pseudo_pic_reg ()) return; @@ -8863,7 +8865,7 @@ ix86_init_pic_reg (void) if (TARGET_64BIT) { if (ix86_cmodel == CM_LARGE_PIC) - ix86_init_large_pic_reg (R11_REG); + label = ix86_init_large_pic_reg (R11_REG); else emit_insn (gen_set_got_rex64 (pic_offset_table_rtx)); } @@ -8887,6 +8889,22 @@ ix86_init_pic_reg (void) entry_edge = single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun)); insert_insn_on_edge (seq, entry_edge); commit_one_edge_insertion (entry_edge); + + if (label) + { + basic_block bb = BLOCK_FOR_INSN (label); + rtx_insn *bb_note = PREV_INSN (label); + /* If the note preceding the label starts a basic block, and the + label is a member of the same basic block, interchange the two. */ + if (bb_note != NULL_RTX + && NOTE_INSN_BASIC_BLOCK_P (bb_note) + && bb != NULL + && bb == BLOCK_FOR_INSN (bb_note)) + { + reorder_insns_nobb (bb_note, bb_note, label); + BB_HEAD (bb) = label; + } + } } /* Initialize a variable CUM of type CUMULATIVE_ARGS --- gcc/testsuite/gcc.target/i386/pr81766.c.jj 2017-08-08 16:10:04.299459808 +0200 +++ gcc/testsuite/gcc.target/i386/pr81766.c 2017-08-08 16:09:28.000000000 +0200 @@ -0,0 +1,9 @@ +/* PR target/81766 */ +/* { dg-do compile { target { pie && lp64 } } } */ +/* { dg-options "-O2 -fpie -mcmodel=large" } */ + +int +main () +{ + return 0; +} Jakub