diff options
author | Martin Liska <mliska@suse.cz> | 2022-08-10 09:18:18 +0200 |
---|---|---|
committer | Martin Liska <mliska@suse.cz> | 2022-08-10 09:18:18 +0200 |
commit | b629a7958faf817ef658e3ce59183bfb9ccefe96 (patch) | |
tree | 4515688b7c5645bbc5d28b8a711bc7f8f9e9b119 | |
parent | 9fce2fbb1dff9f090d98a056df1da459ba45f16f (diff) | |
parent | c16d9f78dc81664e3341157c5a6efb85c0c141f4 (diff) | |
download | gcc-b629a7958faf817ef658e3ce59183bfb9ccefe96.zip gcc-b629a7958faf817ef658e3ce59183bfb9ccefe96.tar.gz gcc-b629a7958faf817ef658e3ce59183bfb9ccefe96.tar.bz2 |
Merge branch 'master' into devel/sphinx
-rw-r--r-- | gcc/ChangeLog | 95 | ||||
-rw-r--r-- | gcc/DATESTAMP | 2 | ||||
-rw-r--r-- | gcc/analyzer/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/analyzer/region-model.cc | 8 | ||||
-rw-r--r-- | gcc/config/i386/i386-features.cc | 95 | ||||
-rw-r--r-- | gcc/config/i386/i386.cc | 16 | ||||
-rw-r--r-- | gcc/config/i386/i386.md | 21 | ||||
-rw-r--r-- | gcc/config/i386/sse.md | 13 | ||||
-rw-r--r-- | gcc/d/ChangeLog | 14 | ||||
-rw-r--r-- | gcc/doc/invoke.texi | 81 | ||||
-rw-r--r-- | gcc/fold-const.cc | 54 | ||||
-rw-r--r-- | gcc/jit/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/jit/libgccjit.h | 4 | ||||
-rw-r--r-- | gcc/match.pd | 45 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 39 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/analyzer/error-uninit.c | 29 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/analyzer/fd-uninit-1.c | 21 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/analyzer/file-uninit-1.c | 52 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/fold-eqandshift-4.c | 46 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/sse4_1-stv-8.c | 11 |
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" } } */ |