Jan Hubicka [Fri, 21 Jul 2023 15:34:31 +0000 (17:34 +0200)]
Implement flat loop profile detection
This patch adds maybe_flat_loop_profile which can be used in loop profile udpate
to detect situation where the profile may be unrealistically flat and should
not be dwonscalled after vectorizing, unrolling and other transforms that
assume that loop has high iteration count even if the CFG profile says
otherwise.
Profile is flat if it was statically detected and at that time we had
no idea about actual number of iterations or we artificially capped them.
So the function considers flat all profiles that have guessed or lower
reliability in their count and there is no nb_iteration_bounds/estimate
which would prove that the profile iteration count is high enough.
gcc/ChangeLog:
* cfgloop.h (maybe_flat_loop_profile): Declare
* cfgloopanal.cc (maybe_flat_loop_profile): New function.
* tree-cfg.cc (print_loop_info): Print info about flat profiles.
Jan Hubicka [Fri, 21 Jul 2023 15:31:34 +0000 (17:31 +0200)]
Fix gcc.dg/tree-ssa/copy-headers-9.c and gcc.dg/tree-ssa/dce-1.c failures
This patch fixes template in the two testcases so it matches the output
correctly. I did not re-test after last changes in the previous patch,
sorry for that.
gcc/testsuite/ChangeLog:
* gcc.dg/tree-ssa/copy-headers-9.c: Fix template for tree-ssa-loop-ch.cc changes.
* gcc.dg/tree-ssa/dce-1.c: Likewise.
Jan Hubicka [Fri, 21 Jul 2023 14:44:01 +0000 (16:44 +0200)]
Fix sreal::to_int and implement sreal::to_nearest_int
while exploring new loop estimate dumps, I noticed that loop iterating 1.8
times by profile is etimated as iterating once instead of 2 by nb_estimate.
While nb_estimate should really be a sreal and I will convert it incrementally,
I found problem is in previous patch doing:
+ *nit = (snit + 0.5).to_int ();
this does not work for sreal because it has only constructor from integer, so
first 0.5 is rounded to 0 and then added to snit.
Some code uses sreal(1, -1) which produces 0.5, but it reuqires unnecessary
addition, so I decided to add to_nearest_int. Testing it I noticed that to_int
is buggy:
(sreal(3)/2).to_int () == 1
while
(sreal(-3)/2).to_int () == -2
Fix is easy, we need to correctly shift in positive values. This patch fixes
it and adds the to_nearest_int alternative.
Jan Hubicka [Fri, 21 Jul 2023 12:54:23 +0000 (14:54 +0200)]
loop-ch improvements, part 5
Currently loop-ch skips all do-while loops. But when loop is not do-while
in addition to original goal of turining it to do-while it can do additional
things:
1) move out loop invariant computations
2) duplicate loop invariant conditionals and eliminate them in loop body.
3) prove that some exits are always true in first iteration
and can be skipped
Most of time 1 can be done by lim (exception is when the invariant computation
is conditional). For 2 we however don't really have other place doing it except
for loop unswitching that is more expensive (it will duplicate the loop and
then optimize out one path to non-loop).
3 can be done by loop peeling but it is also more expensive by duplicating full
loop body.
This patch improves heuristics by not giving up on do-while loops and trying
to find sequence of BBs to duplicate to obtain one of goals:
- turn loop to do-while
- eliminate invariant conditional in loop body
- do partial "peeling" as long as code optimizes enough so this does not
increase code size.
Bootstrapped/regtested x86_64-linux, OK?
gcc/ChangeLog:
* tree-ssa-loop-ch.cc (enum ch_decision): New enum.
(should_duplicate_loop_header_p): Return info on profitability.
(do_while_loop_p): Watch for constant conditionals.
(update_profile_after_ch): Do not sanity check that all
static exits are taken.
(ch_base::copy_headers): Run on all loops.
(pass_ch::process_loop_p): Improve heuristics by handling also
do_while loop and duplicating shortest sequence containing all
winning blocks.
gcc/testsuite/ChangeLog:
* gcc.dg/loop-unswitch-17.c: Disable ch.
* gcc.dg/pr103079.c: Disable ch.
* gcc.dg/tree-ssa/copy-headers-7.c: Update so ch behaves
as expected.
* gcc.dg/tree-ssa/copy-headers.c: Update template.
* gcc.dg/tree-ssa/copy-headers-9.c: New test.
gcc.dg/tree-ssa/forwprop-12.c looks for reconstruction of an
ARRAY_REF from pointer arithmetic and dereference. That's not
safe because ARRAY_REFs carry special semantics we later exploit
during data dependence analysis.
The following removes the testcase, closing the bug as WONTFIX.
Jan Hubicka [Fri, 21 Jul 2023 11:57:34 +0000 (13:57 +0200)]
finite_loop_p tweak
We have finite_p flag in loop structure. finite_loop_p already know to
use it, but we also may set the flag when we prove loop to be finite by
SCEV analysis to avoid duplicated work.
Bootstrapped/regtested x86_64-linux, OK?
gcc/ChangeLog:
* tree-ssa-loop-niter.cc (finite_loop_p): Reorder to do cheap
tests first; update finite_p flag.
Jan Hubicka [Fri, 21 Jul 2023 11:38:29 +0000 (13:38 +0200)]
improfe loop dumps
we have flow_loop_dump and print_loop. While print_loop was extended to dump
stuff from loop structure we added over years (loop info), flow_loop_dump was not.
-fdump-tree-all files contains flow_loop_dump which makes it hard to see what
metadata we have attached to loop.
This patch unifies dumping of these fields from both functions. For example for:
int a[100];
main()
{
for (int i = 0; i < 10; i++)
a[i]=i;
}
we now print:
;; Loop 0
;; header 0, latch 1
;; depth 0, outer -1
;; nodes: 0 1 2 3 4 5
;;
;; Loop 1
;; header 4, latch 3
;; depth 1, outer 0, finite_p
;; upper_bound 10
;; likely_upper_bound 10
;; estimate 10
;; iterations by profile: 10.001101 (unreliable)
finite_p, upper_boud, likely_upper_bound estimate and iterations by profile is new.
Bootstrap/regtest on x86_64 in progress. OK if it passes?
Honza
gcc/ChangeLog:
* cfgloop.cc (flow_loop_dump): Use print_loop_info.
* cfgloop.h (print_loop_info): Declare.
* tree-cfg.cc (print_loop_info): Break out from ...; add
printing of missing fields and profile
(print_loop): ... here.
gcc/testsuite/ChangeLog:
* gcc.dg/tree-ssa/dce-1.c: Update for new loop dumps.
cleanup: make all cond_len_* and mask_len_* consistent on the order of mask and len
This patch is depending on:
https://gcc.gnu.org/pipermail/gcc-patches/2023-July/625121.html
Hi, Richard and Richi.
This patch is to align the order of mask and len.
Currently, According to this piece code:
if (final_len && final_mask)
call = gimple_build_call_internal (
IFN_LEN_MASK_GATHER_LOAD, 7, dataref_ptr,
vec_offset, scale, zero, final_mask, final_len,
bias);
You can see the order of mask and len, is {mask,len,bias}.
"mask" comes before "len". The reason of this order is that we want to
reuse the current codes of MASK_GATHER_LOAD/MASK_SCATTER_STORE.
Same situation for COND_LEN_*, we want to reuse the codes of COND_*.
Reusing codes from the existing MASK_* or COND_* can allow us not to
change the codes too much and make the codes elegant and easy to maintain && read.
To avoid any confusions of auto-vectorization patterns that includes both mask and len,
this patch align the order of mask and len for both Gimple IR and RTL pattern into
{mask, len, bias} to make everything cleaner and more elegant.
Since start from LEN_MASK_GATHER_LOAD/LEN_MASK_SCATTER_STORE, COND_LEN_* patterns,
the order of len and mask is {mask,len,bias}.
The reason we make "mask" argument comes before "len" is because we want to keep
the "mask" location same as mask_* or cond_* patterns to make use of current codes flow
of mask_* and cond_*. Otherwise, we will need to change codes much more and make codes
hard to maintain.
Now, we already have COND_LEN_*, it's naturally that we should rename "LEN_MASK" into "MASK_LEN"
to keep name scheme consistent.
This patch only changes the name "LEN_MASK" into "MASK_LEN".
No codes functionality change.
Richard Biener [Thu, 13 Jul 2023 06:58:58 +0000 (08:58 +0200)]
tree-optimization/88540 - FP x > y ? x : y if-conversion without -ffast-math
The following makes sure that FP x > y ? x : y style max/min operations
are if-converted at the GIMPLE level. While we can neither match
it to MAX_EXPR nor .FMAX as both have different semantics with IEEE
than the ternary ?: operation we can make sure to maintain this form
as a COND_EXPR so backends have the chance to match this to instructions
their ISA offers.
The patch does this in phiopt where we recognize min/max and instead
of giving up when we have to honor NaNs we alter the generated code
to a COND_EXPR.
This resolves PR88540 and we can then SLP vectorize the min operation
for its testcase. It also resolves part of the regressions observed
with the change matching bit-inserts of bit-field-refs to vec_perm.
Expansion from a COND_EXPR rather than from compare-and-branch
gcc.target/i386/pr54855-9.c by producing extra moves while the
corresponding min/max operations are now already synthesized by
RTL expansion, register selection isn't optimal. This can be also
provoked without this change by altering the operand order in the source.
I have XFAILed that part of the test.
PR tree-optimization/88540
* tree-ssa-phiopt.cc (minmax_replacement): Do not give up
with NaNs but handle the simple case by if-converting to a
COND_EXPR.
This adds a simple match pattern to simplify
`max<max<a,b>,a>` to `max<a,b>`. Reassociation handles
this already (r0-77700-ge969dbde29bfd396259357) but
seems like we should be able to handle this even before
reassociation.
This fixes part of PR tree-optimization/80574 but more
work is needed fix it the rest of the way. The original
testcase there is fixed but the RTL level is what fixes
it the rest of the way.
OK? Bootstrapped and tested on x86_64-linux-gnu.
gcc/ChangeLog:
* match.pd (minmax<minmax<a,b>,a>->minmax<a,b>): New
transformation.
gcc/testsuite/ChangeLog:
* gcc.dg/tree-ssa/reassoc-12.c: Disable all of
the passes that enables match-and-simplify.
* gcc.dg/tree-ssa/minmax-23.c: New test.
Richard Biener [Thu, 20 Jul 2023 11:09:17 +0000 (13:09 +0200)]
tree-optimization/110742 - fix latent issue with permuting existing vectors
When we materialize a layout we push edge permutes to constant/external
defs without checking we can actually do so. For externals defined
by vector stmts rather than scalar components we can't.
PR tree-optimization/110742
* tree-vect-slp.cc (vect_optimize_slp_pass::get_result_with_layout):
Do not materialize an edge permutation in an external node with
vector defs.
(vect_slp_analyze_node_operations_1): Guard purely internal
nodes better.
Jan Hubicka [Fri, 21 Jul 2023 06:52:00 +0000 (08:52 +0200)]
Cleanup expected_loop_iterations
this patch cleanups API for determining expected loop iteraitons from profile.
We started with having expected_loop_iterations and only source was the integer
represented BB counts. It did some work on guessing number of iteration if
profile was absent or bogus. Later we introduced loop_info and added
get_estimated_loop_iterations which made expected_loop_iterations useful mostly
when doing profile updates and not for loop optimization heuristics. The
naming is bit ambiguous so this difference is not clear. Even later we
introduced precision tracking to profile and exended the API to return
reliablity of result but did not update all uses to do reasonable stuff with
it. There is also some cofusion about +-1s concering latch execution counts
versus header execution counts.
This patch aims to obsolette expected_loop_iterations and
expected_loop_iterations_unbounded (and "suceeds" modulo 1 use of each of two).
It adds expected_loop_iterations_by_profile which computes sreal and does
correct precision/presence tracking.
Unlike old code, it is based on CFG profile only and does not attempt to
provide fake answer when info is missing and does not check sanity with
loop_info.
We now define iterations consistently as lath execution in loop_info so I use
that here too.
I converted almost all calls to new API: dumps, code produing loop_info from
CFG profile and profile updating. Remaining uses are in loop unrolling and
prefetching that needs more TLC I will do incrementally.
There are some improvements possible which I can play with incrementally.
- for simple loops with one exit dominating latch we can use exit
probability for easier to preserve info in loop itraionts.
THis is probably not too critical since all esitmates should be recorded
in loop_info and would help mostly if new loop is constructed or old
loop is lost and redicovered.
- We may want to avoid trusting the profile if it is obviously inconsistent
on header.
gcc/ChangeLog:
* cfgloop.cc: Include sreal.h.
(flow_loop_dump): Dump sreal iteration exsitmate.
(get_estimated_loop_iterations): Update.
* cfgloop.h (expected_loop_iterations_by_profile): Declare.
* cfgloopanal.cc (expected_loop_iterations_by_profile): New function.
(expected_loop_iterations_unbounded): Use new API.
* cfgloopmanip.cc (scale_loop_profile): Use
expected_loop_iterations_by_profile
* predict.cc (pass_profile::execute): Likewise.
* profile.cc (branch_prob): Likewise.
* tree-ssa-loop-niter.cc: Include sreal.h.
(estimate_numbers_of_iterations): Likewise
Andrew Pinski [Fri, 21 Jul 2023 02:26:09 +0000 (02:26 +0000)]
libfortran: Fix build for targets that don't have 10byte or 16 byte floating point
So the problem here is EXPAND_INTER_MACRO_16 expands to nothing if 16 byte FP does not
exist but we still add a comma after it and that causes a build failure.
The same is true for EXPAND_INTER_MACRO_10 too.
Committed as obvious after a bootstrap and test on x86_64-linux-gnu and aarch64-linux-gnu.
libgfortran/ChangeLog:
PR libfortran/110759
* ieee/ieee_arithmetic.F90
(COMP_INTERFACE): Remove the comma after EXPAND_INTER_MACRO_16
and EXPAND_INTER_MACRO_10.
(EXPAND_INTER_MACRO_16): Add comma here if 16 byte fp exist.
(EXPAND_INTER_MACRO_10): Likewise.
Kewen Lin [Fri, 21 Jul 2023 05:18:19 +0000 (00:18 -0500)]
sccvn: Correct the index of bias for IFN_LEN_STORE [PR110744]
Commit r14-2267-gb8806f6ffbe72e adjusts the arguments order
of LEN_STORE from {len,vector,bias} to {len,bias,vector},
in order to make them consistent with LEN_MASK_STORE and
MASK_STORE. But it missed to update the related handlings
in tree-ssa-sccvn.cc, it caused the failure shown in PR
110744. This patch is to fix the related handlings with
the correct index.
PR tree-optimization/110744
gcc/ChangeLog:
* tree-ssa-sccvn.cc (vn_reference_lookup_3): Correct the index of bias
operand for ifn IFN_LEN_STORE.
Kewen Lin [Fri, 21 Jul 2023 05:16:29 +0000 (00:16 -0500)]
testsuite: Add a test case for PR110729 [PR110729]
As PR110729 reported, there was one issue for .section
__patchable_function_entries with -ffunction-sections, that
is we put the same symbol as link_to section symbol for all
functions wrongly. The commit r13-4294 for PR99889 has
fixed this with the corresponding label LPFE* which sits in
the function_section.
As Fangrui suggested [1], this patch is to add a bit more
test coverage. I didn't find a good way to check all
linked_to symbols are different, so I checked for LPFE[012].
liuhongt [Fri, 12 May 2023 07:15:08 +0000 (15:15 +0800)]
Provide -fcf-protection=branch,return.
Use EnumSet instead of EnumBitSet since CF_FULL is not power of 2.
It is a bit tricky for sets classification, cf_branch and cf_return
should be in different sets, but they both "conflicts" cf_full,
cf_none. And current EnumSet don't handle this well.
So in the current implementation, only cf_full,cf_none are exclusive
to each other, but they can be combined with any cf_branch, cf_return,
cf_check. It's not perfect, but still an improvement than original
one.
gcc/ChangeLog:
PR target/89701
* common.opt: (fcf-protection=): Add EnumSet attribute to
support combination of params.
gcc/testsuite/ChangeLog:
* c-c++-common/fcf-protection-10.c: New test.
* c-c++-common/fcf-protection-11.c: New test.
* c-c++-common/fcf-protection-12.c: New test.
* c-c++-common/fcf-protection-8.c: New test.
* c-c++-common/fcf-protection-9.c: New test.
* gcc.target/i386/pr89701-1.c: New test.
* gcc.target/i386/pr89701-2.c: New test.
* gcc.target/i386/pr89701-3.c: New test.
> I see some regressions most likely with this change on i686-linux,
> in particular:
> +FAIL: gcc.dg/pr107547.c (test for excess errors)
> +FAIL: gcc.dg/torture/floatn-convert.c -O0 (test for excess errors)
> +UNRESOLVED: gcc.dg/torture/floatn-convert.c -O0 compilation failed to produce executable
> +FAIL: gcc.dg/torture/floatn-convert.c -O1 (test for excess errors)
> +UNRESOLVED: gcc.dg/torture/floatn-convert.c -O1 compilation failed to produce executable
> +FAIL: gcc.dg/torture/floatn-convert.c -O2 (test for excess errors)
> +UNRESOLVED: gcc.dg/torture/floatn-convert.c -O2 compilation failed to produce executable
> +FAIL: gcc.dg/torture/floatn-convert.c -O2 -flto (test for excess errors)
> +UNRESOLVED: gcc.dg/torture/floatn-convert.c -O2 -flto compilation failed to produce executable
> +FAIL: gcc.dg/torture/floatn-convert.c -O2 -flto -flto-partition=none (test for excess errors)
> +UNRESOLVED: gcc.dg/torture/floatn-convert.c -O2 -flto -flto-partition=none compilation failed to produce executable
> +FAIL: gcc.dg/torture/floatn-convert.c -O3 -fomit-frame-pointer -funroll-loops -fpeel-loops -ftracer -finline-functions (test for excess errors)
> +UNRESOLVED: gcc.dg/torture/floatn-convert.c -O3 -fomit-frame-pointer -funroll-loops -fpeel-loops -ftracer -finline-functions compilation failed to produce executable
> +FAIL: gcc.dg/torture/floatn-convert.c -O3 -g (test for excess errors)
> +UNRESOLVED: gcc.dg/torture/floatn-convert.c -O3 -g compilation failed to produce executable
> +FAIL: gcc.dg/torture/floatn-convert.c -Os (test for excess errors)
> +UNRESOLVED: gcc.dg/torture/floatn-convert.c -Os compilation failed to produce executable
> +FAIL: gcc.target/i386/float16-7.c (test for errors, line 7)
>
> Perhaps we need to tweak
> gcc/testsuite/lib/target-supports.exp (add_options_for_float16)
> so that it adds -msse2 for i?86-*-* x86_64-*-* (that would likely
> fix up floatn-convert) and for the others perhaps
> /* { dg-add-options float16 } */
> ?
David Malcolm [Fri, 21 Jul 2023 00:24:10 +0000 (20:24 -0400)]
analyzer: avoid usage of TYPE_PRECISION on vector types [PR110455]
gcc/analyzer/ChangeLog:
PR analyzer/110455
* region-model.cc (region_model::get_gassign_result): Only check
for bad shift counts when dealing with an integral type.
gcc/testsuite/ChangeLog:
PR analyzer/110455
* gcc.dg/analyzer/pr110455.c: New test.
Signed-off-by: David Malcolm <dmalcolm@redhat.com>
David Malcolm [Fri, 21 Jul 2023 00:24:01 +0000 (20:24 -0400)]
analyzer: fix ICE on certain pointer subtractions [PR110387]
gcc/analyzer/ChangeLog:
PR analyzer/110387
* region.h (struct cast_region::key_t): Support "m_type" being
null by using "m_original_region" for empty/deleted slots.
gcc/testsuite/ChangeLog:
PR analyzer/110387
* gcc.dg/analyzer/out-of-bounds-pr110387.c: New test.
Signed-off-by: David Malcolm <dmalcolm@redhat.com>
Gaius Mulley [Thu, 20 Jul 2023 21:32:22 +0000 (22:32 +0100)]
[modula2] Implement limited VAR parameter static analysis
This patch implements limited VAR parameter static analysis for pointer
parameters.
gcc/m2/ChangeLog:
* gm2-compiler/M2SymInit.mod (IsExempt): Remove parameter exemption.
(CheckIndrX): Call SetupLAlias between lhs and content.
(trashParam): Re-write.
(SetVarLRInitialized): Indicate shadow and heap are initialized.
Call SetupIndr between shadow and heap.
* gm2-compiler/P2SymBuild.mod: Import
PutProcedureParameterHeapVars.
(EndBuildProcedure): Call PutProcedureParameterHeapVars.
* gm2-compiler/SymbolTable.def (GetParameterHeapVar): New
procedure function.
(PutProcedureParameterHeapVars): New procedure function.
* gm2-compiler/SymbolTable.mod (MakeParameterHeapVar): New
procedure function.
(GetParameterHeapVar): New procedure function.
(PuttParameterHeapVar): New procedure function.
(PutProcedureParameterHeapVars): New procedure.
(VarParam): HeapVar new record field.
(PutVarParam): HeapVar assigned to NulSym.
gcc/testsuite/ChangeLog:
* gm2/switches/uninit-variable-checking/procedures/fail/testdispose3.mod: New test.
* gm2/switches/uninit-variable-checking/procedures/fail/testdispose4.mod: New test.
* gm2/switches/uninit-variable-checking/procedures/pass/testdispose3.mod: New test.
* gm2/switches/uninit-variable-checking/procedures/pass/testdispose4.mod: New test.
Ian Lance Taylor [Thu, 20 Jul 2023 18:21:13 +0000 (11:21 -0700)]
cmd/go: don't collect package CGOLDFLAGS when using gccgo
They are already collected via cmd/cgo.
The gccgo_link_c test is tweaked to do real linking as with this
change the cgo ldflags are not fully reflected in go build -n output,
since they now only come from the built archive.
This is a backport of https://go.dev/cl/497117 from the main repo.
When sign-extending the value in a double-word register pair using shift and
ashiftrt sequence with the same count immediate value less than word width,
there is no need to shift the lower word of the value. The sign-extension
could be limited to the upper word, but we uselessly shift the lower word
with it as well:
movq %rdi, %rax
movq %rsi, %rdx
shldq $59, %rdi, %rdx
salq $59, %rax
shrdq $59, %rdx, %rax
sarq $59, %rdx
ret
for -m64 and
movl 4(%esp), %eax
movl 8(%esp), %edx
shldl $27, %eax, %edx
sall $27, %eax
shrdl $27, %edx, %eax
sarl $27, %edx
ret
for -m32.
The patch introduces a new post-reload splitter to provide the combined
ASHIFTRT/SHIFT instruction pattern. The instruction is split to a sequence
of SAL and SAR insns with the same count immediate operand:
movq %rsi, %rdx
movq %rdi, %rax
salq $59, %rdx
sarq $59, %rdx
ret
Some complication is required to properly handle STV transform, where we
emit a sequence with DImode PSLLQ and PSRAQ insns for 32-bit AVX512VL
targets when profitable.
The patch also fixes a small oversight and enables STV transform of SImode
ASHIFTRT to PSRAD also for SSE2 targets.
PR target/110717
gcc/ChangeLog:
* config/i386/i386-features.cc
(general_scalar_chain::compute_convert_gain): Calculate gain
for extend higpart case.
(general_scalar_chain::convert_op): Handle
ASHIFTRT/ASHIFT combined RTX.
(general_scalar_to_vector_candidate_p): Enable ASHIFTRT for
SImode for SSE2 targets. Handle ASHIFTRT/ASHIFT combined RTX.
* config/i386/i386.md (*extend<dwi>2_doubleword_highpart):
New define_insn_and_split pattern.
(*extendv2di2_highpart_stv): Ditto.
[LRA]: Exclude reloading of frame pointer in subreg for some cases
LRA for avr port reloads frame pointer in subreg although we can just
simplify the subreg. It results in generation of bad performance code. The following
patch fixes this.
libgomp.texi: Split OpenMP routines chapter into sections
The previous list of OpenMP routines was rather lengthy and the order seemed
to be rather random - especially for outputs which did not have @menu as then
the sectioning was not visible.
The OpenMP specification split in 5.1 the lengthy list by adding
sections to the chapter and grouping the routines under them.
This patch follow suite and uses the same sections and order. The commit also
prepares for adding not-yet-documented routines by listening those in the
@menu (@c commented - both for just undocumented and for also unimplemented
routines). See also PR 110364.
libgomp/ChangeLog:
* libgomp.texi (OpenMP Runtime Library Routines):
Split long list by adding sections and moving routines there.
(OMP_ALLOCATORS): Fix typo.
Andrew Pinski [Sat, 21 Sep 2019 01:27:34 +0000 (01:27 +0000)]
Move combine over to statistics_counter_event.
Since we have statistics_counter_event now, combine should use that
instead of it is own custom printing of statistics.
The only thing that is not done any more after this patch is printing
out the total stats for the whole TU.
Note you need to use -fdump-rtl-combine-stats to get the stats in the combine
dump unlike before where the stats was dumped directly into the file.
OK? Bootstrapped and tested on x86_64-linux-gnu with no regressions.
Marek Polacek [Wed, 19 Jul 2023 12:47:29 +0000 (08:47 -0400)]
c++: fix ICE with designated initializer [PR110114]
r13-1227 added an assert checking that the index in a CONSTRUCTOR
is a FIELD_DECL. That's a reasonable assumption but in this case
we never called reshape_init due to the type being incomplete, and
so the index remained an identifier node: get_class_binding never
got around to looking up the FIELD_DECL.
We can avoid the crash by returning early in implicit_conversion_1; we'd
return NULL anyway due to:
if (i < CONSTRUCTOR_NELTS (ctor))
return NULL;
in build_aggr_conv.
PR c++/110114
gcc/cp/ChangeLog:
* call.cc (implicit_conversion_1): Return early if the type isn't
complete.
gcc/testsuite/ChangeLog:
* g++.dg/cpp0x/initlist100.C: Adjust expected diagnostic.
* g++.dg/cpp2a/desig28.C: New test.
* g++.dg/cpp2a/desig29.C: New test.
I plan to refine the codes that I recently support for RVV auto-vectorization.
This patch is inspired last review comments from Richard:
https://patchwork.sourceware.org/project/gcc/patch/20230712042124.111818-1-juzhe.zhong@rivai.ai/
Richard said he prefer the the code structure as follows:
Please instead switch the if condition so that the structure is:
if (...)
vect_record_loop_mask (...)
else if (...)
vect_record_loop_len (...)
else
can't use partial vectors
This is his last comments.
So, I come back to refine this piece of codes.
Does it look reasonable ?
This next refine patch is change all names of "LEN_MASK" into "MASK_LEN" but should come after this
patch.
Jan Hubicka [Thu, 20 Jul 2023 13:41:39 +0000 (15:41 +0200)]
loop-ch improvements, part 3
Make tree-ssa-loop-ch understand if-combined conditionals (which
are quite common) and remove the IV-derived heuristics. That heuristics is
quite dubious because every variable with PHI in header of integral or pointer
type is seen as IV, so in the first basic block we match all loop invariants as
invariants and everything that chagnes in loop as IV-like.
I think the heuristics was mostly there to make header duplication happen when
the exit conditional is constant false in the first iteration and with ranger
we can work this out in good enough precision.
The patch adds notion of "combined exit" which has conditional that is
and/or/xor of loop invariant exit and exit known to be false in first
iteration. Copying these is a win since the loop conditional will simplify
in both copies.
It seems that those are usual bit or/and/xor and the code size accounting is
true only when the values have at most one bit set or when the static constant
and invariant versions are simple (such as all zeros). I am not testing this,
so the code may be optimistic here. I think it is not common enough to matter
and I can not think of correct condition that is not quite complex.
I also improved code size estimate not accounting non-conditionals that are
know to be constant in peeled copy and improved debug output.
This requires testsuite compensaiton. uninit-pred-loop-1.c.C does:
extern int bar();
int foo(int n, int m)
{
for (;;) {
int err = ({int _err;
for (int i = 0; i < 16; ++i) {
if (m+i > n)
break;
_err = 17;
_err = bar();
}
_err;
});
if (err == 0) return 17;
}
Before path we duplicate
if (m+i > n)
which makes maybe-uninitialized warning to not be output. I do not quite see
why copying this out would be a win, since it won't simlify. Also I think the
warning is correct. if m>n the loop will bail out before initializing _err and
it will be used unitialized. I think it is bug elsewhere that header
duplication supresses this.
copy headers does:
int is_sorted(int *a, int n, int m, int k)
{
for (int i = 0; i < n - 1 && m && k > i; i++)
if (a[i] > a[i + 1])
return 0;
return 1;
}
it tests that all three for statement conditionals are duplicaed. With patch
we no longer do k>i since it is not going to simplify. So I added test
ensuring that k is positive. Also the tests requires disabling if-combining and
vrp to avoid conditionals becoming combined ones. So I aded new version of test
that we now behave correctly aslo with if-combine.
ivopt_mult_2.c and ivopt_mult_1.c seems to require loop header
duplication for ivopts to behave particular way, so I also ensured by value
range that the header is duplicated.
Bootstrapped/regtested x86_64-linux, OK?
gcc/ChangeLog:
* tree-ssa-loop-ch.cc (edge_range_query): Rename to ...
(get_range_query): ... this one; do
(static_loop_exit): Add query parametr, turn ranger to reference.
(loop_static_stmt_p): New function.
(loop_static_op_p): New function.
(loop_iv_derived_p): Remove.
(loop_combined_static_and_iv_p): New function.
(should_duplicate_loop_header_p): Discover combined onditionals;
do not track iv derived; improve dumps.
(pass_ch::execute): Fix whitespace.
gcc/testsuite/ChangeLog:
* g++.dg/uninit-pred-loop-1_c.C: Allow warning.
* gcc.dg/tree-ssa/copy-headers-7.c: Add tests so exit conditition is
static; update template.
* gcc.dg/tree-ssa/ivopt_mult_1.c: Add test so exit condition is static.
* gcc.dg/tree-ssa/ivopt_mult_2.c: Add test so exit condition is static.
* gcc.dg/tree-ssa/copy-headers-8.c: New test.
Richard Biener [Mon, 17 Jul 2023 10:15:29 +0000 (12:15 +0200)]
tree-optimization/110204 - second level redundancy and simplification
When PRE discovers a full redundancy during insertion it cannot unite
the two value sets. Instead it inserts a copy old-val = new-val where
new-val can also be a constant. The following looks through such
copies during elimination, providing one extra level of constant and
copy propagation. For the PR this helps avoiding a bogus diagnostic
that's emitted on unreachable code during loop optimization.
PR tree-optimization/110204
* tree-ssa-sccvn.cc (eliminate_dom_walker::eliminate_avail):
Look through copies generated by PRE.
vectorizer: Avoid an OOB access from vectorization
Our checks for whether the vectorization of a given loop would make an
out of bounds access miss the case when the vector we load is so large
as to span multiple iterations worth of data (while only being there to
implement a single iteration).
This patch adds a check for such an access.
Example where this was going wrong (smaller version of testcase added):
```
extern unsigned short multi_array[5][16][16];
extern void initialise_s(int *);
extern int get_sval();
void foo() {
int s0 = get_sval();
int s[31];
int i,j;
initialise_s(&s[0]);
s0 = get_sval();
for (j=0; j < 16; j++)
for (i=0; i < 16; i++)
multi_array[1][j][i]=s[j*2];
}
```
With the above loop we would load the `s[j*2]` integer into a 4 element
vector, which reads 3 extra elements than the scalar loop would.
`get_group_load_store_type` identifies that the loop requires a scalar
epilogue due to gaps. However we do not identify that the above code
requires *two* scalar loops to be peeled due to the fact that each
iteration loads an amount of data from the *next* iteration (while not
using it).
Bootstrapped and regtested on aarch64-none-linux-gnu.
N.b. out of interest we came across this working with Morello.
gcc/ChangeLog:
* tree-vect-stmts.cc (get_group_load_store_type): Account for
`gap` when checking if need to peel twice.
Fortran: add IEEE_QUIET_* and IEEE_SIGNALING_* comparisons
Those operations were added to Fortran 2018, and correspond to
well-defined IEEE comparison operations, with defined signaling
semantics for NaNs. All are implemented in terms of GCC expressions and
built-ins, with no library support needed.
iseqsig() is a C2x library function, for signaling floating-point
equality checks. Provide a GCC-builtin for it, which is folded to
a series of comparisons.
gcc/testsuite/
* gcc.dg/torture/builtin-iseqsig-1.c: New test.
* gcc.dg/torture/builtin-iseqsig-2.c: New test.
* gcc.dg/torture/builtin-iseqsig-3.c: New test.
Pan Li [Thu, 20 Jul 2023 08:31:10 +0000 (16:31 +0800)]
RISC-V: Fix one incorrect match operand for RVV reduction
There are 2 of the RVV reduction pattern mask operand takes
vector_merge_operand instead of vector_mask_operand by mistake. This
patch would like to fix this.
Signed-off-by: Pan Li <pan2.li@intel.com>
gcc/ChangeLog:
Roger Sayle [Thu, 20 Jul 2023 08:23:11 +0000 (09:23 +0100)]
i386: More TImode parameter passing improvements.
This patch is the next piece of a solution to the x86_64 ABI issues in
PR 88873. This splits the *concat<mode><dwi>3_3 define_insn_and_split
into two patterns, a TARGET_64BIT *concatditi3_3 and a !TARGET_64BIT
*concatsidi3_3. This allows us to add an additional alternative to the
the 64-bit version, enabling the register allocator to perform this
operation using SSE registers, which is implemented/split after reload
using vec_concatv2di.
To demonstrate the improvement, the test case from PR88873:
typedef struct { double x, y; } s_t;
s_t foo (s_t a, s_t b, s_t c)
{
return (s_t){ __builtin_fma(a.x, b.x, c.x), __builtin_fma (a.y, b.y, c.y) };
}
when compiled with -O2 -march=cascadelake, currently generates:
2023-07-20 Roger Sayle <roger@nextmovesoftware.com>
gcc/ChangeLog
* config/i386/i386-expand.cc (ix86_expand_move): Don't call
force_reg, to use SUBREG rather than create a new pseudo when
inserting DFmode fields into TImode with insvti_{high,low}part.
* config/i386/i386.md (*concat<mode><dwi>3_3): Split into two
define_insn_and_split...
(*concatditi3_3): 64-bit implementation. Provide alternative
that allows register allocation to use SSE registers that is
split into vec_concatv2di after reload.
(*concatsidi3_3): 32-bit implementation.
gcc/testsuite/ChangeLog
* gcc.target/i386/pr88873.c: New test case.
Richard Biener [Tue, 18 Jul 2023 11:19:11 +0000 (13:19 +0200)]
middle-end/61747 - conditional move expansion and constants
When expanding a COND_EXPR or a VEC_COND_EXPR the x86 backend for
example tries to match FP min/max instructions. But this only
works when it can see the equality of the comparison and selected
operands. This breaks in both prepare_cmp_insn and vector_compare_rtx
where the former forces expensive constants to a register and the
latter performs legitimization. The patch below fixes this in
the caller preserving former equalities.
PR middle-end/61747
* internal-fn.cc (expand_vec_cond_optab_fn): When the
value operands are equal to the original comparison operands
preserve that equality by re-using the comparison expansion.
* optabs.cc (emit_conditional_move): When the value operands
are equal to the comparison operands and would be forced to
a register by prepare_cmp_insn do so earlier, preserving the
equality.
Current machine modes layout is hard to maintain && read && understand.
For a LMUL = 1 SI vector mode:
1. VNx1SI mode when TARGET_MIN_VLEN = 32.
2. VNx2SI mode when TARGET_MIN_VLEN = 64.
3. VNx4SI mode when TARGET_MIN_VLEN = 128.
Such implementation produces redundant machine modes and thus redudant machine description patterns.
Now, this patch refactor machine modes into 3 follow formats:
1. mask mode: RVVMF64BImode, RVVMF32BImode, ...., RVVM1BImode.
RVVMF64BImode means such mask mode occupy 1/64 of a RVV M1 reg.
RVVM1BImode size = LMUL = 1 reg.
2. non-tuple vector modes:
RVV<LMUL><BASE_MODE>: E.g. RVVMF8QImode = SEW = 8 && LMUL = MF8
3. tuple vector modes:
RVV<LMUL>x<NF><BASE_MODE>.
For example, for SEW = 16, LMUL = MF2 , int mode is always RVVMF4HImode, then adjust its size according to TARGET_MIN_VLEN.
Before this patch, the machine description patterns: 17551
After this patch, the machine description patterns: 14132 =====> reduce 3K+ patterns.
Jonathan Wakely [Wed, 19 Jul 2023 20:15:17 +0000 (21:15 +0100)]
libstdc++: Do not define inaccurate from_chars for _Float128 [PR110077]
I think r14-1431-g7037e7b6e4ac41 was wrong to try to define the
_Float128 overload unconditionally. Not all targets need it, so defining
the lossy fallback using long double is not useful (and caused an ABI
change on Solaris x86).
Making the definition depend on USE_STRTOF128_FOR_FROM_CHARS again
partially reverts the change for PR 109921, however that should still be
fixed because the changes to make USE_STRTOF128_FOR_FROM_CHARS depend on
USE_STRTOD_FOR_FROM_CHARS are not reverted.
libstdc++-v3/ChangeLog:
PR libstdc++/110077
* src/c++17/floating_from_chars.cc (from_chars): Only define
_Float128 overload when using __strfromf128.
Jonathan Wakely [Wed, 19 Jul 2023 17:18:46 +0000 (18:18 +0100)]
libstdc++: Check for std::ratio in arithmetic and comparisons [PR110593]
The standard says that it should be ill-formed to use std::ratio_equal
etc. with types which are not specializations of std::ratio. This
implements that requirement.
We don't need to add assertions to every one of the class templates,
because many of them are implemented in terms of other ones. For
example, ratio_divide and ratio_subtract can rely on the assertions in
ratio_multiply and ratio_add respectively.
libstdc++-v3/ChangeLog:
PR libstdc++/110593
* include/bits/chrono.h (duration): Improve static assert
messages.
(__is_ratio): Move to ...
* include/std/ratio (__is_ratio): ... here.
(__is_ratio_v): New variable template and partial
specialization.
(__are_both_ratios): New function template.
(__ratio_multiply, ratio_equal, ratio_less, __ratio_add):
Add static assertion.
* testsuite/20_util/ratio/requirements/type_constraints.cc:
New test.
* testsuite/20_util/duration/requirements/typedefs_neg1.cc:
Adjust expected error.
* testsuite/20_util/duration/requirements/typedefs_neg2.cc:
Likewise.
David Malcolm [Wed, 19 Jul 2023 21:55:09 +0000 (17:55 -0400)]
analyzer: fix ICE on division of tainted floating-point values [PR110700]
gcc/analyzer/ChangeLog:
PR analyzer/110700
* region-model-manager.cc
(region_model_manager::get_or_create_int_cst): Assert that we have
an integral or pointer type.
* sm-taint.cc (taint_state_machine::check_for_tainted_divisor):
Don't check non-integral types.
gcc/testsuite/ChangeLog:
PR analyzer/110700
* gcc.dg/analyzer/taint-divisor-2.c: New test.
Signed-off-by: David Malcolm <dmalcolm@redhat.com>
Patrick Palka [Wed, 19 Jul 2023 20:11:38 +0000 (16:11 -0400)]
c++: deducing empty type vs non-type argument pack
Within a template parameter list, a non-type template parameter pack is
represented as a PARM_DECL. But in a couple of spots where we need to
deduce and create an empty argument pack, we test for TEMPLATE_PARM_INDEX
(within a template parameter list) instead of for PARM_DECL, and so we
end up creating a TYPE_ARGUMENT_PACK even in the non-type case. This
patch fixes this (seemingly harmless) bug.
gcc/cp/ChangeLog:
* pt.cc (type_unification_real): Test for PARM_DECL instead
of TEMPLATE_PARM_INDEX to distinguish a type vs non-type
template parameter pack.
(type_targs_deducible_from): Likewise.
Patrick Palka [Wed, 19 Jul 2023 20:10:20 +0000 (16:10 -0400)]
c++: redundant targ coercion for var/alias tmpls
When stepping through the variable/alias template specialization code
paths, I noticed we perform template argument coercion twice: first from
lookup_template_variable / instantiate_alias_template and again from
tsubst_decl (during instantiate_template). It'd be nice to avoid this
redundant second coercion.
It turns out this coercion in tsubst_decl could be safely elided whenever
fully specializing a primary variable/alias template, because we can rely
on lookup_template_variable / instantiate_alias_template to already have
coerced the arguments.
The only other situation to consider seems to be when fully specializing
a partial variable template specialization (from instantiate_template),
in which case the passed 'args' are the (already coerced) arguments
relative to the partial template, and the resulting 'argvec' are the
(uncoerced) arguments relative to the primary template, so coercion is
still necessary. But computing 'argvec' here is only really necessary
in order to look up (and insert into) the specializations table. And
instantiate_template already performs a lookup, so if we just made it
register the resulting specialization too then we could avoid having to
compute 'argvec' when called from instantiate_template, which in turns
means we could avoid the coercion altogether. This patch implements
this approach.
gcc/cp/ChangeLog:
* pt.cc (tsubst_function_decl): Add defaulted 'use_spec_table'
flag parameter. Don't look up or insert into the specializations
table if 'use_spec_table' is false.
(tsubst_decl): Add defaulted 'use_spec_table' flag parameter.
Check for error_mark_node.
<case FUNCTION_DECL>: Pass 'use_spec_table' to
tsubst_function_decl.
<case TYPE/VAR_DECL>: Don't call coerce_template_parms.
Don't look up or insert into the specializations table if
'use_spec_table' is false. Exit earlier if the substituted
type is erroneous and we're not complaining, and do so for
alias specializations as well.
(instantiate_template): Pass false as 'use_spec_table'
to tsubst_decl. Call register_specialization afterwards.
Gaius Mulley [Wed, 19 Jul 2023 20:01:53 +0000 (21:01 +0100)]
PR modula2/110284 Make-lang-in m2flex.o and m2pp.o
This patch moves the rule c-family/m2pp.o from Make-lang.in into
Make-maintainer.in. It also adds m2/gm2-gcc/rtegraph.o and
m2/gm2-compiler-boot/m2flex.o to m2_OBJS. The object
m2/gm2-compiler-boot/m2flex.o is needed by cc1gm2 whereas
m2/gm2-compiler/m2flex.o is required by m2/stage2/cc1gm2
(which is only built in maintainer to allow debugging via m2
sources rather than the translated to C++ sources).
[LRA]: Check and update frame to stack pointer elimination after stack slot allocation
Avr is an interesting target which does not use stack pointer to
address stack slots. The elimination of stack pointer to frame pointer
is impossible if there are stack slots. During LRA works, the
stack slots can be allocated and used and the elimination can be done
anymore. The situation can be complicated even more if some pseudos
were allocated to the frame pointer.
gcc/ChangeLog:
* lra-int.h (lra_update_fp2sp_elimination): New prototype.
(lra_asm_insn_error): New prototype.
* lra-spills.cc (remove_pseudos): Add check for pseudo slot memory
existence.
(lra_spill): Call lra_update_fp2sp_elimination.
* lra-eliminations.cc: Remove trailing spaces.
(elimination_fp2sp_occured_p): New static flag.
(lra_eliminate_regs_1): Set the flag up.
(update_reg_eliminate): Modify the assert for stack to frame
pointer elimination.
(lra_update_fp2sp_elimination): New function.
(lra_eliminate): Clear flag elimination_fp2sp_occured_p.
Gaius Mulley [Wed, 19 Jul 2023 16:46:52 +0000 (17:46 +0100)]
[modula2] Location improvement and bugfix when issuing parameter errors
This patch improves the accuracy of error messages mentioning a
parameter in M2Quads.mod (when handling builtins). The error location
now points to the parameter rather than the function or procedure.
gcc/m2/ChangeLog:
* gm2-compiler/M2Quads.mod (BuildDifAdrFunction): Removed
unnecessary in error message. Use vartok for location.
(BuildOddFunction): Use optok for location.
(BuildAbsFunction): Use vartok for location. Bugfix set vartok.
(BuildCapFunction): Use optok for location.
(BuildOrdFunction): Use optok for location and correct format
specifier.
(BuildShiftFunction): Use vartok for location.
(BuildRotateFunction): Use vartok for location.
(BuildTruncFunction): Use vartok for location.
(BuildFloatFunction): Use vartok for location.
(BuildReFunction): Use vartok for location.
(BuildImFunction): Use vartok for location.
* gm2-compiler/M2SymInit.mod (trashParam): Remove commented code.
gcc/testsuite/ChangeLog:
* gm2/errors/fail/badabs.mod: New test.
* gm2/errors/fail/badenum.mod: New test.
Andrew Carlotti [Tue, 7 Mar 2023 14:37:00 +0000 (14:37 +0000)]
aarch64: Remove architecture dependencies from intrinsics
Many intrinsics currently depend on both an architecture version and a
feature, despite the corresponding instructions being available within
GCC at lower architecture versions.
LLVM has already removed these explicit architecture version
dependences; this patch does the same for GCC. Note that +fp16 does not
imply +simd, so we need to add an explicit +simd for the Neon fp16
intrinsics.
Binutils did not previously support all of these architecture+feature
combinations, but this problem is already reachable from GCC. For
example, compiling the test gcc.target/aarch64/usadv16qi-dotprod.c
with -O3 -march=armv8-a+dotprod has resulted in an assembler error since
GCC 10. This is fixed in Binutils 2.41.
This patch retains explicit architecture version dependencies for
features that do not currently have a separate feature flag.
* gcc.target/aarch64/feature-bf16-backport.c: New test.
* gcc.target/aarch64/feature-dotprod-backport.c: New test.
* gcc.target/aarch64/feature-fp16-backport.c: New test.
* gcc.target/aarch64/feature-fp16-scalar-backport.c: New test.
* gcc.target/aarch64/feature-fp16fml-backport.c: New test.
* gcc.target/aarch64/feature-i8mm-backport.c: New test.
* gcc.target/aarch64/feature-memtag-backport.c: New test.
* gcc.target/aarch64/feature-sha3-backport.c: New test.
* gcc.target/aarch64/feature-sm4-backport.c: New test.
Andrew Pinski [Fri, 14 Jul 2023 22:55:34 +0000 (15:55 -0700)]
[PATCH] Fix tree-opt/110252: wrong code due to phiopt using flow sensitive info during match
Match will query ranger via tree_nonzero_bits/get_nonzero_bits for 2 and 3rd
operand of the COND_EXPR and phiopt tries to do create the COND_EXPR even if we moving
one statement. That one statement could have some flow sensitive information on it
based on the condition that is for the COND_EXPR but that might create wrong code
if the statement was moved out.
This is similar to the previous version of the patch except now we use
flow_sensitive_info_storage instead of manually doing the save/restore
and also handle all defs on a gimple statement rather than just for lhs
of the gimple statement. Oh and a few more testcases were added that
was failing before.
OK? Bootsrapped and tested on x86_64-linux-gnu with no regressions.
PR tree-optimization/110252
gcc/ChangeLog:
* tree-ssa-phiopt.cc (class auto_flow_sensitive): New class.
(auto_flow_sensitive::auto_flow_sensitive): New constructor.
(auto_flow_sensitive::~auto_flow_sensitive): New deconstructor.
(match_simplify_replacement): Temporarily
remove the flow sensitive info on the two statements that might
be moved.
gcc/testsuite/ChangeLog:
* gcc.dg/tree-ssa/phi-opt-25b.c: Updated as
__builtin_parity loses the nonzerobits info.
* gcc.c-torture/execute/pr110252-1.c: New test.
* gcc.c-torture/execute/pr110252-2.c: New test.
* gcc.c-torture/execute/pr110252-3.c: New test.
* gcc.c-torture/execute/pr110252-4.c: New test.
Andrew Pinski [Fri, 14 Jul 2023 22:14:59 +0000 (15:14 -0700)]
Add flow_sensitive_info_storage and use it in gimple-fold.
This adds flow_sensitive_info_storage and uses it in
maybe_fold_comparisons_from_match_pd as mentioned in
https://gcc.gnu.org/pipermail/gcc-patches/2023-June/621817.html .
Since using it in maybe_fold_comparisons_from_match_pd was easy
and allowed me to test the storage earlier, I did it.
This also hides better how the flow sensitive information is
stored and only a single place needs to be updated if that
ever changes (again).
OK? Bootstrapped and tested on x86_64-linux-gnu with no regressions.
gcc/ChangeLog:
* gimple-fold.cc (fosa_unwind): Replace `vrange_storage *`
with flow_sensitive_info_storage.
(follow_outer_ssa_edges): Update how to save off the flow
sensitive info.
(maybe_fold_comparisons_from_match_pd): Update restoring
of flow sensitive info.
* tree-ssanames.cc (flow_sensitive_info_storage::save): New method.
(flow_sensitive_info_storage::restore): New method.
(flow_sensitive_info_storage::save_and_clear): New method.
(flow_sensitive_info_storage::clear_storage): New method.
* tree-ssanames.h (class flow_sensitive_info_storage): New class.
Andrew Pinski [Tue, 18 Jul 2023 21:11:46 +0000 (21:11 +0000)]
Fix PR110726: a | (a == b) can sometimes produce wrong code
So I had missed/forgot that EQ_EXPR could have an non boolean
type for generic when I implemented r14-2556-g0407ae8a7732d9.
This patch adds check for one bit precision intergal type
which fixes the problem.
OK? Bootstrapped and tested on x86_64-linux-gnu with no regressions.
PR tree-optimization/110726
gcc/ChangeLog:
* match.pd ((a|b)&(a==b),a|(a==b),(a&b)|(a==b)):
Add checks to make sure the type was one bit precision
intergal type.
Jonathan Wakely [Wed, 19 Jul 2023 13:42:51 +0000 (14:42 +0100)]
libstdc++: Fix formatting of negative chrono::hh_mm_ss
When formatting with an empty chrono spec ("{}") two minus signs were
being added to hh_mm_ss values. This is because the __is_neg flag was
checked to add one explicitly, and then the ostream operator added
another one.
We should only check the __is_neg flag for durations, because those are
the only types which are modified to be non-negative before calling
_M_format. We don't change hh_mm_ss values to be negative, because that
would require performing arithmetic on the hh_mm_ss members to sum them,
and then again to construct a new hh_mm_ss object with the positive
value. Instead, we can just be careful about using the __is_neg flag
correctly.
To fix the bug, _M_format_to_ostream no longer checks the __is_neg flag
for non-durations, and _M_format doesn't set it for hh_mm_ss until after
the call to _M_format_to_ostream. We can also avoid setting it for types
that it doesn't apply to, by making the __print_sign lambda only inspect
it for duration and hh_mm_ss types.
libstdc++-v3/ChangeLog:
* include/bits/chrono_io.h (__formatter_chrono::_M_format):
Do not set __is_neg for hh_mm_ss before calling
_M_format_to_ostream. Change __print_sign lambda to only check
__is_neg for durations and hh_mm_ss types.
(__formatter_chrono::_M_format_to_ostream): Only check __is_neg
for duration types.
* testsuite/std/time/hh_mm_ss/io.cc: Check negative values.
VECT: Add mask_len_fold_left_plus for in-order floating-point reduction
Hi, Richard and Richi.
This patch adds mask_len_fold_left_plus pattern to support in-order floating-point
reduction for target support len loop control.
Consider this following case:
double
foo2 (double *__restrict a,
double init,
int *__restrict cond,
int n)
{
for (int i = 0; i < n; i++)
if (cond[i])
init += a[i];
return init;
}
Gaius Mulley [Wed, 19 Jul 2023 12:38:07 +0000 (13:38 +0100)]
[modula2] Variable analysis understands DISPOSE and NIL
This patch allows the uninitialized variable analysis to detect pointer
through NIL and incorrectly reusing a pointer after a call to DISPOSE.
gcc/m2/ChangeLog:
* gm2-compiler/M2Quads.mod (BuildRealFuncProcCall): Set the trash
parameter value to NIL if DEALLOCATE is detected.
* gm2-compiler/M2SymInit.mod (CheckDeferredRecordAccess): Pass
tok to SetVarInitialized. Pass tok to GetVarComponentInitialized.
(ComponentFindVar): Add tok parameter. Check aliased pointer
against Nil and generate warning if necessary.
(deRefComponent): Add tok and sym parameters and pass them to
getContent.
(SetVarComponentInitialized): Add tok parameter. Pass tok to
ComponentFindVar. Pass tok and sym to deRefComponent.
(GetVarComponentInitialized): Add tok parameter. Pass tok to
ComponentFindVar. Pass tok to deRefComponent.
(SetVarInitialized): Add tok parameter. Pass tok to
SetVarComponentInitialized.
(doGetVarInitialized): Add tok parameter. Pass tok to
GetVarComponentInitialized.
(CheckXIndr): Pass lhs and lhstok to getContent.
(CheckIndrX): Pass rhs and rhstok to getContent.
(CheckBecomes): Pass destok to ComponentFindVar. Pass des and
destok to deRefComponent.
(CheckAddr): Pass contenttok to GetVarInitialized. Pass ptrtok
to SetVarInitialized.
(CheckReadBeforeInitQuad): Pass op1tok to SetVarInitialized for
op1 cases and op3tok for op3 cases.
(trashParam): Get operand tokens. Pass op3tok to
SetVarInitialized. Pass op3 and op3tok to getContent.
Alias ptr to NIL if procedure is DEALLOCATE. Pass op3tok to
SetVarInitialized.
(IsDeallocate): New procedure function.
(DetectTrash): Use IsDeallocate.
(SetupLAlias): Allow exp to be Nil.
(getContent): Generate warning message if ptr is Nil.
gcc/testsuite/ChangeLog:
* gm2/switches/uninit-variable-checking/procedures/fail/testdispose.mod: New test.
* gm2/switches/uninit-variable-checking/procedures/fail/testdispose2.mod: New test.
* gm2/switches/uninit-variable-checking/procedures/fail/testnil.mod: New test.
Jakub Jelinek [Wed, 19 Jul 2023 11:48:53 +0000 (13:48 +0200)]
wide-int: Fix up wi::divmod_internal [PR110731]
As the following testcase shows, wi::divmod_internal doesn't handle
correctly signed division with precision > 64 when the dividend (and likely
divisor as well) is the type's minimum and the precision isn't divisible
by 64.
A few lines above what the patch hunk changes is:
/* Make the divisor and dividend positive and remember what we
did. */
if (sgn == SIGNED)
{
if (wi::neg_p (dividend))
{
neg_dividend = -dividend;
dividend = neg_dividend;
dividend_neg = true;
}
if (wi::neg_p (divisor))
{
neg_divisor = -divisor;
divisor = neg_divisor;
divisor_neg = true;
}
}
i.e. we negate negative dividend or divisor and remember those.
But, after we do that, when unpacking those values into b_dividend and
b_divisor we need to always treat the wide_ints as UNSIGNED,
because divmod_internal_2 performs an unsigned division only.
Now, if precision <= 64, we don't reach here at all, earlier code
handles it. If dividend or divisor aren't the most negative values,
the negation clears their most significant bit, so it doesn't really
matter if we unpack SIGNED or UNSIGNED. And if precision is multiple
of HOST_BITS_PER_WIDE_INT, there is no difference in behavior, while
-0x80000000000000000000000000000000 negates to
-0x80000000000000000000000000000000 the unpacking of it as SIGNED
or UNSIGNED works the same.
In the testcase, we have signed precision 119 and the dividend is
val = { 0, 0xffc0000000000000 }, len = 2, precision = 119
both before and after negation.
Divisor is
val = { 2 }, len = 1, precision = 119
But we really want to divide 0x400000000000000000000000000000 by 2
unsigned and then negate at the end.
If it is unsigned precision 119 division
0x400000000000000000000000000000 by 2
dividend is
val = { 0, 0xffc0000000000000 }, len = 2, precision = 119
but as we unpack it UNSIGNED, it is unpacked into
0, 0, 0, 0x00400000
The following patch fixes it by always using UNSIGNED unpacking
because we've already negated negative values at that point if
sgn == SIGNED and so most negative constants should be treated as
positive.
2023-07-19 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/110731
* wide-int.cc (wi::divmod_internal): Always unpack dividend and
divisor as UNSIGNED regardless of sgn.
Jonathan Wakely [Tue, 18 Jul 2023 21:14:32 +0000 (22:14 +0100)]
libstdc++: Avoid warning in std::format
With -Wmaybe-uninitialized -Wsystem-headers there's a warning about
creating a string_view from an uninitalized array. Initializing the
first element of the array avoids the warning.
libstdc++-v3/ChangeLog:
* include/std/format (__write_padded): Initialize first element
of array to avoid a -Wmaybe-uninitialized warning.
This fixes some TODOs in the C++20 <chrono> format support, where the
locale-specific output was incorrect or unimplemented. The approach
taken here is to either use the formatting locale's std::time_put facet
to do the formatting, or to remove subsecond precision from time points
so that locale-specific formats don't print fractional seconds. This
ensures that we are consistent with what the std::time_put facet would
print (which never includes fractional seconds) even if we actually
reimplement the formatting by hand instead of using the facet.
This also fixes a misplaced statement that allowed modifiers for %Z
which should have been on %z instead. There was also some ill-formed
code in an untested branch for formatting time zone names to wide
characters. A new test for zoned_time I/O has been added to exercise
that code properly.
libstdc++-v3/ChangeLog:
PR libstdc++/110719
* include/bits/chrono_io.h (__formatter_chrono::_M_parse): Fix
allowed modifiers for %z and %Z. Fix -Wparentheses and
-Wnarrowing warnings.
(__formatter_chrono::_M_format): Call new functions for %d, %e,
%H, %I, %m and %M.
(__formatter_chrono::_M_c): Use _S_floor_seconds to remove
subsecond precision.
(__formatter_chrono::_M_C_y_Y): Use _M_locale_fmt to handle
modifiers.
(__formatter_chrono::_M_e): Replace with _M_d_e and use
_M_locale_fmt.
(__formatter_chrono::_M_I): Replace with _M_H_I and use
_M_locale_fmt.
(__formatter_chrono::_M_m): New function.
(__formatter_chrono::_M_M): New function.
(__formatter_chrono::_M_r): Use _M_locale_fmt.
(__formatter_chrono::_M_S): Likewise.
(__formatter_chrono::_M_u_w): Likewise.
(__formatter_chrono::_M_U_V_W): Likewise.
(__formatter_chrono::_M_X): Use _S_floor_seconds.
(__formatter_chrono::_M_Z): Fix untested branch for wchar_t.
(__formatter_chrono::_S_altnum): Remove function.
(__formatter_chrono::_S_dd_zero_fill): Remove function.
(__formatter_chrono::_S_floor_seconds): New function.
(__formatter_chrono::_M_locale_fmt): New function.
* testsuite/std/time/clock/system/io.cc: Adjust expected output
for locale-specific formats and check modified formats.
* testsuite/std/time/clock/utc/io.cc: Likewise.
* testsuite/std/time/zoned_time/io.cc: New test.
Jonathan Wakely [Tue, 18 Jul 2023 09:36:37 +0000 (10:36 +0100)]
libstdc++: Check for multiple modifiers in chrono format string [PR110708]
The logic for handling modified chrono specs like %Ey was just
restarting the loop after each modifier, and not checking whether we'd
already seen a modifier.
libstdc++-v3/ChangeLog:
PR libstdc++/110708
* include/bits/chrono_io.h (__formatter_chrono::_M_parse): Only
allow a single modifier.
* testsuite/std/time/format.cc: Check multiple modifiers.
Jonathan Wakely [Sat, 15 Jul 2023 19:58:22 +0000 (20:58 +0100)]
libstdc++: Enable tests for std::stoi etc. unconditionally [PR110653]
Since the narrow string versions of std::stoi, std::stol, std::stoul,
std::stof and std::stod are now always defined, we don't need to check
dg-require-string-conversions in the relevant tests.
Jonathan Wakely [Thu, 13 Jul 2023 09:44:57 +0000 (10:44 +0100)]
libstdc++: Check autoconf macros for strtof and strtold [PR110653]
As well as the _GLIBCXX_USE_C99_STDLIB check, we also have a separate
check in linkage.m4 for just strtof and strtold. We can use that to
declare std::strtof and std::strtold in <cstdlib> for additional
targets. That allows us to enable std::stold on hpux11.11 which is
missing strtoll, strtoull and strtof, so doesn't define
_GLIBCXX_USE_C99_STDLIB. Although it doesn't help hpux11.11, we can
define std::stof for more targets this way too.
As with the previous commit for PR110653, this only affects the narrow
character overloads. std::stof and std::stold for wstring still requires
C99 <wchar.h> support.
OpenMP/Fortran: Non-rectangular loops with constant steps other than 1 or -1 [PR107424]
Before this commit, gfortran produced with OpenMP for 'do i = 1,10,2'
the code
for (count.0 = 0; count.0 < 5; count.0 = count.0 + 1)
i = count.0 * 2 + 1;
While such an inner loop can be collapsed, a non-rectangular could not.
With this commit and for all constant loop steps, a simple loop such
as 'for (i = 1; i <= 10; i = i + 2)' is created. (Before only for the
constant steps of 1 and -1.)
The constant step permits to know the direction (increasing/decreasing)
that is required for the loop condition.
The new code is only valid if one assumes no overflow of the loop variable.
However, the Fortran standard can be read that this must be ensured by
the user. Namely, the Fortran standard requires (F2023, 10.1.5.2.4):
"The execution of any numeric operation whose result is not defined by
the arithmetic used by the processor is prohibited."
And, for DO loops, F2023's "11.1.7.4.3 The execution cycle" has the
following: The number of loop iterations handled by an iteration count,
which would permit code like 'do i = huge(i)-5, huge(i),4'. However,
in step (3), this count is not only decremented by one but also:
"... The DO variable, if any, is incremented by the value of the
incrementation parameter m3."
And for the example above, 'i' would be 'huge(i)+3' in the last
execution cycle, which exceeds the largest model number and should
render the example as invalid.
PR fortran/107424
gcc/fortran/ChangeLog:
* trans-openmp.cc (gfc_nonrect_loop_expr): Accept all
constant loop steps.
(gfc_trans_omp_do): Likewise; use sign to determine
loop direction.
libgomp/ChangeLog:
* libgomp.texi (Impl. Status 5.0): Add link to new PR110735.
* testsuite/libgomp.fortran/non-rectangular-loop-1.f90: Enable
commented tests.
* testsuite/libgomp.fortran/non-rectangular-loop-1a.f90: Remove
test file; tests are in non-rectangular-loop-1.f90.
* testsuite/libgomp.fortran/non-rectangular-loop-5.f90: Change
testcase to use a non-constant step to retain the 'sorry' test.
* testsuite/libgomp.fortran/non-rectangular-loop-6.f90: New test.
gcc/testsuite/ChangeLog:
* gfortran.dg/gomp/linear-2.f90: Update dump to remove
the additional count variable.
RISC-V: Throw compilation error for unknown extensions
This tiny patch add a check for extension starts with 'z' or 's' in `-march`
option. Currently this unknown extension will be passed to the assembler, which
then reports an error. With this patch, the compiler will throw a compilation
error if the extension starts with 'z' or 's' is not a standard sub-extension or
supervisor extension. Along with two extra changes. The first is to reduce
repeated errors, which are currently reported at least twice. The second is to
report as many mistakes as possible.
e.g.:
Run `riscv64-unknown-elf-gcc -march=rv64gvcw_zvl128_s123_x123 -mabi=lp64d a.c`
will throw these error:
riscv64-unknown-elf-gcc: error: '-march=rv64gcv_zvl128_s123': ISA string is not in canonical order. 'c'
riscv64-unknown-elf-gcc: error: '-march=rv64gcv_zvl128_s123': extension 'w' is unsupported standard single letter extension
riscv64-unknown-elf-gcc: error: '-march=rv64gcv_zvl128_s123': extension 'zvl128' start with `z` but is unsupported standard extension
riscv64-unknown-elf-gcc: error: '-march=rv64gcv_zvl128_s123': extension 's123' start with `s` but is unsupported standard supervisor extension
riscv64-unknown-elf-gcc: error: '-march=rv64gcv_zvl128_s123': extension 'x123' start with `x` but is unsupported non-standard extension
gcc/ChangeLog:
* common/config/riscv/riscv-common.cc (riscv_supported_std_ext): Init.
(standard_extensions_p): Add check.
(riscv_subset_list::add): Just return NULL if it failed before.
(riscv_subset_list::parse_std_ext): Continue parse when find a error
(riscv_subset_list::parse): Just return NULL if it failed before.
* config/riscv/riscv-subset.h (class riscv_subset_list): Add field.
Jan Beulich [Wed, 19 Jul 2023 08:11:49 +0000 (10:11 +0200)]
x86: avoid maybe_gen_...()
In the (however unlikely) event that no insn can be found for the
requested mode, using maybe_gen_...() without (really) checking its
result for being a null rtx would lead to silent bad code generation.
gcc/
* config/i386/i386-expand.cc (ix86_expand_vector_init_duplicate):
Use gen_vec_set_0.
(ix86_expand_vector_extract): Use gen_vec_extract_lo /
gen_vec_extract_hi.
(expand_vec_perm_broadcast_1): Use gen_vec_interleave_high /
gen_vec_interleave_low. Rename local variable.
Jan Beulich [Wed, 19 Jul 2023 08:11:11 +0000 (10:11 +0200)]
x86: slightly enhance "vec_dupv2df<mask_name>"
Introduce a new alternative permitting all 32 registers to be used as
source without AVX512VL, by broadcasting to the full 512 bits in that
case. (The insn would also permit all registers to be used as
destination, but V2DFmode doesn't.)
gcc/
* config/i386/sse.md (vec_dupv2df<mask_name>): Add new AVX512F
alternative. Move AVX512VL part of condition to new "enabled"
attribute.
RISC-V: Fix testcase failed when default -mcmodel=medany
This patch fix testcase failed when I build RISC-V GCC with -mcmodel=medany
as default. If set to medany, stack_save_restore.c testcase will fail because of
the reduced use of s3 registers in assembly (thus calling __riscv_save/store_3
instead of __riscv_save/store_4). So relax assert from
`__riscv_save/restore_4` to `__riscv_save/restore_(3|4)` to let this
testcase not brittle on any -mcmodel and add another testcase that use
-march=rv64imafc.
gcc/testsuite/ChangeLog:
* gcc.target/riscv/stack_save_restore.c: Moved to...
* gcc.target/riscv/stack_save_restore_2.c: ...here.
* gcc.target/riscv/stack_save_restore_1.c: New test.
Lewis Hyatt [Tue, 18 Jul 2023 21:16:08 +0000 (17:16 -0400)]
libcpp: Handle extended characters in user-defined literal suffix [PR103902]
The PR complains that we do not handle UTF-8 in the suffix for a user-defined
literal, such as:
bool operator ""_π (unsigned long long);
In fact we don't handle any extended identifier characters there, whether
UTF-8, UCNs, or the $ sign. We do handle it fine if the optional space after
the "" tokens is included, since then the identifier is lexed in the
"normal" way as its own token. But when it is lexed as part of the string
token, this is handled in lex_string() with a one-off loop that is not aware
of extended characters.
This patch fixes it by adding a new function scan_cur_identifier() that can
be used to lex an identifier while in the middle of lexing another token.
BTW, the other place that has been mis-lexing identifiers is
lex_identifier_intern(), which is used to implement #pragma push_macro
and #pragma pop_macro. This does not support extended characters either.
I will add that in a subsequent patch, because it can't directly reuse the
new function, but rather needs to lex from a string instead of a cpp_buffer.
With scan_cur_identifier(), we do also correctly warn about bidi and
normalization issues in the extended identifiers comprising the suffix.
libcpp/ChangeLog:
PR preprocessor/103902
* lex.cc (identifier_diagnostics_on_lex): New function refactoring
some common code.
(lex_identifier_intern): Use the new function.
(lex_identifier): Don't run identifier diagnostics here, rather let
the call site do it when needed.
(_cpp_lex_direct): Adjust the call sites of lex_identifier ()
acccordingly.
(struct scan_id_result): New struct.
(scan_cur_identifier): New function.
(create_literal2): New function.
(lit_accum::create_literal2): New function.
(is_macro): Folded into new function...
(maybe_ignore_udl_macro_suffix): ...here.
(is_macro_not_literal_suffix): Folded likewise.
(lex_raw_string): Handle UTF-8 in UDL suffix via
scan_cur_identifier ().
(lex_string): Likewise.
gcc/testsuite/ChangeLog:
PR preprocessor/103902
* g++.dg/cpp0x/udlit-extended-id-1.C: New test.
* g++.dg/cpp0x/udlit-extended-id-2.C: New test.
* g++.dg/cpp0x/udlit-extended-id-3.C: New test.
* g++.dg/cpp0x/udlit-extended-id-4.C: New test.
Enable _Float16 and __bf16 all the time but issue errors when the
types are used in conversion, unary operation, binary operation,
parameter passing or value return when TARGET_SSE2 is not available.
Also undef macros which are used by libgcc/libstdc++ to check the
backend support of the _Float16/__bf16 types when TARGET_SSE2 is not
available.
gcc/ChangeLog:
PR target/109504
* config/i386/i386-builtins.cc
(ix86_register_float16_builtin_type): Remove TARGET_SSE2.
(ix86_register_bf16_builtin_type): Ditto.
* config/i386/i386-c.cc (ix86_target_macros): When TARGET_SSE2
isn't available, undef the macros which are used to check the
backend support of the _Float16/__bf16 types when building
libstdc++ and libgcc.
* config/i386/i386.cc (construct_container): Issue errors for
HFmode/BFmode when TARGET_SSE2 is not available.
(function_value_32): Ditto.
(ix86_scalar_mode_supported_p): Remove TARGET_SSE2 for HFmode/BFmode.
(ix86_libgcc_floating_mode_supported_p): Ditto.
(ix86_emit_support_tinfos): Adjust codes.
(ix86_invalid_conversion): Return diagnostic message string
when there's conversion from/to BF/HFmode w/o TARGET_SSE2.
(ix86_invalid_unary_op): New function.
(ix86_invalid_binary_op): Ditto.
(TARGET_INVALID_UNARY_OP): Define.
(TARGET_INVALID_BINARY_OP): Define.
* config/i386/immintrin.h [__SSE2__]: Remove for fp16/bf16
related instrinsics header files.
* config/i386/i386.h (VALID_SSE2_TYPE_MODE): New macro.
gcc/testsuite/ChangeLog:
* gcc.target/i386/pr109504.c: New test.
* gcc.target/i386/sse2-bfloat16-1.c: Adjust error info.
* gcc.target/i386/sse2-float16-1.c: Ditto.
* gcc.target/i386/sse2-float16-4.c: New test.
* gcc.target/i386/sse2-float16-5.c: New test.
* g++.target/i386/float16-1.C: Adjust error info.
libgcc/ChangeLog:
* config/i386/t-softfp: Add -msse2 to libbid HFtype related
files.
Marek Polacek [Tue, 18 Jul 2023 17:26:39 +0000 (13:26 -0400)]
c++: Add tests for P2621, no UB in lexer [PR110340]
C++26 P2621 removes UB in the lexer and either makes the construct valid
or ill-formed. We're already handling this correctly so this patch only
adds tests.
PR c++/110340
gcc/testsuite/ChangeLog:
* g++.dg/cpp/string-4.C: New test.
* g++.dg/cpp/ucn-2.C: New test.
Marek Polacek [Wed, 5 Jul 2023 21:43:31 +0000 (17:43 -0400)]
testsuite: fix dwarf2/utf-1.C with DWARF4
Running
$ make check-c++ RUNTESTFLAGS='--target_board=unix\{-gdwarf-5,-gdwarf-4\} dwarf2.exp=utf-1.C'
shows
FAIL: g++.dg/debug/dwarf2/utf-1.C -std=gnu++20 scan-assembler-times DW_AT_encoding \\(0x10\\) 3
because with -gdwarf-4 the output is:
.byte 0x10 # DW_AT_encoding
but with -gdwarf-5 the output is the expected:
# DW_AT_encoding (0x10)
The difference is caused by the DWARF5 optimize_implicit_const
optimization:
<https://gcc.gnu.org/pipermail/gcc-patches/2016-October/459762.html>
I suppose we could do what testsuite/rust/debug/chartype.rs does
and just run the test with -gdwarf-4.
gcc/testsuite/ChangeLog:
* g++.dg/debug/dwarf2/utf-1.C: Use -gdwarf-4. Adjust expected
output.
dwarf2: Change return type of predicate functions from int to bool
Also change some internal variables and function arguments from int to bool.
gcc/ChangeLog:
* dwarf2asm.cc: Change FALSE to false.
* dwarf2cfi.cc (execute_dwarf2_frame): Change return type to void.
* dwarf2out.cc (matches_main_base): Change return type from
int to bool. Change "last_match" variable to bool.
(dump_struct_debug): Change return type from int to bool.
Change "matches" and "result" function arguments to bool.
(is_pseudo_reg): Change return type from int to bool.
(is_tagged_type): Ditto.
(same_loc_p): Ditto.
(same_dw_val_p): Change return type from int to bool and adjust
function body accordingly.
(same_attr_p): Ditto.
(same_die_p): Ditto.
(is_type_die): Ditto.
(is_declaration_die): Ditto.
(should_move_die_to_comdat): Ditto.
(is_base_type): Ditto.
(is_based_loc): Ditto.
(local_scope_p): Ditto.
(class_scope_p): Ditto.
(class_or_namespace_scope_p): Ditto.
(is_tagged_type): Ditto.
(is_rust): Use void argument.
(is_nested_in_subprogram): Change return type from int to bool.
(contains_subprogram_definition): Ditto.
(gen_struct_or_union_type_die): Change "nested", "complete"
and "ns_decl" variables to bool.
(is_naming_typedef_decl): Change FALSE to false.
Jan Hubicka [Tue, 18 Jul 2023 15:47:50 +0000 (17:47 +0200)]
tree-ssa-loop-ch improvements, part 3
Extend range query done by loop-ch to also support basic blocks
that are not headers of the loop. This is easy to do, since we already
do path specific query so we only need to extend the path by headers we decided
to dulicate earlier.
This makes it possible to track situations where exit that is always false in
the first iteration (wihch is a common case) is not in the first iteration of
the loop. Doing so lets us to update profile better and do better heuristics.
In particular I changed logic as follows
1) should_duplicate_loop_header_p counts size of duplicated region. When we
know that a given conditional will be constant true or constant false either
in the duplicated region, by range query, or in the loop body after
duplication (since it is loop invariant), we do not account it to code size
costs
2) don't need account loop invariant compuations that will be duplicated
as they will become fully invariant
(maybe we want to have some cap for register pressure eventually?)
3) optimize_size logic is now different. Originally we started duplicating
iff the first conditional was known to be true by ranger query, but then
we used same limits as for -O2.
I now simply lower limits to 0. This means that every conditional
in duplicated sequence must be either loop invariant or constant when
duplicated and we only duplicate statements computing loop invariants
and those we account to 0 size anyway,
This makes code IMO more logical, but makes little difference in practice.
The problem is that in loop:
void test2();
void test(int n)
{
for (int i = 0; n && i < 10; i++)
test2();
}
and do not understand that the final conditional is a combination of a conditional
that is always true in first iteration and a conditional that is loop invariant.
This is also the case of
void test2();
void test(int n)
{
for (int i = 0; n; i++)
{
if (i > 10)
break;
test2();
}
}
Which we turn to the earlier case in ifcombine.
With disabled ifcombine things however works as exepcted. This is something
I plan to handle incrementally. However extending loop-ch and peeling passes
to understand such combined conditionals is still not good enough: at the time ifcombine
merged the two conditionals we lost profile information on how often n is 0,
so we can't recover correct profile or know what is expected number of iterations
after the transofrm.
gcc/ChangeLog:
* tree-ssa-loop-ch.cc (edge_range_query): Take loop argument; be ready
for queries not in headers.
(static_loop_exit): Add basic blck parameter; update use of
edge_range_query
(should_duplicate_loop_header_p): Add ranger and static_exits
parameter. Do not account statements that will be optimized
out after duplicaiton in overall size. Add ranger query to
find static exits.
(update_profile_after_ch): Take static_exits has set instead of
single eliminated_edge.
(ch_base::copy_headers): Do all analysis in the first pass;
remember invariant_exits and static_exits.
Jason Merrill [Fri, 14 Jul 2023 16:25:51 +0000 (12:25 -0400)]
c++: constexpr bit_cast with empty field
The change to only cache constexpr calls that are
reduced_constant_expression_p tripped on bit-cast3.C, which failed that
predicate due to the presence of an empty field in the result of
native_interpret_aggregate, which reduced_constant_expression_p rejects to
avoid confusing output_constructor.
This patch proposes to skip such fields in native_interpret_aggregate, since
they aren't actually involved in the value representation.
This patch fixes many limitations of the uninitialized static analysis.
NEW is understood, local variable pointers and non var parameters
will be tracked.
gcc/ChangeLog:
* doc/gm2.texi (Semantic checking): Change example testwithptr
to testnew6.
gcc/m2/ChangeLog:
* Make-lang.in: Minor formatting change.
* gm2-compiler/M2GCCDeclare.mod
(DeclareUnboundedProcedureParameters): Rename local variables.
(WalkUnboundedProcedureParameters): Rename local variables.
(DoVariableDeclaration): Avoid declaration of a variable if
it is on the heap (used by static analysis only).
* gm2-compiler/M2GenGCC.mod: Formatting.
* gm2-compiler/M2Quads.def (GetQuadTrash): New procedure function.
* gm2-compiler/M2Quads.mod (GetQuadTrash): New procedure function.
(QuadFrame): Add Trash field.
(BuildRealFuncProcCall): Detect ALLOCATE and DEALLOCATE and create
a heap variable for parameter 1 saving it as the trashed variable
for static analysis.
(GenQuadOTrash): New procedure.
(DisplayQuadRange): Bugfix. Write the scope number.
* gm2-compiler/M2SymInit.mod: Rewritten to separate LValue
equivalence from LValue to RValue pairings. Comprehensive
detection of variant record implemented. Allow dereferencing
of pointers through LValue/RValue chains.
* gm2-compiler/SymbolTable.def (PutVarHeap): New procedure.
(IsVarHeap): New procedure function.
(ForeachParamSymDo): New procedure.
* gm2-compiler/SymbolTable.mod (PutVarHeap): New procedure.
(IsVarHeap): New procedure function.
(ForeachParamSymDo): New procedure.
(MakeVariableForParam): Reformatted.
(CheckForUnknownInModule): Reformatted.
(SymVar): Add field Heap.
(MakeVar): Assign Heap to FALSE.
gcc/testsuite/ChangeLog:
* gm2/switches/uninit-variable-checking/pass/assignparam.mod: New test.
* gm2/switches/uninit-variable-checking/pass/tiny.mod: New test.
* gm2/switches/uninit-variable-checking/procedures/fail/switches-uninit-variable-checking-procedures-fail.exp:
New test.
* gm2/switches/uninit-variable-checking/procedures/fail/testnew.mod: New test.
* gm2/switches/uninit-variable-checking/procedures/fail/testnew2.mod: New test.
* gm2/switches/uninit-variable-checking/procedures/fail/testnew3.mod: New test.
* gm2/switches/uninit-variable-checking/procedures/fail/testnew4.mod: New test.
* gm2/switches/uninit-variable-checking/procedures/fail/testnew5.mod: New test.
* gm2/switches/uninit-variable-checking/procedures/fail/testnew6.mod: New test.
* gm2/switches/uninit-variable-checking/procedures/fail/testptrptr.mod: New test.
* gm2/switches/uninit-variable-checking/procedures/pass/assignparam2.mod: New test.
* gm2/switches/uninit-variable-checking/procedures/pass/switches-uninit-variable-checking-procedures-pass.exp:
New test.
* gm2/switches/uninit-variable-checking/procedures/pass/testnew5.mod: New test.
* gm2/switches/uninit-variable-checking/procedures/pass/testnew6.mod: New test.
* gm2/switches/uninit-variable-checking/procedures/pass/testparamlvalue.mod: New test.
* gm2/switches/uninit-variable-checking/procedures/pass/testparamrvalue.mod: New test.
* gm2/switches/uninit-variable-checking/procedures/pass/testproc.mod: New test.
* gm2/switches/uninit-variable-checking/procedures/pass/testptrptr.mod: New test.
Richard Biener [Tue, 18 Jul 2023 08:02:52 +0000 (10:02 +0200)]
middle-end/105715 - missed RTL if-conversion with COND_EXPR expansion
When the COND_EXPR condition operand was split out to a separate stmt
it became subject to CSE with other condition evaluations. This
unfortunately leads to TER no longer applying and in turn RTL
expansion of COND_EXPRs no longer seeing the condition and thus
failing to try conditional move expansion. This can be seen with
gcc.target/i386/pr45685.c when built with -march=cascadelake which
then FAILs to produce the expected number of cmovs.
It can also be seen when we create more COND_EXPRs early like for
instruction selection of MIN/MAX operations that map to IEEE
a > b ? a : b expression semantics.
Patrick Palka [Tue, 18 Jul 2023 13:22:49 +0000 (09:22 -0400)]
c++: non-standalone surrogate call template
I noticed we're accidentally prevented from considering a pointer- or
reference-to-function conversion function template if it's not the first
conversion function that's considered, which for the testcase below
results in us accepting the B call but not the A call despite the only
difference between A and B being their order of member declarations.
This patch fixes this so that the outcome of overload resolution doesn't
arbitrarily depend on declaration order here.
gcc/cp/ChangeLog:
* call.cc (add_template_conv_candidate): Don't check for
non-empty 'candidates' here.
(build_op_call): Check it here, before we've considered any
conversion functions.
We weren't checking constraints on pointer/reference-to-function conversion
functions during overload resolution, which caused us to ICE on the first
testcase and reject the second testcase.
Tom Tromey [Thu, 29 Jun 2023 15:56:59 +0000 (09:56 -0600)]
ada: Use new typedefs in gcc-interface
This changes gcc-interface to use the typedefs that were recently
introduced in gnat. This is another step toward switching the code
generator to emit enums rather than preprocessor defines.
In a couple of spots, a 'default' case is also added. These avoid
warnings from -Wswitch when the typedefs are changed to be enums.
gcc/ada/
* gcc-interface/decl.cc (check_ok_for_atomic_type): Use Pragma_Id.
* gcc-interface/trans.cc (lvalue_required_p, Pragma_to_gnu): Use
Pragma_Id.
(get_type_length, Attribute_to_gnu, get_atomic_access): Use
Attribute_Id.
Javier Miranda [Sun, 9 Jul 2023 10:58:05 +0000 (10:58 +0000)]
ada: Constraint_Error caused by 'Image applied to interface type
When the prefix of 'Image is used with a class-wide interface
type object, the frontend does not generate code to displace
the pointer to the underlying object to reference its base,
and this is required to invoke Ada.Tags.Wide_Wide_Expanded_Name.
gcc/ada/
* exp_imgv.adb (Rewrite_Object_Image): fix type of formal. Found
reading sources.
(Expand_Wide_Image_Attribute): ditto.
(Expand_Wide_Wide_Image_Attribute): ditto.
(Rewrite_Object_Image): ditto.
* exp_put_image.adb (Build_Image_Call): For class-wide interface
type prefix generate code to displace the pointer to the object to
reference the base of the underlying object.
ada: Avoid iterator conflicts in container aggregates
Create temporary scope for the iterators defined in a
container aggregate so that it would not be put to the
same scope where the expression was used. This would
otherwise lead to multiple aggregates with iterators that have
the same name leading to a name conflict.
gcc/ada/
* sem_aggr.adb (Resolve_Iterated_Association): Add temporary scope
when analyzing the Iterator Specification. Use preanalysis instead
of Analysis to avoid polluting the tree.