[C] Fix thinko in new warning on type punning for storage order purposes
I obviously forgot that in C, unlike in Ada, the storage order of arrays is that of their component type, so you need to look at it when deciding to warn. The bug reporter also complains about a bogus warning on the assignment of a pointer returned by alloca or malloc, so this also fixes that. Tested on x86-64/Linux, applied on the mainline as obvious. 2021-06-06 Eric Botcazou PR c/100920 * c-decl.c (finish_struct): Fix thinko in previous change. * c-typeck.c (convert_for_assignment): Do not warn on pointer assignment and initialization for storage order purposes if the RHS is a call to a DECL_IS_MALLOC function. 2021-06-06 Eric Botcazou * gcc.dg/sso-14.c: New test. -- Eric Botcazoudiff --git a/gcc/c/c-decl.c b/gcc/c/c-decl.c index 28f851b9d0b..a86792bbe06 100644 --- a/gcc/c/c-decl.c +++ b/gcc/c/c-decl.c @@ -8854,12 +8854,21 @@ finish_struct (location_t loc, tree t, tree fieldlist, tree attributes, } } + /* Warn on problematic type punning for storage order purposes. */ if (TREE_CODE (t) == UNION_TYPE - && AGGREGATE_TYPE_P (TREE_TYPE (field)) - && TYPE_REVERSE_STORAGE_ORDER (t) - != TYPE_REVERSE_STORAGE_ORDER (TREE_TYPE (field))) - warning_at (DECL_SOURCE_LOCATION (field), OPT_Wscalar_storage_order, - "type punning toggles scalar storage order"); + && TREE_CODE (field) == FIELD_DECL + && AGGREGATE_TYPE_P (TREE_TYPE (field))) + { + tree ftype = TREE_TYPE (field); + if (TREE_CODE (ftype) == ARRAY_TYPE) + ftype = strip_array_types (ftype); + if (RECORD_OR_UNION_TYPE_P (ftype) + && TYPE_REVERSE_STORAGE_ORDER (ftype) + != TYPE_REVERSE_STORAGE_ORDER (t)) + warning_at (DECL_SOURCE_LOCATION (field), + OPT_Wscalar_storage_order, + "type punning toggles scalar storage order"); + } } /* Now we have the truly final field list. diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c index be3f4f09f6e..daa2e12a25f 100644 --- a/gcc/c/c-typeck.c +++ b/gcc/c/c-typeck.c @@ -7295,6 +7295,8 @@ convert_for_assignment (location_t location, location_t expr_loc, tree type, && (AGGREGATE_TYPE_P (ttl) && TYPE_REVERSE_STORAGE_ORDER (ttl)) != (AGGREGATE_TYPE_P (ttr) && TYPE_REVERSE_STORAGE_ORDER (ttr))) { + tree t; + switch (errtype) { case ic_argpass: @@ -7307,14 +7309,23 @@ convert_for_assignment (location_t location, location_t expr_loc, tree type, "scalar storage order", parmnum, rname); break; case ic_assign: - warning_at (location, OPT_Wscalar_storage_order, - "assignment to %qT from pointer type %qT with " - "incompatible scalar storage order", type, rhstype); + /* Do not warn if the RHS is a call to a function that returns a + pointer that is not an alias. */ + if (TREE_CODE (rhs) != CALL_EXPR + || (t = get_callee_fndecl (rhs)) == NULL_TREE + || !DECL_IS_MALLOC (t)) + warning_at (location, OPT_Wscalar_storage_order, + "assignment to %qT from pointer type %qT with " + "incompatible scalar storage order", type, rhstype); break; case ic_init: - warning_at (location, OPT_Wscalar_storage_order, - "initialization of %qT from pointer type %qT with " - "incompatible scalar storage order", type, rhstype); + /* Likewise. */ + if (TREE_CODE (rhs) != CALL_EXPR + || (t = get_callee_fndecl (rhs)) == NULL_TREE + || !DECL_IS_MALLOC (t)) + warning_at (location, OPT_Wscalar_storage_order, + "initialization of %qT from pointer type %qT with " + "incompatible scalar storage order", type, rhstype); break; case ic_return: warning_at (location, OPT_Wscalar_storage_order, /* PR c/100920 */ /* Testcase by George Thopas */ /* { dg-do compile } */ #include #include #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ #define REV_ENDIANNESS __attribute__((scalar_storage_order("big-endian"))) #else #define REV_ENDIANNESS __attribute__((scalar_storage_order("little-endian"))) #endif struct s_1 { int val; } REV_ENDIANNESS; typedef struct s_1 t_1; struct s_2 { char val; } REV_ENDIANNESS; typedef struct s_2 t_2; struct s12 { t_1 a[1]; t_2 b[1]; } REV_ENDIANNESS; typedef struct s12 t_s12; union u12 { t_1 a[1]; t_2 b[1]; } REV_ENDIANNESS; typedef union u12 t_u12; int main(void) { t_s12 *msg1 = __builtin_alloca(10); t_u12 *msg2 = __builtin_alloca(10); msg1 = malloc (sizeof (t_s12)); msg2 = malloc (sizeof (t_u12)); msg1->a[0].val = 0; msg2->a[0].val = 0; return 0; }
Re: [PATCH PR100740]Fix overflow check in simplifying exit cond comparing two IVs.
On Wed, Jun 2, 2021 at 3:28 PM Richard Biener via Gcc-patches wrote: > > On Tue, Jun 1, 2021 at 4:00 PM bin.cheng via Gcc-patches > wrote: > > > > Hi, > > As described in patch summary, this fixes the wrong code issue by adding > > overflow-ness > > check for iv1.step - iv2.step. > > > > Bootstrap and test on x86_64. Any comments? > > + bool wrap_p = TYPE_OVERFLOW_WRAPS (step_type); > + if (wrap_p) > + { > + tree t = fold_binary_to_constant (GE_EXPR, step_type, > + iv0->step, iv1->step); > + wrap_p = integer_zerop (t); > + } > > I think we can't use TYPE_OVERFLOW_WRAPS/TYPE_OVERFLOW_UNDEFINED since > that's only relevant for expressions written by the user - we're > computing iv0.step - iv1.step > which can even overflow when TYPE_OVERFLOW_UNDEFINED (in fact we may not > even generate this expression then!). So I think we have to do sth like > >/* If the iv0->step - iv1->step wraps, fail. */ >if (!operand_equal_p (iv0->step, iv1->step) >&& (TREE_CODE (iv0->step) != INTEGER_CST || TREE_CODE > (iv1->step) != INTEGER_CST) >&& !wi::gt (wi::to_widest (iv0->step), wi::to_widest (iv1->step)) > return false; > > which only handles equality and all integer constant steps. You could Thanks for the suggestion. I realized that we have LE/LT/NE conditions here, and for LE/LT what we need to check is iv0/iv1 converge to each other, rather than diverge. Also steps here can only be constants, so there is no need to use range information. > also use ranges > like > > wide_int min0, max0, min1, max1; > if (!operand_equal_p (iv->step, iv1->step) > && (determine_value_range (iv0->step, &min0, &max0) != VR_RANGE > || determine_value_range (iv1->step, &min1, &max1) != VR_RANGE > || !wi::ge (min0, max1))) >return false; > > Note I'm not sure why > >iv0->step = step; >if (!POINTER_TYPE_P (type)) > iv0->no_overflow = false; I don't exactly remember, this was added sometime when no_overflow was introduced. Note we only do various checks for non NE_EXPR so the step isn't always less in absolute value? I will check if we should reset it in all cases. Patch updated. test ongoing. Thanks, bin > > here the no_overflow reset does not happen for pointer types? Or > rather why does > it happen at all? Don't we strictly make the step less in absolute value? > > > Thanks, > > bin From 395dd6595cabebb7fd3e71a5fbfe84544d598608 Mon Sep 17 00:00:00 2001 Author: Bin Cheng Date: Fri, 28 May 2021 16:49:54 +0800 Subject: [PATCH] Simplify exit cond comparing two IVs only if they converge. We should also check that iv1.step >= iv2.step so that the two IVs converge to each other under comparison condition LE_EXPR/LT_EXPR. gcc: PR tree-optimization/100740 * tree-ssa-loop-niter.c (number_of_iterations_cond): Check IVs converge or not. gcc/testsuite: * gcc.c-torture/execute/pr100740.c --- .../gcc.c-torture/execute/pr100740.c | 11 ++ gcc/tree-ssa-loop-niter.c | 20 +-- 2 files changed, 25 insertions(+), 6 deletions(-) create mode 100644 gcc/testsuite/gcc.c-torture/execute/pr100740.c diff --git a/gcc/testsuite/gcc.c-torture/execute/pr100740.c b/gcc/testsuite/gcc.c-torture/execute/pr100740.c new file mode 100644 index 000..8fcdaffef3b --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/pr100740.c @@ -0,0 +1,11 @@ +/* PR tree-optimization/100740 */ + +unsigned a, b; +int main() { + unsigned c = 0; + for (a = 0; a < 2; a++) +for (b = 0; b < 2; b++) + if (++c < a) +__builtin_abort (); + return 0; +} diff --git a/gcc/tree-ssa-loop-niter.c b/gcc/tree-ssa-loop-niter.c index 325bd978609..6240084782a 100644 --- a/gcc/tree-ssa-loop-niter.c +++ b/gcc/tree-ssa-loop-niter.c @@ -1782,7 +1782,9 @@ number_of_iterations_cond (class loop *loop, provided that either below condition is satisfied: a) the test is NE_EXPR; - b) iv0.step - iv1.step is integer and iv0/iv1 don't overflow. + b) iv0.step and iv1.step are integers and: + - iv0 and iv1 don't overflow. + - iv0 and iv1 converge to each other, under cond LE_EXPR/LT_EXPR. This rarely occurs in practice, but it is simple enough to manage. */ if (!integer_zerop (iv0->step) && !integer_zerop (iv1->step)) @@ -1790,14 +1792,20 @@ number_of_iterations_cond (class loop *loop, tree step_type = POINTER_TYPE_P (type) ? sizetype : type; tree step = fold_binary_to_constant (MINUS_EXPR, step_type, iv0->step, iv1->step); + if (code != NE_EXPR) + { + if (TREE_CODE (step) != INTEGER_CST) + return false; + + if (!iv0->no_overflow || !iv1->no_overflow) + return false; + + if (tree_int_cst_lt (iv0->step, iv1->step)) + return false;
Re: [COMITTED, Patch, Fortran, backport 2 gcc-11] PR98301 Re: RANDOM_INIT() and coarray Fortran
Hi Steve, hi all, the patch for pr98301 has been backported to gcc-11 as 002745ca3668fc5e87c22acc81caaeaaadf9c47a Regards, Andre On Sat, 5 Jun 2021 09:27:16 -0700 Steve Kargl wrote: > On Sat, Jun 05, 2021 at 04:04:51PM +0200, Andre Vehreschild wrote: > > > > I was asked to backport the patch for pr98301 to gcc-11. The patches have > > been in mainline for two weeks without any defect reports I could fined. The > > patch for mainline applied with a bit of shift cleanly. > > > > Regstested fine on x86_64/f33. Ok for backport gcc-11? > > > > I think the backport is fine. > -- Andre Vehreschild * Email: vehre ad gmx dot de
[PATCH] libgomp: Compile tests with -march=i486 if needed
Don't add -march=i486 if atomic compare-and-swap is supported on 'int'. This fixes libgomp tests with "-march=x86-64 -m32 -fcf-protection". * testsuite/lib/libgomp.exp (libgomp_init): Don't add -march=i486 if atomic compare-and-swap is supported on 'int'. --- libgomp/testsuite/lib/libgomp.exp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libgomp/testsuite/lib/libgomp.exp b/libgomp/testsuite/lib/libgomp.exp index 0f4eb6fd4ff..fc5015de42f 100644 --- a/libgomp/testsuite/lib/libgomp.exp +++ b/libgomp/testsuite/lib/libgomp.exp @@ -210,7 +210,8 @@ proc libgomp_init { args } { # We use atomic operations in the testcases to validate results. if { ([istarget i?86-*-*] || [istarget x86_64-*-*]) -&& [check_effective_target_ia32] } { +&& [check_effective_target_ia32] +&& ![check_effective_target_cas_char] } { lappend ALWAYS_CFLAGS "additional_flags=-march=i486" } -- 2.31.1
[PATCH][OBVIOUS] docs: Add missing @headitem for tables.
Quite some TEXI tables do miss table header. The patch adds that. Pushed to master as obvious. Martin gcc/ChangeLog: * doc/extend.texi: Add missing @headitem. * doc/invoke.texi: Likewise. * doc/objc.texi: Likewise. --- gcc/doc/extend.texi | 12 ++-- gcc/doc/invoke.texi | 2 +- gcc/doc/objc.texi | 6 +++--- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index 8711745bbe8..22f9e93073f 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -15419,7 +15419,7 @@ to make this classification clear at a glance, the arguments and return values are given the following pseudo types: @multitable @columnfractions .20 .30 .15 .35 -@item Pseudo type @tab Real C type @tab Constant? @tab Description +@headitem Pseudo type @tab Real C type @tab Constant? @tab Description @item @code{uh} @tab @code{unsigned short} @tab No @tab an unsigned halfword @item @code{uw1} @tab @code{unsigned int} @tab No @tab an unsigned word @item @code{sw1} @tab @code{int} @tab No @tab a signed word @@ -15455,7 +15455,7 @@ for more details. The functions listed below map directly to FR-V I-type instructions. @multitable @columnfractions .45 .32 .23 -@item Function prototype @tab Example usage @tab Assembly output +@headitem Function prototype @tab Example usage @tab Assembly output @item @code{sw1 __ADDSS (sw1, sw1)} @tab @code{@var{c} = __ADDSS (@var{a}, @var{b})} @tab @code{ADDSS @var{a},@var{b},@var{c}} @@ -15494,7 +15494,7 @@ The functions listed below map directly to FR-V I-type instructions. The functions listed below map directly to FR-V M-type instructions. @multitable @columnfractions .45 .32 .23 -@item Function prototype @tab Example usage @tab Assembly output +@headitem Function prototype @tab Example usage @tab Assembly output @item @code{uw1 __MABSHS (sw1)} @tab @code{@var{b} = __MABSHS (@var{a})} @tab @code{MABSHS @var{a},@var{b}} @@ -15886,7 +15886,7 @@ hardware support exists. @code{a} and @code{b} are @code{v4i8} values, and @code{c} and @code{d} are @code{v2q15} values. @multitable @columnfractions .50 .50 -@item C code @tab MIPS instruction +@headitem C code @tab MIPS instruction @item @code{a + b} @tab @code{addu.qb} @item @code{c + d} @tab @code{addq.ph} @item @code{a - b} @tab @code{subu.qb} @@ -15898,7 +15898,7 @@ hardware support exists for the DSP ASE REV 2. @code{e} and @code{f} are @code{v2i16} values. @multitable @columnfractions .50 .50 -@item C code @tab MIPS instruction +@headitem C code @tab MIPS instruction @item @code{e * f} @tab @code{mul.ph} @end multitable @@ -16284,7 +16284,7 @@ support exists. @code{a}, @code{b} and @code{c} are @code{v2sf} values and @code{x} is an integral value. @multitable @columnfractions .50 .50 -@item C code @tab MIPS instruction +@headitem C code @tab MIPS instruction @item @code{a + b} @tab @code{add.ps} @item @code{a - b} @tab @code{sub.ps} @item @code{-a} @tab @code{neg.ps} diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 7102999cf31..04048cd8332 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -23602,7 +23602,7 @@ and @samp{cpu32}. The ColdFire @var{cpu}s are given by the table below, which also classifies the CPUs into families: @multitable @columnfractions 0.20 0.80 -@item @strong{Family} @tab @strong{@samp{-mcpu} arguments} +@headitem @strong{Family} @tab @strong{@samp{-mcpu} arguments} @item @samp{51} @tab @samp{51} @samp{51ac} @samp{51ag} @samp{51cn} @samp{51em} @samp{51je} @samp{51jf} @samp{51jg} @samp{51jm} @samp{51mm} @samp{51qe} @samp{51qm} @item @samp{5206} @tab @samp{5202} @samp{5204} @samp{5206} @item @samp{5206e} @tab @samp{5206e} diff --git a/gcc/doc/objc.texi b/gcc/doc/objc.texi index a8c59429af9..cfd2470bc7a 100644 --- a/gcc/doc/objc.texi +++ b/gcc/doc/objc.texi @@ -382,7 +382,7 @@ compiler on an i386 machine: @sp 1 @multitable @columnfractions .60 .40 -@item Objective-C type +@headitem Objective-C type @tab Compiler encoding @item @smallexample @@ -416,7 +416,7 @@ Objective-C type specifiers: @sp 1 @multitable @columnfractions .25 .75 -@item Specifier +@headitem Specifier @tab Encoding @item @code{const} @tab @code{r} @@ -445,7 +445,7 @@ Note how @code{const} interacts with pointers: @sp 1 @multitable @columnfractions .25 .75 -@item Objective-C type +@headitem Objective-C type @tab Compiler encoding @item @smallexample -- 2.31.1
[PATCH][pushed] docs: remove extra character.
Fix of a typo. Martin gcc/ChangeLog: * doc/invoke.texi: Remove extra character. --- gcc/doc/invoke.texi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index eb8142f596d..7102999cf31 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -20105,7 +20105,7 @@ For some ARM implementations better performance can be obtained by using this option. Permissible names are: @samp{arm7tdmi}, @samp{arm7tdmi-s}, @samp{arm710t}, @samp{arm720t}, @samp{arm740t}, @samp{strongarm}, @samp{strongarm110}, -@samp{strongarm1100}, 0@samp{strongarm1110}, @samp{arm8}, @samp{arm810}, +@samp{strongarm1100}, @samp{strongarm1110}, @samp{arm8}, @samp{arm810}, @samp{arm9}, @samp{arm9e}, @samp{arm920}, @samp{arm920t}, @samp{arm922t}, @samp{arm946e-s}, @samp{arm966e-s}, @samp{arm968e-s}, @samp{arm926ej-s}, @samp{arm940t}, @samp{arm9tdmi}, @samp{arm10tdmi}, @samp{arm1020t}, -- 2.31.1
[PATCH][pushed] genhooks: remove dead code
Hello. We not longer use @Fcode in .def target hooks and I'm going to remove a dead code. Pushed to master. Martin gcc/ChangeLog: * genhooks.c (emit_findices): Remove unused function. (emit_documentation): Do not call emit_findices and do not search for @Fcode directives. --- gcc/genhooks.c | 33 +++-- 1 file changed, 3 insertions(+), 30 deletions(-) diff --git a/gcc/genhooks.c b/gcc/genhooks.c index 2e63940ffdf..ebe0d0954e6 100644 --- a/gcc/genhooks.c +++ b/gcc/genhooks.c @@ -38,26 +38,6 @@ static struct hook_desc hook_array[] = { #undef DEFHOOK }; -/* For each @Fcode in the first paragraph of the documentation string DOC, - print an @findex directive. HOOK_NAME is the name of the hook this bit of - documentation pertains to. */ -static void -emit_findices (const char *doc, const char *hook_name) -{ - const char *end = strstr (doc, "\n\n"); - const char *fcode; - - while ((fcode = strstr (doc, "@Fcode{")) && (!end || fcode < end)) -{ - fcode += strlen ("@Fcode{"); - doc = strchr (fcode, '}'); - if (!doc) - fatal ("Malformed @Fcode for hook %s\n", hook_name); - printf ("@findex %.*s\n", (int) (doc - fcode), fcode); - doc = fcode; -} -} - /* Return an upper-case copy of IN. */ static char * upstrdup (const char *in) @@ -99,8 +79,8 @@ s_hook_eq_p (const void *p1, const void *p2) signature, followed by the string from the doc field. The documentation is bracketed in @deftypefn / @deftypevr and a matching @end. - While emitting the doc field, @Fcode is translated to @code, and an - @findex entry is added to the affected paragraph. + While emitting the doc field, an @findex entry is added + to the affected paragraph. If the doc field starts with '*', the leading '*' is stripped, and the doc field is otherwise emitted unaltered; no function signature/ @deftypefn/deftypevr/@end is emitted. @@ -206,7 +186,7 @@ emit_documentation (const char *in_fname) { const char *q, *e; const char *deftype; - const char *doc, *fcode, *p_end; + const char *doc, *p_end; /* A leading '*' means to output the documentation string without further processing. */ @@ -216,7 +196,6 @@ emit_documentation (const char *in_fname) { if (i != shp->pos) printf ("\n\n"); - emit_findices (hook_array[i].doc, name); /* Print header. Function-valued hooks have a parameter list, unlike POD-valued ones. */ @@ -262,13 +241,7 @@ emit_documentation (const char *in_fname) /* Find paragraph end. */ p_end = strstr (doc, "\n\n"); p_end = (p_end ? p_end + 2 : doc + strlen (doc)); - /* Print paragraph, emitting @Fcode as @code. */ - for (; (fcode = strstr (doc, "@Fcode{")) && fcode < p_end; - doc = fcode + 2) - printf ("%.*s@", (int) (fcode - doc), doc); printf ("%.*s", (int) (p_end - doc), doc); - /* Emit function indices for next paragraph. */ - emit_findices (p_end, name); } printf ("\n@end %s", deftype); } -- 2.31.1
[PATCH] Reformat target.def for better parsing.
Hello. I'll need to parse output of tm.texi when converted to Sphinx for the future conversion. So that I split DEFHOOK documentation entries with newlines. I'll install the patch if there are no comments? Thanks, Martin gcc/c-family/ChangeLog: * c-target.def: Split long lines and replace them with '\n\'. gcc/ChangeLog: * common/common-target.def: Split long lines and replace them with '\n\'. * target.def: Likewise. * doc/tm.texi: Re-generated. --- gcc/c-family/c-target.def| 70 ++--- gcc/common/common-target.def | 32 +-- gcc/doc/tm.texi | 364 +- gcc/target.def | 485 +++ 4 files changed, 612 insertions(+), 339 deletions(-) diff --git a/gcc/c-family/c-target.def b/gcc/c-family/c-target.def index f2a1b7ef7c5..164f1b31694 100644 --- a/gcc/c-family/c-target.def +++ b/gcc/c-family/c-target.def @@ -43,73 +43,73 @@ DEFHOOK DEFHOOK (objc_construct_string_object, - "Targets may provide a string object type that can be used within\ - and between C, C++ and their respective Objective-C dialects.\ - A string object might, for example, embed encoding and length information.\ - These objects are considered opaque to the compiler and handled as references.\ - An ideal implementation makes the composition of the string object\ - match that of the Objective-C @code{NSString} (@code{NXString} for GNUStep),\ - allowing efficient interworking between C-only and Objective-C code.\ - If a target implements string objects then this hook should return a\ - reference to such an object constructed from the normal `C' string\ - representation provided in @var{string}.\ - At present, the hook is used by Objective-C only, to obtain a\ + "Targets may provide a string object type that can be used within\n\ +and between C, C++ and their respective Objective-C dialects.\n\ +A string object might, for example, embed encoding and length information.\n\ +These objects are considered opaque to the compiler and handled as references.\n\ +An ideal implementation makes the composition of the string object\n\ +match that of the Objective-C @code{NSString} (@code{NXString} for GNUStep),\n\ +allowing efficient interworking between C-only and Objective-C code.\n\ +If a target implements string objects then this hook should return a\n\ +reference to such an object constructed from the normal `C' string\n\ +representation provided in @var{string}.\n\ +At present, the hook is used by Objective-C only, to obtain a\n\ common-format string object when the target provides one.", tree, (tree string), NULL) DEFHOOK (objc_declare_unresolved_class_reference, - "Declare that Objective C class @var{classname} is referenced\ - by the current TU.", + "Declare that Objective C class @var{classname} is referenced\n\ +by the current TU.", void, (const char *classname), NULL) DEFHOOK (objc_declare_class_definition, - "Declare that Objective C class @var{classname} is defined\ - by the current TU.", + "Declare that Objective C class @var{classname} is defined\n\ +by the current TU.", void, (const char *classname), NULL) DEFHOOK (string_object_ref_type_p, - "If a target implements string objects then this hook should return\ - @code{true} if @var{stringref} is a valid reference to such an object.", + "If a target implements string objects then this hook should return\n\ +@code{true} if @var{stringref} is a valid reference to such an object.", bool, (const_tree stringref), hook_bool_const_tree_false) DEFHOOK (check_string_object_format_arg, - "If a target implements string objects then this hook should should\ - provide a facility to check the function arguments in @var{args_list}\ - against the format specifiers in @var{format_arg} where the type of\ - @var{format_arg} is one recognized as a valid string reference type.", + "If a target implements string objects then this hook should should\n\ +provide a facility to check the function arguments in @var{args_list}\n\ +against the format specifiers in @var{format_arg} where the type of\n\ +@var{format_arg} is one recognized as a valid string reference type.", void, (tree format_arg, tree args_list), NULL) DEFHOOK (c_preinclude, - "Define this hook to return the name of a header file to be included at\ - the start of all compilations, as if it had been included with\ - @code{#include <@var{file}>}. If this hook returns @code{NULL}, or is\ - not defined, or the header is not found, or if the user specifies\ - @option{-ffreestanding} or @option{-nostdinc}, no header is included.\n\ + "Define this hook to return the name of a header file to be included at\n\ +the start of all compilations, as if it had been included with\n\ +@code{#include <@var{file}>}. If this hook returns @code{NULL}, or is\n\ +not defined, or the header is not found, or if the user specifies\n\ +@option{-ffreestanding} or @option{-nostdinc}, no head
[PATCH] tree-inline: Fix up __builtin_va_arg_pack handling [PR100898]
Hi! The following testcase ICEs, because gimple_call_arg_ptr (..., 0) asserts that there is at least one argument, while we were using it even if we didn't copy anything just to get a pointer from/to which the zero arguments should be copied. Fixed by guarding the memcpy calls. Also, the code was calling gimple_call_num_args too many times - 5 times instead of 2, so the patch adds two temporaries for those. Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? 2021-06-06 Jakub Jelinek PR middle-end/100898 * tree-inline.c (copy_bb): Only use gimple_call_arg_ptr if memcpy should copy any arguments. Don't call gimple_call_num_args on id->call_stmt or call_stmt more than once. * g++.dg/ext/va-arg-pack-3.C: New test. --- gcc/tree-inline.c.jj2021-06-04 11:15:26.0 +0200 +++ gcc/tree-inline.c 2021-06-04 15:15:07.358413674 +0200 @@ -2090,27 +2090,29 @@ copy_bb (copy_body_data *id, basic_block tree p; gcall *new_call; vec argarray; - size_t nargs = gimple_call_num_args (id->call_stmt); - size_t n; + size_t nargs_caller = gimple_call_num_args (id->call_stmt); + size_t nargs = nargs_caller; for (p = DECL_ARGUMENTS (id->src_fn); p; p = DECL_CHAIN (p)) nargs--; /* Create the new array of arguments. */ - n = nargs + gimple_call_num_args (call_stmt); + size_t nargs_callee = gimple_call_num_args (call_stmt); + size_t n = nargs + nargs_callee; argarray.create (n); argarray.safe_grow_cleared (n, true); /* Copy all the arguments before '...' */ - memcpy (argarray.address (), - gimple_call_arg_ptr (call_stmt, 0), - gimple_call_num_args (call_stmt) * sizeof (tree)); + if (nargs_callee) + memcpy (argarray.address (), + gimple_call_arg_ptr (call_stmt, 0), + nargs_callee * sizeof (tree)); /* Append the arguments passed in '...' */ - memcpy (argarray.address () + gimple_call_num_args (call_stmt), - gimple_call_arg_ptr (id->call_stmt, 0) - + (gimple_call_num_args (id->call_stmt) - nargs), - nargs * sizeof (tree)); + if (nargs) + memcpy (argarray.address () + nargs_callee, + gimple_call_arg_ptr (id->call_stmt, 0) + + (nargs_caller - nargs), nargs * sizeof (tree)); new_call = gimple_build_call_vec (gimple_call_fn (call_stmt), argarray); --- gcc/testsuite/g++.dg/ext/va-arg-pack-3.C.jj 2021-06-04 15:32:28.213079130 +0200 +++ gcc/testsuite/g++.dg/ext/va-arg-pack-3.C2021-06-04 15:31:29.777883575 +0200 @@ -0,0 +1,18 @@ +// PR middle-end/100898 + +int a; +int bar (int, ...); + +static inline __attribute__((always_inline)) int +foo (...) +{ + while (a) +return bar (0, __builtin_va_arg_pack ()); + return 0; +} + +void +baz (void) +{ + foo (); +} Jakub
Re:[Patch, fortran] PR fortran/93308/93963/94327/94331/97046 problems raised by descriptor handling
Hi José, Patch tested only on x86_64-pc-linux-gnu. Also tested on darwin20. The patch is OK for me provided the updated PR94331.c test file replaces the original one. Since the PRs are about wrong code, I think the patch should be backported to at least GCC11 (applied and regtested OK). Thanks for the work, Dominique
[PATCH] i386: Clean up constraints.md
No functional changes. 2021-06-06 Uroš Bizjak gcc/ * config/i386/constraints.md (Bs): Remove boolean operators from match_test RTX. (Bw): Ditto. (L): Ditto. (M): Use "mode" variable instead of GET_MODE (op) in match_test RTX. (Wz): Ditto. Bootstrapped and regression tested on x86_64-linux-gnu {,-m32}. Pushed to master. Uros. diff --git a/gcc/config/i386/constraints.md b/gcc/config/i386/constraints.md index eaa582d2055..485e3f5b2cf 100644 --- a/gcc/config/i386/constraints.md +++ b/gcc/config/i386/constraints.md @@ -198,7 +198,8 @@ (define_constraint "Bs" (ior (and (not (match_test "TARGET_INDIRECT_BRANCH_REGISTER")) (not (match_test "TARGET_X32")) (match_operand 0 "sibcall_memory_operand")) - (and (match_test "TARGET_X32 && Pmode == DImode") + (and (match_test "TARGET_X32") + (match_test "Pmode == DImode") (match_operand 0 "GOT_memory_operand" (define_constraint "Bw" @@ -206,7 +207,8 @@ (define_constraint "Bw" (ior (and (not (match_test "TARGET_INDIRECT_BRANCH_REGISTER")) (not (match_test "TARGET_X32")) (match_operand 0 "memory_operand")) - (and (match_test "TARGET_X32 && Pmode == DImode") + (and (match_test "TARGET_X32") + (match_test "Pmode == DImode") (match_operand 0 "GOT_memory_operand" (define_constraint "Bz" @@ -239,8 +241,9 @@ (define_constraint "L" "@code{0xFF}, @code{0x} or @code{0x} for AND as a zero-extending move." (and (match_code "const_int") - (match_test "ival == 0xff || ival == 0x - || ival == (HOST_WIDE_INT) 0x"))) + (ior (match_test "ival == 0xff") + (match_test "ival == 0x") + (match_test "ival == (HOST_WIDE_INT) 0x" (define_constraint "M" "0, 1, 2, or 3 (shifts for the @code{lea} instruction)." @@ -289,14 +292,14 @@ (define_constraint "We" to fit that range (for sign-extending conversion operations that require non-VOIDmode immediate operands)." (and (match_operand 0 "x86_64_immediate_operand") - (match_test "GET_MODE (op) != VOIDmode"))) + (match_test "mode != VOIDmode"))) (define_constraint "Wz" "32-bit unsigned integer constant, or a symbolic reference known to fit that range (for zero-extending conversion operations that require non-VOIDmode immediate operands)." (and (match_operand 0 "x86_64_zext_immediate_operand") - (match_test "GET_MODE (op) != VOIDmode"))) + (match_test "mode != VOIDmode"))) (define_constraint "Wd" "128-bit integer constant where both the high and low 64-bit word
[PATCH,AIX] Use assemble_name to output BSS section name.
aix: Use assemble_name to output BSS section name. The code to emit BSS CSECT needs to support user assembler name. * config/rs6000/rs6000.c (rs6000_xcoff_asm_output_aligned_decl_common): Use assemble_name to output BSS section name. diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 835af7708f9..b01bb5c8191 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -21654,10 +21654,16 @@ rs6000_xcoff_asm_output_aligned_decl_common (FILE *stream, /* Globalize TLS BSS. */ if (TREE_PUBLIC (decl) && DECL_THREAD_LOCAL_P (decl)) - fprintf (stream, "\t.globl %s\n", name); + { + fputs (GLOBAL_ASM_OP, stream); + assemble_name (stream, name); + fputc ('\n', stream); + } /* Switch to section and skip space. */ - fprintf (stream, "\t.csect %s,%u\n", name, align2); + fputs ("\t.csect ", stream); + assemble_name (stream, name); + fprintf (stream, ",%u\n", align2); ASM_DECLARE_OBJECT_NAME (stream, name, decl); ASM_OUTPUT_SKIP (stream, size ? size : 1); return;
[SPARC] Reimplement LEAF_REG_REMAP macro
The current implementation as an array of chars is indeed a bit awkward so this reimplements it as a function taking and returning an int. Tested on SPARC/Solaris, applied on the mainline. 2021-06-06 Eric Botcazou * config/sparc/sparc-protos.h (order_regs_for_local_alloc): Rename to... (sparc_order_regs_for_local_alloc): ...this. (sparc_leaf_reg_remap): Declare. * config/sparc/sparc.h (ADJUST_REG_ALLOC_ORDER): Adjust. (LEAF_REG_REMAP): Reimplement as call to sparc_leaf_reg_remap. * config/sparc/sparc.c (leaf_reg_remap): Delete. (order_regs_for_local_alloc): Rename to... (sparc_order_regs_for_local_alloc): ...this. (sparc_leaf_reg_remap): New function. (sparc_conditional_register_usage): Do not modify leaf_reg_remap. -- Eric Botcazoudiff --git a/gcc/config/sparc/sparc-protos.h b/gcc/config/sparc/sparc-protos.h index ad875cc07f2..8879ac3925d 100644 --- a/gcc/config/sparc/sparc-protos.h +++ b/gcc/config/sparc/sparc-protos.h @@ -30,7 +30,8 @@ extern void init_cumulative_args (CUMULATIVE_ARGS *, tree, rtx, tree); extern unsigned long sparc_type_code (tree); #endif /* TREE_CODE */ -extern void order_regs_for_local_alloc (void); +extern void sparc_order_regs_for_local_alloc (void); +extern int sparc_leaf_reg_remap (int); extern int sparc_initial_elimination_offset (int); extern void sparc_expand_prologue (void); extern void sparc_flat_expand_prologue (void); diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c index b6e66dcc228..04fc80f0ee6 100644 --- a/gcc/config/sparc/sparc.c +++ b/gcc/config/sparc/sparc.c @@ -507,25 +507,6 @@ static const struct processor_costs *sparc_costs = &cypress_costs; ((TARGET_ARCH64 && !TARGET_CM_MEDLOW) || flag_pic) #endif -/* Vector to say how input registers are mapped to output registers. - HARD_FRAME_POINTER_REGNUM cannot be remapped by this function to - eliminate it. You must use -fomit-frame-pointer to get that. */ -char leaf_reg_remap[] = -{ 0, 1, 2, 3, 4, 5, 6, 7, - -1, -1, -1, -1, -1, -1, 14, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - 8, 9, 10, 11, 12, 13, -1, 15, - - 32, 33, 34, 35, 36, 37, 38, 39, - 40, 41, 42, 43, 44, 45, 46, 47, - 48, 49, 50, 51, 52, 53, 54, 55, - 56, 57, 58, 59, 60, 61, 62, 63, - 64, 65, 66, 67, 68, 69, 70, 71, - 72, 73, 74, 75, 76, 77, 78, 79, - 80, 81, 82, 83, 84, 85, 86, 87, - 88, 89, 90, 91, 92, 93, 94, 95, - 96, 97, 98, 99, 100, 101, 102}; - /* Vector, indexed by hard register number, which contains 1 for a register that is allowable in a candidate for leaf function treatment. */ @@ -8863,18 +8844,18 @@ epilogue_renumber (rtx *where, int test) /* Leaf functions and non-leaf functions have different needs. */ -static const int -reg_leaf_alloc_order[] = REG_LEAF_ALLOC_ORDER; +static const int reg_leaf_alloc_order[] = REG_LEAF_ALLOC_ORDER; -static const int -reg_nonleaf_alloc_order[] = REG_ALLOC_ORDER; +static const int reg_nonleaf_alloc_order[] = REG_ALLOC_ORDER; -static const int *const reg_alloc_orders[] = { +static const int *const reg_alloc_orders[] = +{ reg_leaf_alloc_order, - reg_nonleaf_alloc_order}; + reg_nonleaf_alloc_order +}; void -order_regs_for_local_alloc (void) +sparc_order_regs_for_local_alloc (void) { static int last_order_nonleaf = 1; @@ -8886,7 +8867,28 @@ order_regs_for_local_alloc (void) FIRST_PSEUDO_REGISTER * sizeof (int)); } } - + +int +sparc_leaf_reg_remap (int regno) +{ + gcc_checking_assert (regno >= 0); + + /* Do not remap in flat mode. */ + if (TARGET_FLAT) +return regno; + + /* Do not remap global, stack pointer or floating-point registers. */ + if (regno < 8 || regno == STACK_POINTER_REGNUM || regno > SPARC_LAST_INT_REG) +return regno; + + /* Neither out nor local nor frame pointer registers must appear. */ + if ((regno >= 8 && regno <= 23) || regno == HARD_FRAME_POINTER_REGNUM) +return -1; + + /* Remap in to out registers. */ + return regno - 16; +} + /* Return 1 if REG and MEM are legitimate enough to allow the various MEM<-->REG splits to be run. */ @@ -12983,14 +12985,11 @@ sparc_conditional_register_usage (void) fixed_regs[4] = 1; else if (fixed_regs[4] == 2) fixed_regs[4] = 0; + + /* Disable leaf function optimization in flat mode. */ if (TARGET_FLAT) -{ - int regno; - /* Disable leaf functions. */ - memset (sparc_leaf_regs, 0, FIRST_PSEUDO_REGISTER); - for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) - leaf_reg_remap [regno] = regno; -} +memset (sparc_leaf_regs, 0, FIRST_PSEUDO_REGISTER); + if (TARGET_VIS) global_regs[SPARC_GSR_REG] = 1; } diff --git a/gcc/config/sparc/sparc.h b/gcc/config/sparc/sparc.h index 48345753b6f..4da5a06df2f 100644 --- a/gcc/config/sparc/sparc.h +++ b/gcc/config/sparc/sparc.h @@ -965,13 +965,12 @@ extern enum reg_class sparc_regno_reg_class[FIRST_PSEUDO_REGISTER]; 96, 97, 98, 99, /* %fcc0-3 */ \ 1
[PATCH] Add --enable-default-semantic-interposition to GCC configure
From: Fangrui Song --enable-default-semantic-interposition=no makes -fPIC default to -fno-semantic-interposition which enables interprocedural optimizations for default visibility non-vague-linkage function definitions. The suppression of interprocedural optimizations and inlining for such functions is the biggest difference between -fPIE/-fPIC. Distributions may want to enable default -fno-semantic-interposition to reclaim the lost performance (e.g. CPython is said to be 27% faster; Clang is 3% faster). gcc/ PR 100937 * common.opt (fsemantic-interposition): Initialize to -1. * configure.ac: Add --enable-default-semantic-interposition. Default to yes. * defaults.h (DEFAULT_FLAG_SEMANTIC_INTERPOSITION): New. * opts.c (finish_options): Update opts->x_flag_semantic_interposition if it is -1. * doc/install.texi: Document --enable-default-semantic-interposition. * config.in: Add template. * configure: Regenerate. --- gcc/common.opt | 2 +- gcc/config.in| 6 ++ gcc/configure| 22 -- gcc/configure.ac | 12 gcc/defaults.h | 6 ++ gcc/doc/install.texi | 3 +++ gcc/opts.c | 3 +++ 7 files changed, 51 insertions(+), 3 deletions(-) diff --git a/gcc/common.opt b/gcc/common.opt index ffb968d90f8..68fcbac96b1 100644 --- a/gcc/common.opt +++ b/gcc/common.opt @@ -2480,7 +2480,7 @@ Common Var(flag_sel_sched_reschedule_pipelined) Init(0) Optimization Reschedule pipelined regions without pipelining. fsemantic-interposition -Common Var(flag_semantic_interposition) Init(1) +Common Var(flag_semantic_interposition) Init(-1) Allow interposing function (or variables) by ones with different semantics (or initializer) respectively by dynamic linker. ; sched_stalled_insns means that insns can be moved prematurely from the queue diff --git a/gcc/config.in b/gcc/config.in index e54f59ce0c3..7f1d56c1903 100644 --- a/gcc/config.in +++ b/gcc/config.in @@ -125,6 +125,12 @@ #endif +/* Define if -fPIC defaults to -fsemantic-interposition */ +#ifndef USED_FOR_TARGET +#undef ENABLE_DEFAULT_SEMANTIC_INTERPOSITION +#endif + + /* Define if your target supports default stack protector and it is enabled. */ #ifndef USED_FOR_TARGET diff --git a/gcc/configure b/gcc/configure index 4a9e4fa08ab..3835b22f6a5 100755 --- a/gcc/configure +++ b/gcc/configure @@ -632,6 +632,7 @@ ac_includes_default="\ ac_subst_vars='LTLIBOBJS LIBOBJS CET_HOST_FLAGS +enable_default_semantic_interposition NO_PIE_FLAG NO_PIE_CFLAGS enable_default_pie @@ -1027,6 +1028,7 @@ with_linker_hash_style with_diagnostics_color with_diagnostics_urls enable_default_pie +enable_default_semantic_interposition enable_cet enable_s390_excess_float_precision ' @@ -1787,6 +1789,8 @@ Optional Features: --disable-libquadmath-support disable libquadmath support for Fortran --enable-default-pieenable Position Independent Executable as default + --enable-default-semantic-interposition + enable -fsemantic-interposition as -fPIC default --enable-cetenable Intel CET in host libraries [default=auto] --enable-s390-excess-float-precision on s390 targets, evaluate float with double @@ -19435,7 +19439,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 19438 "configure" +#line 19454 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -19541,7 +19545,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 19544 "configure" +#line 19560 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -31893,6 +31897,20 @@ if test "$gcc_cv_no_pie" = "yes"; then fi +# Check whether --enable-default-semantic-interposition=no was given. +if test "${enable_default_semantic_interposition+set}" = set; then : + enableval=$enable_default_semantic_interposition; enable_default_semantic_interposition=$enableval +else + enable_default_semantic_interposition=yes +fi + +if test x$enable_default_semantic_interposition != xno ; then + +$as_echo "#define ENABLE_DEFAULT_SEMANTIC_INTERPOSITION 1" >>confdefs.h + +fi + + # Enable Intel CET on Intel CET enabled host if jit is enabled. # Check whether --enable-cet was given. if test "${enable_cet+set}" = set; then : diff --git a/gcc/configure.ac b/gcc/configure.ac index d9fc3c219e8..1cdf8b4ce00 100644 --- a/gcc/configure.ac +++ b/gcc/configure.ac @@ -7419,6 +7419,18 @@ if test "$gcc_cv_no_pie" = "yes"; then fi AC_SUBST([NO_PIE_FLAG]) +# Check whether --enable-default-semantic-interposition=no was given. +AC_ARG_ENABLE(default-semantic-interposition, +[AS_HELP_STRING([--enable-default-semantic-interposition], + [enable -fsemantic-interposition as -fPIC default])], +enable_default_semantic_interposition=$enableval, +enable_default_semantic
Re: [PATCH] Add --enable-default-semantic-interposition to GCC configure
On Sun, Jun 6, 2021 at 4:13 PM Fangrui Song via Gcc-patches wrote: > > From: Fangrui Song > > --enable-default-semantic-interposition=no makes -fPIC default to > -fno-semantic-interposition which enables interprocedural optimizations > for default visibility non-vague-linkage function definitions. > > The suppression of interprocedural optimizations and inlining for such > functions is the biggest difference between -fPIE/-fPIC. > Distributions may want to enable default -fno-semantic-interposition to > reclaim the lost performance (e.g. CPython is said to be 27% faster; > Clang is 3% faster). This breaks assumptions across the board. If software packages want to use -fno-semantic-interposition that is one thing. But distros should not be changing the default. This is just like using -ffast-math :). Thanks, Andrew Pinski > > gcc/ > > PR 100937 > * common.opt (fsemantic-interposition): Initialize to -1. > * configure.ac: Add --enable-default-semantic-interposition. Default > to yes. > * defaults.h (DEFAULT_FLAG_SEMANTIC_INTERPOSITION): New. > * opts.c (finish_options): Update > opts->x_flag_semantic_interposition if it is -1. > * doc/install.texi: Document --enable-default-semantic-interposition. > * config.in: Add template. > * configure: Regenerate. > --- > gcc/common.opt | 2 +- > gcc/config.in| 6 ++ > gcc/configure| 22 -- > gcc/configure.ac | 12 > gcc/defaults.h | 6 ++ > gcc/doc/install.texi | 3 +++ > gcc/opts.c | 3 +++ > 7 files changed, 51 insertions(+), 3 deletions(-) > > diff --git a/gcc/common.opt b/gcc/common.opt > index ffb968d90f8..68fcbac96b1 100644 > --- a/gcc/common.opt > +++ b/gcc/common.opt > @@ -2480,7 +2480,7 @@ Common Var(flag_sel_sched_reschedule_pipelined) Init(0) > Optimization > Reschedule pipelined regions without pipelining. > > fsemantic-interposition > -Common Var(flag_semantic_interposition) Init(1) > +Common Var(flag_semantic_interposition) Init(-1) > Allow interposing function (or variables) by ones with different semantics > (or initializer) respectively by dynamic linker. > > ; sched_stalled_insns means that insns can be moved prematurely from the > queue > diff --git a/gcc/config.in b/gcc/config.in > index e54f59ce0c3..7f1d56c1903 100644 > --- a/gcc/config.in > +++ b/gcc/config.in > @@ -125,6 +125,12 @@ > #endif > > > +/* Define if -fPIC defaults to -fsemantic-interposition */ > +#ifndef USED_FOR_TARGET > +#undef ENABLE_DEFAULT_SEMANTIC_INTERPOSITION > +#endif > + > + > /* Define if your target supports default stack protector and it is enabled. > */ > #ifndef USED_FOR_TARGET > diff --git a/gcc/configure b/gcc/configure > index 4a9e4fa08ab..3835b22f6a5 100755 > --- a/gcc/configure > +++ b/gcc/configure > @@ -632,6 +632,7 @@ ac_includes_default="\ > ac_subst_vars='LTLIBOBJS > LIBOBJS > CET_HOST_FLAGS > +enable_default_semantic_interposition > NO_PIE_FLAG > NO_PIE_CFLAGS > enable_default_pie > @@ -1027,6 +1028,7 @@ with_linker_hash_style > with_diagnostics_color > with_diagnostics_urls > enable_default_pie > +enable_default_semantic_interposition > enable_cet > enable_s390_excess_float_precision > ' > @@ -1787,6 +1789,8 @@ Optional Features: >--disable-libquadmath-support >disable libquadmath support for Fortran >--enable-default-pieenable Position Independent Executable as default > + --enable-default-semantic-interposition > + enable -fsemantic-interposition as -fPIC default >--enable-cetenable Intel CET in host libraries [default=auto] >--enable-s390-excess-float-precision >on s390 targets, evaluate float with double > @@ -19435,7 +19439,7 @@ else >lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 >lt_status=$lt_dlunknown >cat > conftest.$ac_ext <<_LT_EOF > -#line 19438 "configure" > +#line 19454 "configure" > #include "confdefs.h" > > #if HAVE_DLFCN_H > @@ -19541,7 +19545,7 @@ else >lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 >lt_status=$lt_dlunknown >cat > conftest.$ac_ext <<_LT_EOF > -#line 19544 "configure" > +#line 19560 "configure" > #include "confdefs.h" > > #if HAVE_DLFCN_H > @@ -31893,6 +31897,20 @@ if test "$gcc_cv_no_pie" = "yes"; then > fi > > > +# Check whether --enable-default-semantic-interposition=no was given. > +if test "${enable_default_semantic_interposition+set}" = set; then : > + enableval=$enable_default_semantic_interposition; > enable_default_semantic_interposition=$enableval > +else > + enable_default_semantic_interposition=yes > +fi > + > +if test x$enable_default_semantic_interposition != xno ; then > + > +$as_echo "#define ENABLE_DEFAULT_SEMANTIC_INTERPOSITION 1" >>confdefs.h > + > +fi > + > + > # Enable Intel CET on Intel CET enabled host if jit is enabled. > # Check whether --enable-cet was given. > if test "${enable
Re: [PATCH] Add --enable-default-semantic-interposition to GCC configure
On 2021-06-06, Andrew Pinski wrote: On Sun, Jun 6, 2021 at 4:13 PM Fangrui Song via Gcc-patches wrote: From: Fangrui Song --enable-default-semantic-interposition=no makes -fPIC default to -fno-semantic-interposition which enables interprocedural optimizations for default visibility non-vague-linkage function definitions. The suppression of interprocedural optimizations and inlining for such functions is the biggest difference between -fPIE/-fPIC. Distributions may want to enable default -fno-semantic-interposition to reclaim the lost performance (e.g. CPython is said to be 27% faster; Clang is 3% faster). This breaks assumptions across the board. If software packages want to use -fno-semantic-interposition that is one thing. But distros should not be changing the default. This is just like using -ffast-math :). Thanks, Andrew Pinski What assumption? Vague linkage function definitions already support IPO/inlining. For a large non-vague linkage function, presumably GCC will not inline it into the call sites in the same TU, users can keep using LD_PRELOAD to interpose that single symbol. Even if the non-vague function is small and inlined, users can use LD_PRELOAD to interpose both the callee and callers. You cannot do such interposition for Windows. macOS two-level namespace requires explicit `ld -flat_interpose` for such definition interposition. Users are free to add noinline or -fsemantic-interposition. gcc/ PR 100937 * common.opt (fsemantic-interposition): Initialize to -1. * configure.ac: Add --enable-default-semantic-interposition. Default to yes. * defaults.h (DEFAULT_FLAG_SEMANTIC_INTERPOSITION): New. * opts.c (finish_options): Update opts->x_flag_semantic_interposition if it is -1. * doc/install.texi: Document --enable-default-semantic-interposition. * config.in: Add template. * configure: Regenerate. --- gcc/common.opt | 2 +- gcc/config.in| 6 ++ gcc/configure| 22 -- gcc/configure.ac | 12 gcc/defaults.h | 6 ++ gcc/doc/install.texi | 3 +++ gcc/opts.c | 3 +++ 7 files changed, 51 insertions(+), 3 deletions(-) diff --git a/gcc/common.opt b/gcc/common.opt index ffb968d90f8..68fcbac96b1 100644 --- a/gcc/common.opt +++ b/gcc/common.opt @@ -2480,7 +2480,7 @@ Common Var(flag_sel_sched_reschedule_pipelined) Init(0) Optimization Reschedule pipelined regions without pipelining. fsemantic-interposition -Common Var(flag_semantic_interposition) Init(1) +Common Var(flag_semantic_interposition) Init(-1) Allow interposing function (or variables) by ones with different semantics (or initializer) respectively by dynamic linker. ; sched_stalled_insns means that insns can be moved prematurely from the queue diff --git a/gcc/config.in b/gcc/config.in index e54f59ce0c3..7f1d56c1903 100644 --- a/gcc/config.in +++ b/gcc/config.in @@ -125,6 +125,12 @@ #endif +/* Define if -fPIC defaults to -fsemantic-interposition */ +#ifndef USED_FOR_TARGET +#undef ENABLE_DEFAULT_SEMANTIC_INTERPOSITION +#endif + + /* Define if your target supports default stack protector and it is enabled. */ #ifndef USED_FOR_TARGET diff --git a/gcc/configure b/gcc/configure index 4a9e4fa08ab..3835b22f6a5 100755 --- a/gcc/configure +++ b/gcc/configure @@ -632,6 +632,7 @@ ac_includes_default="\ ac_subst_vars='LTLIBOBJS LIBOBJS CET_HOST_FLAGS +enable_default_semantic_interposition NO_PIE_FLAG NO_PIE_CFLAGS enable_default_pie @@ -1027,6 +1028,7 @@ with_linker_hash_style with_diagnostics_color with_diagnostics_urls enable_default_pie +enable_default_semantic_interposition enable_cet enable_s390_excess_float_precision ' @@ -1787,6 +1789,8 @@ Optional Features: --disable-libquadmath-support disable libquadmath support for Fortran --enable-default-pieenable Position Independent Executable as default + --enable-default-semantic-interposition + enable -fsemantic-interposition as -fPIC default --enable-cetenable Intel CET in host libraries [default=auto] --enable-s390-excess-float-precision on s390 targets, evaluate float with double @@ -19435,7 +19439,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 19438 "configure" +#line 19454 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -19541,7 +19545,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 19544 "configure" +#line 19560 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -31893,6 +31897,20 @@ if test "$gcc_cv_no_pie" = "yes"; then fi +# Check whether --enable-default-semantic-interposition=no was given. +if test "${enable_default_semantic_interposition+set}" = set; then : + enableval=$enable_default_semantic_interposition; enable_de
Ping: [PATCH] rs6000: Fix wrong code generation for vec_sel [PR94613]
Gentle ping, thanks. https://gcc.gnu.org/pipermail/gcc-patches/2021-May/570333.html On 2021/5/14 14:57, Xionghu Luo via Gcc-patches wrote: Hi, On 2021/5/13 18:49, Segher Boessenkool wrote: Hi! On Fri, Apr 30, 2021 at 01:32:58AM -0500, Xionghu Luo wrote: The vsel instruction is a bit-wise select instruction. Using an IF_THEN_ELSE to express it in RTL is wrong and leads to wrong code being generated in the combine pass. Per element selection is a subset of per bit-wise selection,with the patch the pattern is written using bit operations. But there are 8 different patterns to define "op0 := (op1 & ~op3) | (op2 & op3)": (~op3&op1) | (op3&op2), (~op3&op1) | (op2&op3), (op3&op2) | (~op3&op1), (op2&op3) | (~op3&op1), (op1&~op3) | (op3&op2), (op1&~op3) | (op2&op3), (op3&op2) | (op1&~op3), (op2&op3) | (op1&~op3), Combine pass will swap (op1&~op3) to (~op3&op1) due to commutative canonical, which could reduce it to the FIRST 4 patterns, but it won't swap (op2&op3) | (~op3&op1) to (~op3&op1) | (op2&op3), so this patch handles it with two patterns with different NOT op3 position and check equality inside it. Yup, that latter case does not have canonicalisation rules. Btw, not only combine does this canonicalisation: everything should, non-canonical RTL is invalid RTL (in the instruction stream, you can do everything in temporary code of course, as long as the RTL isn't malformed). -(define_insn "*altivec_vsel" +(define_insn "altivec_vsel" [(set (match_operand:VM 0 "altivec_register_operand" "=v") - (if_then_else:VM - (ne:CC (match_operand:VM 1 "altivec_register_operand" "v") - (match_operand:VM 4 "zero_constant" "")) - (match_operand:VM 2 "altivec_register_operand" "v") - (match_operand:VM 3 "altivec_register_operand" "v")))] - "VECTOR_MEM_ALTIVEC_P (mode)" - "vsel %0,%3,%2,%1" + (ior:VM + (and:VM + (not:VM (match_operand:VM 3 "altivec_register_operand" "v")) + (match_operand:VM 1 "altivec_register_operand" "v")) + (and:VM + (match_operand:VM 2 "altivec_register_operand" "v") + (match_operand:VM 4 "altivec_register_operand" "v"] + "VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode) + && (rtx_equal_p (operands[2], operands[3]) + || rtx_equal_p (operands[4], operands[3]))" + { + if (rtx_equal_p (operands[2], operands[3])) + return "vsel %0,%1,%4,%3"; + else + return "vsel %0,%1,%2,%3"; + } [(set_attr "type" "vecmove")]) That rtx_equal_p stuff is nice and tricky, but it is a bit too tricky I think. So please write this as two patterns (and keep the expand if that helps). I was a bit concerned that there would be a lot of duplicate code if we write two patterns for each vsel, totally 4 similar patterns in altivec.md and another 4 in vsx.md make it difficult to maintain, however I updated it since you prefer this way, as you pointed out the xxsel in vsx.md could be folded by later patch. +(define_insn "altivec_vsel2" (same here of course). ;; Fused multiply add. diff --git a/gcc/config/rs6000/rs6000-call.c b/gcc/config/rs6000/rs6000-call.c index f5676255387..d65bdc01055 100644 --- a/gcc/config/rs6000/rs6000-call.c +++ b/gcc/config/rs6000/rs6000-call.c @@ -3362,11 +3362,11 @@ const struct altivec_builtin_types altivec_overloaded_builtins[] = { RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_unsigned_V2DI }, { ALTIVEC_BUILTIN_VEC_SEL, ALTIVEC_BUILTIN_VSEL_2DI, RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_V2DI }, - { ALTIVEC_BUILTIN_VEC_SEL, ALTIVEC_BUILTIN_VSEL_2DI, + { ALTIVEC_BUILTIN_VEC_SEL, ALTIVEC_BUILTIN_VSEL_2DI_UNS, Are the _uns things still used for anything? But, let's not change this until Bill's stuff is in :-) Why do you want to change this here, btw? I don't understand. OK, they are actually "unsigned type" overload builtin functions, change it or not so far won't cause functionality issue, I will revert this change in the updated patch. + if (target == 0 + || GET_MODE (target) != tmode + || ! (*insn_data[icode].operand[0].predicate) (target, tmode)) No space after ! and other unary operators (except for casts and other operators you write with alphanumerics, like "sizeof"). I know you copied this code, but :-) OK, thanks. @@ -15608,8 +15606,6 @@ rs6000_emit_vector_cond_expr (rtx dest, rtx op_true, rtx op_false, case GEU: case LTU: case LEU: - /* Mark unsigned tests with CCUNSmode. */ - cc_mode = CCUNSmode; /* Invert condition to avoid compound test if necessary. */ if (rcode == GEU || rcode == LEU) So this is related to the _uns thing. Could you split off that change? Probably as an earlier patch (but either works for me). Not related to the ALTIVEC_BUILTIN_VSEL_2DI_UNS things, previously cc_mode is a parameter to generate the condition for IF_THEN_ELSE instruction, now we don't need it again as we use IOR (AND... AND...) style, remove it to avoid build error. - c
[PATCH 0/3]: C N2653 char8_t implementation
This series of patches implements the core language features for the WG14 N2653 [1] proposal to provide char8_t support in C. These changes are intended to align char8_t support in C with the support provided in C++20 via WG21 P0482R6 [2]. These changes do not impact default gcc behavior. The existing -fchar8_t option is extended to C compilation to enable the N2653 changes, and -fno-char8_t is extended to explicitly disable them. N2653 has not yet been accepted by WG14, so no changes are made to handling of the C2X language dialect. Patch 1: Language support Patch 2: New tests Patch 3: Documentation updates Tom. [1]: WG14 N2653 "char8_t: A type for UTF-8 characters and strings (Revision 1)" http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2653.htm [2]: WG21 P0482R6 "char8_t: A type for UTF-8 characters and strings (Revision 6)" https://wg21.link/p0482r6
[PATCH 1/3]: C N2653 char8_t: Language support
This patch implements the core language and compiler dependent library changes proposed in WG14 N2653 [1] for C. The changes include: - Use of the existing -fchar8_t and -fno-char8_t options to opt-in to (or opt-out of) the following changes when compiling C code. - Change of type for UTF-8 string literals from array of char to array of char8_t (unsigned char). - A new atomic_char8_t typedef. - A new ATOMIC_CHAR8_T_LOCK_FREE macro defined in terms of a new predefined ATOMIC_CHAR8_T_LOCK_FREE macro. When -fchar8_t support is enabled for non-C++ modes, the _CHAR8_T_SOURCE macro is predefined. This is the mechanism proposed to glibc to opt-in to declarations of the char8_t typedef and c8rtomb and mbrtoc8 functions proposed in N2653. See [2]. Tested on Linux x86_64. gcc/ChangeLog: 2021-05-31 Tom Honermann * ginclude/stdatomic.h (atomic_char8_t, ATOMIC_CHAR8_T_LOCK_FREE): New typedef and macro. gcc/c/ChangeLog: 2021-05-31 Tom Honermann * c-parser.c (c_parser_string_literal): Use char8_t as the type of CPP_UTF8STRING when char8_t support is enabled. * c-typeck.c (digest_init): Handle initialization of an array of character type by a string literal with type array of unsigned char. gcc/c-family/ChangeLog: 2021-05-31 Tom Honermann * c-cppbuiltin.c (c_cpp_builtins): Define _CHAR8_T_SOURCE if char8_t support is enabled in non-C++ language modes. * c-lex.c (lex_string): Use char8_t as the type of CPP_UTF8STRING when char8_t support is enabled. * c-opts.c (c_common_handle_option): Inform the preprocessor if char8_t support is enabled. * c.opt (fchar8_t): Enable for C language modes. libcpp/ChangeLog: 2021-05-31 Tom Honermann * include/cpplib.h (cpp_options): Add char8. Tom. [1]: WG14 N2653 "char8_t: A type for UTF-8 characters and strings (Revision 1)" http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2653.htm [2]: C++20 P0482R6 and C2X N2653: support for char8_t, mbrtoc8(), and c8rtomb(). [Patch 0]: https://sourceware.org/pipermail/libc-alpha/2021-June/127230.html [Patch 1]: https://sourceware.org/pipermail/libc-alpha/2021-June/127231.html [Patch 2]: https://sourceware.org/pipermail/libc-alpha/2021-June/127232.html [Patch 3]: https://sourceware.org/pipermail/libc-alpha/2021-June/127233.html commit c4260c7c49822522945377cc2fb93ee9830cefc8 Author: Tom Honermann Date: Sat Feb 13 09:02:34 2021 -0500 N2653 char8_t for C: Language support This patch implements the core language and compiler dependent library changes proposed in WG14 N2653 for C. The changes include: - Use of the existing -fchar8_t and -fno-char8_t options to opt-in to (or opt-out of) the following changes when compiling C code. - Change of type for UTF-8 string literals from array of const char to array of const char8_t (unsigned char). - A new atomic_char8_t typedef. - A new ATOMIC_CHAR8_T_LOCK_FREE macro defined in terms of a new predefined ATOMIC_CHAR8_T_LOCK_FREE macro. When -fchar8_t support is enabled for non-C++ modes, the _CHAR8_T_SOURCE macro is predefined. This is the mechanism proposed to glibc to opt-in to declarations of the char8_t typedef and c8rtomb and mbrtoc8 functions proposed in N2653. diff --git a/gcc/c-family/c-cppbuiltin.c b/gcc/c-family/c-cppbuiltin.c index 42b7604c9ac..3e944ec2b86 100644 --- a/gcc/c-family/c-cppbuiltin.c +++ b/gcc/c-family/c-cppbuiltin.c @@ -1467,6 +1467,11 @@ c_cpp_builtins (cpp_reader *pfile) if (flag_iso) cpp_define (pfile, "__STRICT_ANSI__"); + /* Express intent for char8_t support in C (not C++) to the C library if + requested. */ + if (!c_dialect_cxx () && flag_char8_t) +cpp_define (pfile, "_CHAR8_T_SOURCE"); + if (!flag_signed_char) cpp_define (pfile, "__CHAR_UNSIGNED__"); diff --git a/gcc/c-family/c-lex.c b/gcc/c-family/c-lex.c index c44e7a13489..e30e44e9f5c 100644 --- a/gcc/c-family/c-lex.c +++ b/gcc/c-family/c-lex.c @@ -1335,7 +1335,14 @@ lex_string (const cpp_token *tok, tree *valp, bool objc_string, bool translate) default: case CPP_STRING: case CPP_UTF8STRING: - value = build_string (1, ""); + if (type == CPP_UTF8STRING && flag_char8_t) + { + value = build_string (TYPE_PRECISION (char8_type_node) +/ TYPE_PRECISION (char_type_node), +""); /* char8_t is 8 bits */ + } + else + value = build_string (1, ""); break; case CPP_STRING16: value = build_string (TYPE_PRECISION (char16_type_node) diff --git a/gcc/c-family/c-opts.c b/gcc/c-family/c-opts.c index 60b5802722c..eefc607dac6 100644 --- a/gcc/c-family/c-opts.c +++ b/gcc/c-family/c-opts.c @@ -718,6 +718,10 @@ c_common_handle_option (size_t scode, const char *arg, HOST_WIDE_INT value, case OPT_v: verbose = true; break; + +case OPT_fchar8_t: + c
[PATCH 2/3]: C N2653 char8_t: New tests
This patch provides new tests for the core language and compiler dependent library changes proposed in WG14 N2653 [1] for C. Most of the tests are provided in both a positive (-fchar8_t) and negative (-fno-char8_t) form to ensure behaviors are appropriately present or absent in each mode. Tested on Linux x86_64. gcc/testsuite/ChangeLog: 2021-05-31 Tom Honermann * gcc.dg/atomic/stdatomic-lockfree-char8_t.c: New test. * gcc.dg/char8_t-init-string-literal-1.c: New test. * gcc.dg/char8_t-predefined-macros-1.c: New test. * gcc.dg/char8_t-predefined-macros-2.c: New test. * gcc.dg/char8_t-string-literal-1.c: New test. * gcc.dg/char8_t-string-literal-2.c: New test. Tom. [1]: WG14 N2653 "char8_t: A type for UTF-8 characters and strings (Revision 1)" http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2653.htm commit 900aa3507defd80339828e5791c215a28efd9fea Author: Tom Honermann Date: Sat Feb 13 10:02:41 2021 -0500 N2653 char8_t for C: New tests This change provides new tests for the core language and compiler dependent library changes proposed in WG14 N2653 for C. Some of the tests are provided in both a positive (-fchar8_t) and negative (-fno-char8_t) form to ensure behaviors are appropriately present or absent in each mode. diff --git a/gcc/testsuite/gcc.dg/atomic/stdatomic-lockfree-char8_t.c b/gcc/testsuite/gcc.dg/atomic/stdatomic-lockfree-char8_t.c new file mode 100644 index 000..bb9eae84e83 --- /dev/null +++ b/gcc/testsuite/gcc.dg/atomic/stdatomic-lockfree-char8_t.c @@ -0,0 +1,42 @@ +/* Test atomic_is_lock_free for char8_t. */ +/* { dg-do run } */ +/* { dg-options "-std=c11 -fchar8_t -pedantic-errors" } */ + +#include +#include + +extern void abort (void); + +_Atomic __CHAR8_TYPE__ ac8a; +atomic_char8_t ac8t; + +#define CHECK_TYPE(MACRO, V1, V2) \ + do \ +{ \ + int r1 = MACRO;\ + int r2 = atomic_is_lock_free (&V1); \ + int r3 = atomic_is_lock_free (&V2); \ + if (r1 != 0 && r1 != 1 && r1 != 2) \ + abort ();\ + if (r2 != 0 && r2 != 1) \ + abort ();\ + if (r3 != 0 && r3 != 1) \ + abort ();\ + if (r1 == 2 && r2 != 1) \ + abort ();\ + if (r1 == 2 && r3 != 1) \ + abort ();\ + if (r1 == 0 && r2 != 0) \ + abort ();\ + if (r1 == 0 && r3 != 0) \ + abort ();\ +} \ + while (0) + +int +main () +{ + CHECK_TYPE (ATOMIC_CHAR8_T_LOCK_FREE, ac8a, ac8t); + + return 0; +} diff --git a/gcc/testsuite/gcc.dg/char8_t-init-string-literal-1.c b/gcc/testsuite/gcc.dg/char8_t-init-string-literal-1.c new file mode 100644 index 000..4d587e90a26 --- /dev/null +++ b/gcc/testsuite/gcc.dg/char8_t-init-string-literal-1.c @@ -0,0 +1,13 @@ +/* Test that char, signed char, and unsigned char arrays can still be + initialized by UTF-8 string literals if -fchar8_t is enabled. */ +/* { dg-do compile } */ +/* { dg-options "-fchar8_t" } */ + +char cbuf1[] = u8"text"; +char cbuf2[] = { u8"text" }; + +signed char scbuf1[] = u8"text"; +signed char scbuf2[] = { u8"text" }; + +unsigned char ucbuf1[] = u8"text"; +unsigned char ucbuf2[] = { u8"text" }; diff --git a/gcc/testsuite/gcc.dg/char8_t-predefined-macros-1.c b/gcc/testsuite/gcc.dg/char8_t-predefined-macros-1.c new file mode 100644 index 000..884c634990d --- /dev/null +++ b/gcc/testsuite/gcc.dg/char8_t-predefined-macros-1.c @@ -0,0 +1,16 @@ +// Test that char8_t related predefined macros are not present when -fchar8_t is +// not enabled. +// { dg-do compile } +// { dg-options "-fno-char8_t" } + +#if defined(_CHAR8_T_SOURCE) +# error _CHAR8_T_SOURCE is defined! +#endif + +#if defined(__CHAR8_TYPE__) +# error __CHAR8_TYPE__ is defined! +#endif + +#if defined(__GCC_ATOMIC_CHAR8_T_LOCK_FREE) +# error __GCC_ATOMIC_CHAR8_T_LOCK_FREE is defined! +#endif diff --git a/gcc/testsuite/gcc.dg/char8_t-predefined-macros-2.c b/gcc/testsuite/gcc.dg/char8_t-predefined-macros-2.c new file mode 100644 index 000..7f425357f57 --- /dev/null +++ b/gcc/testsuite/gcc.dg/char8_t-predefined-macros-2.c @@ -0,0 +1,16 @@ +// Test that char8_t related predefined macros are present when -fchar8_t is +// enabled. +// { dg-do compile } +// { dg-options "-fchar8_t" } + +#if !defined(_CHAR8_T_SOURCE) +# error _CHAR8_T_SOURCE is not defined! +#endif + +#if !defined(__CHAR8_TYPE__) +# error __CHAR8_TYPE__ is not defined! +#endif + +#if !defined(__GCC_ATOMIC_CHAR8_T_LOCK_FREE) +# error __GCC_ATOMIC_CHAR8_T_LOCK_FREE is not defined! +#endif diff --git a/gcc/testsuite/gcc.dg/char8_t-string-literal-1.c b/gcc/testsuite/gcc.dg/char8_t-string-literal-1.c new file mode 100644 index 000..df94582ac1d --- /dev/null +++ b/gcc/testsuite/gcc.dg/char8_t-string-literal-1.c @@ -0,0 +1,6 @@ +// Test that UTF-8 string literals have type char[] if -fchar8_t is not enabled. +// { dg-do compile } +// { dg-options "-std=c11 -fno-char8_t" } + +_Static_assert (_Generic (u8"text", char*: 1, unsi
[PATCH 3/3]: C N2653 char8_t: Documentation updates
This patch updates documentation for the -fchar8_t and -fno-char8_t options to describe their effect on C code as proposed in WG14 N2653 [1]. Tested on Linux x86_64. 2021-05-31 Tom Honermann * doc/invoke.texi (-fchar8_t): update for char8_t support for C. Tom. [1]: WG14 N2653 "char8_t: A type for UTF-8 characters and strings (Revision 1)" http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2653.htm commit d3cb3c6648cc15fe1beea6c9799e044cb722148a Author: Tom Honermann Date: Sun May 30 16:57:09 2021 -0400 N2653 char8_t for C: Documentation updates This change updates documentation for the -fchar8_t option to describe its affect on C code as proposed in WG14 N2653 for C. diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 5cd4e2d993c..ba4c60a6179 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -2884,14 +2884,27 @@ This flag is enabled by default for @option{-std=c++17}. @itemx -fno-char8_t @opindex fchar8_t @opindex fno-char8_t -Enable support for @code{char8_t} as adopted for C++20. This includes -the addition of a new @code{char8_t} fundamental type, changes to the -types of UTF-8 string and character literals, new signatures for -user-defined literals, associated standard library updates, and new -@code{__cpp_char8_t} and @code{__cpp_lib_char8_t} feature test macros. +Enable support for @code{char8_t} for C as proposed in N2653, and for +C++ as adopted for C++20. + +For C, this changes the type of UTF-8 string literals from array of +@code{char} to array of @code{unsigned char} and defines the +@code{_CHAR8_T_SOURCE} macro to inform the C standard library that the +@code{char8_t} typedef name and the @code{mbrtoc8} and @code{c8rtomb} +functions should be declared by @code{}, and that the +@code{atomic_char8_t} typedef name and the @code{ATOMIC_CHAR8_T_LOCK_FREE} +macro should be defined by @code{}. + +For C++, this enables the @code{char8_t} fundamental type, changes the +type of UTF-8 string literals from array of @code{char} to array of +@code{char8_t}, changes the type of character literals from @code{char} +to @code{char8_t}, adds additional @code{char8_t}-based signatures for +user-defined literals, enables associated standard library updates, and +defines the @code{__cpp_char8_t} and @code{__cpp_lib_char8_t} feature +test macros. This option enables functions to be overloaded for ordinary and UTF-8 -strings: +strings in C++: @smallexample int f(const char *);// #1
Re: Ping^2: [PATCH 1/2] correct BB frequencies after loop changed
Gentle ping ;) BR. Jiufu Guo On 2021-05-20 15:19, guojiufu via Gcc-patches wrote: Gentle ping^. On 2021-05-07 10:36, guojiufu via Gcc-patches wrote: Gentle ping. Original message: https://gcc.gnu.org/pipermail/gcc-patches/2020-October/555871.html Thanks, Jiufu Guo.
Re: [PATCH] Use _GLIBCXX_ASSERTIONS as _GLIBCXX_DEBUG light
On 03/06/21 2:31 pm, Jonathan Wakely wrote: On 27/05/21 19:37 +0200, François Dumont via Libstdc++ wrote: We have been talking for a long time of a debug mode with less impact on performances. We already have it, that's what _GLIBCXX_ASSERTIONS already is :-) I propose to simply use the existing _GLIBCXX_ASSERTIONS macro. libstdc++: [_GLIBCXX_ASSERTIONS] Activate basic debug checks Use _GLIBCXX_ASSERTIONS as a _GLIBCXX_DEBUG light mode. When defined it activates all _GLIBCXX_DEBUG checks but skipping those requiring to loop through the iterator range unless in case of constexpr. libstdc++-v3/ChangeLog: * include/debug/debug.h [_GLIBCXX_ASSERTIONS]: Define debug macros non-empty. * include/debug/helper_functions.h: Cleanup comment about removed _Iter_base. * include/debug/functions.h (__skip_debug_runtime_check): New, returns false if _GLIBCXX_DEBUG is defined or if constant evaluated. (__check_sorted, __check_partitioned_lower, __check_partitioned_upper): Use latter. Tested under Linux x64. Ok to commit ? François diff --git a/libstdc++-v3/include/debug/debug.h b/libstdc++-v3/include/debug/debug.h index 116f2f023e2..2e6ce1c8a93 100644 --- a/libstdc++-v3/include/debug/debug.h +++ b/libstdc++-v3/include/debug/debug.h @@ -61,7 +61,7 @@ namespace __gnu_debug struct _Safe_iterator; } -#ifndef _GLIBCXX_DEBUG +#ifndef _GLIBCXX_ASSERTIONS # define __glibcxx_requires_cond(_Cond,_Msg) # define __glibcxx_requires_valid_range(_First,_Last) diff --git a/libstdc++-v3/include/debug/functions.h b/libstdc++-v3/include/debug/functions.h index 6cac11f2abd..ee0eb877568 100644 --- a/libstdc++-v3/include/debug/functions.h +++ b/libstdc++-v3/include/debug/functions.h @@ -48,6 +48,25 @@ namespace __gnu_debug template struct _Is_contiguous_sequence : std::__false_type { }; + _GLIBCXX20_CONSTEXPR Should this be simply _GLIBCXX_CONSTEXPR so that it can be constexpr in C++14 mode too? Or are there are never any debug checks in functions that are already constexpr in C++14 or C++17? + inline bool + __skip_debug_runtime_check() + { + // We could be here while only _GLIBCXX_ASSERTIONS has been defined. + // In this case we skip expensive runtime checks, constexpr will still + // be checked. + return +#ifndef _GLIBCXX_DEBUG +# if _GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED + !__builtin_is_constant_evaluated(); +# else + true; +# endif +#else + false; +#endif I think this would be simpler without the nesting, and without the preprocessor checks halfway through the return statement: #ifdef _GLIBCXX_DEBUG return false; #elif _GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED return !__builtin_is_constant_evaluated(); #else return true; #endif + } + /* Checks that [first, last) is a valid range, and then returns * __first. This routine is useful when we can't use a separate * assertion statement because, e.g., we are in a constructor. @@ -260,8 +279,9 @@ namespace __gnu_debug inline bool __check_sorted(const _InputIterator& __first, const _InputIterator& __last) { - return __check_sorted_aux(__first, __last, - std::__iterator_category(__first)); + return __skip_debug_runtime_check() + || __check_sorted_aux(__first, __last, + std::__iterator_category(__first)); Currently this function is never called at all ifndef _GLIBCXX_DEBUG. With this change, it's going to be present for _GLIBCXX_ASSERTIONS, and if it isn't inlined it's going to explode the code size. Some linux distros are already building the entire distro with _GLIBCXX_ASSERTIONS so I think we need to be quite careful about this kind of large change affecting every algo. So maybe we shouldn't enable these checks via _GLIBCXX_ASSERTIONS, but a new macro. _GLIBCXX_DEBUG is already rarely used, so will be yet another mode. So let's forget about all this, thanks. François
Ping^2: [PATCH] rs6000: Expand fmod and remainder when built with fast-math [PR97142]
Ping, thanks. On 2021/5/14 15:13, Xionghu Luo via Gcc-patches wrote: Test SPEC2017 Ofast P8LE for this patch : 511.povray_r +1.14%, 526.blender_r +1.72%, no obvious changes to others. On 2021/5/6 10:36, Xionghu Luo via Gcc-patches wrote: Gentle ping, thanks. On 2021/4/16 15:10, Xiong Hu Luo wrote: fmod/fmodf and remainder/remainderf could be expanded instead of library call when fast-math build, which is much faster. fmodf: fdivs f0,f1,f2 friz f0,f0 fnmsubs f1,f2,f0,f1 remainderf: fdivs f0,f1,f2 frin f0,f0 fnmsubs f1,f2,f0,f1 gcc/ChangeLog: 2021-04-16 Xionghu Luo PR target/97142 * config/rs6000/rs6000.md (fmod3): New define_expand. (remainder3): Likewise. gcc/testsuite/ChangeLog: 2021-04-16 Xionghu Luo PR target/97142 * gcc.target/powerpc/pr97142.c: New test. --- gcc/config/rs6000/rs6000.md | 36 ++ gcc/testsuite/gcc.target/powerpc/pr97142.c | 30 ++ 2 files changed, 66 insertions(+) create mode 100644 gcc/testsuite/gcc.target/powerpc/pr97142.c diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index a1315523fec..7e0e94e6ba4 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -4902,6 +4902,42 @@ (define_insn "fre" [(set_attr "type" "fp") (set_attr "isa" "*,")]) +(define_expand "fmod3" + [(use (match_operand:SFDF 0 "gpc_reg_operand")) + (use (match_operand:SFDF 1 "gpc_reg_operand")) + (use (match_operand:SFDF 2 "gpc_reg_operand"))] + "TARGET_HARD_FLOAT + && TARGET_FPRND + && flag_unsafe_math_optimizations" +{ + rtx div = gen_reg_rtx (mode); + emit_insn (gen_div3 (div, operands[1], operands[2])); + + rtx friz = gen_reg_rtx (mode); + emit_insn (gen_btrunc2 (friz, div)); + + emit_insn (gen_nfms4 (operands[0], operands[2], friz, operands[1])); + DONE; + }) + +(define_expand "remainder3" + [(use (match_operand:SFDF 0 "gpc_reg_operand")) + (use (match_operand:SFDF 1 "gpc_reg_operand")) + (use (match_operand:SFDF 2 "gpc_reg_operand"))] + "TARGET_HARD_FLOAT + && TARGET_FPRND + && flag_unsafe_math_optimizations" +{ + rtx div = gen_reg_rtx (mode); + emit_insn (gen_div3 (div, operands[1], operands[2])); + + rtx frin = gen_reg_rtx (mode); + emit_insn (gen_round2 (frin, div)); + + emit_insn (gen_nfms4 (operands[0], operands[2], frin, operands[1])); + DONE; + }) + (define_insn "*rsqrt2" [(set (match_operand:SFDF 0 "gpc_reg_operand" "=,wa") (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" ",wa")] diff --git a/gcc/testsuite/gcc.target/powerpc/pr97142.c b/gcc/testsuite/gcc.target/powerpc/pr97142.c new file mode 100644 index 000..48f25ca5b5b --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/pr97142.c @@ -0,0 +1,30 @@ +/* { dg-do compile } */ +/* { dg-options "-Ofast" } */ + +#include + +float test1 (float x, float y) +{ + return fmodf (x, y); +} + +double test2 (double x, double y) +{ + return fmod (x, y); +} + +float test3 (float x, float y) +{ + return remainderf (x, y); +} + +double test4 (double x, double y) +{ + return remainder (x, y); +} + +/* { dg-final { scan-assembler-not {\mbl fmod\M} } } */ +/* { dg-final { scan-assembler-not {\mbl fmodf\M} } } */ +/* { dg-final { scan-assembler-not {\mbl remainder\M} } } */ +/* { dg-final { scan-assembler-not {\mbl remainderf\M} } } */ + -- Thanks, Xionghu
Ping: [PATCH] rs6000: Remove unspecs for vec_mrghl[bhw]
Ping, thanks. On 2021/5/24 17:02, Xionghu Luo wrote: From: Xiong Hu Luo vmrghb only accepts permute index {0, 16, 1, 17, 2, 18, 3, 19, 4, 20, 5, 21, 6, 22, 7, 23} no matter for BE or LE in ISA, similarly for vmrghlb. Remove UNSPEC_VMRGH_DIRECT/UNSPEC_VMRGL_DIRECT pattern as vec_select + vec_concat as normal RTL. Tested pass on P8LE, P9LE and P8BE{m32}, ok for trunk? gcc/ChangeLog: * config/rs6000/altivec.md (*altivec_vmrghb_internal): Delete. (altivec_vmrghb_direct): New. (*altivec_vmrghh_internal): Delete. (altivec_vmrghh_direct): New. (*altivec_vmrghw_internal): Delete. (altivec_vmrghw_direct_): New. (altivec_vmrghw_direct): Delete. (*altivec_vmrglb_internal): Delete. (altivec_vmrglb_direct): New. (*altivec_vmrglh_internal): Delete. (altivec_vmrglh_direct): New. (*altivec_vmrglw_internal): Delete. (altivec_vmrglw_direct_): New. (altivec_vmrglw_direct): Delete. * config/rs6000/rs6000-p8swap.c (rtx_is_swappable_p): Adjust. * config/rs6000/rs6000.c (altivec_expand_vec_perm_const): Adjust. * config/rs6000/vsx.md (vsx_xxmrghw_): Adjust. (vsx_xxmrglw_): gcc/testsuite/ChangeLog: * gcc.target/powerpc/builtins-1.c: Update instruction counts. --- gcc/config/rs6000/altivec.md | 231 ++ gcc/config/rs6000/rs6000-p8swap.c | 2 - gcc/config/rs6000/rs6000.c| 10 +- gcc/config/rs6000/vsx.md | 18 +- gcc/testsuite/gcc.target/powerpc/builtins-1.c | 8 +- 5 files changed, 95 insertions(+), 174 deletions(-) diff --git a/gcc/config/rs6000/altivec.md b/gcc/config/rs6000/altivec.md index 208d6343225..cae05be2c2d 100644 --- a/gcc/config/rs6000/altivec.md +++ b/gcc/config/rs6000/altivec.md @@ -143,8 +143,6 @@ (define_c_enum "unspec" UNSPEC_VUPKHU_V4SF UNSPEC_VUPKLU_V4SF UNSPEC_VGBBD - UNSPEC_VMRGH_DIRECT - UNSPEC_VMRGL_DIRECT UNSPEC_VSPLT_DIRECT UNSPEC_VMRGEW_DIRECT UNSPEC_VMRGOW_DIRECT @@ -1291,44 +1289,29 @@ (define_expand "altivec_vmrghb" (use (match_operand:V16QI 2 "register_operand"))] "TARGET_ALTIVEC" { - rtvec v = gen_rtvec (16, GEN_INT (0), GEN_INT (16), GEN_INT (1), GEN_INT (17), - GEN_INT (2), GEN_INT (18), GEN_INT (3), GEN_INT (19), - GEN_INT (4), GEN_INT (20), GEN_INT (5), GEN_INT (21), - GEN_INT (6), GEN_INT (22), GEN_INT (7), GEN_INT (23)); - rtx x = gen_rtx_VEC_CONCAT (V32QImode, operands[1], operands[2]); - x = gen_rtx_VEC_SELECT (V16QImode, x, gen_rtx_PARALLEL (VOIDmode, v)); - emit_insn (gen_rtx_SET (operands[0], x)); + if (BYTES_BIG_ENDIAN) +emit_insn ( + gen_altivec_vmrghb_direct (operands[0], operands[1], operands[2])); + else +emit_insn ( + gen_altivec_vmrglb_direct (operands[0], operands[2], operands[1])); DONE; }) -(define_insn "*altivec_vmrghb_internal" +(define_insn "altivec_vmrghb_direct" [(set (match_operand:V16QI 0 "register_operand" "=v") -(vec_select:V16QI +(vec_select:V16QI (vec_concat:V32QI (match_operand:V16QI 1 "register_operand" "v") (match_operand:V16QI 2 "register_operand" "v")) - (parallel [(const_int 0) (const_int 16) -(const_int 1) (const_int 17) -(const_int 2) (const_int 18) -(const_int 3) (const_int 19) -(const_int 4) (const_int 20) -(const_int 5) (const_int 21) -(const_int 6) (const_int 22) -(const_int 7) (const_int 23)])))] - "TARGET_ALTIVEC" -{ - if (BYTES_BIG_ENDIAN) -return "vmrghb %0,%1,%2"; - else -return "vmrglb %0,%2,%1"; -} - [(set_attr "type" "vecperm")]) - -(define_insn "altivec_vmrghb_direct" - [(set (match_operand:V16QI 0 "register_operand" "=v") - (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v") - (match_operand:V16QI 2 "register_operand" "v")] - UNSPEC_VMRGH_DIRECT))] + (parallel [(const_int 0) (const_int 16) +(const_int 1) (const_int 17) +(const_int 2) (const_int 18) +(const_int 3) (const_int 19) +(const_int 4) (const_int 20) +(const_int 5) (const_int 21) +(const_int 6) (const_int 22) +(const_int 7) (const_int 23)])))] "TARGET_ALTIVEC" "vmrghb %0,%1,%2" [(set_attr "type" "vecperm")]) @@ -1339,16 +1322,16 @@ (define_expand "altivec_vmrghh" (use (match_operand:V8HI 2 "register_operand"))] "TARGET_ALTIVEC" { - rtvec v = gen_rtvec (8, GEN_INT (0), GEN_INT (8), GEN_INT (1), GEN_INT (9), - GEN_INT (2), GEN_INT (10), GEN_INT (3), GEN_INT (11)); - rtx x = gen_rtx_VEC_CONCAT (V16HImode, operands[1], operands[2
Re: [PATCH] Reformat target.def for better parsing.
On Sun, Jun 6, 2021 at 7:13 PM Martin Liška wrote: > > Hello. > > I'll need to parse output of tm.texi when converted to Sphinx for the future > conversion. So that I split DEFHOOK documentation entries with newlines. > > I'll install the patch if there are no comments? Hmm, what's the problem with parsing the strings? The newlines are only because of our line length limits and hard-coding them looks both error-prone and ugly. Richard. > Thanks, > Martin > > gcc/c-family/ChangeLog: > > * c-target.def: Split long lines and replace them > with '\n\'. > > gcc/ChangeLog: > > * common/common-target.def: Split long lines and replace them > with '\n\'. > * target.def: Likewise. > * doc/tm.texi: Re-generated. > --- > gcc/c-family/c-target.def| 70 ++--- > gcc/common/common-target.def | 32 +-- > gcc/doc/tm.texi | 364 +- > gcc/target.def | 485 +++ > 4 files changed, 612 insertions(+), 339 deletions(-) > > diff --git a/gcc/c-family/c-target.def b/gcc/c-family/c-target.def > index f2a1b7ef7c5..164f1b31694 100644 > --- a/gcc/c-family/c-target.def > +++ b/gcc/c-family/c-target.def > @@ -43,73 +43,73 @@ DEFHOOK > > DEFHOOK > (objc_construct_string_object, > - "Targets may provide a string object type that can be used within\ > - and between C, C++ and their respective Objective-C dialects.\ > - A string object might, for example, embed encoding and length information.\ > - These objects are considered opaque to the compiler and handled as > references.\ > - An ideal implementation makes the composition of the string object\ > - match that of the Objective-C @code{NSString} (@code{NXString} for > GNUStep),\ > - allowing efficient interworking between C-only and Objective-C code.\ > - If a target implements string objects then this hook should return a\ > - reference to such an object constructed from the normal `C' string\ > - representation provided in @var{string}.\ > - At present, the hook is used by Objective-C only, to obtain a\ > + "Targets may provide a string object type that can be used within\n\ > +and between C, C++ and their respective Objective-C dialects.\n\ > +A string object might, for example, embed encoding and length information.\n\ > +These objects are considered opaque to the compiler and handled as > references.\n\ > +An ideal implementation makes the composition of the string object\n\ > +match that of the Objective-C @code{NSString} (@code{NXString} for > GNUStep),\n\ > +allowing efficient interworking between C-only and Objective-C code.\n\ > +If a target implements string objects then this hook should return a\n\ > +reference to such an object constructed from the normal `C' string\n\ > +representation provided in @var{string}.\n\ > +At present, the hook is used by Objective-C only, to obtain a\n\ >common-format string object when the target provides one.", >tree, (tree string), >NULL) > > DEFHOOK > (objc_declare_unresolved_class_reference, > - "Declare that Objective C class @var{classname} is referenced\ > - by the current TU.", > + "Declare that Objective C class @var{classname} is referenced\n\ > +by the current TU.", >void, (const char *classname), >NULL) > > DEFHOOK > (objc_declare_class_definition, > - "Declare that Objective C class @var{classname} is defined\ > - by the current TU.", > + "Declare that Objective C class @var{classname} is defined\n\ > +by the current TU.", >void, (const char *classname), >NULL) > > DEFHOOK > (string_object_ref_type_p, > - "If a target implements string objects then this hook should return\ > - @code{true} if @var{stringref} is a valid reference to such an object.", > + "If a target implements string objects then this hook should return\n\ > +@code{true} if @var{stringref} is a valid reference to such an object.", >bool, (const_tree stringref), >hook_bool_const_tree_false) > > DEFHOOK > (check_string_object_format_arg, > - "If a target implements string objects then this hook should should\ > - provide a facility to check the function arguments in @var{args_list}\ > - against the format specifiers in @var{format_arg} where the type of\ > - @var{format_arg} is one recognized as a valid string reference type.", > + "If a target implements string objects then this hook should should\n\ > +provide a facility to check the function arguments in @var{args_list}\n\ > +against the format specifiers in @var{format_arg} where the type of\n\ > +@var{format_arg} is one recognized as a valid string reference type.", >void, (tree format_arg, tree args_list), >NULL) > > DEFHOOK > (c_preinclude, > - "Define this hook to return the name of a header file to be included at\ > - the start of all compilations, as if it had been included with\ > - @code{#include <@var{file}>}. If this hook returns @code{NULL}, or is\ > - not defined, or the header is not
Re: [PATCH] tree-inline: Fix up __builtin_va_arg_pack handling [PR100898]
On Sun, 6 Jun 2021, Jakub Jelinek wrote: > Hi! > > The following testcase ICEs, because gimple_call_arg_ptr (..., 0) > asserts that there is at least one argument, while we were using > it even if we didn't copy anything just to get a pointer from/to which > the zero arguments should be copied. > > Fixed by guarding the memcpy calls. Also, the code was calling > gimple_call_num_args too many times - 5 times instead of 2, so the patch > adds two temporaries for those. > > Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? OK. Richard. > 2021-06-06 Jakub Jelinek > > PR middle-end/100898 > * tree-inline.c (copy_bb): Only use gimple_call_arg_ptr if memcpy > should copy any arguments. Don't call gimple_call_num_args > on id->call_stmt or call_stmt more than once. > > * g++.dg/ext/va-arg-pack-3.C: New test. > > --- gcc/tree-inline.c.jj 2021-06-04 11:15:26.0 +0200 > +++ gcc/tree-inline.c 2021-06-04 15:15:07.358413674 +0200 > @@ -2090,27 +2090,29 @@ copy_bb (copy_body_data *id, basic_block > tree p; > gcall *new_call; > vec argarray; > - size_t nargs = gimple_call_num_args (id->call_stmt); > - size_t n; > + size_t nargs_caller = gimple_call_num_args (id->call_stmt); > + size_t nargs = nargs_caller; > > for (p = DECL_ARGUMENTS (id->src_fn); p; p = DECL_CHAIN (p)) > nargs--; > > /* Create the new array of arguments. */ > - n = nargs + gimple_call_num_args (call_stmt); > + size_t nargs_callee = gimple_call_num_args (call_stmt); > + size_t n = nargs + nargs_callee; > argarray.create (n); > argarray.safe_grow_cleared (n, true); > > /* Copy all the arguments before '...' */ > - memcpy (argarray.address (), > - gimple_call_arg_ptr (call_stmt, 0), > - gimple_call_num_args (call_stmt) * sizeof (tree)); > + if (nargs_callee) > + memcpy (argarray.address (), > + gimple_call_arg_ptr (call_stmt, 0), > + nargs_callee * sizeof (tree)); > > /* Append the arguments passed in '...' */ > - memcpy (argarray.address () + gimple_call_num_args (call_stmt), > - gimple_call_arg_ptr (id->call_stmt, 0) > - + (gimple_call_num_args (id->call_stmt) - nargs), > - nargs * sizeof (tree)); > + if (nargs) > + memcpy (argarray.address () + nargs_callee, > + gimple_call_arg_ptr (id->call_stmt, 0) > + + (nargs_caller - nargs), nargs * sizeof (tree)); > > new_call = gimple_build_call_vec (gimple_call_fn (call_stmt), > argarray); > --- gcc/testsuite/g++.dg/ext/va-arg-pack-3.C.jj 2021-06-04 > 15:32:28.213079130 +0200 > +++ gcc/testsuite/g++.dg/ext/va-arg-pack-3.C 2021-06-04 15:31:29.777883575 > +0200 > @@ -0,0 +1,18 @@ > +// PR middle-end/100898 > + > +int a; > +int bar (int, ...); > + > +static inline __attribute__((always_inline)) int > +foo (...) > +{ > + while (a) > +return bar (0, __builtin_va_arg_pack ()); > + return 0; > +} > + > +void > +baz (void) > +{ > + foo (); > +} > > Jakub > > -- Richard Biener SUSE Software Solutions Germany GmbH, Maxfeldstrasse 5, 90409 Nuernberg, Germany; GF: Felix Imendörffer; HRB 36809 (AG Nuernberg)
Re: [PATCH] Simplify (view_convert ~a) < 0 to (view_convert a) >= 0 [PR middle-end/100738]
On Fri, Jun 4, 2021 at 4:18 PM Marc Glisse wrote: > > On Fri, 4 Jun 2021, Hongtao Liu via Gcc-patches wrote: > > > On Tue, Jun 1, 2021 at 6:17 PM Marc Glisse wrote: > >> > >> On Tue, 1 Jun 2021, Hongtao Liu via Gcc-patches wrote: > >> > >>> Hi: > >>> This patch is about to simplify (view_convert:type ~a) < 0 to > >>> (view_convert:type a) >= 0 when type is signed integer. Similar for > >>> (view_convert:type ~a) >= 0. > >>> Bootstrapped and regtested on x86_64-linux-gnu{-m32,}. > >>> Ok for the trunk? > >>> > >>> gcc/ChangeLog: > >>> > >>>PR middle-end/100738 > >>>* match.pd ((view_convert ~a) < 0 --> (view_convert a) >= 0, > >>>(view_convert ~a) >= 0 --> (view_convert a) < 0): New GIMPLE > >>>simplification. > >> > >> We already have > >> > >> /* Fold ~X op C as X op' ~C, where op' is the swapped comparison. */ > >> (for cmp (simple_comparison) > >> scmp (swapped_simple_comparison) > >> (simplify > >>(cmp (bit_not@2 @0) CONSTANT_CLASS_P@1) > >>(if (single_use (@2) > >> && (TREE_CODE (@1) == INTEGER_CST || TREE_CODE (@1) == VECTOR_CST)) > >> (scmp @0 (bit_not @1) > >> > >> Would it make sense to try and generalize it a bit, say with > >> > >> (cmp (nop_convert1? (bit_not @0)) CONSTANT_CLASS_P) > >> > >> (scmp (view_convert:XXX @0) (bit_not @1)) > >> > > Thanks for your advice, it looks great. > > And can I use *view_convert1?* instead of *nop_convert1?* here, > > because the original case is view_convert, and nop_convert would fail > > to simplify the case. > > Near the top of match.pd, you can see > > /* With nop_convert? combine convert? and view_convert? in one pattern > plus conditionalize on tree_nop_conversion_p conversions. */ > (match (nop_convert @0) > (convert @0) > (if (tree_nop_conversion_p (type, TREE_TYPE (@0) > (match (nop_convert @0) > (view_convert @0) > (if (VECTOR_TYPE_P (type) && VECTOR_TYPE_P (TREE_TYPE (@0)) >&& known_eq (TYPE_VECTOR_SUBPARTS (type), > TYPE_VECTOR_SUBPARTS (TREE_TYPE (@0))) >&& tree_nop_conversion_p (TREE_TYPE (type), TREE_TYPE (TREE_TYPE > (@0)) > Oh, it's restricted to the same number of elements which is not the case i tested. That's why nop_convert failed to simplify the case. Guess we can define another nop1_convert to handle vector types with different number of elements, but still tree_nop_convertion_p? > So at least the intention is that it can handle both NOP_EXPR for scalars > and VIEW_CONVERT_EXPR for vectors, and I think we alread use it that way > in some places in match.pd, like > > (simplify > (negate (nop_convert? (bit_not @0))) > (plus (view_convert @0) { build_each_one_cst (type); })) > > (simplify > (bit_xor:c (nop_convert?:s (bit_not:s @0)) @1) > (if (tree_nop_conversion_p (type, TREE_TYPE (@0))) >(bit_not (bit_xor (view_convert @0) @1 > > (the 'if' seems redundant for this one) > > (simplify >(negate (nop_convert? (negate @1))) >(if (!TYPE_OVERFLOW_SANITIZED (type) > && !TYPE_OVERFLOW_SANITIZED (TREE_TYPE (@1))) > (view_convert @1))) > > etc. > > > At some point this got some genmatch help, to handle '?' and numbers, so I > don't remember all the details, but following these examples should work. > > -- > Marc Glisse -- BR, Hongtao
Re: [PATCH] fold-const: Fix up fold_read_from_vector [PR100887]
On Fri, 4 Jun 2021, Jakub Jelinek wrote: > On Fri, Jun 04, 2021 at 04:06:43PM +0200, Richard Biener wrote: > > On June 4, 2021 10:44:42 AM GMT+02:00, Jakub Jelinek > > wrote: > > >Hi! > > > > > >The callers of fold_read_from_vector expect that the index they pass is > > >an index of an element in the vector and the function does that most of > > >the > > >time. But we allow CONSTRUCTORs with VECTOR_TYPE to have VECTOR_TYPE > > >elements and in that case every CONSTRUCTOR element represents not just > > >one > > >index (with the exception of V1 vectors), but multiple. > > >So returning zero vector if i >= CONSTRUCTOR_NELTS or returning some > > >CONSTRUCTOR_ELT's value might not be what the callers expect. > > > > > >Fixed by punting if the first element has vector type. > > >Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? > > > > > >In theory we could instead recurse (and assert that for CONSTRUCTORs of > > >vector elements we have always all elements specified like tree-cfg.c > > >verifies?) after adjusting the index appropriately. > > > > I think we do this in the corresponding BIT_FIELD_REF match.pd rule. > > The fold_read_from_vector is indeed only called from the BIT_FIELD_REF > match.pd rule (3 times there), but I don't see there any number of elements > checking or this vector elt checking. > > Do you want me to do this check in match.pd instead of > fold_read_from_vector? Hmm, since fold_read_from_vector is stand-alone we should make it work for any CONSTRUCTOR so the guard there is OK. The match.pd rule using it is the vec_perm one - what I was remembering is that we have /* Simplify vector extracts. */ (simplify (BIT_FIELD_REF CONSTRUCTOR@0 @1 @2) ... /* Constructor elements can be subvectors. */ poly_uint64 k = 1; ... so I suppose implementing fold_read_from_vector in terms of simplifying the corresponding bit-field-ref should "work". But then I think your original patch is OK. Thanks, Richard. > > Note I don't think we allow CONSTRUCTOR (as in GENERIC) elements, so you'd > > only see SSA names with vector type here? > > The match.pd rule is both GIMPLE and GENERIC, so I don't see why > it couldn't be there a VECTOR_TYPE CONSTRUCTOR with CONSTRUCTOR elements > (or e.g. one VAR_DECL element and one CONSTRUCTOR element). > In particular, on the testcase I see in *.original > W D.2844 = { 0, 0, 0, 0, 0, 0, 0, 0 }; > > return VIEW_CONVERT_EXPR(BIT_FIELD_REF < VEC_PERM_EXPR < <<< Unknown > tree: compound_literal_expr > W D.2844 = { 0, 0, 0, 0, 0, 0, 0, 0 }; >>> , {v, { 0, 0, 0, 0 }} , { 0, > 8, 2, 3, 4, 5, 6, 7 } > , 128, 0>); > In this case fold_read_from_vector is called on the {v, { 0, 0, 0, 0 }} > CONSTRUCTOR with 0 and so the recursion would be on VAR_DECL and would punt, > but if the permutation was e.g. > { 0, 13, 2, 3, 4, 5, 6, 7 } > then it would be called with 5 as index and it could see that > it is in the second half (aka. the { 0, 0, 0, 0 } constructor) and > read the 5-4 element from there. > Even in GIMPLE, I see up to before veclower21 > _1 = {v_3(D), { 0, 0, 0, 0 }}; > _2 = VEC_PERM_EXPR <{ 0, 0, 0, 0, 0, 0, 0, 0 }, _1, { 0, 8, 2, 3, 4, 5, 6, > 7 }>; > which seems like CONSTRUCTOR inside of CONSTRUCTOR. > But sure, it could be an SSA_NAME too and if we wanted to recurse it > would need to handle that case too and look at SSA_NAME_DEF_STMT. > > Jakub > > -- Richard Biener SUSE Software Solutions Germany GmbH, Maxfeldstrasse 5, 90409 Nuernberg, Germany; GF: Felix Imendörffer; HRB 36809 (AG Nuernberg)