On Thu, Oct 1, 2015 at 8:08 AM, Segher Boessenkool <seg...@kernel.crashing.org> wrote: > After the shrink-wrapping patches the prologue will often be pushed > "deeper" into the function, which in turn means the software trace cache > pass will more often want to duplicate the basic block containing the > prologue. This caused failures for 32-bit SVR4 with -msecure-plt PIC. > > This configuration uses the load_toc_v4_PIC_1 instruction, which creates > assembler labels without using the normal machinery for that. If now > the compiler decides to duplicate the insn, it will emit the same label > twice. Boom. > > It isn't so easy to fix this to use labels the compiler knows about (let > alone test that properly). Instead, this patch wires up a "cannot_copy" > attribute to be used by TARGET_CANNOT_COPY_P, and sets that attribute on > these insns we do not want copied. > > Bootstrapped and tested on powerpc64-linux, with the usual configurations > (-m32,-m32/-mpowerpc64,-m64,-m64/-mlra); new testcase fails before, works > after (on 32-bit). > > Is this okay for mainline?
Isn't that quite expensive? So even if not "easy", can you try? Do we have other ports with local labels in define_insns? I see some in darwin.md as well which your patch doesn't handle btw., otherwise suspicious %0: also appears (only) in h8300.md. arc.md also has a suspicious case in its doloop_end_i pattern. Richard. > > Segher > > > 2015-09-30 Segher Boessenkool <seg...@kernel.crashing.org> > > PR target/67788 > PR target/67789 > * config/rs6000/rs6000.c (TARGET_CANNOT_COPY_INSN_P): New. > (rs6000_cannot_copy_insn_p): New function. > * config/rs6000/rs6000.md (cannot_copy): New attribute. > (load_toc_v4_PIC_1_normal): Set cannot_copy. > (load_toc_v4_PIC_1_476): Ditto. > > gcc/testsuite/ > PR target/67788 > PR target/67789 > * gcc.target/powerpc/pr67789.c: New testcase. > > --- > gcc/config/rs6000/rs6000.c | 11 +++++++++ > gcc/config/rs6000/rs6000.md | 9 +++++-- > gcc/testsuite/gcc.target/powerpc/pr67789.c | 39 > ++++++++++++++++++++++++++++++ > 3 files changed, 57 insertions(+), 2 deletions(-) > create mode 100644 gcc/testsuite/gcc.target/powerpc/pr67789.c > > diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c > index 93bb725..29fd198 100644 > --- a/gcc/config/rs6000/rs6000.c > +++ b/gcc/config/rs6000/rs6000.c > @@ -1513,6 +1513,8 @@ static const struct attribute_spec > rs6000_attribute_table[] = > #define TARGET_REGISTER_MOVE_COST rs6000_register_move_cost > #undef TARGET_MEMORY_MOVE_COST > #define TARGET_MEMORY_MOVE_COST rs6000_memory_move_cost > +#undef TARGET_CANNOT_COPY_INSN_P > +#define TARGET_CANNOT_COPY_INSN_P rs6000_cannot_copy_insn_p > #undef TARGET_RTX_COSTS > #define TARGET_RTX_COSTS rs6000_rtx_costs > #undef TARGET_ADDRESS_COST > @@ -31226,6 +31228,15 @@ rs6000_xcoff_encode_section_info (tree decl, rtx > rtl, int first) > #endif /* HAVE_AS_TLS */ > #endif /* TARGET_XCOFF */ > > +/* Return true if INSN should not be copied. */ > + > +static bool > +rs6000_cannot_copy_insn_p (rtx_insn *insn) > +{ > + return recog_memoized (insn) >= 0 > + && get_attr_cannot_copy (insn); > +} > + > /* Compute a (partial) cost for rtx X. Return true if the complete > cost has been computed, and false if subexpressions should be > scanned. In either case, *TOTAL contains the cost result. */ > diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md > index cfdb286..8c53c40 100644 > --- a/gcc/config/rs6000/rs6000.md > +++ b/gcc/config/rs6000/rs6000.md > @@ -226,6 +226,9 @@ (define_attr "var_shift" "no,yes" > (const_string "no")) > (const_string "no"))) > > +;; Is copying of this instruction disallowed? > +(define_attr "cannot_copy" "no,yes" (const_string "no")) > + > ;; Define floating point instruction sub-types for use with Xfpu.md > (define_attr "fp_type" > "fp_default,fp_addsub_s,fp_addsub_d,fp_mul_s,fp_mul_d,fp_div_s,fp_div_d,fp_maddsub_s,fp_maddsub_d,fp_sqrt_s,fp_sqrt_d" > (const_string "fp_default")) > > @@ -9130,7 +9133,8 @@ (define_insn "load_toc_v4_PIC_1_normal" > && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))" > "bcl 20,31,%0\\n%0:" > [(set_attr "type" "branch") > - (set_attr "length" "4")]) > + (set_attr "length" "4") > + (set_attr "cannot_copy" "yes")]) > > (define_insn "load_toc_v4_PIC_1_476" > [(set (reg:SI LR_REGNO) > @@ -9148,7 +9152,8 @@ (define_insn "load_toc_v4_PIC_1_476" > return templ; > }" > [(set_attr "type" "branch") > - (set_attr "length" "4")]) > + (set_attr "length" "4") > + (set_attr "cannot_copy" "yes")]) > > (define_expand "load_toc_v4_PIC_1b" > [(parallel [(set (reg:SI LR_REGNO) > diff --git a/gcc/testsuite/gcc.target/powerpc/pr67789.c > b/gcc/testsuite/gcc.target/powerpc/pr67789.c > new file mode 100644 > index 0000000..d1bd047 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/powerpc/pr67789.c > @@ -0,0 +1,39 @@ > +/* { dg-do assemble } */ > +/* { dg-options "-O2 -msecure-plt -fPIC" } */ > + > +#define FE_TONEAREST 0 > +#define FE_UPWARD 1 > +#define FE_DOWNWARD 2 > +#define FE_TOWARDZERO 3 > + > +extern int fesetround(int); > + > +void > +set_fpu_rounding_mode (int mode) > +{ > + int rnd_mode; > + > + switch (mode) > + { > + case 2: > + rnd_mode = FE_TONEAREST; > + break; > + > + case 4: > + rnd_mode = FE_UPWARD; > + break; > + > + case 1: > + rnd_mode = FE_DOWNWARD; > + break; > + > + case 3: > + rnd_mode = FE_TOWARDZERO; > + break; > + > + default: > + return; > + } > + > + fesetround (rnd_mode); > +} > -- > 1.8.1.4 >