Merge branch 'master' into devel/sphinx
This commit is contained in:
commit
b629a7958f
|
@ -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
|
||||
|
|
|
@ -1 +1 @@
|
|||
20220809
|
||||
20220810
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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);
|
||||
{
|
||||
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, copy_rtx_if_shared (tmp),
|
||||
copy_rtx_if_shared (tmp)),
|
||||
UNSPEC_PTEST);
|
||||
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));
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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}},
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
45
gcc/match.pd
45
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))
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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'" } */
|
||||
}
|
|
@ -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'" } */
|
||||
}
|
|
@ -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'" } */
|
||||
}
|
|
@ -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" } } */
|
||||
|
|
@ -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" } } */
|
Loading…
Reference in New Issue