As mentioned in [1], there is one pre-existing issue before
the refactoring of FOR_EACH_LOOP_FN. The macro will always
set the given LOOP as NULL at the end of iterating unless
there is some early break inside, obviously there is no
early break and dloop will be set as NULL after the loop
iterating. It's kept as NULL after the factoring.
I tried to debug the test case gcc.dg/graphite/pr83359.c
with commit 555758de90074 (also reproduced the ICE with
555758de90074~), and noticed the compilation of the test
case only covers the hunk:
else
{
moved_orig_loop_num[dloop->orig_loop_num] = -1;
dloop->orig_loop_num = 0;
}
it doesn't touch the if condition hunk to increase
"moved_orig_loop_num[dloop->orig_loop_num]". So the
following hunk guarded with
if (moved_orig_loop_num[orig_loop_num] == 2)
using dloop for dereference doesn't get executed. It
explains why the problem doesn't get exposed before.
By looking to the code using dloop, I think it's a copy
paste typo, the modified assertion codes have the same
words as the above condition check. In that context, the
expected original number has been assigned to variable
orig_loop_num by extracting from the arg0 of the call
IFN_LOOP_DIST_ALIAS.
[1] https://gcc.gnu.org/pipermail/gcc-patches/2021-July/576367.html
gcc/ChangeLog:
* tree-cfg.c (move_sese_region_to_fn): Fix typos on dloop.
In passing, this also renames the template parameter _O2 to _Out2 in
ranges::partition_copy and uglifies two of its function parameters,
out_true and out_false.
PR libstdc++/101599
libstdc++-v3/ChangeLog:
* include/bits/ranges_algo.h (__reverse_copy_fn::operator()):
Add missing std::move in return statement.
(__partition_copy_fn::operator()): Rename templtae parameter
_O2 to _Out2. Uglify function parameters out_true and out_false.
* include/bits/ranges_algobase.h (__copy_or_move): Add missing
std::move to recursive call that unwraps a __normal_iterator
output iterator.
* testsuite/25_algorithms/copy/constrained.cc (test06): New test.
* testsuite/25_algorithms/move/constrained.cc (test05): New test.
In r12-569 I accidentally applied the LWG 3533 change to
elements_view::iterator::base instead to elements_view::base.
This patch corrects this, and also applies the corresponding LWG 3533
change to lazy_split_view::inner-iter::base now that we implement P2210.
PR libstdc++/101589
libstdc++-v3/ChangeLog:
* include/std/ranges (lazy_split_view::_InnerIter::base): Make
the const& overload unconstrained and return a const reference
as per LWG 3533. Make unconditionally noexcept.
(elements_view::base): Revert accidental r12-569 change.
(elements_view::_Iterator::base): Make the const& overload
unconstrained and return a const reference as per LWG 3533.
Make unconditionally noexcept.
Also pass -mno-sse to vect8-ret.c to disable XMM load/store when running
GCC tests with "-march=x86-64 -m32".
* gcc.target/i386/vect8-ret.c: Also pass -mno-sse.
Also pass -mno-avx to sw-1.c for ia32 since copying data with YMM or ZMM
registers disables shrink-wrapping when the second argument is passed on
stack.
* gcc.target/i386/sw-1.c: Also pass -mno-avx for ia32.
We can use TImode/OImode/XImode integers for piecewise move and store.
1. Define MAX_MOVE_MAX to 64, which is the constant maximum number of
bytes that a single instruction can move quickly between memory and
registers or between two memory locations.
2. Define MOVE_MAX to the maximum number of bytes we can move from memory
to memory in one reasonably fast instruction. The difference between
MAX_MOVE_MAX and MOVE_MAX is that MAX_MOVE_MAX must be a constant,
independent of compiler options, since it is used in reload.h to define
struct target_reload and MOVE_MAX can vary, depending on compiler options.
3. When vector register is used for piecewise move and store, we don't
increase stack_alignment_needed since vector register spill isn't
required for piecewise move and store. Since stack_realign_needed is
set to true by checking stack_alignment_estimated set by pseudo vector
register usage, we also need to check stack_realign_needed to eliminate
frame pointer.
gcc/
* config/i386/i386.c (ix86_finalize_stack_frame_flags): Also
check stack_realign_needed for stack realignment.
(ix86_legitimate_constant_p): Always allow CONST_WIDE_INT smaller
than the largest integer supported by vector register.
* config/i386/i386.h (MAX_MOVE_MAX): New. Set to 64.
(MOVE_MAX): Set to bytes of the largest integer supported by
vector register.
(STORE_MAX_PIECES): New.
gcc/testsuite/
* gcc.target/i386/pr90773-1.c: Adjust to expect movq for 32-bit.
* gcc.target/i386/pr90773-4.c: Also run for 32-bit.
* gcc.target/i386/pr90773-15.c: Likewise.
* gcc.target/i386/pr90773-16.c: Likewise.
* gcc.target/i386/pr90773-17.c: Likewise.
* gcc.target/i386/pr90773-24.c: Likewise.
* gcc.target/i386/pr90773-25.c: Likewise.
* gcc.target/i386/pr100865-1.c: Likewise.
* gcc.target/i386/pr100865-2.c: Likewise.
* gcc.target/i386/pr100865-3.c: Likewise.
* gcc.target/i386/pr90773-14.c: Also run for 32-bit and expect
XMM movd to store 4 bytes.
* gcc.target/i386/pr100865-4a.c: Also run for 32-bit and expect
YMM registers.
* gcc.target/i386/pr100865-4b.c: Likewise.
* gcc.target/i386/pr100865-10a.c: Expect YMM registers.
* gcc.target/i386/pr100865-10b.c: Likewise.
To avoid stack realignment, use SCRATCH_SSE_REG to copy data from one
memory location to another.
gcc/
* config/i386/i386-expand.c (ix86_expand_vector_move): Call
ix86_gen_scratch_sse_rtx to get a scratch SSE register to copy
data from one memory location to another.
gcc/testsuite/
* gcc.target/i386/eh_return-1.c: New test.
When the comparison with a nullptr_t is ill-formed, there is an
additional error for C++11 mode due to the constexpr function body being
invalid.
Signed-off-by: Jonathan Wakely <jwakely@redhat.com>
libstdc++-v3/ChangeLog:
* testsuite/20_util/tuple/comparison_operators/overloaded2.cc:
Add dg-error for c++11_only target.
This was meant to be an internal construct, but I see folks are using
it and submitting PRs against it. Let's just remove this to avoid
further confusion.
Tested on x86-64 Linux.
gcc/ChangeLog:
PR tree-optimization/101724
* params.opt: Remove --param=threader-iterative.
* tree-ssa-threadbackward.c (pass_thread_jumps::execute): Remove
iterative mode.
Improve nonnull attribute documentation in a number of ways:
Reorganize discussion of effects into:
- effects for calls to functions with nonnull-marked parameters, and
- effects for function definitions with nonnull-marked parameters.
This makes it clear that -fno-delete-null-pointer-checks has no effect for
optimizations based on nonnull-marked parameters in function definitions
(see PR100404).
Mention -Wnonnull-compare.
gcc/ChangeLog:
2021-07-28 Tom de Vries <tdevries@suse.de>
PR middle-end/101665
* doc/extend.texi (nonnull attribute): Improve documentation.
Just like the old bug PR9651, unsigned_fix rtl should
also be handled as a trapping instruction.
OK? Bootstrapped and tested on x86_64-linux-gnu with no regressions.
gcc/ChangeLog:
PR rtl-optimization/101683
* rtlanal.c (may_trap_p_1): Handle UNSIGNED_FIX.
Constraint subsumption is implemented in two steps. The first step
computes the disjunctive (or conjunctive) normal form of one of the
constraints, and the second step verifies that each clause in the
decomposed form implies the other constraint. Performing these two
steps separately is problematic because in the first step the DNF/CNF
can be exponentially larger than the original constraint, and by
computing it ahead of time we'd have to keep all of it in memory.
This patch fixes this exponential blowup in memory usage by interleaving
the two steps, so that as soon as we decompose one clause we check
implication for it. In turn, memory usage during subsumption is now
worst case linear in the size of the constraints rather than
exponential, and so we can safely remove the hard limit of 16 clauses
without introducing runaway memory usage on some inputs. (Note the
_time_ complexity of subsumption is still exponential in the worst case.)
In order for this to work we need to make formula::branch() insert the
copy of the current clause directly after the current clause rather than
at the end of the list, so that we fully decompose a clause shortly
after creating it. Otherwise we'd end up accumulating exponentially
many (partially decomposed) clauses in memory anyway.
PR c++/100828
gcc/cp/ChangeLog:
* logic.cc (formula::formula): Use emplace_back instead of
push_back.
(formula::branch): Insert a copy of m_current directly after
m_current instead of at the end of the list.
(formula::erase): Define.
(decompose_formula): Remove.
(decompose_antecedents): Remove.
(decompose_consequents): Remove.
(derive_proofs): Remove.
(max_problem_size): Remove.
(diagnose_constraint_size): Remove.
(subsumes_constraints_nonnull): Rewrite directly in terms of
decompose_clause and derive_proof, interleaving decomposition
with implication checking. Remove limit on constraint complexity.
Use formula::erase to free the current clause before moving on to
the next one.
Many thanks again to Jakub Jelinek for a speedy fix for PR 101642.
Interestingly, that test case "bswap16(x) ? : x" also reveals a
missed optimization opportunity. The resulting "x ? bswap(x) : 0"
can be further simplified to just bswap(x).
Conveniently, tree-ssa-phiopt.c already recognizes/optimizes the
related "x ? popcount(x) : 0", so this patch simply makes that
transformation make general, additionally handling bswap, parity,
ffs and clrsb. All of the required infrastructure is already
present thanks to Jakub previously adding support for clz/ctz.
To reflect this generalization, the name of the function is changed
from cond_removal_in_popcount_clz_ctz_pattern to the hopefully
equally descriptive cond_removal_in_builtin_zero_pattern.
2021-08-02 Roger Sayle <roger@nextmovesoftware.com>
gcc/ChangeLog
* tree-ssa-phiopt.c (cond_removal_in_builtin_zero_pattern):
Renamed from cond_removal_in_popcount_clz_ctz_pattern.
Add support for BSWAP, FFS, PARITY and CLRSB builtins.
(tree_ssa_phiop_worker): Update call to function above.
gcc/testsuite/ChangeLog
* gcc.dg/tree-ssa/phi-opt-25.c: New test case.
Add a zero_extend patten for bsr_rex64_1 and use it to split SImode
constant - __builtin_clzll to avoid unncessary zero_extend.
gcc/
PR target/78103
* config/i386/i386.md (bsr_rex64_1_zext): New.
(combine splitter for constant - clzll): Replace gen_bsr_rex64_1
with gen_bsr_rex64_1_zext.
gcc/testsuite/
PR target/78103
* gcc.target/i386/pr78103-2.c: Also scan incl.
* gcc.target/i386/pr78103-3.c: Scan leal|addl|incl for x32. Also
scan incq.
pinski pointed out that my recent change to reject anonymous structs with
bases was relevant to this PR. But we still ICEd after giving that error;
this fixes the ICE.
PR c++/96636
gcc/cp/ChangeLog:
* decl.c (fixup_anonymous_aggr): Clear TYPE_NEEDS_CONSTRUCTING
after error.
gcc/testsuite/ChangeLog:
* g++.dg/ext/anon-struct9.C: New test.
With -m32, this test case is sensitive to the instruction timings of
the target (for ifcvt to normalize bar() to foo() during the ce1 pass,
prior to the transformations actually being tested here). Specifying
-march=core2 prevents these failures. Committed as obvious.
2021-07-31 Roger Sayle <roger@nextmovesoftware.com>
gcc/testsuite/ChangeLog
* gcc.target/i386/dec-cmov-2.c: Require -march=core2 with -m32.
Now that we parse attribute-declaration (outside of functions), the following
patch handles OpenMP directives in its attribute(s).
What needs handling incrementally is diagnose mismatching begin/end pair
like
[[omp::directive (declare target)]];
int a;
#pragma omp end declare target
or
#pragma omp declare target
int b;
[[omp::directive (end declare target)]];
and handling declare simd/declare variant on declarations (function
definitions and declarations), for those in two different spots.
2021-07-31 Jakub Jelinek <jakub@redhat.com>
* parser.c (cp_parser_declaration): Handle OpenMP directives
in attribute-declaration.
* g++.dg/gomp/attrs-9.C: New test.
This patch improves emitted code for the non-TARGET_LZCNT case.
As __builtin_clz* is UB on 0 argument and for !TARGET_LZCNT
CLZ_VALUE_DEFINED_AT_ZERO is 0, it is UB even at RTL time and so we
can take advantage of that and assume the result will be 0 to 31 or
0 to 63.
Given that, sign or zero extension of that result are the same and
are actually already performed by bsrl or xorl instructions.
And constant - __builtin_clz* can be simplified into
bsr + constant - bitmask.
For TARGET_LZCNT, a lot of this is already fine as is (e.g. the sign or
zero extensions), and other optimizations are IMHO not possible
(if we have lzcnt, we've lost information on whether it is UB at
zero or not and so can't transform it into bsr even when that is
1-2 insns shorter).
The changes on the 3 testcases between unpatched and patched gcc
are for -m64:
pr78103-1.s:
bsrq %rdi, %rax
- xorq $63, %rax
- cltq
+ xorl $63, %eax
...
bsrq %rdi, %rax
- xorq $63, %rax
- cltq
+ xorl $63, %eax
...
bsrl %edi, %eax
xorl $31, %eax
- cltq
...
bsrl %edi, %eax
xorl $31, %eax
- cltq
pr78103-2.s:
bsrl %edi, %edi
- movl $32, %eax
- xorl $31, %edi
- subl %edi, %eax
+ leal 1(%rdi), %eax
...
- bsrl %edi, %edi
- movl $31, %eax
- xorl $31, %edi
- subl %edi, %eax
+ bsrl %edi, %eax
...
bsrq %rdi, %rdi
- movl $64, %eax
- xorq $63, %rdi
- subl %edi, %eax
+ leal 1(%rdi), %eax
...
- bsrq %rdi, %rdi
- movl $63, %eax
- xorq $63, %rdi
- subl %edi, %eax
+ bsrq %rdi, %rax
pr78103-3.s:
bsrl %edi, %edi
- movl $32, %eax
- xorl $31, %edi
- movslq %edi, %rdi
- subq %rdi, %rax
+ leaq 1(%rdi), %rax
...
- bsrl %edi, %edi
- movl $31, %eax
- xorl $31, %edi
- movslq %edi, %rdi
- subq %rdi, %rax
+ bsrl %edi, %eax
...
bsrq %rdi, %rdi
- movl $64, %eax
- xorq $63, %rdi
- movslq %edi, %rdi
- subq %rdi, %rax
+ leaq 1(%rdi), %rax
...
- bsrq %rdi, %rdi
- movl $63, %eax
- xorq $63, %rdi
- movslq %edi, %rdi
- subq %rdi, %rax
+ bsrq %rdi, %rax
Most of the changes are done with combine splitters, but for
*bsr_rex64_2 and *bsr_2 I had to use define_insn_and_split, because
as mentioned in the PR the combiner unfortunately doesn't create LOG_LINKS
in between the two insns created by combine splitter, so it can't be
combined further with following instructions.
2021-07-31 Jakub Jelinek <jakub@redhat.com>
PR target/78103
* config/i386/i386.md (bsr_rex64_1, bsr_1, bsr_zext_1): New
define_insn patterns.
(*bsr_rex64_2, *bsr_2): New define_insn_and_split patterns.
Add combine splitters for constant - clz.
(clz<mode>2): Use a temporary pseudo for bsr result.
* gcc.target/i386/pr78103-1.c: New test.
* gcc.target/i386/pr78103-2.c: New test.
* gcc.target/i386/pr78103-3.c: New test.
Commit r12-432, rewriting the dg-stuff, reverted the
adjustment for mmix-knuth-mmixware that I added in r11-2335.
(See those commits for context.)
Hopefully this variant will age better, just skipping it
with a trivial extra line less prone to pile-on. (Not much
is won by covering this generic case for MMIX too; might as
well skip it.)
Beware that the dg-skip-if text can't say
"temporary variables are not x and y but x::3 and y::4"
because that leads to (on one line):
ERROR: gcc.dg/tree-ssa/ssa-dse-26.c: can't set "{temporary
variables are not x and y but x::3 and y::4} {
mmix-knuth-mmixware }": parent namespace doesn't exist for
" dg-skip-if 4 "temporary variables are not x and y but
x::3 and y::4" { mmix-knuth-mmixware } "
gcc/testsuite:
* gcc.dg/tree-ssa/ssa-dse-26.c: Skip on mmix-knuth-mmixware.
Looks like MMIX is the "correct target" too (cf. 2f6bdd51cfe15)
and from
https://gcc.gnu.org/pipermail/gcc-testresults/2021-July/710188.html
it seems powerpc-ibm-aix7.2.3.0 is too, but I've not found
other targets failing.
gcc/testsuite:
PR middle-end/101674
* gcc.dg/uninit-pred-9_b.c: Xfail for mmix-*-* too.
Add the tests for _mm_floor_pd, _mm_floor_ps, _mm_floor_sd, _mm_floor_ss.
These are modelled after (and depend upon parts of) the tests for
_mm_ceil intrinsics, recently posted.
Copy a test for _mm_floor_sd from gcc/testsuite/gcc.target/i386.
2021-07-30 Paul A. Clarke <pc@us.ibm.com>
gcc/testsuite
* gcc.target/powerpc/sse4_1-floorpd.c: New.
* gcc.target/powerpc/sse4_1-floorps.c: New.
* gcc.target/powerpc/sse4_1-floorsd.c: New.
* gcc.target/powerpc/sse4_1-floorss.c: New.
* gcc.target/powerpc/sse4_1-roundpd-2.c: Copy from
gcc/testsuite/gcc.target/i386 and adjust dg directives to suit.
Add the tests for _mm_ceil_pd, _mm_ceil_ps, _mm_ceil_sd, _mm_ceil_ss.
Copy a test for _mm_ceil_pd and _mm_ceil_ps from
gcc/testsuite/gcc.target/i386.
Define __VSX_SSE2__ to pick up some union definitions in
m128-check.h.
2021-07-30 Paul A. Clarke <pc@us.ibm.com>
gcc/testsuite
* gcc.target/powerpc/sse4_1-ceilpd.c: New.
* gcc.target/powerpc/sse4_1-ceilps.c: New.
* gcc.target/powerpc/sse4_1-ceilsd.c: New.
* gcc.target/powerpc/sse4_1-ceilss.c: New.
* gcc.target/powerpc/sse4_1-round-data.h: New.
* gcc.target/powerpc/sse4_1-round.h: New.
* gcc.target/powerpc/sse4_1-round2.h: New.
* gcc.target/powerpc/sse4_1-roundpd-3.c: Copy from gcc.target/i386
and adjust dg directives to suit.
* gcc.target/powerpc/sse4_1-check.h (__VSX_SSE2__): Define.
Copy the tests for _mm_blend_pd, _mm_blendv_pd, _mm_blend_ps,
_mm_blendv_ps from gcc/testsuite/gcc.target/i386.
2021-07-30 Paul A. Clarke <pc@us.ibm.com>
gcc/testsuite
* gcc.target/powerpc/sse4_1-blendpd.c: Copy from gcc.target/i386
and adjust dg directives to suit.
* gcc.target/powerpc/sse4_1-blendps-2.c: Likewise.
* gcc.target/powerpc/sse4_1-blendps.c: Likewise.
* gcc.target/powerpc/sse4_1-blendvpd.c: Likewise.
_mm_blend_epi16 and _mm_blendv_epi8 were added earlier.
Add these four to complete the set.
2021-07-30 Paul A. Clarke <pc@us.ibm.com>
gcc
* config/rs6000/smmintrin.h (_mm_blend_pd, _mm_blendv_pd,
_mm_blend_ps, _mm_blendv_ps): New.
The following patch to the x86_64 backend improves the code generated
for a decrement followed by a conditional move. The primary change is
to recognize that after subtracting one, checking the result is -1 (or
equivalently that the original value was zero) can be implemented using
the borrow/carry flag instead of requiring an explicit test instruction.
This is achieved by a new define_insn_and_split that allows combine to
split the desired sequence/composite into a *subsi_3 and *movsicc_noc.
The other change with this patch is/are a pair of peephole2 optimizations
to eliminate register-to-register moves generated during register
allocation. During reload, the compiler doesn't know that inverting
the condition of a conditional cmove can sometimes reduce register
pressure, but this is easy to tidy up during the peephole2 pass (where
swapping the order of the insn's operands performs the required
logic inversion).
Both improvements are demonstrated by the case below:
int foo(int x) {
if (x == 0)
x = 16;
else x--;
return x;
}
Before:
foo: leal -1(%rdi), %eax
testl %edi, %edi
movl $16, %edx
cmove %edx, %eax
ret
After:
foo: subl $1, %edi
movl $16, %eax
cmovnc %edi, %eax
ret
And the value of the peephole2 clean-up can be seen on its own in:
int bar(int x) {
x--;
if (x == 0)
x = 16;
return x;
}
Before:
bar: movl %edi, %eax
movl $16, %edx
subl $1, %eax
cmove %edx, %eax
ret
After:
bar: subl $1, %edi
movl $16, %eax
cmovne %edi, %eax
ret
These idioms were inspired by the source code of NIST SciMark4's
Random_nextDouble function, where the tweaks above result in
a ~1% improvement in the MonteCarlo benchmark kernel.
2021-07-30 Roger Sayle <roger@nextmovesoftware.com>
Uroš Bizjak <ubizjak@gmail.com>
gcc/ChangeLog
* config/i386/i386.md (*dec_cmov<mode>): New define_insn_and_split
to generate a conditional move using the carry flag after sub $1.
(peephole2): Eliminate a register-to-register move by inverting
the condition of a conditional move.
gcc/testsuite/ChangeLog
* gcc.target/i386/dec-cmov-1.c: New test.
* gcc.target/i386/dec-cmov-2.c: New test.
I guess the best way to describe these operands, at least for MMIX, is
"ballast". Some targets seem to drag along one or two of the incoming
pattern operands through the rtl passes and not dropping them until
assembly output. Let's stop doing that for MMIX. There really are
*two* unused parameters: one is a number corresponding to the
stack-size of arguments as a const_int and the other is whatever the
target yields for targetm.calls.function_arg (args_so_far,
function_arg_info::end_marker ()). There's a mandatory second
argument to the "call" RTX, but the target doesn't have to keep it a
variable number; it can be replaced by (const_int 0) early, like this.
Astute readers may object that as the MMIX call-type insns (PUSHJ,
PUSHGO) have a parameter in addition to the address of the called
function, so should the emitted RTL. But, that parameter depends only
on the local function, not the called function (IOW, it's the same for
all calls in a function), and its value isn't known until frame layout
time. Having it a parameter in the emitted RTL for the call would
just be confusing. (Maybe this will be amended later, if/when
improving "shrink-wrapping".)
gcc:
* config/mmix/mmix.md ("call", "call_value", "*call_real")
("*call_value_real"): Don't generate rtx mentioning the generic
operands 1 and 2 to "call", and similarly for "call_value".
* config/mmix/mmix.c (mmix_print_operand_punct_valid_p)
(mmix_print_operand): Use '!' instead of 'p'.
An old itch being scratched: the documentation lies; it's not "the
number of registers used as operands", unless the target makes a
special arrangement to that effect, and there's nothing in the guts of
gcc setting up or assuming those semantics.
Instead, see calls.c:expand_call, variable next_arg_reg. Or just
consider the variable name. The text is somewhat transcribed from the
head comment of emit_call_1 for parameter next_arg_reg. Most
important is to document the relation to function_arg_info::end_marker()
and the TARGET_FUNCTION_ARG hook.
The "normally" in the head comment, in "normally it is the first
arg-register beyond those used for args in this call, or 0 if all the
arg-registers are used in this call" means "by default", unless the
target tests end_marker_p and does something special, but the port is
free to return whatever it likes when it sees the end-marker.
And, I do mean "whatever it likes" because if the port doesn't
actually mention that operand in the RTX emitted for its "call" or
"call_value" patterns ("usually" define_expands), it can be any
mumbo-jumbo, such as a VOIDmode register, which seems like it happens
for some targets, or NULL, that happens for others. Returning a
VOIDmode register until recently included MMIX, where it made it into
the emitted RTL, confusing later passes, recently exposed as an ICE.
Tested by inspecting the info and generated pdf for sanity.
gcc:
* doc/md.texi (call): Correct information about operand 2.
* config/mmix/mmix.md ("call", "call_value"): Remove fixed FIXMEs.
Handle const % const, as wi_fold_in_parts may now provide this. Before this
[10, 10] % [4, 4] would produce [0, 3] instead of [2, 2].
gcc/
* range-op.cc (operator_trunc_mod::wi_fold): Fold constants.
gcc/testsuite/
* gcc.dg/tree-ssa/pr61839_2.c: Adjust. Add new const fold test.
Instead of VARYING, we can get better results by treating divide by zero
as producing an undefined result.
gcc/
* range-op.cc (operator_div::wi_fold): Return UNDEFINED for [0, 0] divisor.
gcc/testsuite/
* gcc.dg/tree-ssa/pr61839_2.c: Adjust.