aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Liska <mliska@suse.cz>2022-08-10 09:18:18 +0200
committerMartin Liska <mliska@suse.cz>2022-08-10 09:18:18 +0200
commitb629a7958faf817ef658e3ce59183bfb9ccefe96 (patch)
tree4515688b7c5645bbc5d28b8a711bc7f8f9e9b119
parent9fce2fbb1dff9f090d98a056df1da459ba45f16f (diff)
parentc16d9f78dc81664e3341157c5a6efb85c0c141f4 (diff)
downloadgcc-b629a7958faf817ef658e3ce59183bfb9ccefe96.zip
gcc-b629a7958faf817ef658e3ce59183bfb9ccefe96.tar.gz
gcc-b629a7958faf817ef658e3ce59183bfb9ccefe96.tar.bz2
Merge branch 'master' into devel/sphinx
-rw-r--r--gcc/ChangeLog95
-rw-r--r--gcc/DATESTAMP2
-rw-r--r--gcc/analyzer/ChangeLog6
-rw-r--r--gcc/analyzer/region-model.cc8
-rw-r--r--gcc/config/i386/i386-features.cc95
-rw-r--r--gcc/config/i386/i386.cc16
-rw-r--r--gcc/config/i386/i386.md21
-rw-r--r--gcc/config/i386/sse.md13
-rw-r--r--gcc/d/ChangeLog14
-rw-r--r--gcc/doc/invoke.texi81
-rw-r--r--gcc/fold-const.cc54
-rw-r--r--gcc/jit/ChangeLog5
-rw-r--r--gcc/jit/libgccjit.h4
-rw-r--r--gcc/match.pd45
-rw-r--r--gcc/testsuite/ChangeLog39
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/error-uninit.c29
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/fd-uninit-1.c21
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/file-uninit-1.c52
-rw-r--r--gcc/testsuite/gcc.dg/fold-eqandshift-4.c46
-rw-r--r--gcc/testsuite/gcc.target/i386/sse4_1-stv-8.c11
20 files changed, 562 insertions, 95 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 36879ec..9450838 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,98 @@
+2022-08-09 Roger Sayle <roger@nextmovesoftware.com>
+
+ * config/i386/i386-features.cc (scalar_chain::convert_compare):
+ Create new pseudos only when/if needed. Add support for TEST,
+ i.e. (COMPARE (AND x y) (const_int 0)), using UNSPEC_PTEST.
+ When broadcasting V2DImode and V4SImode use new pseudo register.
+ (timode_scalar_chain::convert_op): Do nothing if operand is
+ already V1TImode. Avoid generating useless SUBREG conversions,
+ i.e. (SUBREG:V1TImode (REG:V1TImode) 0). Handle CONST_WIDE_INT
+ in addition to CONST_INT by using CONST_SCALAR_INT_P.
+ (convertible_comparison_p): Use CONST_SCALAR_INT_P to match both
+ CONST_WIDE_INT and CONST_INT. Recognize new *testti_doubleword
+ pattern as an STV candidate.
+ (timode_scalar_to_vector_candidate_p): Allow CONST_SCALAR_INT_P
+ operands in binary logic operations.
+ * config/i386/i386.cc (ix86_rtx_costs) <case UNSPEC>: Add costs
+ for UNSPEC_PTEST; a PTEST that performs an AND has the same cost
+ as regular PTEST, i.e. cost->sse_op.
+ * config/i386/i386.md (*testti_doubleword): New pre-reload
+ define_insn_and_split that recognizes comparison of TI mode AND
+ against zero.
+ * config/i386/sse.md (*ptest<mode>_and): New pre-reload
+ define_insn_and_split that recognizes UNSPEC_PTEST of identical
+ AND operands.
+
+2022-08-09 Roger Sayle <roger@nextmovesoftware.com>
+ Richard Biener <rguenther@suse.de>
+
+ PR middle-end/21137
+ PR tree-optimization/98954
+ * fold-const.cc (fold_binary_loc): Remove optimizations to
+ optimize ((X >> C1) & C2) ==/!= 0.
+ * match.pd (cmp (bit_and (lshift @0 @1) @2) @3): Remove wi::ctz
+ check, and handle all values of INTEGER_CSTs @2 and @3.
+ (cmp (bit_and (rshift @0 @1) @2) @3): Likewise, remove wi::clz
+ checks, and handle all values of INTEGER_CSTs @2 and @3.
+
+2022-08-09 David Malcolm <dmalcolm@redhat.com>
+
+ * doc/invoke.texi (Static Analyzer Options): Add notes on which
+ functions the analyzer has hardcoded knowledge of.
+
+2022-08-09 Andrew Stubbs <ams@codesourcery.com>
+
+ * config/gcn/gcn.cc (gcn_function_value): Allow vector return values.
+ (num_arg_regs): Allow vector arguments.
+ (gcn_function_arg): Likewise.
+ (gcn_function_arg_advance): Likewise.
+ (gcn_arg_partial_bytes): Likewise.
+ (gcn_return_in_memory): Likewise.
+ (gcn_expand_epilogue): Get return value from v8.
+ * config/gcn/gcn.h (RETURN_VALUE_REG): Set to v8.
+ (FIRST_PARM_REG): USE FIRST_SGPR_REG for clarity.
+ (FIRST_VPARM_REG): New.
+ (FUNCTION_ARG_REGNO_P): Allow vector parameters.
+ (struct gcn_args): Add vnum field.
+ (LIBCALL_VALUE): All vector return values.
+ * config/gcn/gcn.md (gcn_call_value): Add vector constraints.
+ (gcn_call_value_indirect): Likewise.
+
+2022-08-09 Richard Biener <rguenther@suse.de>
+
+ * omp-expand.cc (expand_omp_atomic_load): Emit GIMPLE
+ directly. Avoid update_ssa when in SSA form.
+ (expand_omp_atomic_store): Likewise.
+ (expand_omp_atomic_fetch_op): Avoid update_ssa when in SSA
+ form.
+ (expand_omp_atomic_pipeline): Likewise.
+ (expand_omp_atomic_mutex): Likewise.
+ * tree-parloops.cc (gen_parallel_loop): Use
+ TODO_update_ssa_no_phi after loop_version.
+
+2022-08-09 Richard Biener <rguenther@suse.de>
+
+ * doc/invoke.texi (max-fsm-thread-length): Remove.
+ * params.opt (max-fsm-thread-length): Likewise.
+ * tree-ssa-threadbackward.cc
+ (back_threader_profitability::profitable_path_p): Do not
+ check max-fsm-thread-length.
+
+2022-08-09 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/106514
+ * params.opt (max-jump-thread-paths): New.
+ * doc/invoke.texi (max-jump-thread-paths): Document.
+ * tree-ssa-threadbackward.cc (back_threader::find_paths_to_names):
+ Honor max-jump-thread-paths, take overall_path argument.
+ (back_threader::find_paths): Pass 1 as initial overall_path.
+
+2022-08-09 Tobias Burnus <tobias@codesourcery.com>
+
+ PR middle-end/106492
+ * omp-low.cc (lower_rec_input_clauses): Add missing folding
+ to data type of linear-clause list item.
+
2022-08-08 Andrew MacLeod <amacleod@redhat.com>
PR tree-optimization/106556
diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
index 8bd1173..9049af1 100644
--- a/gcc/DATESTAMP
+++ b/gcc/DATESTAMP
@@ -1 +1 @@
-20220809
+20220810
diff --git a/gcc/analyzer/ChangeLog b/gcc/analyzer/ChangeLog
index 0b93219..b16971b 100644
--- a/gcc/analyzer/ChangeLog
+++ b/gcc/analyzer/ChangeLog
@@ -1,3 +1,9 @@
+2022-08-09 David Malcolm <dmalcolm@redhat.com>
+
+ PR analyzer/106573
+ * region-model.cc (region_model::on_call_pre): Ensure that we call
+ get_arg_svalue on all arguments.
+
2022-08-05 David Malcolm <dmalcolm@redhat.com>
PR analyzer/105947
diff --git a/gcc/analyzer/region-model.cc b/gcc/analyzer/region-model.cc
index a140f4d..8393c7d 100644
--- a/gcc/analyzer/region-model.cc
+++ b/gcc/analyzer/region-model.cc
@@ -1355,6 +1355,14 @@ region_model::on_call_pre (const gcall *call, region_model_context *ctxt,
&& gimple_call_internal_fn (call) == IFN_DEFERRED_INIT)
return false;
+ /* Get svalues for all of the arguments at the callsite, to ensure that we
+ complain about any uninitialized arguments. This might lead to
+ duplicates if any of the handling below also looks up the svalues,
+ but the deduplication code should deal with that. */
+ if (ctxt)
+ for (unsigned arg_idx = 0; arg_idx < cd.num_args (); arg_idx++)
+ cd.get_arg_svalue (arg_idx);
+
/* Some of the cases below update the lhs of the call based on the
return value, but not all. Provide a default value, which may
get overwritten below. */
diff --git a/gcc/config/i386/i386-features.cc b/gcc/config/i386/i386-features.cc
index 5e3a7ff..effc2f2 100644
--- a/gcc/config/i386/i386-features.cc
+++ b/gcc/config/i386/i386-features.cc
@@ -919,8 +919,7 @@ general_scalar_chain::convert_op (rtx *op, rtx_insn *insn)
rtx
scalar_chain::convert_compare (rtx op1, rtx op2, rtx_insn *insn)
{
- rtx tmp = gen_reg_rtx (vmode);
- rtx src;
+ rtx src, tmp;
/* Comparison against anything other than zero, requires an XOR. */
if (op2 != const0_rtx)
{
@@ -929,6 +928,7 @@ scalar_chain::convert_compare (rtx op1, rtx op2, rtx_insn *insn)
/* If both operands are MEMs, explicitly load the OP1 into TMP. */
if (MEM_P (op1) && MEM_P (op2))
{
+ tmp = gen_reg_rtx (vmode);
emit_insn_before (gen_rtx_SET (tmp, op1), insn);
src = tmp;
}
@@ -943,34 +943,56 @@ scalar_chain::convert_compare (rtx op1, rtx op2, rtx_insn *insn)
rtx op12 = XEXP (op1, 1);
convert_op (&op11, insn);
convert_op (&op12, insn);
- if (MEM_P (op11))
+ if (!REG_P (op11))
{
+ tmp = gen_reg_rtx (vmode);
emit_insn_before (gen_rtx_SET (tmp, op11), insn);
op11 = tmp;
}
src = gen_rtx_AND (vmode, gen_rtx_NOT (vmode, op11), op12);
}
+ else if (GET_CODE (op1) == AND)
+ {
+ rtx op11 = XEXP (op1, 0);
+ rtx op12 = XEXP (op1, 1);
+ convert_op (&op11, insn);
+ convert_op (&op12, insn);
+ if (!REG_P (op11))
+ {
+ tmp = gen_reg_rtx (vmode);
+ emit_insn_before (gen_rtx_SET (tmp, op11), insn);
+ op11 = tmp;
+ }
+ return gen_rtx_UNSPEC (CCmode, gen_rtvec (2, op11, op12),
+ UNSPEC_PTEST);
+ }
else
{
convert_op (&op1, insn);
src = op1;
}
- emit_insn_before (gen_rtx_SET (tmp, src), insn);
+
+ if (!REG_P (src))
+ {
+ tmp = gen_reg_rtx (vmode);
+ emit_insn_before (gen_rtx_SET (tmp, src), insn);
+ src = tmp;
+ }
if (vmode == V2DImode)
- emit_insn_before (gen_vec_interleave_lowv2di (copy_rtx_if_shared (tmp),
- copy_rtx_if_shared (tmp),
- copy_rtx_if_shared (tmp)),
- insn);
+ {
+ tmp = gen_reg_rtx (vmode);
+ emit_insn_before (gen_vec_interleave_lowv2di (tmp, src, src), insn);
+ src = tmp;
+ }
else if (vmode == V4SImode)
- emit_insn_before (gen_sse2_pshufd (copy_rtx_if_shared (tmp),
- copy_rtx_if_shared (tmp),
- const0_rtx),
- insn);
-
- return gen_rtx_UNSPEC (CCmode, gen_rtvec (2, copy_rtx_if_shared (tmp),
- copy_rtx_if_shared (tmp)),
- UNSPEC_PTEST);
+ {
+ tmp = gen_reg_rtx (vmode);
+ emit_insn_before (gen_sse2_pshufd (tmp, src, const0_rtx), insn);
+ src = tmp;
+ }
+
+ return gen_rtx_UNSPEC (CCmode, gen_rtvec (2, src, src), UNSPEC_PTEST);
}
/* Helper function for converting INSN to vector mode. */
@@ -1289,6 +1311,9 @@ timode_scalar_chain::fix_debug_reg_uses (rtx reg)
void
timode_scalar_chain::convert_op (rtx *op, rtx_insn *insn)
{
+ if (GET_MODE (*op) == V1TImode)
+ return;
+
*op = copy_rtx_if_shared (*op);
if (REG_P (*op))
@@ -1296,19 +1321,19 @@ timode_scalar_chain::convert_op (rtx *op, rtx_insn *insn)
else if (MEM_P (*op))
{
rtx tmp = gen_reg_rtx (V1TImode);
- emit_insn_before (gen_rtx_SET (gen_rtx_SUBREG (V1TImode, tmp, 0),
+ emit_insn_before (gen_rtx_SET (tmp,
gen_gpr_to_xmm_move_src (V1TImode, *op)),
insn);
- *op = gen_rtx_SUBREG (V1TImode, tmp, 0);
+ *op = tmp;
if (dump_file)
fprintf (dump_file, " Preloading operand for insn %d into r%d\n",
INSN_UID (insn), REGNO (tmp));
}
- else if (CONST_INT_P (*op))
+ else if (CONST_SCALAR_INT_P (*op))
{
rtx vec_cst;
- rtx tmp = gen_rtx_SUBREG (V1TImode, gen_reg_rtx (TImode), 0);
+ rtx tmp = gen_reg_rtx (V1TImode);
/* Prefer all ones vector in case of -1. */
if (constm1_operand (*op, TImode))
@@ -1329,7 +1354,7 @@ timode_scalar_chain::convert_op (rtx *op, rtx_insn *insn)
emit_insn_before (seq, insn);
}
- emit_insn_before (gen_move_insn (copy_rtx (tmp), vec_cst), insn);
+ emit_insn_before (gen_move_insn (tmp, vec_cst), insn);
*op = tmp;
}
else
@@ -1609,14 +1634,26 @@ convertible_comparison_p (rtx_insn *insn, enum machine_mode mode)
rtx op2 = XEXP (src, 1);
/* *cmp<dwi>_doubleword. */
- if ((CONST_INT_P (op1)
+ if ((CONST_SCALAR_INT_P (op1)
|| ((REG_P (op1) || MEM_P (op1))
&& GET_MODE (op1) == mode))
- && (CONST_INT_P (op2)
+ && (CONST_SCALAR_INT_P (op2)
|| ((REG_P (op2) || MEM_P (op2))
&& GET_MODE (op2) == mode)))
return true;
+ /* *testti_doubleword. */
+ if (op2 == const0_rtx
+ && GET_CODE (op1) == AND
+ && REG_P (XEXP (op1, 0)))
+ {
+ rtx op12 = XEXP (op1, 1);
+ return GET_MODE (XEXP (op1, 0)) == TImode
+ && (CONST_SCALAR_INT_P (op12)
+ || ((REG_P (op12) || MEM_P (op12))
+ && GET_MODE (op12) == TImode));
+ }
+
/* *test<dwi>_not_doubleword. */
if (op2 == const0_rtx
&& GET_CODE (op1) == AND
@@ -1803,15 +1840,21 @@ timode_scalar_to_vector_candidate_p (rtx_insn *insn)
if (!MEM_P (dst)
&& GET_CODE (XEXP (src, 0)) == NOT
&& REG_P (XEXP (XEXP (src, 0), 0))
- && (REG_P (XEXP (src, 1)) || timode_mem_p (XEXP (src, 1))))
+ && (REG_P (XEXP (src, 1))
+ || CONST_SCALAR_INT_P (XEXP (src, 1))
+ || timode_mem_p (XEXP (src, 1))))
return true;
return REG_P (XEXP (src, 0))
- && (REG_P (XEXP (src, 1)) || timode_mem_p (XEXP (src, 1)));
+ && (REG_P (XEXP (src, 1))
+ || CONST_SCALAR_INT_P (XEXP (src, 1))
+ || timode_mem_p (XEXP (src, 1)));
case IOR:
case XOR:
return REG_P (XEXP (src, 0))
- && (REG_P (XEXP (src, 1)) || timode_mem_p (XEXP (src, 1)));
+ && (REG_P (XEXP (src, 1))
+ || CONST_SCALAR_INT_P (XEXP (src, 1))
+ || timode_mem_p (XEXP (src, 1)));
case NOT:
return REG_P (XEXP (src, 0)) || timode_mem_p (XEXP (src, 0));
diff --git a/gcc/config/i386/i386.cc b/gcc/config/i386/i386.cc
index 5e30dc8..5be76e1 100644
--- a/gcc/config/i386/i386.cc
+++ b/gcc/config/i386/i386.cc
@@ -21063,11 +21063,25 @@ ix86_rtx_costs (rtx x, machine_mode mode, int outer_code_i, int opno,
case UNSPEC:
if (XINT (x, 1) == UNSPEC_TP)
*total = 0;
- else if (XINT(x, 1) == UNSPEC_VTERNLOG)
+ else if (XINT (x, 1) == UNSPEC_VTERNLOG)
{
*total = cost->sse_op;
return true;
}
+ else if (XINT (x, 1) == UNSPEC_PTEST)
+ {
+ *total = cost->sse_op;
+ if (XVECLEN (x, 0) == 2
+ && GET_CODE (XVECEXP (x, 0, 0)) == AND)
+ {
+ rtx andop = XVECEXP (x, 0, 0);
+ *total += rtx_cost (XEXP (andop, 0), GET_MODE (andop),
+ AND, opno, speed)
+ + rtx_cost (XEXP (andop, 1), GET_MODE (andop),
+ AND, opno, speed);
+ return true;
+ }
+ }
return false;
case VEC_SELECT:
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index fd30c57..2fde8cd 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -9756,6 +9756,27 @@
[(set_attr "type" "test")
(set_attr "mode" "QI")])
+;; Provide a *testti instruction that STV can implement using ptest.
+;; This pattern splits into *andti3_doubleword and *cmpti_doubleword.
+(define_insn_and_split "*testti_doubleword"
+ [(set (reg:CCZ FLAGS_REG)
+ (compare:CCZ
+ (and:TI (match_operand:TI 0 "register_operand")
+ (match_operand:TI 1 "general_operand"))
+ (const_int 0)))]
+ "TARGET_64BIT
+ && ix86_pre_reload_split ()"
+ "#"
+ "&& 1"
+ [(parallel [(set (match_dup 2) (and:TI (match_dup 0) (match_dup 1)))
+ (clobber (reg:CC FLAGS_REG))])
+ (set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 2) (const_int 0)))]
+{
+ operands[2] = gen_reg_rtx (TImode);
+ if (!x86_64_hilo_general_operand (operands[1], TImode))
+ operands[1] = force_reg (TImode, operands[1]);
+})
+
;; Combine likes to form bit extractions for some tests. Humor it.
(define_insn_and_split "*testqi_ext_3"
[(set (match_operand 0 "flags_reg_operand")
diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md
index 14d12d1..ccd9d00 100644
--- a/gcc/config/i386/sse.md
+++ b/gcc/config/i386/sse.md
@@ -23021,6 +23021,19 @@
(set_attr "prefix" "orig,orig,vex")
(set_attr "mode" "TI")])
+(define_insn_and_split "*ptest<mode>_and"
+ [(set (reg:CC FLAGS_REG)
+ (unspec:CC [(and:V_AVX (match_operand:V_AVX 0 "register_operand")
+ (match_operand:V_AVX 1 "vector_operand"))
+ (and:V_AVX (match_dup 0) (match_dup 1))]
+ UNSPEC_PTEST))]
+ "TARGET_SSE4_1
+ && ix86_pre_reload_split ()"
+ "#"
+ "&& 1"
+ [(set (reg:CC FLAGS_REG)
+ (unspec:CC [(match_dup 0) (match_dup 1)] UNSPEC_PTEST))])
+
(define_expand "nearbyint<mode>2"
[(set (match_operand:VFH 0 "register_operand")
(unspec:VFH
diff --git a/gcc/d/ChangeLog b/gcc/d/ChangeLog
index 0bb74b1..0af724b 100644
--- a/gcc/d/ChangeLog
+++ b/gcc/d/ChangeLog
@@ -1,3 +1,17 @@
+2022-08-09 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ PR d/106563
+ * decl.cc (DeclVisitor::visit (FuncDeclaration *)): Set semanticRun
+ before generating its symbol.
+ (function_defined_in_root_p): New function.
+ (function_needs_inline_definition_p): New function.
+ (maybe_build_decl_tree): New function.
+ (get_symbol_decl): Call maybe_build_decl_tree before returning symbol.
+ (start_function): Use function_defined_in_root_p instead of inline
+ test for locally defined symbols.
+ (set_linkage_for_decl): Check for inline functions before private or
+ protected symbols.
+
2022-08-08 Iain Buclaw <ibuclaw@gdcproject.org>
PR d/106555
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 1c2caab..8a0d1f2 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -10244,6 +10244,87 @@ See @uref{https://cwe.mitre.org/data/definitions/457.html, CWE-457: Use of Unini
@end table
+The analyzer has hardcoded knowledge about the behavior of the following
+memory-management functions:
+
+@itemize @bullet
+@item @code{alloca}
+@item The built-in functions @code{__builtin_alloc},
+@code{__builtin_alloc_with_align}, @item @code{__builtin_calloc},
+@code{__builtin_free}, @code{__builtin_malloc}, @code{__builtin_memcpy},
+@code{__builtin_memcpy_chk}, @code{__builtin_memset},
+@code{__builtin_memset_chk}, @code{__builtin_realloc},
+@code{__builtin_stack_restore}, and @code{__builtin_stack_save}
+@item @code{calloc}
+@item @code{free}
+@item @code{malloc}
+@item @code{memset}
+@item @code{operator delete}
+@item @code{operator delete []}
+@item @code{operator new}
+@item @code{operator new []}
+@item @code{realloc}
+@item @code{strdup}
+@item @code{strndup}
+@end itemize
+
+of the following functions for working with file descriptors:
+
+@itemize @bullet
+@item @code{open}
+@item @code{close}
+@item @code{creat}
+@item @code{dup}, @code{dup2} and @code{dup3}
+@item @code{read}
+@item @code{write}
+@end itemize
+
+of the following functions for working with @code{<stdio.h>} streams:
+@itemize @bullet
+@item The built-in functions @code{__builtin_fprintf},
+@code{__builtin_fprintf_unlocked}, @code{__builtin_fputc},
+@code{__builtin_fputc_unlocked}, @code{__builtin_fputs},
+@code{__builtin_fputs_unlocked}, @code{__builtin_fwrite},
+@code{__builtin_fwrite_unlocked}, @code{__builtin_printf},
+@code{__builtin_printf_unlocked}, @code{__builtin_putc},
+@code{__builtin_putchar}, @code{__builtin_putchar_unlocked},
+@code{__builtin_putc_unlocked}, @code{__builtin_puts},
+@code{__builtin_puts_unlocked}, @code{__builtin_vfprintf}, and
+@code{__builtin_vprintf}
+@item @code{fopen}
+@item @code{fclose}
+@item @code{fgets}
+@item @code{fgets_unlocked}
+@item @code{fread}
+@item @code{getchar}
+@item @code{fprintf}
+@item @code{printf}
+@item @code{fwrite}
+@end itemize
+
+and of the following functions:
+
+@itemize @bullet
+@item The built-in functions @code{__builtin_expect},
+@code{__builtin_expect_with_probability}, @code{__builtin_strchr},
+@code{__builtin_strcpy}, @code{__builtin_strcpy_chk},
+@code{__builtin_strlen}, @code{__builtin_va_copy}, and
+@code{__builtin_va_start}
+@item The GNU extensions @code{error} and @code{error_at_line}
+@item @code{getpass}
+@item @code{longjmp}
+@item @code{putenv}
+@item @code{setjmp}
+@item @code{siglongjmp}
+@item @code{signal}
+@item @code{sigsetjmp}
+@item @code{strchr}
+@item @code{strlen}
+@end itemize
+
+In addition, various functions with an @code{__analyzer_} prefix have
+special meaning to the analyzer, described in the GCC Internals manual.
+
Pertinent parameters for controlling the exploration are:
@option{--param analyzer-bb-explosion-factor=@var{value}},
@option{--param analyzer-max-enodes-per-program-point=@var{value}},
diff --git a/gcc/fold-const.cc b/gcc/fold-const.cc
index 99021a8..4f4ec81 100644
--- a/gcc/fold-const.cc
+++ b/gcc/fold-const.cc
@@ -12204,60 +12204,6 @@ fold_binary_loc (location_t loc, enum tree_code code, tree type,
}
}
- /* Fold ((X >> C1) & C2) == 0 and ((X >> C1) & C2) != 0 where
- C1 is a valid shift constant, and C2 is a power of two, i.e.
- a single bit. */
- if (TREE_CODE (arg0) == BIT_AND_EXPR
- && integer_pow2p (TREE_OPERAND (arg0, 1))
- && integer_zerop (arg1))
- {
- tree arg00 = TREE_OPERAND (arg0, 0);
- STRIP_NOPS (arg00);
- if (TREE_CODE (arg00) == RSHIFT_EXPR
- && TREE_CODE (TREE_OPERAND (arg00, 1)) == INTEGER_CST)
- {
- tree itype = TREE_TYPE (arg00);
- tree arg001 = TREE_OPERAND (arg00, 1);
- prec = TYPE_PRECISION (itype);
-
- /* Check for a valid shift count. */
- if (wi::ltu_p (wi::to_wide (arg001), prec))
- {
- tree arg01 = TREE_OPERAND (arg0, 1);
- tree arg000 = TREE_OPERAND (arg00, 0);
- unsigned HOST_WIDE_INT log2 = tree_log2 (arg01);
- /* If (C2 << C1) doesn't overflow, then
- ((X >> C1) & C2) != 0 can be rewritten as
- (X & (C2 << C1)) != 0. */
- if ((log2 + TREE_INT_CST_LOW (arg001)) < prec)
- {
- tem = fold_build2_loc (loc, LSHIFT_EXPR, itype,
- arg01, arg001);
- tem = fold_build2_loc (loc, BIT_AND_EXPR, itype,
- arg000, tem);
- return fold_build2_loc (loc, code, type, tem,
- fold_convert_loc (loc, itype, arg1));
- }
- /* Otherwise, for signed (arithmetic) shifts,
- ((X >> C1) & C2) != 0 is rewritten as X < 0, and
- ((X >> C1) & C2) == 0 is rewritten as X >= 0. */
- else if (!TYPE_UNSIGNED (itype))
- return fold_build2_loc (loc, code == EQ_EXPR ? GE_EXPR
- : LT_EXPR,
- type, arg000,
- build_int_cst (itype, 0));
- /* Otherwise, of unsigned (logical) shifts,
- ((X >> C1) & C2) != 0 is rewritten as (X,false), and
- ((X >> C1) & C2) == 0 is rewritten as (X,true). */
- else
- return omit_one_operand_loc (loc, type,
- code == EQ_EXPR ? integer_one_node
- : integer_zero_node,
- arg000);
- }
- }
- }
-
/* If this is a comparison of a field, we may be able to simplify it. */
if ((TREE_CODE (arg0) == COMPONENT_REF
|| TREE_CODE (arg0) == BIT_FIELD_REF)
diff --git a/gcc/jit/ChangeLog b/gcc/jit/ChangeLog
index df8bf40..314b831 100644
--- a/gcc/jit/ChangeLog
+++ b/gcc/jit/ChangeLog
@@ -1,3 +1,8 @@
+2022-08-09 Vibhav Pant <vibhavp@gmail.com>
+
+ * libgccjit.h (LIBGCCJIT_HAVE_gcc_jit_context_new_bitcast): Move
+ definition out of comment.
+
2022-07-28 David Malcolm <dmalcolm@redhat.com>
* docs/internals/index.rst: Remove reference to ".c" extensions
diff --git a/gcc/jit/libgccjit.h b/gcc/jit/libgccjit.h
index 062f06d..b3c389e 100644
--- a/gcc/jit/libgccjit.h
+++ b/gcc/jit/libgccjit.h
@@ -1252,10 +1252,10 @@ gcc_jit_context_new_cast (gcc_jit_context *ctxt,
gcc_jit_rvalue *rvalue,
gcc_jit_type *type);
-/* Reinterpret a value as another type.
-
#define LIBGCCJIT_HAVE_gcc_jit_context_new_bitcast
+/* Reinterpret a value as another type.
+
The types must be of the same size.
This API entrypoint was added in LIBGCCJIT_ABI_21; you can test for its
diff --git a/gcc/match.pd b/gcc/match.pd
index f82f94a..c22bc2c 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -3601,21 +3601,44 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
(cmp (bit_and:s (lshift:s @0 INTEGER_CST@1) INTEGER_CST@2) INTEGER_CST@3)
(if (tree_fits_shwi_p (@1)
&& tree_to_shwi (@1) > 0
- && tree_to_shwi (@1) < TYPE_PRECISION (TREE_TYPE (@0))
- && tree_to_shwi (@1) <= wi::ctz (wi::to_wide (@3)))
- (with { wide_int c1 = wi::to_wide (@1);
- wide_int c2 = wi::lrshift (wi::to_wide (@2), c1);
- wide_int c3 = wi::lrshift (wi::to_wide (@3), c1); }
- (cmp (bit_and @0 { wide_int_to_tree (TREE_TYPE (@0), c2); })
- { wide_int_to_tree (TREE_TYPE (@0), c3); }))))
+ && tree_to_shwi (@1) < TYPE_PRECISION (TREE_TYPE (@0)))
+ (if (tree_to_shwi (@1) > wi::ctz (wi::to_wide (@3)))
+ { constant_boolean_node (cmp == NE_EXPR, type); }
+ (with { wide_int c1 = wi::to_wide (@1);
+ wide_int c2 = wi::lrshift (wi::to_wide (@2), c1);
+ wide_int c3 = wi::lrshift (wi::to_wide (@3), c1); }
+ (cmp (bit_and @0 { wide_int_to_tree (TREE_TYPE (@0), c2); })
+ { wide_int_to_tree (TREE_TYPE (@0), c3); })))))
(simplify
(cmp (bit_and:s (rshift:s @0 INTEGER_CST@1) INTEGER_CST@2) INTEGER_CST@3)
(if (tree_fits_shwi_p (@1)
&& tree_to_shwi (@1) > 0
- && tree_to_shwi (@1) < TYPE_PRECISION (TREE_TYPE (@0))
- && tree_to_shwi (@1) <= wi::clz (wi::to_wide (@2))
- && tree_to_shwi (@1) <= wi::clz (wi::to_wide (@3)))
- (cmp (bit_and @0 (lshift @2 @1)) (lshift @3 @1)))))
+ && tree_to_shwi (@1) < TYPE_PRECISION (TREE_TYPE (@0)))
+ (with { tree t0 = TREE_TYPE (@0);
+ unsigned int prec = TYPE_PRECISION (t0);
+ wide_int c1 = wi::to_wide (@1);
+ wide_int c2 = wi::to_wide (@2);
+ wide_int c3 = wi::to_wide (@3);
+ wide_int sb = wi::set_bit_in_zero (prec - 1, prec); }
+ (if ((c2 & c3) != c3)
+ { constant_boolean_node (cmp == NE_EXPR, type); }
+ (if (TYPE_UNSIGNED (t0))
+ (if ((c3 & wi::arshift (sb, c1 - 1)) != 0)
+ { constant_boolean_node (cmp == NE_EXPR, type); }
+ (cmp (bit_and @0 { wide_int_to_tree (t0, c2 << c1); })
+ { wide_int_to_tree (t0, c3 << c1); }))
+ (with { wide_int smask = wi::arshift (sb, c1); }
+ (switch
+ (if ((c2 & smask) == 0)
+ (cmp (bit_and @0 { wide_int_to_tree (t0, c2 << c1); })
+ { wide_int_to_tree (t0, c3 << c1); }))
+ (if ((c3 & smask) == 0)
+ (cmp (bit_and @0 { wide_int_to_tree (t0, (c2 << c1) | sb); })
+ { wide_int_to_tree (t0, c3 << c1); }))
+ (if ((c2 & smask) != (c3 & smask))
+ { constant_boolean_node (cmp == NE_EXPR, type); })
+ (cmp (bit_and @0 { wide_int_to_tree (t0, (c2 << c1) | sb); })
+ { wide_int_to_tree (t0, (c3 << c1) | sb); })))))))))
/* Fold (X << C1) & C2 into (X << C1) & (C2 | ((1 << C1) - 1))
(X >> C1) & C2 into (X >> C1) & (C2 | ~((type) -1 >> C1))
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 19a5303..9a31d8d 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,42 @@
+2022-08-09 David Malcolm <dmalcolm@redhat.com>
+
+ PR analyzer/106573
+ * gcc.dg/analyzer/error-uninit.c: New test.
+ * gcc.dg/analyzer/fd-uninit-1.c: New test.
+ * gcc.dg/analyzer/file-uninit-1.c: New test.
+
+2022-08-09 Roger Sayle <roger@nextmovesoftware.com>
+
+ * gcc.target/i386/sse4_1-stv-8.c: New test case.
+
+2022-08-09 Roger Sayle <roger@nextmovesoftware.com>
+ Richard Biener <rguenther@suse.de>
+
+ PR middle-end/21137
+ PR tree-optimization/98954
+ * gcc.dg/fold-eqandshift-4.c: New test case.
+
+2022-08-09 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ PR d/106563
+ * gdc.dg/torture/torture.exp (srcdir): New proc.
+ * gdc.dg/torture/imports/pr106563math.d: New test.
+ * gdc.dg/torture/imports/pr106563regex.d: New test.
+ * gdc.dg/torture/imports/pr106563uni.d: New test.
+ * gdc.dg/torture/pr106563.d: New test.
+
+2022-08-09 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/106514
+ * gcc.dg/tree-ssa/ssa-thread-16.c: New testcase.
+ * gcc.dg/tree-ssa/ssa-thread-17.c: Likewise.
+ * gcc.dg/tree-ssa/ssa-dom-thread-7.c: Adjust.
+
+2022-08-09 Tobias Burnus <tobias@codesourcery.com>
+
+ PR middle-end/106492
+ * g++.dg/gomp/pr106492.C: New test.
+
2022-08-08 Andrew MacLeod <amacleod@redhat.com>
PR tree-optimization/106556
diff --git a/gcc/testsuite/gcc.dg/analyzer/error-uninit.c b/gcc/testsuite/gcc.dg/analyzer/error-uninit.c
new file mode 100644
index 0000000..8d52a17
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/error-uninit.c
@@ -0,0 +1,29 @@
+/* Verify that we check for uninitialized values passed to functions
+ that we have special-cased region-model handling for. */
+
+extern void error (int __status, int __errnum, const char *__format, ...)
+ __attribute__ ((__format__ (__printf__, 3, 4)));
+
+void test_uninit_status (int arg)
+{
+ int st;
+ error (st, 42, "test: %s", arg); /* { dg-warning "use of uninitialized value 'st'" } */
+}
+
+void test_uninit_errnum (int st)
+{
+ int num;
+ error (st, num, "test"); /* { dg-warning "use of uninitialized value 'num'" } */
+}
+
+void test_uninit_fmt (int st)
+{
+ const char *fmt;
+ error (st, 42, fmt); /* { dg-warning "use of uninitialized value 'fmt'" } */
+}
+
+void test_uninit_vargs (int st)
+{
+ int arg;
+ error (st, 42, "test: %s", arg); /* { dg-warning "use of uninitialized value 'arg'" } */
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/fd-uninit-1.c b/gcc/testsuite/gcc.dg/analyzer/fd-uninit-1.c
new file mode 100644
index 0000000..b5b189e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/fd-uninit-1.c
@@ -0,0 +1,21 @@
+/* Verify that we check for uninitialized values passed to functions
+ that we have special-cased state-machine handling for. */
+
+int dup (int old_fd);
+int not_dup (int old_fd);
+
+int
+test_1 ()
+{
+ int m;
+ return dup (m); /* { dg-warning "use of uninitialized value 'm'" "uninit" } */
+ /* { dg-bogus "'dup' on possibly invalid file descriptor 'm'" "invalid fd false +ve" { xfail *-*-* } .-1 } */
+ /* XFAIL: probably covered by fix for PR analyzer/106551. */
+}
+
+int
+test_2 ()
+{
+ int m;
+ return not_dup (m); /* { dg-warning "use of uninitialized value 'm'" } */
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/file-uninit-1.c b/gcc/testsuite/gcc.dg/analyzer/file-uninit-1.c
new file mode 100644
index 0000000..0f8ac54
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/file-uninit-1.c
@@ -0,0 +1,52 @@
+/* Verify that we check for uninitialized values passed to functions
+ that we have special-cased state-machine handling for. */
+
+typedef struct FILE FILE;
+
+FILE* fopen (const char*, const char*);
+int fclose (FILE*);
+int fseek (FILE *, long, int);
+
+FILE *
+test_fopen_uninit_path (void)
+{
+ const char *path;
+ FILE *f = fopen (path, "r"); /* { dg-warning "use of uninitialized value 'path'" } */
+ return f;
+}
+
+FILE *
+test_fopen_uninit_mode (const char *path)
+{
+ const char *mode;
+ FILE *f = fopen (path, mode); /* { dg-warning "use of uninitialized value 'mode'" } */
+ return f;
+}
+
+void
+test_fclose_uninit (void)
+{
+ FILE *f;
+ fclose (f); /* { dg-warning "use of uninitialized value 'f'" } */
+}
+
+int
+test_fseek_uninit_stream (void)
+{
+ FILE *stream;
+ return fseek (stream, 0, 0); /* { dg-warning "use of uninitialized value 'stream'" } */
+}
+
+int
+test_fseek_uninit_offset (FILE *stream, int whence)
+{
+ long offset;
+ return fseek (stream, offset, whence); /* { dg-warning "use of uninitialized value 'offset'" } */
+}
+
+int
+test_fseek_uninit_whence (FILE *stream, long offset)
+{
+ int whence;
+ return fseek (stream, offset, whence); /* { dg-warning "use of uninitialized value 'whence'" } */
+}
diff --git a/gcc/testsuite/gcc.dg/fold-eqandshift-4.c b/gcc/testsuite/gcc.dg/fold-eqandshift-4.c
new file mode 100644
index 0000000..fbba438
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/fold-eqandshift-4.c
@@ -0,0 +1,46 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+
+int sr30eq00(signed char x) { return ((x >> 4) & 0x30) == 0; }
+int sr30ne00(signed char x) { return ((x >> 4) & 0x30) != 0; }
+int sr30eq20(signed char z) { return ((z >> 4) & 0x30) == 0x20; }
+int sr30ne20(signed char z) { return ((z >> 4) & 0x30) != 0x20; }
+int sr30eq30(signed char x) { return ((x >> 4) & 0x30) == 0x30; }
+int sr30ne30(signed char x) { return ((x >> 4) & 0x30) != 0x30; }
+int sr33eq33(signed char x) { return ((x >> 4) & 0x33) == 0x33; }
+int sr33ne33(signed char x) { return ((x >> 4) & 0x33) != 0x33; }
+
+int ur30eq00(unsigned char z) { return ((z >> 4) & 0x30) == 0; }
+int ur30ne00(unsigned char z) { return ((z >> 4) & 0x30) != 0; }
+int ur30eq30(unsigned char z) { return ((z >> 4) & 0x30) == 0x30; }
+int ur30ne30(unsigned char z) { return ((z >> 4) & 0x30) != 0x30; }
+int ur33eq03(unsigned char x) { return ((x >> 4) & 0x33) == 0x03; }
+int ur33ne03(unsigned char x) { return ((x >> 4) & 0x33) != 0x03; }
+int ur33eq30(unsigned char z) { return ((z >> 4) & 0x33) == 0x30; }
+int ur33ne30(unsigned char z) { return ((z >> 4) & 0x33) != 0x30; }
+int ur33eq33(unsigned char z) { return ((z >> 4) & 0x33) == 0x33; }
+int ur33ne33(unsigned char z) { return ((z >> 4) & 0x33) != 0x33; }
+
+int sl30eq00(char x) { return ((char)(x << 4) & 0x30) == 0; }
+int sl30ne00(char x) { return ((char)(x << 4) & 0x30) != 0; }
+int sl30eq20(char x) { return ((char)(x << 4) & 0x30) == 0x20; }
+int sl30ne20(char x) { return ((char)(x << 4) & 0x30) != 0x20; }
+int sl30eq30(char x) { return ((char)(x << 4) & 0x30) == 0x30; }
+int sl30ne30(char x) { return ((char)(x << 4) & 0x30) != 0x30; }
+int sl33eq00(char x) { return ((char)(x << 4) & 0x33) == 0; }
+int sl33ne00(char x) { return ((char)(x << 4) & 0x33) != 0; }
+int sl33eq03(char z) { return ((char)(z << 4) & 0x33) == 0x03; }
+int sl33ne03(char z) { return ((char)(z << 4) & 0x33) != 0x03; }
+int sl33eq30(char x) { return ((char)(x << 4) & 0x33) == 0x30; }
+int sl33ne30(char x) { return ((char)(x << 4) & 0x33) != 0x30; }
+int sl33eq33(char z) { return ((char)(z << 4) & 0x33) == 0x33; }
+int sl33ne33(char z) { return ((char)(z << 4) & 0x33) != 0x33; }
+
+/* { dg-final { scan-tree-dump-not " >> " "optimized" } } */
+/* { dg-final { scan-tree-dump-not " << " "optimized" } } */
+/* { dg-final { scan-tree-dump-not "z_\[0-9\]\\(D\\)" "optimized" } } */
+/* { dg-final { scan-tree-dump-times "return \[01\]" 14 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "char z\\)" 14 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "x_\[0-9\]\\(D\\)" 18 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "char x\\)" 18 "optimized" } } */
+
diff --git a/gcc/testsuite/gcc.target/i386/sse4_1-stv-8.c b/gcc/testsuite/gcc.target/i386/sse4_1-stv-8.c
new file mode 100644
index 0000000..5c5d803
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/sse4_1-stv-8.c
@@ -0,0 +1,11 @@
+/* { dg-do compile { target int128 } } */
+/* { dg-options "-O2 -msse4.1 -mstv -mno-stackrealign" } */
+
+__int128 a,b;
+int foo()
+{
+ return (a & b) != 0;
+}
+
+/* { dg-final { scan-assembler-not "pand" } } */
+/* { dg-final { scan-assembler "ptest" } } */