diff --git a/.gitignore b/.gitignore index 21dcf61..990b516 100644 --- a/.gitignore +++ b/.gitignore @@ -58,3 +58,4 @@ /gcc-12.0.0-20220112.tar.xz /gcc-12.0.0-20220115.tar.xz /gcc-12.0.1-20220118.tar.xz +/gcc-12.0.1-20220125.tar.xz diff --git a/gcc.spec b/gcc.spec index 5379e6f..49a94f6 100644 --- a/gcc.spec +++ b/gcc.spec @@ -1,4 +1,4 @@ -%global DATE 20220118 +%global DATE 20220125 %global gitrev c682bc883d1a29c3f697f065af23759f3d6757bc %global gcc_version 12.0.1 %global gcc_major 12 @@ -11,6 +11,7 @@ %global _performance_build 1 # Hardening slows the compiler way too much. %undefine _hardened_build +%undefine _auto_set_build_flags %if 0%{?fedora} > 27 || 0%{?rhel} > 7 # Until annobin is fixed (#1519165). %undefine _annotated_build @@ -119,7 +120,7 @@ Summary: Various compilers (C, C++, Objective-C, ...) Name: gcc Version: %{gcc_version} -Release: %{gcc_release}.2%{?dist} +Release: %{gcc_release}.3%{?dist} # libgcc, libgfortran, libgomp, libstdc++ and crtstuff have # GCC Runtime Exception. License: GPLv3+ and GPLv3+ with exceptions and GPLv2+ with exceptions and LGPLv2+ and BSD @@ -269,9 +270,9 @@ Patch8: gcc12-no-add-needed.patch Patch9: gcc12-Wno-format-security.patch Patch10: gcc12-rh1574936.patch Patch11: gcc12-d-shared-libphobos.patch -Patch12: gcc12-pr104025.patch -Patch13: gcc12-pr104103.patch -Patch14: gcc12-pr104104.patch +Patch12: gcc12-pr104194.patch +Patch13: gcc12-pr94193.patch +Patch14: gcc12-ifcvt-revert.patch Patch100: gcc12-fortran-fdec-duplicates.patch Patch101: gcc12-fortran-flogical-as-integer.patch @@ -793,9 +794,9 @@ to NVidia PTX capable devices if available. %patch10 -p0 -b .rh1574936~ %endif %patch11 -p0 -b .d-shared-libphobos~ -%patch12 -p0 -b .pr104025~ -%patch13 -p0 -b .pr104103~ -%patch14 -p0 -b .pr104104~ +%patch12 -p0 -b .pr104194~ +%patch13 -p0 -b .pr94193~ +%patch14 -p0 -b .ifcvt-revert~ %if 0%{?rhel} >= 9 %patch100 -p1 -b .fortran-fdec-duplicates~ @@ -3155,6 +3156,36 @@ end %endif %changelog +* Tue Jan 24 2022 Jakub Jelinek 12.0.1-0.3 +- update from trunk + - PRs ada/103538, analyzer/94362, analyzer/103685, analyzer/104062, + analyzer/104089, analyzer/104150, analyzer/104159, bootstrap/104135, + bootstrap/104170, c++/20040, c++/55227, c++/91911, c++/101072, + c++/101405, c++/101715, c++/102300, c++/102338, c++/103631, + c++/103672, c++/103681, c++/104025, c++/104055, c++/104084, + c++/104134, c++/104139, c++/104148, c++/104173, c++/104182, + c++/104197, c/104115, debug/103874, fortran/102621, fortran/103695, + fortran/104127, libgcc/104207, libstdc++/87193, libstdc++/104019, + libstdc++/104032, libstdc++/104099, libstdc++/104101, + libstdc++/104123, libstdc++/104174, middle-end/100786, + middle-end/102860, middle-end/104069, middle-end/104076, + middle-end/104140, other/104176, other/104181, preprocessor/104030, + rtl-optimization/102478, sanitizer/99673, sanitizer/104158, + target/64821, target/94193, target/100784, target/102517, + target/103676, target/103771, target/104090, target/104136, + target/104188, testsuite/102833, testsuite/103763, testsuite/104021, + testsuite/104022, testsuite/104109, tree-optimization/100089, + tree-optimization/100740, tree-optimization/101508, + tree-optimization/101972, tree-optimization/102087, + tree-optimization/102131, tree-optimization/103721, + tree-optimization/103997, tree-optimization/104112, + tree-optimization/104114, tree-optimization/104152, + tree-optimization/104156, tree-optimization/104214 + - don't emit C++ mangling aliases for compatibility with GCC 8.1 ppc64le + IEEE quad long double (PR target/104172) +- mark IEEE quad long double in DWARF as implicit typedef to _Float128 + (PR debug/104194) + * Tue Jan 18 2022 Jakub Jelinek 12.0.1-0.2 - update from trunk - PRs c++/104007, c++/104074, fortran/103692, ipa/103989, libstdc++/101124, diff --git a/gcc12-ifcvt-revert.patch b/gcc12-ifcvt-revert.patch new file mode 100644 index 0000000..2261669 --- /dev/null +++ b/gcc12-ifcvt-revert.patch @@ -0,0 +1,1054 @@ +Revert r12-674{3,4,5,6,7,8,9}, as there are several PRs reported against +those changes: PR104153, PR104154 and PR104198 at least. + +--- gcc/config/rs6000/rs6000.cc ++++ gcc/config/rs6000/rs6000.cc +@@ -16373,10 +16373,10 @@ rs6000_emit_minmax (rtx dest, enum rtx_code code, rtx op0, rtx op1) + c = GEU; + + if (code == SMAX || code == UMAX) +- target = emit_conditional_move (dest, { c, op0, op1, mode }, ++ target = emit_conditional_move (dest, c, op0, op1, mode, + op0, op1, mode, 0); + else +- target = emit_conditional_move (dest, { c, op0, op1, mode }, ++ target = emit_conditional_move (dest, c, op0, op1, mode, + op1, op0, mode, 0); + gcc_assert (target); + if (target != dest) +@@ -22769,7 +22769,7 @@ rs6000_emit_swsqrt (rtx dst, rtx src, bool recip) + + if (mode == SFmode) + { +- rtx target = emit_conditional_move (e, { GT, src, zero, mode }, ++ rtx target = emit_conditional_move (e, GT, src, zero, mode, + e, zero, mode, 0); + if (target != e) + emit_move_insn (e, target); +--- gcc/expmed.cc ++++ gcc/expmed.cc +@@ -4124,8 +4124,8 @@ expand_sdiv_pow2 (scalar_int_mode mode, rtx op0, HOST_WIDE_INT d) + temp = force_reg (mode, temp); + + /* Construct "temp2 = (temp2 < 0) ? temp : temp2". */ +- temp2 = emit_conditional_move (temp2, { LT, temp2, const0_rtx, mode }, +- temp, temp2, mode, 0); ++ temp2 = emit_conditional_move (temp2, LT, temp2, const0_rtx, ++ mode, temp, temp2, mode, 0); + if (temp2) + { + rtx_insn *seq = get_insns (); +@@ -6127,10 +6127,10 @@ emit_store_flag (rtx target, enum rtx_code code, rtx op0, rtx op1, + return 0; + + if (and_them) +- tem = emit_conditional_move (target, { code, op0, op1, mode }, ++ tem = emit_conditional_move (target, code, op0, op1, mode, + tem, const0_rtx, GET_MODE (tem), 0); + else +- tem = emit_conditional_move (target, { code, op0, op1, mode }, ++ tem = emit_conditional_move (target, code, op0, op1, mode, + trueval, tem, GET_MODE (tem), 0); + + if (tem == 0) +--- gcc/expr.cc ++++ gcc/expr.cc +@@ -8824,9 +8824,8 @@ expand_cond_expr_using_cmove (tree treeop0 ATTRIBUTE_UNUSED, + op2 = gen_lowpart (mode, op2); + + /* Try to emit the conditional move. */ +- insn = emit_conditional_move (temp, +- { comparison_code, op00, op01, +- comparison_mode }, ++ insn = emit_conditional_move (temp, comparison_code, ++ op00, op01, comparison_mode, + op1, op2, mode, + unsignedp); + +@@ -9717,9 +9716,8 @@ expand_expr_real_2 (sepops ops, rtx target, machine_mode tmode, + start_sequence (); + + /* Try to emit the conditional move. */ +- insn = emit_conditional_move (target, +- { comparison_code, +- op0, cmpop1, mode }, ++ insn = emit_conditional_move (target, comparison_code, ++ op0, cmpop1, mode, + op0, op1, mode, + unsignedp); + +--- gcc/ifcvt.cc ++++ gcc/ifcvt.cc +@@ -83,7 +83,7 @@ static rtx_insn *last_active_insn (basic_block, int); + static rtx_insn *find_active_insn_before (basic_block, rtx_insn *); + static rtx_insn *find_active_insn_after (basic_block, rtx_insn *); + static basic_block block_fallthru (basic_block); +-static rtx cond_exec_get_condition (rtx_insn *, bool); ++static rtx cond_exec_get_condition (rtx_insn *); + static rtx noce_get_condition (rtx_insn *, rtx_insn **, bool); + static int noce_operand_ok (const_rtx); + static void merge_if_block (ce_if_block *); +@@ -98,14 +98,6 @@ static int dead_or_predicable (basic_block, basic_block, basic_block, + edge, int); + static void noce_emit_move_insn (rtx, rtx); + static rtx_insn *block_has_only_trap (basic_block); +-static void need_cmov_or_rewire (basic_block, hash_set *, +- hash_map *); +-static bool noce_convert_multiple_sets_1 (struct noce_if_info *, +- hash_set *, +- hash_map *, +- auto_vec *, +- auto_vec *, +- auto_vec *, int *); + + /* Count the number of non-jump active insns in BB. */ + +@@ -433,7 +425,7 @@ cond_exec_process_insns (ce_if_block *ce_info ATTRIBUTE_UNUSED, + /* Return the condition for a jump. Do not do any special processing. */ + + static rtx +-cond_exec_get_condition (rtx_insn *jump, bool get_reversed = false) ++cond_exec_get_condition (rtx_insn *jump) + { + rtx test_if, cond; + +@@ -445,10 +437,8 @@ cond_exec_get_condition (rtx_insn *jump, bool get_reversed = false) + + /* If this branches to JUMP_LABEL when the condition is false, + reverse the condition. */ +- if (get_reversed +- || (GET_CODE (XEXP (test_if, 2)) == LABEL_REF +- && label_ref_label (XEXP (test_if, 2)) +- == JUMP_LABEL (jump))) ++ if (GET_CODE (XEXP (test_if, 2)) == LABEL_REF ++ && label_ref_label (XEXP (test_if, 2)) == JUMP_LABEL (jump)) + { + enum rtx_code rev = reversed_comparison_code (cond, jump); + if (rev == UNKNOWN) +@@ -780,7 +770,7 @@ static int noce_try_addcc (struct noce_if_info *); + static int noce_try_store_flag_constants (struct noce_if_info *); + static int noce_try_store_flag_mask (struct noce_if_info *); + static rtx noce_emit_cmove (struct noce_if_info *, rtx, enum rtx_code, rtx, +- rtx, rtx, rtx, rtx = NULL, rtx = NULL); ++ rtx, rtx, rtx); + static int noce_try_cmove (struct noce_if_info *); + static int noce_try_cmove_arith (struct noce_if_info *); + static rtx noce_get_alt_condition (struct noce_if_info *, rtx, rtx_insn **); +@@ -1719,8 +1709,7 @@ noce_try_store_flag_mask (struct noce_if_info *if_info) + + static rtx + noce_emit_cmove (struct noce_if_info *if_info, rtx x, enum rtx_code code, +- rtx cmp_a, rtx cmp_b, rtx vfalse, rtx vtrue, rtx cc_cmp, +- rtx rev_cc_cmp) ++ rtx cmp_a, rtx cmp_b, rtx vfalse, rtx vtrue) + { + rtx target ATTRIBUTE_UNUSED; + int unsignedp ATTRIBUTE_UNUSED; +@@ -1752,30 +1741,23 @@ noce_emit_cmove (struct noce_if_info *if_info, rtx x, enum rtx_code code, + end_sequence (); + } + +- unsignedp = (code == LTU || code == GEU +- || code == LEU || code == GTU); +- +- if (cc_cmp != NULL_RTX && rev_cc_cmp != NULL_RTX) +- target = emit_conditional_move (x, cc_cmp, rev_cc_cmp, +- vtrue, vfalse, GET_MODE (x)); +- else ++ /* Don't even try if the comparison operands are weird ++ except that the target supports cbranchcc4. */ ++ if (! general_operand (cmp_a, GET_MODE (cmp_a)) ++ || ! general_operand (cmp_b, GET_MODE (cmp_b))) + { +- /* Don't even try if the comparison operands are weird +- except that the target supports cbranchcc4. */ +- if (! general_operand (cmp_a, GET_MODE (cmp_a)) +- || ! general_operand (cmp_b, GET_MODE (cmp_b))) +- { +- if (!have_cbranchcc4 +- || GET_MODE_CLASS (GET_MODE (cmp_a)) != MODE_CC +- || cmp_b != const0_rtx) +- return NULL_RTX; +- } +- +- target = emit_conditional_move (x, { code, cmp_a, cmp_b, VOIDmode }, +- vtrue, vfalse, GET_MODE (x), +- unsignedp); ++ if (!have_cbranchcc4 ++ || GET_MODE_CLASS (GET_MODE (cmp_a)) != MODE_CC ++ || cmp_b != const0_rtx) ++ return NULL_RTX; + } + ++ unsignedp = (code == LTU || code == GEU ++ || code == LEU || code == GTU); ++ ++ target = emit_conditional_move (x, code, cmp_a, cmp_b, VOIDmode, ++ vtrue, vfalse, GET_MODE (x), ++ unsignedp); + if (target) + return target; + +@@ -1811,9 +1793,8 @@ noce_emit_cmove (struct noce_if_info *if_info, rtx x, enum rtx_code code, + + promoted_target = gen_reg_rtx (GET_MODE (reg_vtrue)); + +- target = emit_conditional_move (promoted_target, +- { code, cmp_a, cmp_b, VOIDmode }, +- reg_vtrue, reg_vfalse, ++ target = emit_conditional_move (promoted_target, code, cmp_a, cmp_b, ++ VOIDmode, reg_vtrue, reg_vfalse, + GET_MODE (reg_vtrue), unsignedp); + /* Nope, couldn't do it in that mode either. */ + if (!target) +@@ -3160,50 +3141,6 @@ bb_valid_for_noce_process_p (basic_block test_bb, rtx cond, + return false; + } + +-/* Helper function to emit a cmov sequence encapsulated in +- start_sequence () and end_sequence (). If NEED_CMOV is true +- we call noce_emit_cmove to create a cmove sequence. Otherwise emit +- a simple move. If successful, store the first instruction of the +- sequence in TEMP_DEST and the sequence costs in SEQ_COST. */ +- +-static rtx_insn* +-try_emit_cmove_seq (struct noce_if_info *if_info, rtx temp, +- rtx cond, rtx new_val, rtx old_val, bool need_cmov, +- unsigned *cost, rtx *temp_dest, +- rtx cc_cmp = NULL, rtx rev_cc_cmp = NULL) +-{ +- rtx_insn *seq = NULL; +- *cost = 0; +- +- rtx x = XEXP (cond, 0); +- rtx y = XEXP (cond, 1); +- rtx_code cond_code = GET_CODE (cond); +- +- start_sequence (); +- +- if (need_cmov) +- *temp_dest = noce_emit_cmove (if_info, temp, cond_code, +- x, y, new_val, old_val, cc_cmp, rev_cc_cmp); +- else +- { +- *temp_dest = temp; +- if (if_info->then_else_reversed) +- noce_emit_move_insn (temp, old_val); +- else +- noce_emit_move_insn (temp, new_val); +- } +- +- if (*temp_dest != NULL_RTX) +- { +- seq = get_insns (); +- *cost = seq_cost (seq, if_info->speed_p); +- } +- +- end_sequence (); +- +- return seq; +-} +- + /* We have something like: + + if (x > y) +@@ -3261,6 +3198,7 @@ noce_convert_multiple_sets (struct noce_if_info *if_info) + rtx cond = noce_get_condition (jump, &cond_earliest, false); + rtx x = XEXP (cond, 0); + rtx y = XEXP (cond, 1); ++ rtx_code cond_code = GET_CODE (cond); + + /* The true targets for a conditional move. */ + auto_vec targets; +@@ -3269,139 +3207,8 @@ noce_convert_multiple_sets (struct noce_if_info *if_info) + auto_vec temporaries; + /* The insns we've emitted. */ + auto_vec unmodified_insns; +- +- hash_set need_no_cmov; +- hash_map rewired_src; +- +- need_cmov_or_rewire (then_bb, &need_no_cmov, &rewired_src); +- +- int last_needs_comparison = -1; +- +- bool ok = noce_convert_multiple_sets_1 +- (if_info, &need_no_cmov, &rewired_src, &targets, &temporaries, +- &unmodified_insns, &last_needs_comparison); +- if (!ok) +- return false; +- +- /* If there are insns that overwrite part of the initial +- comparison, we can still omit creating temporaries for +- the last of them. +- As the second try will always create a less expensive, +- valid sequence, we do not need to compare and can discard +- the first one. */ +- if (last_needs_comparison != -1) +- { +- end_sequence (); +- start_sequence (); +- ok = noce_convert_multiple_sets_1 +- (if_info, &need_no_cmov, &rewired_src, &targets, &temporaries, +- &unmodified_insns, &last_needs_comparison); +- /* Actually we should not fail anymore if we reached here, +- but better still check. */ +- if (!ok) +- return false; +- } +- +- /* We must have seen some sort of insn to insert, otherwise we were +- given an empty BB to convert, and we can't handle that. */ +- gcc_assert (!unmodified_insns.is_empty ()); +- +- /* Now fixup the assignments. */ +- for (unsigned i = 0; i < targets.length (); i++) +- if (targets[i] != temporaries[i]) +- noce_emit_move_insn (targets[i], temporaries[i]); +- +- /* Actually emit the sequence if it isn't too expensive. */ +- rtx_insn *seq = get_insns (); +- +- if (!targetm.noce_conversion_profitable_p (seq, if_info)) +- { +- end_sequence (); +- return FALSE; +- } +- +- for (insn = seq; insn; insn = NEXT_INSN (insn)) +- set_used_flags (insn); +- +- /* Mark all our temporaries and targets as used. */ +- for (unsigned i = 0; i < targets.length (); i++) +- { +- set_used_flags (temporaries[i]); +- set_used_flags (targets[i]); +- } +- +- set_used_flags (cond); +- set_used_flags (x); +- set_used_flags (y); +- +- unshare_all_rtl_in_chain (seq); +- end_sequence (); +- +- if (!seq) +- return FALSE; +- +- for (insn = seq; insn; insn = NEXT_INSN (insn)) +- if (JUMP_P (insn) +- || recog_memoized (insn) == -1) +- return FALSE; +- +- emit_insn_before_setloc (seq, if_info->jump, +- INSN_LOCATION (unmodified_insns.last ())); +- +- /* Clean up THEN_BB and the edges in and out of it. */ +- remove_edge (find_edge (test_bb, join_bb)); +- remove_edge (find_edge (then_bb, join_bb)); +- redirect_edge_and_branch_force (single_succ_edge (test_bb), join_bb); +- delete_basic_block (then_bb); +- num_true_changes++; +- +- /* Maybe merge blocks now the jump is simple enough. */ +- if (can_merge_blocks_p (test_bb, join_bb)) +- { +- merge_blocks (test_bb, join_bb); +- num_true_changes++; +- } +- +- num_updated_if_blocks++; +- if_info->transform_name = "noce_convert_multiple_sets"; +- return TRUE; +-} +- +-/* This goes through all relevant insns of IF_INFO->then_bb and tries to +- create conditional moves. In case a simple move sufficis the insn +- should be listed in NEED_NO_CMOV. The rewired-src cases should be +- specified via REWIRED_SRC. TARGETS, TEMPORARIES and UNMODIFIED_INSNS +- are specified and used in noce_convert_multiple_sets and should be passed +- to this function.. */ +- +-static bool +-noce_convert_multiple_sets_1 (struct noce_if_info *if_info, +- hash_set *need_no_cmov, +- hash_map *rewired_src, +- auto_vec *targets, +- auto_vec *temporaries, +- auto_vec *unmodified_insns, +- int *last_needs_comparison) +-{ +- basic_block then_bb = if_info->then_bb; +- rtx_insn *jump = if_info->jump; +- rtx_insn *cond_earliest; +- +- /* Decompose the condition attached to the jump. */ +- rtx cond = noce_get_condition (jump, &cond_earliest, false); +- +- rtx cc_cmp = cond_exec_get_condition (jump); +- rtx rev_cc_cmp = cond_exec_get_condition (jump, /* get_reversed */ true); +- +- rtx_insn *insn; + int count = 0; + +- targets->truncate (0); +- temporaries->truncate (0); +- unmodified_insns->truncate (0); +- +- bool second_try = *last_needs_comparison != -1; +- + FOR_BB_INSNS (then_bb, insn) + { + /* Skip over non-insns. */ +@@ -3412,53 +3219,26 @@ noce_convert_multiple_sets_1 (struct noce_if_info *if_info, + gcc_checking_assert (set); + + rtx target = SET_DEST (set); +- rtx temp; +- ++ rtx temp = gen_reg_rtx (GET_MODE (target)); + rtx new_val = SET_SRC (set); +- if (int *ii = rewired_src->get (insn)) +- new_val = simplify_replace_rtx (new_val, (*targets)[*ii], +- (*temporaries)[*ii]); + rtx old_val = target; + +- /* As we are transforming +- if (x > y) +- { +- a = b; +- c = d; +- } +- into +- a = (x > y) ... +- c = (x > y) ... +- +- we potentially check x > y before every set. +- Even though the check might be removed by subsequent passes, this means +- that we cannot transform +- if (x > y) +- { +- x = y; +- ... +- } +- into +- x = (x > y) ... +- ... +- since this would invalidate x and the following to-be-removed checks. +- Therefore we introduce a temporary every time we are about to +- overwrite a variable used in the check. Costing of a sequence with +- these is going to be inaccurate so only use temporaries when +- needed. +- +- If performing a second try, we know how many insns require a +- temporary. For the last of these, we can omit creating one. */ +- if (reg_overlap_mentioned_p (target, cond) +- && (!second_try || count < *last_needs_comparison)) +- temp = gen_reg_rtx (GET_MODE (target)); +- else +- temp = target; +- +- /* We have identified swap-style idioms before. A normal +- set will need to be a cmov while the first instruction of a swap-style +- idiom can be a regular move. This helps with costing. */ +- bool need_cmov = !need_no_cmov->contains (insn); ++ /* If we were supposed to read from an earlier write in this block, ++ we've changed the register allocation. Rewire the read. While ++ we are looking, also try to catch a swap idiom. */ ++ for (int i = count - 1; i >= 0; --i) ++ if (reg_overlap_mentioned_p (new_val, targets[i])) ++ { ++ /* Catch a "swap" style idiom. */ ++ if (find_reg_note (insn, REG_DEAD, new_val) != NULL_RTX) ++ /* The write to targets[i] is only live until the read ++ here. As the condition codes match, we can propagate ++ the set to here. */ ++ new_val = SET_SRC (single_set (unmodified_insns[i])); ++ else ++ new_val = temporaries[i]; ++ break; ++ } + + /* If we had a non-canonical conditional jump (i.e. one where + the fallthrough is to the "else" case) we need to reverse +@@ -3478,9 +3258,7 @@ noce_convert_multiple_sets_1 (struct noce_if_info *if_info, + we'll end up trying to emit r4:HI = cond ? (r1:SI) : (r3:HI). + Wrap the two cmove operands into subregs if appropriate to prevent + that. */ +- +- if (!CONSTANT_P (new_val) +- && GET_MODE (new_val) != GET_MODE (temp)) ++ if (GET_MODE (new_val) != GET_MODE (temp)) + { + machine_mode src_mode = GET_MODE (new_val); + machine_mode dst_mode = GET_MODE (temp); +@@ -3491,8 +3269,7 @@ noce_convert_multiple_sets_1 (struct noce_if_info *if_info, + } + new_val = lowpart_subreg (dst_mode, new_val, src_mode); + } +- if (!CONSTANT_P (old_val) +- && GET_MODE (old_val) != GET_MODE (temp)) ++ if (GET_MODE (old_val) != GET_MODE (temp)) + { + machine_mode src_mode = GET_MODE (old_val); + machine_mode dst_mode = GET_MODE (temp); +@@ -3504,80 +3281,101 @@ noce_convert_multiple_sets_1 (struct noce_if_info *if_info, + old_val = lowpart_subreg (dst_mode, old_val, src_mode); + } + +- /* Try emitting a conditional move passing the backend the +- canonicalized comparison. The backend is then able to +- recognize expressions like +- +- if (x > y) +- y = x; +- +- as min/max and emit an insn, accordingly. */ +- unsigned cost1 = 0, cost2 = 0; +- rtx_insn *seq, *seq1, *seq2; +- rtx temp_dest = NULL_RTX, temp_dest1 = NULL_RTX, temp_dest2 = NULL_RTX; ++ /* Actually emit the conditional move. */ ++ rtx temp_dest = noce_emit_cmove (if_info, temp, cond_code, ++ x, y, new_val, old_val); + +- seq1 = try_emit_cmove_seq (if_info, temp, cond, +- new_val, old_val, need_cmov, +- &cost1, &temp_dest1); +- +- /* Here, we try to pass the backend a non-canonicalized cc comparison +- as well. This allows the backend to emit a cmov directly without +- creating an additional compare for each. If successful, costing +- is easier and this sequence is usually preferred. */ +- seq2 = try_emit_cmove_seq (if_info, target, cond, +- new_val, old_val, need_cmov, +- &cost2, &temp_dest2, cc_cmp, rev_cc_cmp); +- +- /* Check which version is less expensive. */ +- if (seq1 != NULL_RTX && (cost1 <= cost2 || seq2 == NULL_RTX)) +- { +- seq = seq1; +- temp_dest = temp_dest1; +- if (!second_try) +- *last_needs_comparison = count; +- } +- else if (seq2 != NULL_RTX) +- { +- seq = seq2; +- temp_dest = temp_dest2; +- } +- else ++ /* If we failed to expand the conditional move, drop out and don't ++ try to continue. */ ++ if (temp_dest == NULL_RTX) + { +- /* Nothing worked, bail out. */ + end_sequence (); + return FALSE; + } + +- /* End the sub sequence and emit to the main sequence. */ +- emit_insn (seq); +- + /* Bookkeeping. */ + count++; +- targets->safe_push (target); +- temporaries->safe_push (temp_dest); +- unmodified_insns->safe_push (insn); ++ targets.safe_push (target); ++ temporaries.safe_push (temp_dest); ++ unmodified_insns.safe_push (insn); + } + +- return true; +-} ++ /* We must have seen some sort of insn to insert, otherwise we were ++ given an empty BB to convert, and we can't handle that. */ ++ gcc_assert (!unmodified_insns.is_empty ()); ++ ++ /* Now fixup the assignments. */ ++ for (int i = 0; i < count; i++) ++ noce_emit_move_insn (targets[i], temporaries[i]); ++ ++ /* Actually emit the sequence if it isn't too expensive. */ ++ rtx_insn *seq = get_insns (); ++ ++ if (!targetm.noce_conversion_profitable_p (seq, if_info)) ++ { ++ end_sequence (); ++ return FALSE; ++ } ++ ++ for (insn = seq; insn; insn = NEXT_INSN (insn)) ++ set_used_flags (insn); ++ ++ /* Mark all our temporaries and targets as used. */ ++ for (int i = 0; i < count; i++) ++ { ++ set_used_flags (temporaries[i]); ++ set_used_flags (targets[i]); ++ } + ++ set_used_flags (cond); ++ set_used_flags (x); ++ set_used_flags (y); + ++ unshare_all_rtl_in_chain (seq); ++ end_sequence (); ++ ++ if (!seq) ++ return FALSE; ++ ++ for (insn = seq; insn; insn = NEXT_INSN (insn)) ++ if (JUMP_P (insn) ++ || recog_memoized (insn) == -1) ++ return FALSE; ++ ++ emit_insn_before_setloc (seq, if_info->jump, ++ INSN_LOCATION (unmodified_insns.last ())); ++ ++ /* Clean up THEN_BB and the edges in and out of it. */ ++ remove_edge (find_edge (test_bb, join_bb)); ++ remove_edge (find_edge (then_bb, join_bb)); ++ redirect_edge_and_branch_force (single_succ_edge (test_bb), join_bb); ++ delete_basic_block (then_bb); ++ num_true_changes++; ++ ++ /* Maybe merge blocks now the jump is simple enough. */ ++ if (can_merge_blocks_p (test_bb, join_bb)) ++ { ++ merge_blocks (test_bb, join_bb); ++ num_true_changes++; ++ } ++ ++ num_updated_if_blocks++; ++ if_info->transform_name = "noce_convert_multiple_sets"; ++ return TRUE; ++} + + /* Return true iff basic block TEST_BB is comprised of only + (SET (REG) (REG)) insns suitable for conversion to a series + of conditional moves. Also check that we have more than one set + (other routines can handle a single set better than we would), and +- fewer than PARAM_MAX_RTL_IF_CONVERSION_INSNS sets. While going +- through the insns store the sum of their potential costs in COST. */ ++ fewer than PARAM_MAX_RTL_IF_CONVERSION_INSNS sets. */ + + static bool +-bb_ok_for_noce_convert_multiple_sets (basic_block test_bb, unsigned *cost) ++bb_ok_for_noce_convert_multiple_sets (basic_block test_bb) + { + rtx_insn *insn; + unsigned count = 0; + unsigned param = param_max_rtl_if_conversion_insns; +- bool speed_p = optimize_bb_for_speed_p (test_bb); +- unsigned potential_cost = 0; + + FOR_BB_INSNS (test_bb, insn) + { +@@ -3600,9 +3398,9 @@ bb_ok_for_noce_convert_multiple_sets (basic_block test_bb, unsigned *cost) + if (!REG_P (dest)) + return false; + +- if (!((REG_P (src) || CONSTANT_P (src)) +- || (GET_CODE (src) == SUBREG && REG_P (SUBREG_REG (src)) +- && subreg_lowpart_p (src)))) ++ if (!(REG_P (src) ++ || (GET_CODE (src) == SUBREG && REG_P (SUBREG_REG (src)) ++ && subreg_lowpart_p (src)))) + return false; + + /* Destination must be appropriate for a conditional write. */ +@@ -3613,13 +3411,9 @@ bb_ok_for_noce_convert_multiple_sets (basic_block test_bb, unsigned *cost) + if (!can_conditionally_move_p (GET_MODE (dest))) + return false; + +- potential_cost += insn_cost (insn, speed_p); +- + count++; + } + +- *cost += potential_cost; +- + /* If we would only put out one conditional move, the other strategies + this pass tries are better optimized and will be more appropriate. + Some targets want to strictly limit the number of conditional moves +@@ -3667,24 +3461,11 @@ noce_process_if_block (struct noce_if_info *if_info) + to calculate a value for x. + ??? For future expansion, further expand the "multiple X" rules. */ + +- /* First look for multiple SETS. The original costs already include +- a base cost of COSTS_N_INSNS (2): one instruction for the compare +- (which we will be needing either way) and one instruction for the +- branch. When comparing costs we want to use the branch instruction +- cost and the sets vs. the cmovs generated here. Therefore subtract +- the costs of the compare before checking. +- ??? Actually, instead of the branch instruction costs we might want +- to use COSTS_N_INSNS (BRANCH_COST ()) as in other places. */ +- +- unsigned potential_cost = if_info->original_cost - COSTS_N_INSNS (1); +- unsigned old_cost = if_info->original_cost; ++ /* First look for multiple SETS. */ + if (!else_bb + && HAVE_conditional_move +- && bb_ok_for_noce_convert_multiple_sets (then_bb, &potential_cost)) ++ && bb_ok_for_noce_convert_multiple_sets (then_bb)) + { +- /* Temporarily set the original costs to what we estimated so +- we can determine if the transformation is worth it. */ +- if_info->original_cost = potential_cost; + if (noce_convert_multiple_sets (if_info)) + { + if (dump_file && if_info->transform_name) +@@ -3692,9 +3473,6 @@ noce_process_if_block (struct noce_if_info *if_info) + if_info->transform_name); + return TRUE; + } +- +- /* Restore the original costs. */ +- if_info->original_cost = old_cost; + } + + bool speed_p = optimize_bb_for_speed_p (test_bb); +@@ -4036,89 +3814,6 @@ check_cond_move_block (basic_block bb, + return TRUE; + } + +-/* Find local swap-style idioms in BB and mark the first insn (1) +- that is only a temporary as not needing a conditional move as +- it is going to be dead afterwards anyway. +- +- (1) int tmp = a; +- a = b; +- b = tmp; +- +- ifcvt +- --> +- +- tmp = a; +- a = cond ? b : a_old; +- b = cond ? tmp : b_old; +- +- Additionally, store the index of insns like (2) when a subsequent +- SET reads from their destination. +- +- (2) int c = a; +- int d = c; +- +- ifcvt +- --> +- +- c = cond ? a : c_old; +- d = cond ? d : c; // Need to use c rather than c_old here. +-*/ +- +-static void +-need_cmov_or_rewire (basic_block bb, +- hash_set *need_no_cmov, +- hash_map *rewired_src) +-{ +- rtx_insn *insn; +- int count = 0; +- auto_vec insns; +- auto_vec dests; +- +- /* Iterate over all SETs, storing the destinations +- in DEST. +- - If we hit a SET that reads from a destination +- that we have seen before and the corresponding register +- is dead afterwards, the register does not need to be +- moved conditionally. +- - If we encounter a previously changed register, +- rewire the read to the original source. */ +- FOR_BB_INSNS (bb, insn) +- { +- rtx set, src, dest; +- +- if (!active_insn_p (insn)) +- continue; +- +- set = single_set (insn); +- if (set == NULL_RTX) +- continue; +- +- src = SET_SRC (set); +- if (SUBREG_P (src)) +- src = SUBREG_REG (src); +- dest = SET_DEST (set); +- +- /* Check if the current SET's source is the same +- as any previously seen destination. +- This is quadratic but the number of insns in BB +- is bounded by PARAM_MAX_RTL_IF_CONVERSION_INSNS. */ +- if (REG_P (src)) +- for (int i = count - 1; i >= 0; --i) +- if (reg_overlap_mentioned_p (src, dests[i])) +- { +- if (find_reg_note (insn, REG_DEAD, src) != NULL_RTX) +- need_no_cmov->add (insns[i]); +- else +- rewired_src->put (insn, i); +- } +- +- insns.safe_push (insn); +- dests.safe_push (dest); +- +- count++; +- } +-} +- + /* Given a basic block BB suitable for conditional move conversion, + a condition COND, and pointer maps THEN_VALS and ELSE_VALS containing + the register values depending on COND, emit the insns in the block as +--- gcc/optabs.cc ++++ gcc/optabs.cc +@@ -52,8 +52,6 @@ static void prepare_float_lib_cmp (rtx, rtx, enum rtx_code, rtx *, + static rtx expand_unop_direct (machine_mode, optab, rtx, rtx, int); + static void emit_libcall_block_1 (rtx_insn *, rtx, rtx, rtx, bool); + +-static rtx emit_conditional_move_1 (rtx, rtx, rtx, rtx, machine_mode); +- + /* Debug facility for use in GDB. */ + void debug_optab_libfuncs (void); + +@@ -626,13 +624,12 @@ expand_doubleword_shift_condmove (scalar_int_mode op1_mode, optab binoptab, + + /* Select between them. Do the INTO half first because INTO_SUPERWORD + might be the current value of OUTOF_TARGET. */ +- if (!emit_conditional_move (into_target, { cmp_code, cmp1, cmp2, op1_mode }, ++ if (!emit_conditional_move (into_target, cmp_code, cmp1, cmp2, op1_mode, + into_target, into_superword, word_mode, false)) + return false; + + if (outof_target != 0) +- if (!emit_conditional_move (outof_target, +- { cmp_code, cmp1, cmp2, op1_mode }, ++ if (!emit_conditional_move (outof_target, cmp_code, cmp1, cmp2, op1_mode, + outof_target, outof_superword, + word_mode, false)) + return false; +@@ -4854,8 +4851,8 @@ emit_indirect_jump (rtx loc) + is not supported. */ + + rtx +-emit_conditional_move (rtx target, struct rtx_comparison comp, +- rtx op2, rtx op3, ++emit_conditional_move (rtx target, enum rtx_code code, rtx op0, rtx op1, ++ machine_mode cmode, rtx op2, rtx op3, + machine_mode mode, int unsignedp) + { + rtx comparison; +@@ -4877,33 +4874,31 @@ emit_conditional_move (rtx target, struct rtx_comparison comp, + /* If one operand is constant, make it the second one. Only do this + if the other operand is not constant as well. */ + +- if (swap_commutative_operands_p (comp.op0, comp.op1)) ++ if (swap_commutative_operands_p (op0, op1)) + { +- std::swap (comp.op0, comp.op1); +- comp.code = swap_condition (comp.code); ++ std::swap (op0, op1); ++ code = swap_condition (code); + } + + /* get_condition will prefer to generate LT and GT even if the old + comparison was against zero, so undo that canonicalization here since + comparisons against zero are cheaper. */ ++ if (code == LT && op1 == const1_rtx) ++ code = LE, op1 = const0_rtx; ++ else if (code == GT && op1 == constm1_rtx) ++ code = GE, op1 = const0_rtx; + +- if (comp.code == LT && comp.op1 == const1_rtx) +- comp.code = LE, comp.op1 = const0_rtx; +- else if (comp.code == GT && comp.op1 == constm1_rtx) +- comp.code = GE, comp.op1 = const0_rtx; +- +- if (comp.mode == VOIDmode) +- comp.mode = GET_MODE (comp.op0); ++ if (cmode == VOIDmode) ++ cmode = GET_MODE (op0); + +- enum rtx_code orig_code = comp.code; ++ enum rtx_code orig_code = code; + bool swapped = false; + if (swap_commutative_operands_p (op2, op3) +- && ((reversed = +- reversed_comparison_code_parts (comp.code, comp.op0, comp.op1, NULL)) +- != UNKNOWN)) ++ && ((reversed = reversed_comparison_code_parts (code, op0, op1, NULL)) ++ != UNKNOWN)) + { + std::swap (op2, op3); +- comp.code = reversed; ++ code = reversed; + swapped = true; + } + +@@ -4920,10 +4915,8 @@ emit_conditional_move (rtx target, struct rtx_comparison comp, + + for (int pass = 0; ; pass++) + { +- comp.code = unsignedp ? unsigned_condition (comp.code) : comp.code; +- comparison = +- simplify_gen_relational (comp.code, VOIDmode, +- comp.mode, comp.op0, comp.op1); ++ code = unsignedp ? unsigned_condition (code) : code; ++ comparison = simplify_gen_relational (code, VOIDmode, cmode, op0, op1); + + /* We can get const0_rtx or const_true_rtx in some circumstances. Just + punt and let the caller figure out how best to deal with this +@@ -4934,16 +4927,24 @@ emit_conditional_move (rtx target, struct rtx_comparison comp, + save_pending_stack_adjust (&save); + last = get_last_insn (); + do_pending_stack_adjust (); +- machine_mode cmpmode = comp.mode; ++ machine_mode cmpmode = cmode; + prepare_cmp_insn (XEXP (comparison, 0), XEXP (comparison, 1), + GET_CODE (comparison), NULL_RTX, unsignedp, + OPTAB_WIDEN, &comparison, &cmpmode); + if (comparison) + { +- rtx res = emit_conditional_move_1 (target, comparison, +- op2, op3, mode); +- if (res != NULL_RTX) +- return res; ++ class expand_operand ops[4]; ++ ++ create_output_operand (&ops[0], target, mode); ++ create_fixed_operand (&ops[1], comparison); ++ create_input_operand (&ops[2], op2, mode); ++ create_input_operand (&ops[3], op3, mode); ++ if (maybe_expand_insn (icode, 4, ops)) ++ { ++ if (ops[0].value != target) ++ convert_move (target, ops[0].value, false); ++ return target; ++ } + } + delete_insns_since (last); + restore_pending_stack_adjust (&save); +@@ -4955,88 +4956,17 @@ emit_conditional_move (rtx target, struct rtx_comparison comp, + /* If the preferred op2/op3 order is not usable, retry with other + operand order, perhaps it will expand successfully. */ + if (swapped) +- comp.code = orig_code; +- else if ((reversed = +- reversed_comparison_code_parts (orig_code, comp.op0, comp.op1, ++ code = orig_code; ++ else if ((reversed = reversed_comparison_code_parts (orig_code, op0, op1, + NULL)) + != UNKNOWN) +- comp.code = reversed; ++ code = reversed; + else + return NULL_RTX; + std::swap (op2, op3); + } + } + +-/* Helper function that, in addition to COMPARISON, also tries +- the reversed REV_COMPARISON with swapped OP2 and OP3. As opposed +- to when we pass the specific constituents of a comparison, no +- additional insns are emitted for it. It might still be necessary +- to emit more than one insn for the final conditional move, though. */ +- +-rtx +-emit_conditional_move (rtx target, rtx comparison, rtx rev_comparison, +- rtx op2, rtx op3, machine_mode mode) +-{ +- rtx res = emit_conditional_move_1 (target, comparison, op2, op3, mode); +- +- if (res != NULL_RTX) +- return res; +- +- return emit_conditional_move_1 (target, rev_comparison, op3, op2, mode); +-} +- +-/* Helper for emitting a conditional move. */ +- +-static rtx +-emit_conditional_move_1 (rtx target, rtx comparison, +- rtx op2, rtx op3, machine_mode mode) +-{ +- enum insn_code icode; +- +- if (comparison == NULL_RTX || !COMPARISON_P (comparison)) +- return NULL_RTX; +- +- /* If the two source operands are identical, that's just a move. +- As the comparison comes in non-canonicalized, we must make +- sure not to discard any possible side effects. If there are +- side effects, just let the target handle it. */ +- if (!side_effects_p (comparison) && rtx_equal_p (op2, op3)) +- { +- if (!target) +- target = gen_reg_rtx (mode); +- +- emit_move_insn (target, op3); +- return target; +- } +- +- if (mode == VOIDmode) +- mode = GET_MODE (op2); +- +- icode = direct_optab_handler (movcc_optab, mode); +- +- if (icode == CODE_FOR_nothing) +- return NULL_RTX; +- +- if (!target) +- target = gen_reg_rtx (mode); +- +- class expand_operand ops[4]; +- +- create_output_operand (&ops[0], target, mode); +- create_fixed_operand (&ops[1], comparison); +- create_input_operand (&ops[2], op2, mode); +- create_input_operand (&ops[3], op3, mode); +- +- if (maybe_expand_insn (icode, 4, ops)) +- { +- if (ops[0].value != target) +- convert_move (target, ops[0].value, false); +- return target; +- } +- +- return NULL_RTX; +-} +- + + /* Emit a conditional negate or bitwise complement using the + negcc or notcc optabs if available. Return NULL_RTX if such operations +--- gcc/optabs.h ++++ gcc/optabs.h +@@ -279,8 +279,8 @@ extern void emit_indirect_jump (rtx); + #endif + + /* Emit a conditional move operation. */ +-rtx emit_conditional_move (rtx, rtx_comparison, rtx, rtx, machine_mode, int); +-rtx emit_conditional_move (rtx, rtx, rtx, rtx, rtx, machine_mode); ++rtx emit_conditional_move (rtx, enum rtx_code, rtx, rtx, machine_mode, ++ rtx, rtx, machine_mode, int); + + /* Emit a conditional negate or bitwise complement operation. */ + rtx emit_conditional_neg_or_complement (rtx, rtx_code, machine_mode, rtx, +--- gcc/rtl.h ++++ gcc/rtl.h +@@ -4604,16 +4604,7 @@ word_register_operation_p (const_rtx x) + return true; + } + } +- +-/* Holds an rtx comparison to simplify passing many parameters pertaining to a +- single comparison. */ +- +-struct rtx_comparison { +- rtx_code code; +- rtx op0, op1; +- machine_mode mode; +-}; +- ++ + /* gtype-desc.cc. */ + extern void gt_ggc_mx (rtx &); + extern void gt_pch_nx (rtx &); diff --git a/gcc12-pr104025.patch b/gcc12-pr104025.patch deleted file mode 100644 index 3010236..0000000 --- a/gcc12-pr104025.patch +++ /dev/null @@ -1,42 +0,0 @@ -2022-01-18 Jakub Jelinek - - PR c++/104025 - * parser.cc (cp_parser_id_expression): Save and restore input_location - around cp_parser_skip_entire_template_parameter_list call for - -Wmissing-template-keyword. - - * g++.dg/warn/pr104025.C: New test. - ---- gcc/cp/parser.cc.jj 2022-01-17 18:05:04.797307506 +0100 -+++ gcc/cp/parser.cc 2022-01-17 20:27:33.642711859 +0100 -@@ -6254,6 +6254,7 @@ cp_parser_id_expression (cp_parser *pars - OPT_Wmissing_template_keyword)) - { - saved_token_sentinel toks (parser->lexer, STS_ROLLBACK); -+ iloc_sentinel ils (UNKNOWN_LOCATION); - if (cp_parser_skip_entire_template_parameter_list (parser) - /* An operator after the > suggests that the > ends a - template-id; a name or literal suggests that the > is an ---- gcc/testsuite/g++.dg/warn/pr104025.C.jj 2022-01-17 20:31:17.320591249 +0100 -+++ gcc/testsuite/g++.dg/warn/pr104025.C 2022-01-17 20:31:09.068706373 +0100 -@@ -0,0 +1,20 @@ -+// PR c++/104025 -+// { dg-do compile } -+// { dg-options "-Wmissing-template-keyword -fcompare-debug" } -+ -+void bar (int); -+ -+struct S { int i; }; -+ -+template -+struct T -+{ -+ int m; -+ C c; -+ void foo () -+ { -+ bar (c.i < m); -+ } -+}; -+ -+template void T::foo (); diff --git a/gcc12-pr104103.patch b/gcc12-pr104103.patch deleted file mode 100644 index cdf421d..0000000 --- a/gcc12-pr104103.patch +++ /dev/null @@ -1,20 +0,0 @@ -2022-01-18 Jakub Jelinek - - PR middle-end/104103 - * gimple-ssa-warn-access.cc (pass_waccess::check_call): Don't check - .ASAN_MARK calls. - ---- gcc/gimple-ssa-warn-access.cc.jj 2022-01-16 20:55:46.783932110 +0100 -+++ gcc/gimple-ssa-warn-access.cc 2022-01-18 20:56:13.697780325 +0100 -@@ -4232,6 +4232,11 @@ pass_waccess::check_call (gcall *stmt) - if (gimple_call_builtin_p (stmt, BUILT_IN_NORMAL)) - check_builtin (stmt); - -+ /* .ASAN_MARK doesn't access any vars, only modifies shadow memory. */ -+ if (gimple_call_internal_p (stmt) -+ && gimple_call_internal_fn (stmt) == IFN_ASAN_MARK) -+ return; -+ - if (!m_early_checks_p) - if (tree callee = gimple_call_fndecl (stmt)) - { diff --git a/gcc12-pr104104.patch b/gcc12-pr104104.patch deleted file mode 100644 index d81b3f0..0000000 --- a/gcc12-pr104104.patch +++ /dev/null @@ -1,121 +0,0 @@ -2022-01-18 Jakub Jelinek - - PR target/104104 - * config/i386/sse.md - (__, - avx512fp16_sh_v8hf, - avx512dq_mul3, _permvar, - avx2_perm_1, avx512f_perm_1, - avx512dq_rangep, - avx512dq_ranges, - _getmant, - avx512f_vgetmant): - Use vxorps\t%x0, %x0, %x0 instead of vxorps\t{%x0, %x0, %x0}. - - * gcc.target/i386/pr104104.c: New test. - ---- gcc/config/i386/sse.md.jj 2022-01-18 11:58:59.156988142 +0100 -+++ gcc/config/i386/sse.md 2022-01-18 21:20:40.022477778 +0100 -@@ -6539,7 +6539,7 @@ (define_insn "__< - { - if (TARGET_DEST_FALSE_DEP_FOR_GLC - && ) -- output_asm_insn ("vxorps\t{%x0, %x0, %x0}", operands); -+ output_asm_insn ("vxorps\t%x0, %x0, %x0", operands); - return "v\t{%2, %1, %0|%0, %1, %2}"; - } - [(set_attr "type" "ssemul") -@@ -6750,7 +6750,7 @@ (define_insn "avx512fp16_ - { - if (TARGET_DEST_FALSE_DEP_FOR_GLC - && ) -- output_asm_insn ("vxorps\t{%x0, %x0, %x0}", operands); -+ output_asm_insn ("vxorps\t%x0, %x0, %x0", operands); - return "vsh\t{%2, %1, %0|%0, %1, %2}"; - } - [(set_attr "type" "ssemul") -@@ -15222,7 +15222,7 @@ (define_insn "avx512dq_mul3 - && !reg_mentioned_p (operands[0], operands[1]) - && !reg_mentioned_p (operands[0], operands[2])) -- output_asm_insn ("vxorps\t{%x0, %x0, %x0}", operands); -+ output_asm_insn ("vxorps\t%x0, %x0, %x0", operands); - return "vpmullq\t{%2, %1, %0|%0, %1, %2}"; - } - [(set_attr "type" "sseimul") -@@ -24658,7 +24658,7 @@ (define_insn "_permvar - && !reg_mentioned_p (operands[0], operands[1]) - && !reg_mentioned_p (operands[0], operands[2])) -- output_asm_insn ("vxorps\t{%x0, %x0, %x0}", operands); -+ output_asm_insn ("vxorps\t%x0, %x0, %x0", operands); - return "vperm\t{%1, %2, %0|%0, %2, %1}"; - } - [(set_attr "type" "sselog") -@@ -24900,7 +24900,7 @@ (define_insn "avx2_perm_1 - && !reg_mentioned_p (operands[0], operands[1])) -- output_asm_insn ("vxorps\t{%x0, %x0, %x0}", operands); -+ output_asm_insn ("vxorps\t%x0, %x0, %x0", operands); - return "vperm\t{%2, %1, %0|%0, %1, %2}"; - } - [(set_attr "type" "sselog") -@@ -24975,7 +24975,7 @@ (define_insn "avx512f_perm_1 - && !reg_mentioned_p (operands[0], operands[1])) -- output_asm_insn ("vxorps\t{%x0, %x0, %x0}", operands); -+ output_asm_insn ("vxorps\t%x0, %x0, %x0", operands); - return "vperm\t{%2, %1, %0|%0, %1, %2}"; - } - [(set_attr "type" "sselog") -@@ -26880,7 +26880,7 @@ (define_insn "avx512dq_rangep - && !reg_mentioned_p (operands[0], operands[1]) - && !reg_mentioned_p (operands[0], operands[2])) -- output_asm_insn ("vxorps\t{%x0, %x0, %x0}", operands); -+ output_asm_insn ("vxorps\t%x0, %x0, %x0", operands); - return "vrange\t{%3, %2, %1, %0|%0, %1, %2, %3}"; - } - [(set_attr "type" "sse") -@@ -26903,7 +26903,7 @@ (define_insn "avx512dq_ranges - && !reg_mentioned_p (operands[0], operands[1]) - && !reg_mentioned_p (operands[0], operands[2])) -- output_asm_insn ("vxorps\t{%x0, %x0, %x0}", operands); -+ output_asm_insn ("vxorps\t%x0, %x0, %x0", operands); - return "vrange\t{%3, %2, %1, %0|%0, %1, %2, %3}"; - } - [(set_attr "type" "sse") -@@ -26949,7 +26949,7 @@ (define_insn "_getmant - && MEM_P (operands[1])) -- output_asm_insn ("vxorps\t{%x0, %x0, %x0}", operands); -+ output_asm_insn ("vxorps\t%x0, %x0, %x0", operands); - return "vgetmant\t{%2, %1, %0|%0, %1, %2}"; - } - [(set_attr "prefix" "evex") -@@ -26971,7 +26971,7 @@ (define_insn "avx512f_vgetmant - && !reg_mentioned_p (operands[0], operands[1]) - && !reg_mentioned_p (operands[0], operands[2])) -- output_asm_insn ("vxorps\t{%x0, %x0, %x0}", operands); -+ output_asm_insn ("vxorps\t%x0, %x0, %x0", operands); - return "vgetmant\t{%3, %2, %1, %0|%0, %1, %2, %3}"; - } - [(set_attr "prefix" "evex") ---- gcc/testsuite/gcc.target/i386/pr104104.c.jj 2022-01-18 21:38:17.007906673 +0100 -+++ gcc/testsuite/gcc.target/i386/pr104104.c 2022-01-18 21:36:10.475623148 +0100 -@@ -0,0 +1,10 @@ -+/* PR target/104104 */ -+/* { dg-do assemble { target vect_simd_clones } } */ -+/* { dg-require-effective-target masm_intel } */ -+/* { dg-options "-march=alderlake -masm=intel -O1 -fallow-store-data-races -funroll-all-loops" } */ -+ -+__attribute__ ((simd)) short int -+foo (void) -+{ -+ return 0; -+} diff --git a/gcc12-pr104194.patch b/gcc12-pr104194.patch new file mode 100644 index 0000000..f0747c7 --- /dev/null +++ b/gcc12-pr104194.patch @@ -0,0 +1,92 @@ +2022-01-25 Jakub Jelinek + + PR debug/104194 + * dwarf2out.cc (long_double_as_float128): New function. + (modified_type_die): For powerpc64le IEEE 754 quad long double + and complex long double emit those as DW_TAG_typedef to + _Float128 or complex _Float128 base type. + +--- gcc/dwarf2out.cc.jj 2022-01-25 05:47:53.987454934 +0100 ++++ gcc/dwarf2out.cc 2022-01-25 11:54:25.100522089 +0100 +@@ -13568,6 +13568,47 @@ qualified_die_p (dw_die_ref die, int *ma + return type; + } + ++/* If TYPE is long double or complex long double that ++ should be emitted as artificial typedef to _Float128 or ++ complex _Float128, return the type it should be emitted as. ++ This is done in case the target already supports 16-byte ++ composite floating point type (ibm_extended_format). */ ++ ++static tree ++long_double_as_float128 (tree type) ++{ ++ if (type != long_double_type_node ++ && type != complex_long_double_type_node) ++ return NULL_TREE; ++ ++ machine_mode mode, fmode; ++ if (TREE_CODE (type) == COMPLEX_TYPE) ++ mode = TYPE_MODE (TREE_TYPE (type)); ++ else ++ mode = TYPE_MODE (type); ++ if (known_eq (GET_MODE_SIZE (mode), 16) && !MODE_COMPOSITE_P (mode)) ++ FOR_EACH_MODE_IN_CLASS (fmode, MODE_FLOAT) ++ if (known_eq (GET_MODE_SIZE (fmode), 16) ++ && MODE_COMPOSITE_P (fmode)) ++ { ++ if (type == long_double_type_node) ++ { ++ if (float128_type_node ++ && (TYPE_MODE (float128_type_node) ++ == TYPE_MODE (type))) ++ return float128_type_node; ++ return NULL_TREE; ++ } ++ for (int i = 0; i < NUM_FLOATN_NX_TYPES; i++) ++ if (COMPLEX_FLOATN_NX_TYPE_NODE (i) != NULL_TREE ++ && (TYPE_MODE (COMPLEX_FLOATN_NX_TYPE_NODE (i)) ++ == TYPE_MODE (type))) ++ return COMPLEX_FLOATN_NX_TYPE_NODE (i); ++ } ++ ++ return NULL_TREE; ++} ++ + /* Given a pointer to an arbitrary ..._TYPE tree node, return a debugging + entry that chains the modifiers specified by CV_QUALS in front of the + given type. REVERSE is true if the type is to be interpreted in the +@@ -13848,7 +13889,32 @@ modified_type_die (tree type, int cv_qua + } + else if (is_base_type (type)) + { +- mod_type_die = base_type_die (type, reverse); ++ /* If a target supports long double as different floating point ++ modes with the same 16-byte size, use normal DW_TAG_base_type ++ only for the composite (ibm_extended_real_format) type and ++ for the other for the time being emit instead a "_Float128" ++ or "complex _Float128" DW_TAG_base_type and a "long double" ++ or "complex long double" typedef to it. */ ++ if (tree other_type = long_double_as_float128 (type)) ++ { ++ dw_die_ref other_die; ++ if (TYPE_NAME (other_type)) ++ other_die ++ = modified_type_die (other_type, TYPE_UNQUALIFIED, reverse, ++ context_die); ++ else ++ { ++ other_die = base_type_die (type, reverse); ++ add_child_die (comp_unit_die (), other_die); ++ add_name_attribute (other_die, ++ TREE_CODE (type) == COMPLEX_TYPE ++ ? "complex _Float128" : "_Float128"); ++ } ++ mod_type_die = new_die_raw (DW_TAG_typedef); ++ add_AT_die_ref (mod_type_die, DW_AT_type, other_die); ++ } ++ else ++ mod_type_die = base_type_die (type, reverse); + + /* The DIE with DW_AT_endianity is placed right after the naked DIE. */ + if (reverse_base_type) diff --git a/gcc12-pr94193.patch b/gcc12-pr94193.patch new file mode 100644 index 0000000..e669a81 --- /dev/null +++ b/gcc12-pr94193.patch @@ -0,0 +1,39 @@ +2022-01-25 Jakub Jelinek + + PR target/94193 + * config/rs6000/rs6000.md (feclearexceptsi, feraiseexceptsi): + Use general_operand instead of const_int_operand, drop constraint + and FAIL if operands[1] is not CONST_INT_P. + +--- gcc/config/rs6000/rs6000.md.jj 2022-01-25 05:48:01.497340303 +0100 ++++ gcc/config/rs6000/rs6000.md 2022-01-25 13:48:13.752709482 +0100 +@@ -6959,12 +6959,12 @@ (define_expand "fegetroundsi" + ;; Because of these restrictions, this only expands on the desired + ;; cases and fallback to a call to libc on any other case. + (define_expand "feclearexceptsi" +- [(use (match_operand:SI 1 "const_int_operand" "n")) ++ [(use (match_operand:SI 1 "general_operand")) + (set (match_operand:SI 0 "gpc_reg_operand") + (const_int 0))] + "TARGET_HARD_FLOAT" + { +- if (!OPTION_GLIBC) ++ if (!OPTION_GLIBC || !CONST_INT_P (operands[1])) + FAIL; + + unsigned int fe = INTVAL (operands[1]); +@@ -6999,12 +6999,12 @@ (define_expand "feclearexceptsi" + ;; Because of these restrictions, this only expands on the desired + ;; cases and fallback to a call to libc on any other case. + (define_expand "feraiseexceptsi" +- [(use (match_operand:SI 1 "const_int_operand" "n")) ++ [(use (match_operand:SI 1 "general_operand")) + (set (match_operand:SI 0 "gpc_reg_operand") + (const_int 0))] + "TARGET_HARD_FLOAT" + { +- if (!OPTION_GLIBC) ++ if (!OPTION_GLIBC || !CONST_INT_P (operands[1])) + FAIL; + + unsigned int fe = INTVAL (operands[1]); diff --git a/sources b/sources index 43d2957..fcd533a 100644 --- a/sources +++ b/sources @@ -1,4 +1,4 @@ -SHA512 (gcc-12.0.1-20220118.tar.xz) = 5fab239e915e71a8986a122e3f897f2236f21f0f183da33cad2ace8f34823cd8f32c7c0dfceffbfeae17cd99b656f242d30ddeb94eaafe3edf858ea88ec59016 +SHA512 (gcc-12.0.1-20220125.tar.xz) = 09c4b7d7fe3e8a2c0f4181da717e476c0868b2bb1c86cdd22482ee4235aebb9eb0c89b5f87b9a0e6852e0cc2876b652c60457996a86dc6e9b9b02ca2ff87613f SHA512 (isl-0.18.tar.bz2) = 85d0b40f4dbf14cb99d17aa07048cdcab2dc3eb527d2fbb1e84c41b2de5f351025370e57448b63b2b8a8cf8a0843a089c3263f9baee1542d5c2e1cb37ed39d94 SHA512 (newlib-cygwin-50e2a63b04bdd018484605fbb954fd1bd5147fa0.tar.xz) = 002a48a7b689a81abbf16161bcaec001a842e67dfbe372e9e109092703bfc666675f16198f60ca429370e8850d564547dc505df81bc3aaca4ce6defbc014ad6c SHA512 (nvptx-tools-5f6f343a302d620b0868edab376c00b15741e39e.tar.xz) = f6d10db94fa1570ae0f94df073fa3c73c8e5ee16d59070b53d94f7db0de8a031bc44d7f3f1852533da04b625ce758e022263855ed43cfc6867e0708d001e53c7