[gcc(refs/vendors/ibm/heads/mmaplus)] MMA+: Add initial support for some MMA+ built-ins
https://gcc.gnu.org/g:50679b8dc0805a7c628962bef50b40b9ace33d06 commit 50679b8dc0805a7c628962bef50b40b9ace33d06 Author: Peter Bergner Date: Thu May 1 17:49:03 2025 -0500 MMA+: Add initial support for some MMA+ built-ins Add support for MMA+ built-ins __builtin_mma_dmmr, __builtin_mma_dmxor, __builtin_mma_build_dmr, __builtin_mma_dmxvi8gerx4, __builtin_mma_dmxvi8gerx4pp, __builtin_mma_pmdmxvi8gerx4, __builtin_mma_pmdmxvi8gerx4pp . Diff: --- gcc/config/rs6000/mma.md | 190 +-- gcc/config/rs6000/predicates.md | 13 ++- gcc/config/rs6000/rs6000-builtin.cc | 112 +++--- gcc/config/rs6000/rs6000-builtins.def| 55 + gcc/config/rs6000/rs6000-gen-builtins.cc | 46 +++- gcc/config/rs6000/rs6000.md | 16 ++- 6 files changed, 371 insertions(+), 61 deletions(-) diff --git a/gcc/config/rs6000/mma.md b/gcc/config/rs6000/mma.md index 6103dc3c5237..fd3a0e592d88 100644 --- a/gcc/config/rs6000/mma.md +++ b/gcc/config/rs6000/mma.md @@ -24,7 +24,7 @@ ;; __vector_pair types that the MMA built-in functions reference. We ;; use OPAQUE_MODE to prevent anything from trying to open them up. -(define_constants [(MAX_MMA_OPERANDS 7)]) +(define_constants [(MAX_MMA_OPERANDS 9)]) ;; Constants for creating unspecs @@ -93,9 +93,15 @@ UNSPEC_MMA_DMSETDMRZ UNSPEC_DM_INSERT512_UPPER UNSPEC_DM_INSERT512_LOWER + UNSPEC_DM_INSERT1024 UNSPEC_DM_EXTRACT512 UNSPEC_DMR_RELOAD_FROM_MEMORY UNSPEC_DMR_RELOAD_TO_MEMORY + UNSPEC_DMF_DMXOR + UNSPEC_DMF_DMXVI8GERX4 + UNSPEC_DMF_DMXVI8GERX4PP + UNSPEC_DMF_PMDMXVI8GERX4 + UNSPEC_DMF_PMDMXVI8GERX4PP ]) (define_c_enum "unspecv" @@ -138,12 +144,18 @@ ;; MMA instructions with 1 vector pair and 1 vector arguments (define_int_iterator MMA_PV[UNSPEC_MMA_XVF64GER]) +;; DMF instructions with 1 vector pair and 1 vector arguments +(define_int_iterator DMF_PV[UNSPEC_DMF_DMXVI8GERX4]) + ;; MMA instructions with 1 accumulator, 1 vector pair and 1 vector arguments (define_int_iterator MMA_APV [UNSPEC_MMA_XVF64GERPP UNSPEC_MMA_XVF64GERPN UNSPEC_MMA_XVF64GERNP UNSPEC_MMA_XVF64GERNN]) +;; DMF instructions with 1 dmr, 1 vector pair and 1 vector arguments +(define_int_iterator DMF_DPV [UNSPEC_DMF_DMXVI8GERX4PP]) + ;; MMA instructions with 2 vector, 2 4-bit and 1 8-bit arguments (define_int_iterator MMA_VVI4I4I8 [UNSPEC_MMA_PMXVI4GER8]) @@ -193,6 +205,14 @@ (define_int_iterator MMA_AVVI4I4I4 [UNSPEC_MMA_PMXVI8GER4PP UNSPEC_MMA_PMXVI8GER4SPP]) +;; DMF instructions with 1 vector pair, 1 vector and 1 8-bit and 2 4-bit +;; arguments +(define_int_iterator DMF_PVI8I4I4 [UNSPEC_DMF_PMDMXVI8GERX4]) + +;; DMF instructions with 1dmr, 1 vector pair, 1 vector and 1 8-bit and +;; 2 4-bit arguments +(define_int_iterator DMF_DPVI8I4I4 [UNSPEC_DMF_PMDMXVI8GERX4PP]) + (define_int_attr acc [(UNSPEC_MMA_XXMFACC"xxmfacc") (UNSPEC_MMA_XXMTACC"xxmtacc")]) @@ -222,12 +242,14 @@ (UNSPEC_MMA_XVF32GERNP "xvf32gernp") (UNSPEC_MMA_XVF32GERNN "xvf32gernn")]) -(define_int_attr pv[(UNSPEC_MMA_XVF64GER "xvf64ger")]) +(define_int_attr pv[(UNSPEC_MMA_XVF64GER "xvf64ger") +(UNSPEC_DMF_DMXVI8GERX4"dmxvi8gerx4")]) (define_int_attr apv [(UNSPEC_MMA_XVF64GERPP "xvf64gerpp") (UNSPEC_MMA_XVF64GERPN "xvf64gerpn") (UNSPEC_MMA_XVF64GERNP "xvf64gernp") -(UNSPEC_MMA_XVF64GERNN "xvf64gernn")]) +(UNSPEC_MMA_XVF64GERNN "xvf64gernn") +(UNSPEC_DMF_DMXVI8GERX4PP "dmxvi8gerx4pp")]) ;; The "pm" prefix is not in these expansions, so that we can generate ;; pmdmxvi4ger8 on systems with dense math registers and xvi4ger8 on systems @@ -271,6 +293,9 @@ (define_int_attr avvi4i4i4 [(UNSPEC_MMA_PMXVI8GER4PP "xvi8ger4pp") (UNSPEC_MMA_PMXVI8GER4SPP "xvi8ger4spp")]) +(define_int_attr pvi8i4i4 [(UNSPEC_DMF_PMDMXVI8GERX4 "pmdmxvi8gerx4")]) + +(define_int_attr dpvi8i4i4 [(UNSPEC_DMF_PMDMXVI8GERX4PP "pmdmxvi8gerx4pp")]) ;; Vector pair support. OOmode can only live in VSRs. (define_expand "movoo" @@ -430,14 +455,25 @@ ;; instructions. (define_insn "dm_insert512" [(set (match_operand:XO 0 "dmr_operand" "=wD") - (unspec:XO [(match_operand:OO 1 "vsx_register_operand" "wa") - (match_operand:OO 2 "vsx_register_operand" "wa") -
[gcc(refs/vendors/ibm/heads/mmaplus)] MMA+: Fix TARGET_DENSE_MATH usage
https://gcc.gnu.org/g:213136a56382d41afbdea35ec59a089552610db4 commit 213136a56382d41afbdea35ec59a089552610db4 Author: Peter Bergner Date: Fri Apr 25 13:19:12 2025 -0500 MMA+: Fix TARGET_DENSE_MATH usage Diff: --- gcc/config/rs6000/mma.md| 24 gcc/config/rs6000/predicates.md | 2 +- gcc/config/rs6000/rs6000.cc | 24 gcc/config/rs6000/rs6000.h | 4 +--- 4 files changed, 26 insertions(+), 28 deletions(-) diff --git a/gcc/config/rs6000/mma.md b/gcc/config/rs6000/mma.md index bc6631436274..8c47132e4901 100644 --- a/gcc/config/rs6000/mma.md +++ b/gcc/config/rs6000/mma.md @@ -352,7 +352,7 @@ (define_insn_and_split "*movxo_nodm" [(set (match_operand:XO 0 "nonimmediate_operand" "=d,ZwO,d") (match_operand:XO 1 "input_operand" "ZwO,d,d"))] - "TARGET_MMA_NO_DENSE_MATH + "TARGET_MMA && !TARGET_DENSE_MATH && (gpc_reg_operand (operands[0], XOmode) || gpc_reg_operand (operands[1], XOmode))" "@ @@ -372,7 +372,7 @@ (define_insn_and_split "*movxo_dm" [(set (match_operand:XO 0 "nonimmediate_operand" "=wa,ZwO,wa,wD,wD,wa") (match_operand:XO 1 "input_operand""ZwO,wa, wa,wa,wD,wD"))] - "TARGET_MMA_DENSE_MATH + "TARGET_DENSE_MATH && (gpc_reg_operand (operands[0], XOmode) || gpc_reg_operand (operands[1], XOmode))" "@ @@ -502,7 +502,7 @@ [(set (match_operand:XO 0 "accumulator_operand" "=&wD") (unspec:XO [(match_operand:XO 1 "fpr_reg_operand" "0")] MMA_ACC))] - "TARGET_MMA_NO_DENSE_MATH" + "TARGET_MMA && !TARGET_DENSE_MATH" " %A0" [(set_attr "type" "mma")]) @@ -527,7 +527,7 @@ [(set (match_operand:XO 0 "fpr_reg_operand" "=d") (unspec_volatile:XO [(const_int 0)] UNSPECV_MMA_XXSETACCZ))] - "TARGET_MMA_NO_DENSE_MATH" + "TARGET_MMA && !TARGET_DENSE_MATH" "xxsetaccz %A0" [(set_attr "type" "mma")]) @@ -535,7 +535,7 @@ [(set (match_operand:XO 0 "accumulator_operand" "=wD") (unspec [(const_int 0)] UNSPEC_MMA_DMSETDMRZ))] - "TARGET_MMA_DENSE_MATH" + "TARGET_DENSE_MATH" "dmsetdmrz %A0" [(set_attr "type" "mma")]) @@ -760,7 +760,7 @@ (define_expand "movtdo" [(set (match_operand:TDO 0 "nonimmediate_operand") (match_operand:TDO 1 "input_operand"))] - "TARGET_MMA_DENSE_MATH" + "TARGET_DENSE_MATH" { rs6000_emit_move (operands[0], operands[1], TDOmode); DONE; @@ -769,7 +769,7 @@ (define_insn_and_split "*movtdo" [(set (match_operand:TDO 0 "nonimmediate_operand" "=wa,m,wa,wD,wD,wa") (match_operand:TDO 1 "input_operand" "m,wa,wa,wa,wD,wD"))] - "TARGET_MMA_DENSE_MATH + "TARGET_DENSE_MATH && (gpc_reg_operand (operands[0], TDOmode) || gpc_reg_operand (operands[1], TDOmode))" "@ @@ -826,7 +826,7 @@ [(set (match_operand:TDO 0 "dmr_operand" "=wD") (unspec:TDO [(match_operand:XO 1 "vsx_register_operand" "wa")] UNSPEC_DM_INSERT512_UPPER))] - "TARGET_MMA_DENSE_MATH" + "TARGET_DENSE_MATH" "dmxxinstdmr512 %0,%1,%Y1,0" [(set_attr "type" "mma")]) @@ -835,7 +835,7 @@ (unspec:TDO [(match_operand:TDO 1 "dmr_operand" "0") (match_operand:XO 2 "vsx_register_operand" "wa")] UNSPEC_DM_INSERT512_LOWER))] - "TARGET_MMA_DENSE_MATH" + "TARGET_DENSE_MATH" "dmxxinstdmr512 %0,%2,%Y2,1" [(set_attr "type" "mma")]) @@ -846,7 +846,7 @@ (unspec:XO [(match_operand:TDO 1 "dmr_operand" "wD") (match_operand 2 "const_0_to_1_operand" "n")] UNSPEC_DM_EXTRACT512))] - "TARGET_MMA_DENSE_MATH" + "TARGET_DENSE_MATH" "dmxxextfdmr512 %0,%Y0,%1,%2" [(set_attr "type" "mma")]) @@ -856,7 +856,7 @@ (unspec:TDO [(match_operand:TDO 1 "memory_operand" "m")] UNSPEC_DMR_RELOAD_FROM_MEMORY)) (clobber (match_operand:XO 2 "vsx_register_operand" "=wa"))] - "TARGET_MMA_DENSE_MATH" + "TARGET_DENSE_MATH" "#" "&& reload_completed" [(const_int 0)] @@ -884,7 +884,7 @@ (unspec:TDO [(match_operand:TDO 1 "dmr_operand" "wD")] UNSPEC_DMR_RELOAD_TO_MEMORY)) (clobber (match_operand:XO 2 "vsx_register_operand" "=wa"))] - "TARGET_MMA_DENSE_MATH" + "TARGET_DENSE_MATH" "#" "&& reload_completed" [(const_int 0)] diff --git a/gcc/config/rs6000/predicates.md b/gcc/config/rs6000/predicates.md index c95b4336f062..7086a518ab4d 100644 --- a/gcc/config/rs6000/predicates.md +++ b/gcc/config/rs6000/predicates.md @@ -213,7 +213,7 @@ return 1; int r = REGNO (op); - return (TARGET_MMA_DENSE_MATH + return (TARGET_DENSE_MATH ? DMR_REGNO_P (r) : FP_REGNO_P (r) && (r & 3) == 0); }) diff --git a/gcc/config/rs6000/rs6000.cc b/gcc/config/rs6000/rs6000.cc index 7ac45d287d0b..73eda16af415 100644 --- a/gcc/config/rs6000/rs6000.cc +++ b/gcc/config/rs6000/rs6000.cc @@ -13618,7 +13618,7 @@ rs6000_preferred_reload_class (rtx x, enum reg_class rclass) return
[gcc(refs/vendors/ibm/heads/mmaplus)] MMA+: Fix mma.md whitespace
https://gcc.gnu.org/g:692dbe94ad697119f17cfcc6ea86a7bdba747b5f commit 692dbe94ad697119f17cfcc6ea86a7bdba747b5f Author: Peter Bergner Date: Fri Apr 25 14:46:42 2025 -0500 MMA+: Fix mma.md whitespace Diff: --- gcc/config/rs6000/mma.md | 40 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/gcc/config/rs6000/mma.md b/gcc/config/rs6000/mma.md index 2b8e3441b805..52bd7da1b6ca 100644 --- a/gcc/config/rs6000/mma.md +++ b/gcc/config/rs6000/mma.md @@ -583,8 +583,8 @@ "TARGET_MMA" { return (TARGET_DENSE_MATH - ? "pmdm %A0,%x1,%x2,%3,%4,%5" - : "pm %A0,%x1,%x2,%3,%4,%5"); + ? "pmdm %A0,%x1,%x2,%3,%4,%5" + : "pm %A0,%x1,%x2,%3,%4,%5"); } [(set_attr "type" "mma") (set_attr "prefixed" "yes")]) @@ -601,8 +601,8 @@ "TARGET_MMA" { return (TARGET_DENSE_MATH - ? "pmdm %A0,%x2,%x3,%4,%5,%6" - : "pm %A0,%x2,%x3,%4,%5,%6"); + ? "pmdm %A0,%x2,%x3,%4,%5,%6" + : "pm %A0,%x2,%x3,%4,%5,%6"); } [(set_attr "type" "mma") (set_attr "prefixed" "yes")]) @@ -618,8 +618,8 @@ "TARGET_MMA" { return (TARGET_DENSE_MATH - ? "pmdm %A0,%x1,%x2,%3,%4,%5" - : "pm %A0,%x1,%x2,%3,%4,%5"); + ? "pmdm %A0,%x1,%x2,%3,%4,%5" + : "pm %A0,%x1,%x2,%3,%4,%5"); } [(set_attr "type" "mma") (set_attr "prefixed" "yes")]) @@ -636,8 +636,8 @@ "TARGET_MMA" { return (TARGET_DENSE_MATH - ? "pmdm %A0,%x2,%x3,%4,%5,%6" - : "pm %A0,%x2,%x3,%4,%5,%6"); + ? "pmdm %A0,%x2,%x3,%4,%5,%6" + : "pm %A0,%x2,%x3,%4,%5,%6"); } [(set_attr "type" "mma") (set_attr "prefixed" "yes")]) @@ -652,8 +652,8 @@ "TARGET_MMA" { return (TARGET_DENSE_MATH - ? "pmdm %A0,%x1,%x2,%3,%4" - : "pm %A0,%x1,%x2,%3,%4"); + ? "pmdm %A0,%x1,%x2,%3,%4" + : "pm %A0,%x1,%x2,%3,%4"); } [(set_attr "type" "mma") (set_attr "prefixed" "yes")]) @@ -669,8 +669,8 @@ "TARGET_MMA" { return (TARGET_DENSE_MATH - ? "pmdm %A0,%x2,%x3,%4,%5" - : "pm %A0,%x2,%x3,%4,%5"); + ? "pmdm %A0,%x2,%x3,%4,%5" + : "pm %A0,%x2,%x3,%4,%5"); } [(set_attr "type" "mma") (set_attr "prefixed" "yes")]) @@ -685,8 +685,8 @@ "TARGET_MMA" { return (TARGET_DENSE_MATH - ? "pmdm %A0,%x1,%x2,%3,%4" - : "pm %A0,%x1,%x2,%3,%4"); + ? "pmdm %A0,%x1,%x2,%3,%4" + : "pm %A0,%x1,%x2,%3,%4"); } [(set_attr "type" "mma") (set_attr "prefixed" "yes")]) @@ -702,8 +702,8 @@ "TARGET_MMA" { return (TARGET_DENSE_MATH - ? "pmdm %A0,%x2,%x3,%4,%5" - : "pm %A0,%x2,%x3,%4,%5"); + ? "pmdm %A0,%x2,%x3,%4,%5" + : "pm %A0,%x2,%x3,%4,%5"); } [(set_attr "type" "mma") (set_attr "prefixed" "yes")]) @@ -719,8 +719,8 @@ "TARGET_MMA" { return (TARGET_DENSE_MATH - ? "pmdm %A0,%x1,%x2,%3,%4,%5" - : "pm %A0,%x1,%x2,%3,%4,%5"); + ? "pmdm %A0,%x1,%x2,%3,%4,%5" + : "pm %A0,%x1,%x2,%3,%4,%5"); } [(set_attr "type" "mma") (set_attr "prefixed" "yes")]) @@ -737,8 +737,8 @@ "TARGET_MMA" { return (TARGET_DENSE_MATH - ? "pmdm %A0,%x2,%x3,%4,%5,%6" - : "pm %A0,%x2,%x3,%4,%5,%6"); + ? "pmdm %A0,%x2,%x3,%4,%5,%6" + : "pm %A0,%x2,%x3,%4,%5,%6"); } [(set_attr "type" "mma") (set_attr "prefixed" "yes")])
[gcc(refs/vendors/ibm/heads/mmaplus)] MMA+: Remove unneeded mma_xxsetaccz define_expand
https://gcc.gnu.org/g:4c9dc6b25cdb1498635d0be9a279fda05da699da commit 4c9dc6b25cdb1498635d0be9a279fda05da699da Author: Peter Bergner Date: Fri Apr 25 16:47:45 2025 -0500 MMA+: Remove unneeded mma_xxsetaccz define_expand Diff: --- gcc/config/rs6000/mma.md | 19 --- 1 file changed, 4 insertions(+), 15 deletions(-) diff --git a/gcc/config/rs6000/mma.md b/gcc/config/rs6000/mma.md index 4322d0f6ef73..6103dc3c5237 100644 --- a/gcc/config/rs6000/mma.md +++ b/gcc/config/rs6000/mma.md @@ -520,25 +520,14 @@ ;; UNSPEC_VOLATILE. If we have dense math registers, we can just use a normal ;; UNSPEC instead of UNSPEC_VOLATILE. -(define_expand "mma_xxsetaccz" - [(set (match_operand:XO 0 "accumulator_operand") +(define_insn "mma_xxsetaccz" + [(set (match_operand:XO 0 "accumulator_operand" "=wD") (unspec_volatile:XO [(const_int 0)] UNSPECV_MMA_XXSETACCZ))] "TARGET_MMA" { - if (TARGET_DENSE_MATH) -{ - emit_insn (gen_mma_dmsetdmrz (operands[0])); - DONE; -} -}) - -(define_insn "*mma_xxsetaccz" - [(set (match_operand:XO 0 "accumulator_operand" "=wD") - (unspec_volatile:XO [(const_int 0)] - UNSPECV_MMA_XXSETACCZ))] - "TARGET_MMA && !TARGET_DENSE_MATH" - "xxsetaccz %A0" + return TARGET_DENSE_MATH ? "dmsetdmrz %A0" : "xxsetaccz %A0"; +} [(set_attr "type" "mma")]) (define_insn "mma_dmsetdmrz"
[gcc(refs/vendors/ibm/heads/mmaplus)] MMA+: Update mma_assemble_acc for DMF
https://gcc.gnu.org/g:aae6bc2b309f16bfdf512f87e00af10349274c71 commit aae6bc2b309f16bfdf512f87e00af10349274c71 Author: Peter Bergner Date: Fri Apr 25 16:43:34 2025 -0500 MMA+: Update mma_assemble_acc for DMF Diff: --- gcc/config/rs6000/mma.md | 33 - 1 file changed, 28 insertions(+), 5 deletions(-) diff --git a/gcc/config/rs6000/mma.md b/gcc/config/rs6000/mma.md index 52bd7da1b6ca..4322d0f6ef73 100644 --- a/gcc/config/rs6000/mma.md +++ b/gcc/config/rs6000/mma.md @@ -426,6 +426,18 @@ DONE; }) +;; Move from VSX registers to DMR registers via two insert 512 bit +;; instructions. +(define_insn "dm_insert512" + [(set (match_operand:XO 0 "dmr_operand" "=wD") + (unspec:XO [(match_operand:OO 1 "vsx_register_operand" "wa") + (match_operand:OO 2 "vsx_register_operand" "wa") + (match_operand 3 "const_0_to_1_operand")] + UNSPEC_DM_INSERT512_UPPER))] + "TARGET_DENSE_MATH" + "dmxxinstdmr512 %0,%x1,%x2,%3" + [(set_attr "type" "mma")]) + (define_expand "mma_assemble_acc" [(match_operand:XO 0 "accumulator_operand") (match_operand:V16QI 1 "mma_assemble_input_operand") @@ -434,11 +446,22 @@ (match_operand:V16QI 4 "mma_assemble_input_operand")] "TARGET_MMA" { - rtx src = gen_rtx_UNSPEC_VOLATILE (XOmode, -gen_rtvec (4, operands[1], operands[2], - operands[3], operands[4]), -UNSPECV_MMA_ASSEMBLE); - emit_move_insn (operands[0], src); + if (TARGET_DENSE_MATH) +{ + rtx vp0 = gen_reg_rtx (OOmode); + rtx vp1 = gen_reg_rtx (OOmode); + emit_insn (gen_vsx_assemble_pair (vp0, operands[1], operands[2])); + emit_insn (gen_vsx_assemble_pair (vp1, operands[3], operands[4])); + emit_insn (gen_dm_insert512 (operands[0], vp0, vp1, const0_rtx)); +} + else +{ + rtx src = gen_rtx_UNSPEC_VOLATILE (XOmode, +gen_rtvec (4, operands[1], operands[2], + operands[3], operands[4]), +UNSPECV_MMA_ASSEMBLE); + emit_move_insn (operands[0], src); +} DONE; })
[gcc(refs/vendors/ibm/heads/mmaplus)] MMA+: Remove unneeded vsx_assemble_pair define_expand
https://gcc.gnu.org/g:387911c08004aab826812e5b9d058a82f9c2733c commit 387911c08004aab826812e5b9d058a82f9c2733c Author: Peter Bergner Date: Fri Apr 25 13:34:46 2025 -0500 MMA+: Remove unneeded vsx_assemble_pair define_expand Diff: --- gcc/config/rs6000/mma.md | 15 +-- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/gcc/config/rs6000/mma.md b/gcc/config/rs6000/mma.md index 8c47132e4901..d2177264c2c1 100644 --- a/gcc/config/rs6000/mma.md +++ b/gcc/config/rs6000/mma.md @@ -394,23 +394,10 @@ (set_attr "length" "*,*,16,*,*,*") (set_attr "max_prefixed_insns" "2,2,*,*,*,*")]) -(define_expand "vsx_assemble_pair" - [(match_operand:OO 0 "vsx_register_operand") - (match_operand:V16QI 1 "mma_assemble_input_operand") - (match_operand:V16QI 2 "mma_assemble_input_operand")] - "TARGET_MMA" -{ - rtx src = gen_rtx_UNSPEC (OOmode, - gen_rtvec (2, operands[1], operands[2]), - UNSPEC_VSX_ASSEMBLE); - emit_move_insn (operands[0], src); - DONE; -}) - ;; We cannot update the two output registers atomically, so mark the output ;; as an early clobber so we don't accidentally clobber the input operands. */ -(define_insn_and_split "*vsx_assemble_pair" +(define_insn_and_split "vsx_assemble_pair" [(set (match_operand:OO 0 "vsx_register_operand" "=&wa") (unspec:OO [(match_operand:V16QI 1 "mma_assemble_input_operand" "mwa") (match_operand:V16QI 2 "mma_assemble_input_operand" "mwa")]
[gcc(refs/vendors/ibm/heads/mmaplus)] MMA+: Fix up MMA+ constraint and predicate usage
https://gcc.gnu.org/g:a456fc556e2b9a8653ec04bba0e230b076d376ae commit a456fc556e2b9a8653ec04bba0e230b076d376ae Author: Peter Bergner Date: Fri Apr 25 14:31:20 2025 -0500 MMA+: Fix up MMA+ constraint and predicate usage Replace all mma.md "d" constraints with the new "wD" constraint. Replace all mma.md fpr_reg_operand predicate usage with accumulator_operand. Accept DMR registers in the gpc_reg_operand predicate. Diff: --- gcc/config/rs6000/mma.md| 16 gcc/config/rs6000/predicates.md | 3 +++ 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/gcc/config/rs6000/mma.md b/gcc/config/rs6000/mma.md index d2177264c2c1..2b8e3441b805 100644 --- a/gcc/config/rs6000/mma.md +++ b/gcc/config/rs6000/mma.md @@ -350,8 +350,8 @@ }) (define_insn_and_split "*movxo_nodm" - [(set (match_operand:XO 0 "nonimmediate_operand" "=d,ZwO,d") - (match_operand:XO 1 "input_operand" "ZwO,d,d"))] + [(set (match_operand:XO 0 "nonimmediate_operand" "=wD,ZwO,wD") + (match_operand:XO 1 "input_operand" "ZwO,wD,wD"))] "TARGET_MMA && !TARGET_DENSE_MATH && (gpc_reg_operand (operands[0], XOmode) || gpc_reg_operand (operands[1], XOmode))" @@ -427,7 +427,7 @@ }) (define_expand "mma_assemble_acc" - [(match_operand:XO 0 "fpr_reg_operand") + [(match_operand:XO 0 "accumulator_operand") (match_operand:V16QI 1 "mma_assemble_input_operand") (match_operand:V16QI 2 "mma_assemble_input_operand") (match_operand:V16QI 3 "mma_assemble_input_operand") @@ -446,7 +446,7 @@ ;; as an early clobber so we don't accidentally clobber the input operands. */ (define_insn_and_split "*mma_assemble_acc" - [(set (match_operand:XO 0 "fpr_reg_operand" "=&d") + [(set (match_operand:XO 0 "accumulator_operand" "=&wD") (unspec_volatile:XO [(match_operand:V16QI 1 "mma_assemble_input_operand" "mwa") (match_operand:V16QI 2 "mma_assemble_input_operand" "mwa") @@ -454,7 +454,7 @@ (match_operand:V16QI 4 "mma_assemble_input_operand" "mwa")] UNSPECV_MMA_ASSEMBLE))] "TARGET_MMA - && fpr_reg_operand (operands[0], XOmode)" + && accumulator_operand (operands[0], XOmode)" "#" "&& reload_completed" [(const_int 0)] @@ -469,7 +469,7 @@ (define_expand "mma_disassemble_acc" [(match_operand:V16QI 0 "mma_disassemble_output_operand") - (match_operand:XO 1 "fpr_reg_operand") + (match_operand:XO 1 "accumulator_operand") (match_operand 2 "const_0_to_3_operand")] "TARGET_MMA" { @@ -487,7 +487,7 @@ (define_insn "mma_" [(set (match_operand:XO 0 "accumulator_operand" "=&wD") - (unspec:XO [(match_operand:XO 1 "fpr_reg_operand" "0")] + (unspec:XO [(match_operand:XO 1 "accumulator_operand" "0")] MMA_ACC))] "TARGET_MMA && !TARGET_DENSE_MATH" " %A0" @@ -511,7 +511,7 @@ }) (define_insn "*mma_xxsetaccz" - [(set (match_operand:XO 0 "fpr_reg_operand" "=d") + [(set (match_operand:XO 0 "accumulator_operand" "=wD") (unspec_volatile:XO [(const_int 0)] UNSPECV_MMA_XXSETACCZ))] "TARGET_MMA && !TARGET_DENSE_MATH" diff --git a/gcc/config/rs6000/predicates.md b/gcc/config/rs6000/predicates.md index 7086a518ab4d..05899ff14d33 100644 --- a/gcc/config/rs6000/predicates.md +++ b/gcc/config/rs6000/predicates.md @@ -396,6 +396,9 @@ if (TARGET_VSX && VSX_REGNO_P (REGNO (op))) return 1; + if (TARGET_DENSE_MATH && DMR_REGNO_P (REGNO (op))) +return 1; + return INT_REGNO_P (REGNO (op)) || FP_REGNO_P (REGNO (op)); })
[gcc(refs/vendors/ibm/heads/mmaplus)] rs6000: Disassemble opaque modes using subregs to allow optimizations [PR109116]
https://gcc.gnu.org/g:a7e4699f286e48b9de7b8c81542b0e6897df7c0a commit a7e4699f286e48b9de7b8c81542b0e6897df7c0a Author: Peter Bergner Date: Fri Jan 17 16:14:48 2025 -0500 rs6000: Disassemble opaque modes using subregs to allow optimizations [PR109116] PR109116 exposes an issue where using unspecs to access each vector component of an opaque mode variable leads to unneeded register copies, because our rtl optimizers cannot handle unspecs. Instead, use subregs to access each vector register component of the opaque mode variable, which our optimizers know how to handle and optimize. gcc/ * config/rs6000/mma.md (unspec): Delete UNSPEC_MMA_EXTRACT. (vsx_disassemble_pair): Expand into a vector register sized subreg. (mma_disassemble_acc): Likewise. (*vsx_disassemble_pair): Delete. (*mma_disassemble_acc): Likewise. Diff: --- gcc/config/rs6000/mma.md | 51 1 file changed, 4 insertions(+), 47 deletions(-) diff --git a/gcc/config/rs6000/mma.md b/gcc/config/rs6000/mma.md index 6acd37d4e87f..bc6631436274 100644 --- a/gcc/config/rs6000/mma.md +++ b/gcc/config/rs6000/mma.md @@ -30,7 +30,6 @@ (define_c_enum "unspec" [UNSPEC_VSX_ASSEMBLE - UNSPEC_MMA_EXTRACT UNSPEC_MMA_PMXVBF16GER2 UNSPEC_MMA_PMXVBF16GER2NN UNSPEC_MMA_PMXVBF16GER2NP @@ -434,29 +433,8 @@ (match_operand 2 "const_0_to_1_operand")] "TARGET_MMA" { - rtx src; - int regoff = INTVAL (operands[2]); - src = gen_rtx_UNSPEC (V16QImode, - gen_rtvec (2, operands[1], GEN_INT (regoff)), - UNSPEC_MMA_EXTRACT); - emit_move_insn (operands[0], src); - DONE; -}) - -(define_insn_and_split "*vsx_disassemble_pair" - [(set (match_operand:V16QI 0 "mma_disassemble_output_operand" "=mwa") - (unspec:V16QI [(match_operand:OO 1 "vsx_register_operand" "wa") - (match_operand 2 "const_0_to_1_operand")] - UNSPEC_MMA_EXTRACT))] - "TARGET_MMA - && vsx_register_operand (operands[1], OOmode)" - "#" - "&& reload_completed" - [(const_int 0)] -{ - int reg = REGNO (operands[1]); - int regoff = INTVAL (operands[2]); - rtx src = gen_rtx_REG (V16QImode, reg + regoff); + int regoff = INTVAL (operands[2]) * 16; + rtx src = simplify_gen_subreg (V16QImode, operands[1], OOmode, regoff); emit_move_insn (operands[0], src); DONE; }) @@ -508,29 +486,8 @@ (match_operand 2 "const_0_to_3_operand")] "TARGET_MMA" { - rtx src; - int regoff = INTVAL (operands[2]); - src = gen_rtx_UNSPEC (V16QImode, - gen_rtvec (2, operands[1], GEN_INT (regoff)), - UNSPEC_MMA_EXTRACT); - emit_move_insn (operands[0], src); - DONE; -}) - -(define_insn_and_split "*mma_disassemble_acc" - [(set (match_operand:V16QI 0 "mma_disassemble_output_operand" "=mwa") - (unspec:V16QI [(match_operand:XO 1 "fpr_reg_operand" "d") - (match_operand 2 "const_0_to_3_operand")] - UNSPEC_MMA_EXTRACT))] - "TARGET_MMA - && fpr_reg_operand (operands[1], XOmode)" - "#" - "&& reload_completed" - [(const_int 0)] -{ - int reg = REGNO (operands[1]); - int regoff = INTVAL (operands[2]); - rtx src = gen_rtx_REG (V16QImode, reg + regoff); + int regoff = INTVAL (operands[2]) * 16; + rtx src = simplify_gen_subreg (V16QImode, operands[1], XOmode, regoff); emit_move_insn (operands[0], src); DONE; })
[gcc r16-322] Fixup vect_remove_slp_scalar_calls
https://gcc.gnu.org/g:52d3352239f73d3c165550177b4fe917760b85f9 commit r16-322-g52d3352239f73d3c165550177b4fe917760b85f9 Author: Richard Biener Date: Thu Jan 30 15:37:05 2025 +0100 Fixup vect_remove_slp_scalar_calls There's a logic error for vect_remove_slp_scalar_calls where it simply ignores pattern stmts but it should instead look at the original stmt. * tree-vect-slp.cc (vect_remove_slp_scalar_calls): Look at the original stmt. Diff: --- gcc/tree-vect-slp.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/gcc/tree-vect-slp.cc b/gcc/tree-vect-slp.cc index b5a9604d074e..9bf142d0faf5 100644 --- a/gcc/tree-vect-slp.cc +++ b/gcc/tree-vect-slp.cc @@ -11361,12 +11361,12 @@ vect_remove_slp_scalar_calls (vec_info *vinfo, { if (!stmt_info) continue; + if (!PURE_SLP_STMT (stmt_info)) + continue; + stmt_info = vect_orig_stmt (stmt_info); gcall *stmt = dyn_cast (stmt_info->stmt); if (!stmt || gimple_bb (stmt) == NULL) continue; - if (is_pattern_stmt_p (stmt_info) - || !PURE_SLP_STMT (stmt_info)) - continue; lhs = gimple_call_lhs (stmt); if (lhs) new_stmt = gimple_build_assign (lhs, build_zero_cst (TREE_TYPE (lhs)));
[gcc r16-323] Remove non-SLP path from vectorizable_conversion
https://gcc.gnu.org/g:d90d9ba058fb54e1138efab273e06ec9cc6014d0 commit r16-323-gd90d9ba058fb54e1138efab273e06ec9cc6014d0 Author: Richard Biener Date: Wed Apr 30 14:57:03 2025 +0200 Remove non-SLP path from vectorizable_conversion This removes the non-SLP paths from vectorizable_conversion and in the process eliminates uses of 'ncopies' and 'STMT_VINFO_VECTYPE' from the function. * tree-vect-stmts.cc (vectorizable_conversion): Remove non-SLP paths. Diff: --- gcc/tree-vect-stmts.cc | 88 +++--- 1 file changed, 19 insertions(+), 69 deletions(-) diff --git a/gcc/tree-vect-stmts.cc b/gcc/tree-vect-stmts.cc index 38612a166191..42b6059520ac 100644 --- a/gcc/tree-vect-stmts.cc +++ b/gcc/tree-vect-stmts.cc @@ -5528,7 +5528,6 @@ vectorizable_conversion (vec_info *vinfo, tree vec_dest, cvt_op = NULL_TREE; tree scalar_dest; tree op0, op1 = NULL_TREE; - loop_vec_info loop_vinfo = dyn_cast (vinfo); tree_code tc1; code_helper code, code1, code2; code_helper codecvt1 = ERROR_MARK, codecvt2 = ERROR_MARK; @@ -5538,7 +5537,7 @@ vectorizable_conversion (vec_info *vinfo, poly_uint64 nunits_in; poly_uint64 nunits_out; tree vectype_out, vectype_in; - int ncopies, i; + int i; tree lhs_type, rhs_type; /* For conversions between floating point and integer, there're 2 NARROW cases. NARROW_SRC is for FLOAT_EXPR, means @@ -5605,7 +5604,7 @@ vectorizable_conversion (vec_info *vinfo, /* Check types of lhs and rhs. */ scalar_dest = gimple_get_lhs (stmt); lhs_type = TREE_TYPE (scalar_dest); - vectype_out = STMT_VINFO_VECTYPE (stmt_info); + vectype_out = SLP_TREE_VECTYPE (slp_node); /* Check the operands of the operation. */ slp_tree slp_op0, slp_op1 = NULL; @@ -5703,20 +5702,6 @@ vectorizable_conversion (vec_info *vinfo, modifier = WIDEN; } - /* Multiple types in SLP are handled by creating the appropriate number of - vectorized stmts for each SLP node. Hence, NCOPIES is always 1 in - case of SLP. */ - if (slp_node) -ncopies = 1; - else if (modifier == NARROW_DST) -ncopies = vect_get_num_copies (loop_vinfo, vectype_out); - else -ncopies = vect_get_num_copies (loop_vinfo, vectype_in); - - /* Sanity check: make sure that at least one copy of the vectorized stmt - needs to be generated. */ - gcc_assert (ncopies >= 1); - bool found_mode = false; scalar_mode lhs_mode = SCALAR_TYPE_MODE (lhs_type); scalar_mode rhs_mode = SCALAR_TYPE_MODE (rhs_type); @@ -5871,16 +5856,11 @@ vectorizable_conversion (vec_info *vinfo, else if (code == FLOAT_EXPR) { wide_int op_min_value, op_max_value; - if (slp_node) - { - tree def; - /* ??? Merge ranges in case of more than one lane. */ - if (SLP_TREE_LANES (slp_op0) != 1 - || !(def = vect_get_slp_scalar_def (slp_op0, 0)) - || !vect_get_range_info (def, &op_min_value, &op_max_value)) - goto unsupported; - } - else if (!vect_get_range_info (op0, &op_min_value, &op_max_value)) + tree def; + /* ??? Merge ranges in case of more than one lane. */ + if (SLP_TREE_LANES (slp_op0) != 1 + || !(def = vect_get_slp_scalar_def (slp_op0, 0)) + || !vect_get_range_info (def, &op_min_value, &op_max_value)) goto unsupported; cvt_type @@ -5916,9 +5896,8 @@ vectorizable_conversion (vec_info *vinfo, if (!vec_stmt) /* transformation not required. */ { - if (slp_node - && (!vect_maybe_update_slp_op_vectype (slp_op0, vectype_in) - || !vect_maybe_update_slp_op_vectype (slp_op1, vectype_in))) + if (!vect_maybe_update_slp_op_vectype (slp_op0, vectype_in) + || !vect_maybe_update_slp_op_vectype (slp_op1, vectype_in)) { if (dump_enabled_p ()) dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, @@ -5929,16 +5908,14 @@ vectorizable_conversion (vec_info *vinfo, if (modifier == NONE) { STMT_VINFO_TYPE (stmt_info) = type_conversion_vec_info_type; - vect_model_simple_cost (vinfo, stmt_info, - ncopies * (1 + multi_step_cvt), + vect_model_simple_cost (vinfo, stmt_info, (1 + multi_step_cvt), dt, ndts, slp_node, cost_vec); } else if (modifier == NARROW_SRC || modifier == NARROW_DST) { STMT_VINFO_TYPE (stmt_info) = type_demotion_vec_info_type; /* The final packing step produces one vector result per copy. */ - unsigned int nvectors - = (slp_node ? SLP_TREE_NUMBER_OF_VEC_STMTS (slp_node) : ncopies); + unsigned int nvectors = SLP_TREE_NUMBER_OF_VEC_STMTS (slp_node); vect_model_promotion_demotion_cost (stmt_info, dt, nvectors,
[gcc r16-326] c++: avoid weird #line paths in std-name-hint.h
https://gcc.gnu.org/g:51bccb94a74fd5c44b6cc9cc8b9b1a831da8ec8d commit r16-326-g51bccb94a74fd5c44b6cc9cc8b9b1a831da8ec8d Author: Jason Merrill Date: Tue Apr 29 08:32:44 2025 -0400 c++: avoid weird #line paths in std-name-hint.h etags was getting confused by the #line pathnames in std-name-hint.h that don't match my directory layout; let's avoid encoding information about a particular developer's $(srcdir) in the generated file. gcc/cp/ChangeLog: * Make-lang.in: Don't pass the full path to gperf. * std-name-hint.h: Regenerate. Diff: --- gcc/cp/std-name-hint.h | 974 - gcc/cp/Make-lang.in| 4 +- 2 files changed, 489 insertions(+), 489 deletions(-) diff --git a/gcc/cp/std-name-hint.h b/gcc/cp/std-name-hint.h index dde2f9bd7172..c5f800400ead 100644 --- a/gcc/cp/std-name-hint.h +++ b/gcc/cp/std-name-hint.h @@ -144,979 +144,979 @@ std_name_hint_lookup::find (const char *str, size_t len) static const struct std_name_hint wordlist[] = { -#line 130 "../../src/gcc/cp/std-name-hint.gperf" +#line 130 "std-name-hint.gperf" {"regular", "", cxx20}, -#line 292 "../../src/gcc/cp/std-name-hint.gperf" +#line 292 "std-name-hint.gperf" {"reverse_iterator", "", cxx98}, -#line 454 "../../src/gcc/cp/std-name-hint.gperf" +#line 454 "std-name-hint.gperf" {"range_error", "", cxx98}, -#line 408 "../../src/gcc/cp/std-name-hint.gperf" +#line 408 "std-name-hint.gperf" {"set", "", cxx98}, -#line 231 "../../src/gcc/cp/std-name-hint.gperf" +#line 231 "std-name-hint.gperf" {"setbase", "", cxx98}, -#line 325 "../../src/gcc/cp/std-name-hint.gperf" +#line 325 "std-name-hint.gperf" {"reinterpret_pointer_cast", "", cxx17}, -#line 288 "../../src/gcc/cp/std-name-hint.gperf" +#line 288 "std-name-hint.gperf" {"next", "", cxx11}, -#line 171 "../../src/gcc/cp/std-name-hint.gperf" +#line 171 "std-name-hint.gperf" {"format", "", cxx20}, -#line 181 "../../src/gcc/cp/std-name-hint.gperf" +#line 181 "std-name-hint.gperf" {"formatter", "", cxx20}, -#line 196 "../../src/gcc/cp/std-name-hint.gperf" +#line 196 "std-name-hint.gperf" {"basic_filebuf", "", cxx98}, -#line 575 "../../src/gcc/cp/std-name-hint.gperf" +#line 575 "std-name-hint.gperf" {"pair", "", cxx98}, -#line 276 "../../src/gcc/cp/std-name-hint.gperf" +#line 276 "std-name-hint.gperf" {"begin", "", cxx11}, -#line 179 "../../src/gcc/cp/std-name-hint.gperf" +#line 179 "std-name-hint.gperf" {"formattable", "", cxx23}, -#line 541 "../../src/gcc/cp/std-name-hint.gperf" +#line 541 "std-name-hint.gperf" {"bad_cast", "", cxx98}, -#line 233 "../../src/gcc/cp/std-name-hint.gperf" +#line 233 "std-name-hint.gperf" {"setiosflags", "", cxx98}, -#line 393 "../../src/gcc/cp/std-name-hint.gperf" +#line 393 "std-name-hint.gperf" {"print", "", cxx23}, -#line 221 "../../src/gcc/cp/std-name-hint.gperf" +#line 221 "std-name-hint.gperf" {"promise", "", cxx11}, -#line 581 "../../src/gcc/cp/std-name-hint.gperf" +#line 581 "std-name-hint.gperf" {"bad_variant_access", "", cxx17}, -#line 328 "../../src/gcc/cp/std-name-hint.gperf" +#line 328 "std-name-hint.gperf" {"to_address", "", cxx20}, -#line 420 "../../src/gcc/cp/std-name-hint.gperf" +#line 420 "std-name-hint.gperf" {"basic_spanbuf", "", cxx23}, -#line 106 "../../src/gcc/cp/std-name-hint.gperf" +#line 106 "std-name-hint.gperf" {"same_as", "", cxx20}, -#line 336 "../../src/gcc/cp/std-name-hint.gperf" +#line 336 "std-name-hint.gperf" {"pmr", "", cxx17}, -#line 180 "../../src/gcc/cp/std-name-hint.gperf" +#line 180 "std-name-hint.gperf" {"formatted_size", "", cxx20}, -#line 275 "../../src/gcc/cp/std-name-hint.gperf" +#line 275 "std-name-hint.gperf" {"back_inserter", "", cxx98}, -#line 251 "../../src/gcc/cp/std-name-hint.gperf" +#line 251 "std-name-hint.gperf" {"nouppercase", "", cxx98}, -#line 250 "../../src/gcc/cp/std-name-hint.gperf" +#line 250 "std-name-hint.gperf" {"nounitbuf", "", cxx98}, -#line 433 "../../src/gcc/cp/std-name-hint.gperf" +#line 433 "std-name-hint.gperf" {"basic_stringbuf", "", cxx98}, -#line 592 "../../src/gcc/cp/std-name-hint.gperf" +#line 592 "std-name-hint.gperf" {"vector", "", cxx98}, -#line 246 "../../src/gcc/cp/std-name-hint.gperf" +#line 246 "std-name-hint.gperf" {"noshowbase", "", cxx98}, -#line 219 "../../src/gcc/cp/std-name-hint.gperf" +#line 219 "std-name-hint.gperf" {"future", "", cxx11}, -#line 340 "../../src/gcc/cp/std-name-hint.gperf" +#line 340 "std-name-hint.gperf" {"pmr::new_delete_resource", "", cxx17}, -#line 337 "../../src/gcc/cp/std-name-hint.gperf" +#line 337 "std-name-hint.gperf" {"pmr::get_default_resource", "", cxx17}, -#line 343 "../../src/gcc/cp/std-name-hint.gperf" +#line 343 "std-name-hint.gperf" {"pmr::set_default_resource", "", cxx17}, -#line 455 "../../src/gcc/cp/std-na
[gcc r12-11082] df: Treat partial defs as uses in df_simulate_defs [PR116564]
https://gcc.gnu.org/g:91be90b5ae9ee345bd011afdf02df7003d7598d3 commit r12-11082-g91be90b5ae9ee345bd011afdf02df7003d7598d3 Author: Alex Coplan Date: Mon Mar 10 16:44:15 2025 + df: Treat partial defs as uses in df_simulate_defs [PR116564] The PR shows us spinning in dce.cc:fast_dce at the start of combine. This spinning appears to be because of a disagreement between the fast_dce code and the code in df-problems.cc:df_lr_bb_local_compute. Specifically, they disagree on the treatment of partial defs. For the testcase in the PR, we have the following insn in bb 3: (insn 10 8 13 3 (clobber (subreg:V1DF (reg/v:V2x1DF 104 [ __val ]) 8)) -1 (nil)) which gives rise to a DF def with DF_REF_FLAGS = 0x8b0, i.e. DF_REF_PARTIAL | DF_REF_READ_WRITE | DF_REF_MUST_CLOBBER | DF_REF_SUBREG. Eliding the large block comment for readability, the code in df_lr_bb_local_compute does the following (for each insn): FOR_EACH_INSN_INFO_DEF (def, insn_info) { unsigned int dregno = DF_REF_REGNO (def); bitmap_set_bit (&bb_info->def, dregno); if (DF_REF_FLAGS (def) & (DF_REF_PARTIAL | DF_REF_CONDITIONAL)) bitmap_set_bit (&bb_info->use, dregno); else bitmap_clear_bit (&bb_info->use, dregno); } i.e. it models partial defs as a RMW operation; thus for the def arising from i10 above, it records a use of r104; hence it ends up in the live-in set for bb 3. However, as it stands, the code in dce.cc:fast_dce (and its callee dce_process_block) has no such provision for DF_REF_PARTIAL defs. It does not treat these as a RMW and does not compute r104 above as being live-in to bb 3. At the end of dce_process_block we compute the following "did something happen" condition used to decide termination of the analysis: block_changed = !bitmap_equal_p (local_live, DF_LR_IN (bb)); if (block_changed) bitmap_copy (DF_LR_IN (bb), local_live); BITMAP_FREE (local_live); return block_changed; because of the disagreement between df_lr_local_compute and the local analysis done by fast_dce, we invariably have r104 in DF_LR_IN, but not in local_live. Hence we always return true here, call df_analyze_problem (which re-computes DF_LR_IN according to df_lr_bb_local_compute, re-adding r104), and so the analysis never terminates. This patch therefore adjusts df_simulate_defs (called from dce_process_block) to match the behaviour of df_lr_bb_local_compute in this respect, namely we make it model partial defs as RMW operations by setting the relevant register live. This fixes the spinning in fast_dce for this testcase. gcc/ChangeLog: PR rtl-optimization/116564 * df-problems.cc (df_simulate_defs): For partial defs, mark the register live (treat it as a RMW operation). gcc/testsuite/ChangeLog: PR rtl-optimization/116564 * gcc.target/aarch64/torture/pr116564.c: New test. (cherry picked from commit 758e617bcf224dc9d4a7e26dd858d43c1e63b916) Diff: --- gcc/df-problems.cc | 8 +--- gcc/testsuite/gcc.target/aarch64/torture/pr116564.c | 11 +++ 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/gcc/df-problems.cc b/gcc/df-problems.cc index 238424ceac8a..fe027593df98 100644 --- a/gcc/df-problems.cc +++ b/gcc/df-problems.cc @@ -3855,9 +3855,11 @@ df_simulate_defs (rtx_insn *insn, bitmap live) { unsigned int dregno = DF_REF_REGNO (def); - /* If the def is to only part of the reg, it does -not kill the other defs that reach here. */ - if (!(DF_REF_FLAGS (def) & (DF_REF_PARTIAL | DF_REF_CONDITIONAL))) + /* If the def is to only part of the reg, model it as a RMW operation +by marking it live. It only kills the reg if it is a complete def. */ + if (DF_REF_FLAGS (def) & (DF_REF_PARTIAL | DF_REF_CONDITIONAL)) + bitmap_set_bit (live, dregno); + else bitmap_clear_bit (live, dregno); } } diff --git a/gcc/testsuite/gcc.target/aarch64/torture/pr116564.c b/gcc/testsuite/gcc.target/aarch64/torture/pr116564.c new file mode 100644 index ..d471e097294c --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/torture/pr116564.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "" } */ +#include +void test() +{ + for (int L = 0; L < 4; ++L) { +float64_t ResData[1 * 2]; +float64x1x2_t Src1; +vst2_f64(ResData, Src1); + } +}
[gcc r16-331] phiopt: Remove special case for a sequence after match and simplify for early phiopt
https://gcc.gnu.org/g:bbc96c9c09921ca7d59564851d0ed6dcd918c300 commit r16-331-gbbc96c9c09921ca7d59564851d0ed6dcd918c300 Author: Andrew Pinski Date: Wed Apr 30 12:56:13 2025 -0700 phiopt: Remove special case for a sequence after match and simplify for early phiopt r16-189-g99aa410f5e0a72 fixed the case where match-and-simplify there was an extra assignment happening inside the sequence return. phiopt_early_allow had code to workaround that issue but now can be removed and simplify down to only allowing the sequence having only one MIN/MAX if the outer code is MIN/MAX also. Bootstrapped and tested on x86_64-linux-gnu. gcc/ChangeLog: * tree-ssa-phiopt.cc (phiopt_early_allow): Only allow a sequence with one statement for MIN/MAX and the op was MIN/MAX. Signed-off-by: Andrew Pinski Diff: --- gcc/tree-ssa-phiopt.cc | 16 ++-- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/gcc/tree-ssa-phiopt.cc b/gcc/tree-ssa-phiopt.cc index e27166c55a5b..54ecd93495a5 100644 --- a/gcc/tree-ssa-phiopt.cc +++ b/gcc/tree-ssa-phiopt.cc @@ -549,8 +549,7 @@ phiopt_early_allow (gimple_seq &seq, gimple_match_op &op) tree_code code = (tree_code)op.code; /* For non-empty sequence, only allow one statement - except for MIN/MAX, allow max 2 statements, - each with MIN/MAX. */ + a MIN/MAX and an original MIN/MAX. */ if (!gimple_seq_empty_p (seq)) { if (code == MIN_EXPR || code == MAX_EXPR) @@ -565,18 +564,7 @@ phiopt_early_allow (gimple_seq &seq, gimple_match_op &op) code = gimple_assign_rhs_code (stmt); return code == MIN_EXPR || code == MAX_EXPR; } - /* Check to make sure op was already a SSA_NAME. */ - if (code != SSA_NAME) - return false; - if (!gimple_seq_singleton_p (seq)) - return false; - gimple *stmt = gimple_seq_first_stmt (seq); - /* Only allow assignments. */ - if (!is_gimple_assign (stmt)) - return false; - if (gimple_assign_lhs (stmt) != op.ops[0]) - return false; - code = gimple_assign_rhs_code (stmt); + return false; } switch (code)
[gcc r16-332] c++: poor diag w/ non-constexpr dtor called from constexpr ctor
https://gcc.gnu.org/g:9f523d49ada91050445f71821a9a06b0988402f5 commit r16-332-g9f523d49ada91050445f71821a9a06b0988402f5 Author: Patrick Palka Date: Thu May 1 11:40:44 2025 -0400 c++: poor diag w/ non-constexpr dtor called from constexpr ctor When diagnosing a non-constexpr constructor call during constexpr evaluation, explain_invalid_constexpr_fn was passing the genericized body to require_potential_constant_expression rather than the saved non-genericized one. This meant for the below testcase (reduced from PR libstdc++/119282) in which B::B() is deemed non-constexpr due to the local variable having a non-constexpr destructor we would then issue the cryptic diagnostic: constexpr-nonlit19.C:17:16: error: non-constant condition for static assertion 17 | static_assert(f()); | ~^~ constexpr-nonlit19.C:17:16: in ‘constexpr’ expansion of ‘f()’ constexpr-nonlit19.C:13:5: error: ‘constexpr B::B()’ called in a constant expression 13 | B b; | ^ constexpr-nonlit19.C:6:13: note: ‘constexpr B::B()’ is not usable as a ‘constexpr’ function because: 6 | constexpr B() { | ^ constexpr-nonlit19.C:8:5: error: ‘goto’ is not a constant expression 8 | for (int i = 0; i < 10; i++) { } | ^~~ This patch makes us pass the non-genericized body to require_potential_constant_expression, and so we now emit: ... constexpr-nonlit19.C:6:13: note: ‘constexpr B::B()’ is not usable as a ‘constexpr’ function because: 6 | constexpr B() { | ^ constexpr-nonlit19.C:9:3: error: call to non-‘constexpr’ function ‘A::~A()’ 9 | } | ^ constexpr-nonlit19.C:3:12: note: ‘A::~A()’ declared here 3 | struct A { ~A() { } }; |^ gcc/cp/ChangeLog: * constexpr.cc (explain_invalid_constexpr_fn): In the DECL_CONSTRUCTOR_P branch pass the non-genericized body to require_potential_constant_expression. gcc/testsuite/ChangeLog: * g++.dg/cpp23/constexpr-nonlit19.C: New test. Reviewed-by: Jason Merrill Diff: --- gcc/cp/constexpr.cc | 13 + gcc/testsuite/g++.dg/cpp23/constexpr-nonlit19.C | 17 + 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc index 5b7b70f7e657..fa754b9a176a 100644 --- a/gcc/cp/constexpr.cc +++ b/gcc/cp/constexpr.cc @@ -1110,17 +1110,14 @@ explain_invalid_constexpr_fn (tree fun) body = fd->body; else body = DECL_SAVED_TREE (fun); - body = massage_constexpr_body (fun, body); - require_potential_rvalue_constant_expression (body); + tree massaged = massage_constexpr_body (fun, body); + require_potential_rvalue_constant_expression (massaged); if (DECL_CONSTRUCTOR_P (fun)) { - cx_check_missing_mem_inits (DECL_CONTEXT (fun), body, true); + cx_check_missing_mem_inits (DECL_CONTEXT (fun), massaged, true); if (cxx_dialect > cxx11) - { - /* Also check the body, not just the ctor-initializer. */ - body = DECL_SAVED_TREE (fun); - require_potential_rvalue_constant_expression (body); - } + /* Also check the body, not just the ctor-initializer. */ + require_potential_rvalue_constant_expression (body); } } } diff --git a/gcc/testsuite/g++.dg/cpp23/constexpr-nonlit19.C b/gcc/testsuite/g++.dg/cpp23/constexpr-nonlit19.C new file mode 100644 index ..1b73e2d8209d --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp23/constexpr-nonlit19.C @@ -0,0 +1,17 @@ +// { dg-do compile { target c++23 } } + +struct A { ~A() { } }; + +struct B { + constexpr B() { +A a; +for (int i = 0; i < 10; i++) { } + } // { dg-error "call to non-'constexpr' function 'A::~A..'" } +}; + +constexpr bool f() { + B b; // { dg-error "B::B..' called in a constant expression" } + return true; +} + +static_assert(f()); // { dg-error "non-constant" }
[gcc r16-324] Fix gcc.dg/tree-ssa/ssa-dom-thread-7.c for aarch64
https://gcc.gnu.org/g:aa6f1df4ec46a20d2292291b192d3331e51b59f8 commit r16-324-gaa6f1df4ec46a20d2292291b192d3331e51b59f8 Author: Richard Biener Date: Thu May 1 13:56:25 2025 +0200 Fix gcc.dg/tree-ssa/ssa-dom-thread-7.c for aarch64 So on another machine with a cross I see 17 jumps threaded, so adjusted like that. PR tree-optimization/120003 * gcc.dg/tree-ssa/ssa-dom-thread-7.c: Adjust aarch64 expected thread2 number of threads. Diff: --- gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-7.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-7.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-7.c index 8be9878e0cfb..59891f29132c 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-7.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-7.c @@ -12,7 +12,7 @@ jump threading opportunities. Skip the later tests on aarch64. */ /* { dg-final { scan-tree-dump-not "Jumps threaded" "dom3" { target { ! aarch64*-*-* } } } } */ /* { dg-final { scan-tree-dump "Jumps threaded: 10" "thread2" { target { ! aarch64*-*-* } } } } */ -/* { dg-final { scan-tree-dump "Jumps threaded: 14" "thread2" { target { aarch64*-*-* } } } } */ +/* { dg-final { scan-tree-dump "Jumps threaded: 17" "thread2" { target { aarch64*-*-* } } } } */ enum STATE { S0=0,
[gcc r16-327] Aarch64: Use BUILTIN_VHSDF_HSDF for vector and scalar sqrt builtins
https://gcc.gnu.org/g:5c917a585d765b0878afd9435e3b3eece9f820f9 commit r16-327-g5c917a585d765b0878afd9435e3b3eece9f820f9 Author: Ayan Shafqat Date: Thu May 1 06:14:44 2025 -0700 Aarch64: Use BUILTIN_VHSDF_HSDF for vector and scalar sqrt builtins This patch changes the `sqrt` builtin definition from `BUILTIN_VHSDF_DF` to `BUILTIN_VHSDF_HSDF` in `aarch64-simd-builtins.def`, ensuring the builtin covers half, single, and double precision variants. The redundant `VAR1 (UNOP, sqrt, 2, FP, hf)` lines are removed, as they are no longer needed now that `BUILTIN_VHSDF_HSDF` handles those cases. gcc/ChangeLog: * config/aarch64/aarch64-simd-builtins.def: Change BUILTIN_VHSDF_DF to BUILTIN_VHSDF_HSDF. Signed-off-by: Ayan Shafqat Signed-off-by: Andrew Pinski Diff: --- gcc/config/aarch64/aarch64-simd-builtins.def | 5 + 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/gcc/config/aarch64/aarch64-simd-builtins.def b/gcc/config/aarch64/aarch64-simd-builtins.def index 6cc45b18a723..685bf0dc4086 100644 --- a/gcc/config/aarch64/aarch64-simd-builtins.def +++ b/gcc/config/aarch64/aarch64-simd-builtins.def @@ -57,7 +57,7 @@ VAR1 (BINOPP, pmull, 0, DEFAULT, v8qi) VAR1 (BINOPP, pmull_hi, 0, DEFAULT, v16qi) BUILTIN_VHSDF_HSDF (BINOP, fmulx, 0, FP) - BUILTIN_VHSDF_DF (UNOP, sqrt, 2, FP) + BUILTIN_VHSDF_HSDF (UNOP, sqrt, 2, FP) BUILTIN_VDQ_I (BINOP, addp, 0, DEFAULT) BUILTIN_VDQ_I (BINOPU, addp, 0, DEFAULT) BUILTIN_VDQ_BHSI (UNOP, clrsb, 2, DEFAULT) @@ -848,9 +848,6 @@ BUILTIN_VHSDF_HSDF (BINOP_USS, facgt, 0, FP) BUILTIN_VHSDF_HSDF (BINOP_USS, facge, 0, FP) - /* Implemented by sqrt2. */ - VAR1 (UNOP, sqrt, 2, FP, hf) - /* Implemented by hf2. */ VAR1 (UNOP, floatdi, 2, FP, hf) VAR1 (UNOP, floatsi, 2, FP, hf)
[gcc r16-328] Aarch64: Add __sqrt and __sqrtf intrinsics and corresponding tests
https://gcc.gnu.org/g:05df554536a8d33f4c438cfc7b006b3b2083246a commit r16-328-g05df554536a8d33f4c438cfc7b006b3b2083246a Author: Ayan Shafqat Date: Thu May 1 06:17:30 2025 -0700 Aarch64: Add __sqrt and __sqrtf intrinsics and corresponding tests This patch introduces two new inline functions, __sqrt and __sqrtf, in arm_acle.h for Aarch64 targets. These functions wrap the new builtins __builtin_aarch64_sqrtdf and __builtin_aarch64_sqrtsf, respectively, providing direct access to hardware instructions without relying on the standard math library or optimization levels. This patch also introduces acle_sqrt.c in the AArch64 testsuite, verifying that the new __sqrt and __sqrtf intrinsics emit the expected fsqrt instructions for double and float arguments. Coverage for new intrinsics ensures that __sqrt and __sqrtf are correctly expanded to hardware instructions and do not fall back to library calls, regardless of optimization levels. gcc/ChangeLog: * config/aarch64/arm_acle.h (__sqrt, __sqrtf): New function. gcc/testsuite/ChangeLog: * gcc.target/aarch64/acle/acle_sqrt.c: New test. Signed-off-by: Ayan Shafqat Diff: --- gcc/config/aarch64/arm_acle.h | 14 ++ gcc/testsuite/gcc.target/aarch64/acle/acle_sqrt.c | 19 +++ 2 files changed, 33 insertions(+) diff --git a/gcc/config/aarch64/arm_acle.h b/gcc/config/aarch64/arm_acle.h index d9e2401ea9f6..507b6e72bcb1 100644 --- a/gcc/config/aarch64/arm_acle.h +++ b/gcc/config/aarch64/arm_acle.h @@ -118,6 +118,20 @@ __revl (unsigned long __value) return __rev (__value); } +__extension__ extern __inline double +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +__sqrt (double __x) +{ + return __builtin_aarch64_sqrtdf (__x); +} + +__extension__ extern __inline float +__attribute__ ((__always_inline__, __gnu_inline__, __artificial__)) +__sqrtf (float __x) +{ + return __builtin_aarch64_sqrtsf (__x); +} + #pragma GCC push_options #pragma GCC target ("+nothing+jscvt") __extension__ extern __inline int32_t diff --git a/gcc/testsuite/gcc.target/aarch64/acle/acle_sqrt.c b/gcc/testsuite/gcc.target/aarch64/acle/acle_sqrt.c new file mode 100644 index ..482351fa7e66 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/acle/acle_sqrt.c @@ -0,0 +1,19 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +#include "arm_acle.h" + +double +test_acle_sqrt (double x) +{ + return __sqrt (x); +} + +float +test_acle_sqrtf (float x) +{ + return __sqrtf (x); +} + +/* { dg-final { scan-assembler-times "fsqrt\td\[0-9\]" 1 } } */ +/* { dg-final { scan-assembler-times "fsqrt\ts\[0-9\]" 1 } } */
[gcc r14-11717] c++: fix ICE on FUNCTION_DECLs inside coroutines [PR115906]
https://gcc.gnu.org/g:ee0736f665971446f8665a94ef597f683f8128e9 commit r14-11717-gee0736f665971446f8665a94ef597f683f8128e9 Author: Arsen Arsenovic Date: Tue Jul 30 13:42:56 2024 +0200 c++: fix ICE on FUNCTION_DECLs inside coroutines [PR115906] When register_local_var_uses iterates a BIND_EXPRs BIND_EXPR_VARS, it fails to account for the fact that FUNCTION_DECLs might be present, and later passes it to DECL_HAS_VALUE_EXPR_P. This leads to a tree check failure in DECL_HAS_VALUE_EXPR_P: tree check: expected var_decl or parm_decl or result_decl, have function_decl in register_local_var_uses We only care about PARM_DECL and VAR_DECL, so select only those. PR c++/115906 - [coroutines] missing diagnostic and ICE when co_await used as default argument in function declaration gcc/cp/ChangeLog: PR c++/115906 * coroutines.cc (register_local_var_uses): Only process PARM_DECL and VAR_DECLs. gcc/testsuite/ChangeLog: PR c++/115906 * g++.dg/coroutines/coro-function-decl.C: New test. (cherry picked from commit a362c9ca4ef6585e678f899705043a9aa10dd670) Diff: --- gcc/cp/coroutines.cc | 4 ++-- gcc/testsuite/g++.dg/coroutines/coro-function-decl.C | 19 +++ 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/gcc/cp/coroutines.cc b/gcc/cp/coroutines.cc index 200789e89102..5fe9ec422c34 100644 --- a/gcc/cp/coroutines.cc +++ b/gcc/cp/coroutines.cc @@ -3914,8 +3914,8 @@ register_local_var_uses (tree *stmt, int *do_subtree, void *d) local_var.field_idx = local_var.field_id = NULL_TREE; /* Make sure that we only present vars to the tests below. */ - if (TREE_CODE (lvar) == TYPE_DECL - || TREE_CODE (lvar) == NAMESPACE_DECL) + if (TREE_CODE (lvar) != PARM_DECL + && TREE_CODE (lvar) != VAR_DECL) continue; /* We don't move static vars into the frame. */ diff --git a/gcc/testsuite/g++.dg/coroutines/coro-function-decl.C b/gcc/testsuite/g++.dg/coroutines/coro-function-decl.C new file mode 100644 index ..86140569a76e --- /dev/null +++ b/gcc/testsuite/g++.dg/coroutines/coro-function-decl.C @@ -0,0 +1,19 @@ +#include + +struct task +{ + struct promise_type + { +std::suspend_always initial_suspend () { return {}; } +std::suspend_always final_suspend () noexcept { return {}; } +void unhandled_exception () {} +task get_return_object () noexcept { return {}; } +void return_void () {} + }; +}; + +task foo () +{ + void bar (); + co_return; +}
[gcc r14-11716] cp/coroutines: do not rewrite parameters in unevaluated contexts
https://gcc.gnu.org/g:074a89e4c5f9b237176626d464fcc494389905f6 commit r14-11716-g074a89e4c5f9b237176626d464fcc494389905f6 Author: Arsen Arsenović Date: Thu Jul 18 18:16:49 2024 +0200 cp/coroutines: do not rewrite parameters in unevaluated contexts It is possible to use parameters of a parent function of a lambda in unevaluated contexts without capturing them. By not capturing them, we work around the usual mechanism we use to prevent rewriting captured parameters. Prevent this by simply skipping rewrites in unevaluated contexts. Those won't mind the value not being present anyway. This prevents an ICE during parameter substitution. In the testcase from the PR, the rewriting machinery finds a param in the body of the coroutine, which it did not previously encounter while processing the coroutine declaration, and that does not have a DECL_VALUE_EXPR, and fails. gcc/cp/ChangeLog: PR c++/111728 * coroutines.cc (rewrite_param_uses): Skip unevaluated subexpressions. gcc/testsuite/ChangeLog: PR c++/111728 * g++.dg/coroutines/pr111728.C: New test. (cherry picked from commit 1a37d6b732506f8c3f9e9452c9dc6a456f25397b) Diff: --- gcc/cp/coroutines.cc | 7 +++ gcc/testsuite/g++.dg/coroutines/pr111728.C | 29 + 2 files changed, 36 insertions(+) diff --git a/gcc/cp/coroutines.cc b/gcc/cp/coroutines.cc index 882831ce2ec9..200789e89102 100644 --- a/gcc/cp/coroutines.cc +++ b/gcc/cp/coroutines.cc @@ -3755,6 +3755,13 @@ rewrite_param_uses (tree *stmt, int *do_subtree ATTRIBUTE_UNUSED, void *d) return cp_walk_tree (&t, rewrite_param_uses, d, NULL); } + if (unevaluated_p (TREE_CODE (*stmt))) +{ + /* No odr-uses in unevaluated operands. */ + *do_subtree = 0; + return NULL_TREE; +} + if (TREE_CODE (*stmt) != PARM_DECL) return NULL_TREE; diff --git a/gcc/testsuite/g++.dg/coroutines/pr111728.C b/gcc/testsuite/g++.dg/coroutines/pr111728.C new file mode 100644 index ..c1fee4b36a10 --- /dev/null +++ b/gcc/testsuite/g++.dg/coroutines/pr111728.C @@ -0,0 +1,29 @@ +// { dg-do compile } +// https://gcc.gnu.org/PR111728 +#include +struct promise; +struct coroutine : std::coroutine_handle +{ +using promise_type = ::promise; +bool await_ready() { return false; } +void await_suspend(coroutine_handle h) {} +int await_resume() { return {} ;} +}; +struct promise +{ +coroutine get_return_object() { return {coroutine::from_promise(*this)}; } +std::suspend_always initial_suspend() noexcept { return {}; } +std::suspend_always final_suspend() noexcept { return {}; } +void return_void() {} +void unhandled_exception() {} +}; +coroutine +write_fields() { + int static_buffer[10]; + co_await [](auto) + -> coroutine + { +if (sizeof(static_buffer)); + co_return; + }(0); +}
[gcc r14-11719] c++/coroutines: only defer expanding co_{await, return, yield} if dependent [PR112341]
https://gcc.gnu.org/g:ad4c136b906c7658d6e800b3a5241a6dac2e0bdc commit r14-11719-gad4c136b906c7658d6e800b3a5241a6dac2e0bdc Author: Arsen Arsenović Date: Tue Jul 30 23:36:24 2024 +0200 c++/coroutines: only defer expanding co_{await,return,yield} if dependent [PR112341] By doing so, we can get diagnostics in template decls when we know we can. For instance, in the following: awaitable g(); template task f() { co_await g(); co_yield 1; co_return "foo"; } ... the coroutine promise type in each statement is always std::coroutine_handle::promise_type, and all of the operands are not type-dependent, so we can always compute the resulting types (and expected types) of these expressions and statements. Also, when we do not know the type of the CO_AWAIT_EXPR or CO_YIELD_EXPR, we now return NULL_TREE as the type rather than unknown_type_node. This is more correct, since the type is not unknown, it just isn't determined yet. This also means we can remove the CO_AWAIT_EXPR and CO_YIELD_EXPR special-cases from type_dependent_expression_p. PR c++/112341 - error: insufficient contextual information to determine type on co_await result in function template gcc/cp/ChangeLog: PR c++/112341 * coroutines.cc (struct coroutine_info): Also cache the traits type. (ensure_coro_initialized): New function. Makes sure we have initialized the coroutine state successfully, or informs the caller should it fail to do so. Extracted from coro_promise_type_found_p. (coro_get_traits_class): New function. Gets the (cached) coroutine traits type for a given coroutine. Extracted from coro_promise_type_found_p and refactored to cache the result. (coro_promise_type_found_p): Use the two functions above. (build_template_co_await_expr): New function. Builds a CO_AWAIT_EXPR representing a CO_AWAIT_EXPR in a template declaration. (build_co_await): Use the above if processing_template_decl, and give it a proper type. (coro_dependent_p): New function. Returns true iff its argument is a type-dependent expression OR the current functions traits class is type dependent. (finish_co_await_expr): Defer expansion only in the case coro_dependent_p returns true. (finish_co_yield_expr): Ditto. (finish_co_return_stmt): Ditto. * pt.cc (type_dependent_expression_p): Do not treat CO_AWAIT/CO_YIELD specially. gcc/testsuite/ChangeLog: PR c++/112341 * g++.dg/coroutines/pr112341-2.C: New test. * g++.dg/coroutines/pr112341-3.C: New test. * g++.dg/coroutines/torture/co-yield-03-tmpl-nondependent.C: New test. * g++.dg/coroutines/pr112341.C: New test. (cherry picked from commit 32e678b2ed752154b2f96719e33f11a7c6417f20) Diff: --- gcc/cp/coroutines.cc | 157 - gcc/cp/pt.cc | 5 - gcc/testsuite/g++.dg/coroutines/pr112341-2.C | 25 gcc/testsuite/g++.dg/coroutines/pr112341-3.C | 65 + gcc/testsuite/g++.dg/coroutines/pr112341.C | 21 +++ .../torture/co-yield-03-tmpl-nondependent.C| 140 ++ 6 files changed, 376 insertions(+), 37 deletions(-) diff --git a/gcc/cp/coroutines.cc b/gcc/cp/coroutines.cc index 5fe9ec422c34..c4f4843cf216 100644 --- a/gcc/cp/coroutines.cc +++ b/gcc/cp/coroutines.cc @@ -85,6 +85,7 @@ struct GTY((for_user)) coroutine_info tree actor_decl;/* The synthesized actor function. */ tree destroy_decl; /* The synthesized destroy function. */ tree promise_type; /* The cached promise type for this function. */ + tree traits_type; /* The cached traits type for this function. */ tree handle_type; /* The cached coroutine handle for this function. */ tree self_h_proxy; /* A handle instance that is used as the proxy for the one that will eventually be allocated in the coroutine @@ -429,11 +430,12 @@ find_promise_type (tree traits_class) return promise_type; } +/* Perform initialization of the coroutine processor state, if not done + before. */ + static bool -coro_promise_type_found_p (tree fndecl, location_t loc) +ensure_coro_initialized (location_t loc) { - gcc_assert (fndecl != NULL_TREE); - if (!coro_initialized) { /* Trees we only need to create once. @@ -466,6 +468,30 @@ coro_promise_type_found_p (tree fndecl, location_t loc) coro_initialized = true; } + return true; +} + +/* Try to get the coroutine traits class. */ +static tree +coro_get_traits_class (tree fndecl, locatio
[gcc r14-11718] c++: diagnose usage of co_await and co_yield in default args [PR115906]
https://gcc.gnu.org/g:7b4cb031cf7de0ac350197e4ae869df9fe1d08a1 commit r14-11718-g7b4cb031cf7de0ac350197e4ae869df9fe1d08a1 Author: Arsen Arsenović Date: Thu Jul 25 01:00:02 2024 +0200 c++: diagnose usage of co_await and co_yield in default args [PR115906] This is a partial fix for PR115906. Per [expr.await] 2s3, "An await-expression shall not appear in a default argument ([dcl.fct.default])". This patch introduces the diagnostic in that case, and in the case of a co_yield (as co_yield is defined in terms of co_await, so prerequisites of co_await hold). PR c++/115906 - [coroutines] missing diagnostic and ICE when co_await used as default argument in function declaration gcc/cp/ChangeLog: PR c++/115906 * parser.cc (cp_parser_unary_expression): Reject await expressions if use of local variables is currently forbidden. (cp_parser_yield_expression): Reject yield expressions if use of local variables is currently forbidden. gcc/testsuite/ChangeLog: PR c++/115906 * g++.dg/coroutines/pr115906-yield.C: New test. * g++.dg/coroutines/pr115906.C: New test. * g++.dg/coroutines/co-await-syntax-02-outside-fn.C: Don't rely on default arguments. * g++.dg/coroutines/co-yield-syntax-01-outside-fn.C: Ditto. (cherry picked from commit 0c382da0943dc7d14455ba2ada2f620a25bd1366) Diff: --- gcc/cp/parser.cc | 17 .../coroutines/co-await-syntax-02-outside-fn.C | 2 +- .../coroutines/co-yield-syntax-01-outside-fn.C | 3 +- gcc/testsuite/g++.dg/coroutines/pr115906-yield.C | 29 gcc/testsuite/g++.dg/coroutines/pr115906.C | 32 ++ 5 files changed, 80 insertions(+), 3 deletions(-) diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc index 0a703cdc2207..0281d7eb99b6 100644 --- a/gcc/cp/parser.cc +++ b/gcc/cp/parser.cc @@ -9220,6 +9220,14 @@ cp_parser_unary_expression (cp_parser *parser, cp_id_kind * pidk, if (expr == error_mark_node) return error_mark_node; + /* ... but, we cannot use co_await in default arguments. */ + if (parser->local_variables_forbidden_p & LOCAL_VARS_FORBIDDEN) + { + error_at (kw_loc, + "% cannot be used in default arguments"); + return error_mark_node; + } + /* Handle [expr.await]. */ return cp_expr (finish_co_await_expr (kw_loc, expr)); } @@ -29407,6 +29415,15 @@ cp_parser_yield_expression (cp_parser* parser) else expr = cp_parser_assignment_expression (parser); + /* Similar to co_await, we cannot use co_yield in default arguments (as + co_awaits underlie co_yield). */ + if (parser->local_variables_forbidden_p & LOCAL_VARS_FORBIDDEN) +{ + error_at (kw_loc, + "% cannot be used in default arguments"); + return error_mark_node; +} + if (expr == error_mark_node) return expr; diff --git a/gcc/testsuite/g++.dg/coroutines/co-await-syntax-02-outside-fn.C b/gcc/testsuite/g++.dg/coroutines/co-await-syntax-02-outside-fn.C index 4ce5c2e04a0a..132128f27192 100644 --- a/gcc/testsuite/g++.dg/coroutines/co-await-syntax-02-outside-fn.C +++ b/gcc/testsuite/g++.dg/coroutines/co-await-syntax-02-outside-fn.C @@ -2,4 +2,4 @@ #include "coro.h" -auto f (int x = co_await coro::suspend_always{}); // { dg-error {'co_await' cannot be used outside a function} } +auto x = co_await coro::suspend_always{}; // { dg-error {'co_await' cannot be used outside a function} } diff --git a/gcc/testsuite/g++.dg/coroutines/co-yield-syntax-01-outside-fn.C b/gcc/testsuite/g++.dg/coroutines/co-yield-syntax-01-outside-fn.C index 30db0e963b09..51c304625278 100644 --- a/gcc/testsuite/g++.dg/coroutines/co-yield-syntax-01-outside-fn.C +++ b/gcc/testsuite/g++.dg/coroutines/co-yield-syntax-01-outside-fn.C @@ -2,5 +2,4 @@ #include "coro.h" -auto f (int x = co_yield 5); // { dg-error {'co_yield' cannot be used outside a function} } - +auto x = co_yield 5; // { dg-error {'co_yield' cannot be used outside a function} } diff --git a/gcc/testsuite/g++.dg/coroutines/pr115906-yield.C b/gcc/testsuite/g++.dg/coroutines/pr115906-yield.C new file mode 100644 index ..f8b6ded5001c --- /dev/null +++ b/gcc/testsuite/g++.dg/coroutines/pr115906-yield.C @@ -0,0 +1,29 @@ +#include + +struct Promise; + +struct Handle : std::coroutine_handle { +using promise_type = Promise; +}; + +struct Promise { +Handle get_return_object() noexcept { +return {Handle::from_promise(*this)}; +} +std::suspend_never initial_suspend() const noexcept { return {}; } +std::suspend_never final_suspend() const noexcept { return {}; } +void return_void() const noexcept {} +void unhandled_exception() const noexcept {} +
[gcc r14-11715] c++, coroutines, contracts: Handle coroutine and void functions [PR110871, PR110872, PR115434].
https://gcc.gnu.org/g:fbe351c9fa344cc53bff8a4e03068c7121af0d0c commit r14-11715-gfbe351c9fa344cc53bff8a4e03068c7121af0d0c Author: Iain Sandoe Date: Sat Jun 15 17:47:33 2024 +0100 c++, coroutines, contracts: Handle coroutine and void functions [PR110871,PR110872,PR115434]. The current implementation of contracts emits the checks into function bodies in three places; for pre-conditions at the start of the body, for asserts in-line in the function body and for post-conditions as an addition to return statements. In general (at least with existing "2a" contract semantics) the in-line contract asserts behave as expected. However, the mechanism is not applicable to: * Handling pre conditions in coroutines since, for those, the standard specifies a wrapping of the original function body by functionality implementing initial and final suspends (along with some housekeeping to route exceptions). Thus for such transformed function bodies, the preconditions then get actioned after the initial suspend, which does not behave as intended. * Handling post conditions in functions that do not have return statements (which applies to coroutines and void functions). In the following, we identify a potentially transformed function body (in the case of coroutines, this is usually called the "ramp()" function). The patch here re-implements the code insertion in one of the two following ways (code for exposition only): * For functions with no post-conditions we wrap the potentially transformed function as follows: { handle_pre_condition_checking (); potentially_transformed_function_body (); } This implements the intent that the preconditions are processed after the function parameters are initialised but before any other actions. * For functions with post-conditions: if (preconditions_exist) handle_pre_condition_checking (); try { potentially_transformed_function_body (); } finally { handle_post_condition_checking (); } else [only if the function is not marked noexcept(true) ] { ; } In this, post-conditions [that might apply to the return value etc.] are evaluated on every non-exceptional edge out of the function. At present, the model here is that exceptions thrown by the function propagate upwards as if there were no contracts present. If the desired semantic becomes that an exception is counted as equivalent to a contract violation - then we can add a second handler in place of the empty statement. This patch specifically does not address changes to code-gen and constexpr handling that are contained in P2900. PR c++/115434 PR c++/110871 PR c++/110872 gcc/cp/ChangeLog: * constexpr.cc (cxx_eval_constant_expression): Handle EH_ELSE_EXPR. * contracts.cc (finish_contract_attribute): Remove excess line. (build_contract_condition_function): Post condition handlers are void now. (emit_postconditions_cleanup): Remove. (emit_postconditions): New. (add_pre_condition_fn_call): New. (add_post_condition_fn_call): New. (apply_preconditions): New. (apply_postconditions): New. (maybe_apply_function_contracts): New. (apply_postcondition_to_return): Remove. * contracts.h (apply_postcondition_to_return): Remove. (maybe_apply_function_contracts): Add. * coroutines.cc (coro_build_actor_or_destroy_function): Do not copy contracts to coroutine helpers. * decl.cc (finish_function): Handle wrapping a possibly transformed function body in contract checks. * typeck.cc (check_return_expr): Remove handling of post conditions on return expressions. gcc/ChangeLog: * gimplify.cc (struct gimplify_ctx): Add a flag to show we are expending a handler. (gimplify_expr): When we are expanding a handler, and the body transforms might have re-written DECL_RESULT into a gimple var, ensure that hander references to DECL_RESULT are also re-written to refer to the gimple var. When we are processing an EH_ELSE expression, then add it if either of the cleanup slots is in use. gcc/testsuite/ChangeLog: * g++.dg/contracts/pr115434.C: New test. * g++.dg/coroutines/pr110871.C: New test. * g++.dg/coroutines/pr110872.C: New test. Signed-off-by: Iain Sandoe (cherry picked from commit d1706235ed2b274a2d1fa3c3039b5874b4ae7a0e) Diff: --- gcc/cp/cons
[gcc r16-333] OpenMP: Restore lost Fortran testcase for 'omp allocate'
https://gcc.gnu.org/g:08ce1b9f6707e00089c4d77d2bb82963d531bb1d commit r16-333-g08ce1b9f6707e00089c4d77d2bb82963d531bb1d Author: Tobias Burnus Date: Thu May 1 15:39:42 2025 + OpenMP: Restore lost Fortran testcase for 'omp allocate' This testcase, which is present on the OG13 and OG14 branches, was overlooked when the Fortran support for 'omp allocate' was added to mainline (commit d4b6d147920b93297e621124a99ed01e7e310d92 from December 2023). libgomp/ChangeLog * testsuite/libgomp.fortran/allocate-8a.f90: New test. Diff: --- libgomp/testsuite/libgomp.fortran/allocate-8a.f90 | 45 +++ 1 file changed, 45 insertions(+) diff --git a/libgomp/testsuite/libgomp.fortran/allocate-8a.f90 b/libgomp/testsuite/libgomp.fortran/allocate-8a.f90 new file mode 100644 index ..5f6c8c1e2717 --- /dev/null +++ b/libgomp/testsuite/libgomp.fortran/allocate-8a.f90 @@ -0,0 +1,45 @@ +! { dg-additional-options "-fopenmp-allocators" } +! { dg-additional-options "-fdump-tree-omplower" } +program main + use iso_c_binding + use omp_lib + implicit none (type, external) + integer(omp_allocator_handle_kind):: alloc_h + integer :: i, N + integer(c_intptr_t) :: intptr + integer, allocatable :: A(:) + type(omp_alloctrait):: traits(1) = [omp_alloctrait(omp_atk_alignment, 128)] + + N = 10 + alloc_h = omp_init_allocator(omp_default_mem_space, 1, traits) + + !$omp allocate(A) allocator(alloc_h) + allocate(A(N)) + a(:) = [(i, i=1,N)] + if (mod (transfer (loc(a), intptr),128) /= 0) & +stop 1 + if (any (a /= [(i, i=1,N)])) & +stop 2 + deallocate(A) + !$omp allocate(A) allocator(alloc_h) align(512) + allocate(A(N)) + block +integer, allocatable :: B(:) +!$omp allocators allocate(allocator(alloc_h), align(256) : B) +allocate(B(N)) +B(:) = [(2*i, i=1,N)] +A(:) = B +if (mod (transfer (loc(B), intptr), 256) /= 0) & + stop 1 +! end of scope deallocation + end block + if (mod (transfer (loc(a), intptr),512) /= 0) & +stop 1 + if (any (a /= [(2*i, i=1,N)])) & +stop 2 + deallocate(A) ! Must deallocate here - before deallocator is destroyed + call omp_destroy_allocator(alloc_h) + ! No auto dealloc of A because it is SAVE +end +! { dg-final { scan-tree-dump-times "__builtin_GOMP_alloc \\(" 3 "omplower" } } +! { dg-final { scan-tree-dump-times "__builtin_GOMP_free \\(" 3 "omplower" } }
[gcc r16-325] c++: remove TREE_STATIC from constexpr heap vars [PR119162]
https://gcc.gnu.org/g:25fe59805029e164bfbe347adbdf62856d1b1b1e commit r16-325-g25fe59805029e164bfbe347adbdf62856d1b1b1e Author: Jason Merrill Date: Tue Mar 11 11:17:46 2025 -0400 c++: remove TREE_STATIC from constexpr heap vars [PR119162] While working on PR119162 it occurred to me that it would be simpler to detect the problem of a value referring to a heap allocation if we stopped setting TREE_STATIC on them so they naturally are not considered to have a constant address. With that change we no longer need to specifically avoid caching a value that refers to a deleted pointer. But with this change maybe_nonzero_address is not sure whether the variable could have address zero. I don't understand why it returns 1 only for variables in the current function, rather than all non-symtab decls; an auto variable from some other function also won't have address zero. Maybe this made more sense when it was in tree_single_nonzero_warnv_p before r7-5868? But assuming there is some reason for the current behavior, this patch only changes the handling of non-symtab decls when folding_cxx_constexpr. PR c++/119162 gcc/cp/ChangeLog: * constexpr.cc (find_deleted_heap_var): Remove. (cxx_eval_call_expression): Don't call it. Don't set TREE_STATIC on heap vars. (cxx_eval_outermost_constant_expr): Don't mess with varpool. gcc/ChangeLog: * fold-const.cc (maybe_nonzero_address): Return 1 for non-symtab vars if folding_cxx_constexpr. Diff: --- gcc/cp/constexpr.cc | 29 - gcc/fold-const.cc | 25 - 2 files changed, 16 insertions(+), 38 deletions(-) diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc index 8a11e6265f23..5b7b70f7e657 100644 --- a/gcc/cp/constexpr.cc +++ b/gcc/cp/constexpr.cc @@ -1550,7 +1550,6 @@ static tree cxx_eval_bare_aggregate (const constexpr_ctx *, tree, static tree cxx_fold_indirect_ref (const constexpr_ctx *, location_t, tree, tree, bool * = NULL); static tree find_heap_var_refs (tree *, int *, void *); -static tree find_deleted_heap_var (tree *, int *, void *); /* Attempt to evaluate T which represents a call to a builtin function. We assume here that all builtin functions evaluate to scalar types @@ -2975,14 +2974,6 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t, : heap_uninit_identifier, type); DECL_ARTIFICIAL (var) = 1; - TREE_STATIC (var) = 1; - // Temporarily register the artificial var in varpool, - // so that comparisons of its address against NULL are folded - // through nonzero_address even with - // -fno-delete-null-pointer-checks or that comparison of - // addresses of different heap artificial vars is folded too. - // See PR98988 and PR99031. - varpool_node::finalize_decl (var); ctx->global->heap_vars.safe_push (var); ctx->global->put_value (var, NULL_TREE); return fold_convert (ptr_type_node, build_address (var)); @@ -3454,11 +3445,6 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t, cacheable = false; break; } - /* And don't cache a ref to a deleted heap variable (119162). */ - if (cacheable - && (cp_walk_tree_without_duplicates - (&result, find_deleted_heap_var, NULL))) - cacheable = false; } /* Rewrite all occurrences of the function's RESULT_DECL with the @@ -9025,20 +9011,6 @@ find_heap_var_refs (tree *tp, int *walk_subtrees, void */*data*/) return NULL_TREE; } -/* Look for deleted heap variables in the expression *TP. */ - -static tree -find_deleted_heap_var (tree *tp, int *walk_subtrees, void */*data*/) -{ - if (VAR_P (*tp) - && DECL_NAME (*tp) == heap_deleted_identifier) -return *tp; - - if (TYPE_P (*tp)) -*walk_subtrees = 0; - return NULL_TREE; -} - /* Find immediate function decls in *TP if any. */ static tree @@ -9275,7 +9247,6 @@ cxx_eval_outermost_constant_expr (tree t, bool allow_non_constant, r = t; non_constant_p = true; } - varpool_node::get (heap_var)->remove (); } } diff --git a/gcc/fold-const.cc b/gcc/fold-const.cc index c9471ea44b01..35fcf5087fb5 100644 --- a/gcc/fold-const.cc +++ b/gcc/fold-const.cc @@ -9917,22 +9917,29 @@ pointer_may_wrap_p (tree base, tree offset, poly_int64 bitpos) static int maybe_nonzero_address (tree decl) { + if (!DECL_P (decl)) +return -1; + /* Normally, don't do anything for variables and functions before symtab is built; it is quit
[gcc r16-329] Fortran: Source allocation of pure function result rejected [PR119948]
https://gcc.gnu.org/g:0abc77da9d704bba55a376bb5c162a54826ab94a commit r16-329-g0abc77da9d704bba55a376bb5c162a54826ab94a Author: Paul Thomas Date: Thu May 1 15:22:54 2025 +0100 Fortran: Source allocation of pure function result rejected [PR119948] 2025-05-01 Paul Thomas gcc/fortran PR fortran/119948 * resolve.cc (gfc_impure_variable): The result of a module procedure with an interface declaration is not impure even if the current namespace is not the same as the symbol's. gcc/testsuite/ PR fortran/119948 * gfortran.dg/pr119948.f90: New test. Diff: --- gcc/fortran/resolve.cc | 10 +++ gcc/testsuite/gfortran.dg/pr119948.f90 | 50 ++ 2 files changed, 60 insertions(+) diff --git a/gcc/fortran/resolve.cc b/gcc/fortran/resolve.cc index e51f83b6618b..1e62e94788b1 100644 --- a/gcc/fortran/resolve.cc +++ b/gcc/fortran/resolve.cc @@ -18549,6 +18549,16 @@ gfc_impure_variable (gfc_symbol *sym) if (sym->attr.use_assoc || sym->attr.in_common) return 1; + /* The namespace of a module procedure interface holds the arguments and + symbols, and so the symbol namespace can be different to that of the + procedure. */ + if (sym->ns != gfc_current_ns + && gfc_current_ns->proc_name->abr_modproc_decl + && sym->ns->proc_name->attr.function + && sym->attr.result + && !strcmp (sym->ns->proc_name->name, gfc_current_ns->proc_name->name)) +return 0; + /* Check if the symbol's ns is inside the pure procedure. */ for (ns = gfc_current_ns; ns; ns = ns->parent) { diff --git a/gcc/testsuite/gfortran.dg/pr119948.f90 b/gcc/testsuite/gfortran.dg/pr119948.f90 new file mode 100644 index ..9ecb08095613 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/pr119948.f90 @@ -0,0 +1,50 @@ +! { dg-do compile } +! +! Test the fix for PR119948, which used to fail as indicated below with, +! "Error: Bad allocate-object at (1) for a PURE procedure" +! +! Contributed by Damian Rouson +! +module test_m + implicit none + + type test_t +integer, allocatable :: i + end type + + interface +pure module function construct_test(arg) result(test) + implicit none + type(test_t) :: test + type(test_t), intent(in) :: arg +end function +pure module function construct_test_sub(arg) result(test) + implicit none + type(test_t) :: test + type(test_t), intent(in) :: arg +end function + end interface + +contains + module procedure construct_test +allocate(test%i, source = arg%i) ! Used to fail here + end procedure +end module + +submodule (test_m)test_s +contains + module procedure construct_test_sub +allocate(test%i, source = arg%i) ! This was OK. + end procedure +end submodule + + use test_m + type(test_t) :: res, dummy + dummy%i = 42 + res = construct_test (dummy) + if (res%i /= dummy%i) stop 1 + dummy%i = -42 + res = construct_test_sub (dummy) + if (res%i /= dummy%i) stop 2 + deallocate (res%i, dummy%i) +end
[gcc r16-334] c: Suppress -Wdeprecated-non-prototype warnings for builtins
https://gcc.gnu.org/g:b6d37ec1dd2a228d94e7b5b438f3aa53684316bc commit r16-334-gb6d37ec1dd2a228d94e7b5b438f3aa53684316bc Author: Florian Weimer Date: Thu May 1 19:06:45 2025 +0200 c: Suppress -Wdeprecated-non-prototype warnings for builtins Builtins defined with BT_FN_INT_VAR etc. show as functions without a prototype and trigger the warning. gcc/c/ PR c/119950 * c-typeck.cc (convert_arguments): Check for built-in function declaration before warning. gcc/testsuite/ * gcc.dg/Wdeprecated-non-prototype-5.c: New test. Diff: --- gcc/c/c-typeck.cc | 3 ++- gcc/testsuite/gcc.dg/Wdeprecated-non-prototype-5.c | 14 ++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/gcc/c/c-typeck.cc b/gcc/c/c-typeck.cc index d94ecb5b743a..c7a13bf2b2f4 100644 --- a/gcc/c/c-typeck.cc +++ b/gcc/c/c-typeck.cc @@ -4336,7 +4336,8 @@ convert_arguments (location_t loc, vec arg_loc, tree fntype, builtin_typetail = NULL_TREE; } - if (!typetail && parmnum == 0 && !TYPE_NO_NAMED_ARGS_STDARG_P (fntype)) + if (!typetail && parmnum == 0 && !TYPE_NO_NAMED_ARGS_STDARG_P (fntype) + && !fndecl_built_in_p (fundecl)) { auto_diagnostic_group d; bool warned; diff --git a/gcc/testsuite/gcc.dg/Wdeprecated-non-prototype-5.c b/gcc/testsuite/gcc.dg/Wdeprecated-non-prototype-5.c new file mode 100644 index ..b231a74cebe3 --- /dev/null +++ b/gcc/testsuite/gcc.dg/Wdeprecated-non-prototype-5.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ +/* { dg-options "-Wdeprecated-non-prototype" } */ + +static inline +int f (int x) +{ + return __builtin_constant_p (x); +} + +static inline +int g (double x) +{ + return __builtin_isfinite (x); +}
[gcc r14-11711] Darwin: Pass -macos_version_min to the linker [PR119172].
https://gcc.gnu.org/g:86b51d7287e9e12e9f9936f376537545e31ee03a commit r14-11711-g86b51d7287e9e12e9f9936f376537545e31ee03a Author: Iain Sandoe Date: Sun Mar 9 09:24:34 2025 + Darwin: Pass -macos_version_min to the linker [PR119172]. For binaries to be notarised, the SDK version must be available. Since we do not, at present, parse this information we have been passing "0.0" to ld64. This now results in a warning and a fail to notarise. As a quick-fix, we can fall back to letting ld64 figure out the SDK version (which it does for -macos_version_min). TODO: Parse the SDKSetting.plist at some point. cherry-picked from 952e17223d3a9 and fc728cfd569e291a5 PR target/119172 gcc/ChangeLog: * config.in: Regenerate. * config/darwin.h (DARWIN_PLATFORM_ID): Add the option to use -macos_version_min where available. * configure: Regenerate. * configure.ac: Check for ld64 support of -macos_version_min. Co-authored-by: Andrew Pinski Signed-off-by: Iain Sandoe Signed-off-by: Andrew Pinski Diff: --- gcc/config.in | 6 ++ gcc/config/darwin.h | 13 + gcc/configure | 17 + gcc/configure.ac| 12 4 files changed, 44 insertions(+), 4 deletions(-) diff --git a/gcc/config.in b/gcc/config.in index df598c80bb2a..3daa90be0e8b 100644 --- a/gcc/config.in +++ b/gcc/config.in @@ -2296,6 +2296,12 @@ #endif +/* Define to 1 if ld64 supports '-macos_version_min'. */ +#ifndef USED_FOR_TARGET +#undef LD64_HAS_MACOS_VERSION_MIN +#endif + + /* Define to 1 if ld64 supports '-platform_version'. */ #ifndef USED_FOR_TARGET #undef LD64_HAS_PLATFORM_VERSION diff --git a/gcc/config/darwin.h b/gcc/config/darwin.h index 0d8886c026c6..e7a6f5433ce3 100644 --- a/gcc/config/darwin.h +++ b/gcc/config/darwin.h @@ -284,12 +284,17 @@ extern GTY(()) int darwin_ms_struct; #define DARWIN_RDYNAMIC "%{rdynamic:%nrdynamic is not supported}" #endif -#if LD64_HAS_PLATFORM_VERSION -#define DARWIN_PLATFORM_ID \ - "%{mmacosx-version-min=*: -platform_version macos %* 0.0} " +#if LD64_HAS_MACOS_VERSION_MIN +# define DARWIN_PLATFORM_ID \ + "%{mmacosx-version-min=*:-macos_version_min %*} " #else -#define DARWIN_PLATFORM_ID \ +# if LD64_HAS_PLATFORM_VERSION +# define DARWIN_PLATFORM_ID \ + "%{mmacosx-version-min=*: -platform_version macos %* 0.0} " +# else +# define DARWIN_PLATFORM_ID \ "%{mmacosx-version-min=*:-macosx_version_min %*} " +# endif #endif /* Code built with mdynamic-no-pic does not support PIE/PIC, so we disallow diff --git a/gcc/configure b/gcc/configure index 091b5f1f11fe..4e9c65225d34 100755 --- a/gcc/configure +++ b/gcc/configure @@ -32741,6 +32741,7 @@ if test x"$ld64_flag" = x"yes"; then # Set defaults for possibly untestable items. gcc_cv_ld64_export_dynamic=0 gcc_cv_ld64_platform_version=0 + gcc_cv_ld64_macos_version_min=0 gcc_cv_ld64_demangle=0 if test "$build" = "$host"; then @@ -32773,6 +32774,7 @@ $as_echo "$gcc_cv_ld64_major" >&6; } fi if test "$gcc_cv_ld64_major" -ge 512; then gcc_cv_ld64_platform_version=1 + gcc_cv_ld64_macos_version_min=1 fi elif test -x "$gcc_cv_ld" -a "$darwin_try_test" -eq 1; then # If the version was not specified, try to find it. @@ -32811,6 +32813,15 @@ $as_echo_n "checking linker for -platform_version support... " >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_ld64_platform_version" >&5 $as_echo "$gcc_cv_ld64_platform_version" >&6; } + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking linker for -macos_version_min" >&5 +$as_echo_n "checking linker for -macos_version_min... " >&6; } +gcc_cv_ld64_macos_version_min=1 +if $gcc_cv_ld -macos_version_min 10.5 < /dev/null 2>&1 | grep 'unknown option' > /dev/null; then + gcc_cv_ld64_macos_version_min=0 +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_ld64_macos_version_min" >&5 +$as_echo "$gcc_cv_ld64_macos_version_min" >&6; } fi if test x"${gcc_cv_ld64_version}" != x; then @@ -32838,6 +32849,12 @@ cat >>confdefs.h <<_ACEOF #define LD64_HAS_PLATFORM_VERSION $gcc_cv_ld64_platform_version _ACEOF + + +cat >>confdefs.h <<_ACEOF +#define LD64_HAS_MACOS_VERSION_MIN $gcc_cv_ld64_macos_version_min +_ACEOF + fi if test x"$dsymutil_flag" = x"yes"; then diff --git a/gcc/configure.ac b/gcc/configure.ac index 0986853fecdf..89d927cf0ac2 100644 --- a/gcc/configure.ac +++ b/gcc/configure.ac @@ -6430,6 +6430,7 @@ if test x"$ld64_flag" = x"yes"; then # Set defaults for possibly untestable items. gcc_cv_ld64_export_dynamic=0 gcc_cv_ld64_platform_version=0 + gcc_cv_ld64_macos_version_min=0 gcc_cv_ld64_demangle=0 if test "$build" = "$host"; then @@ -6460,6 +6461,7 @@ if test x"$ld64_flag" = x"yes"; then fi if test "$gcc_cv_ld64_major" -ge 512; then gcc_cv_ld64_platform_v
[gcc r14-11710] fixincludes: adjust stdio fix for macOS 15 headers
https://gcc.gnu.org/g:bfed396d6a0e9c1450d5a9ccf63d38799e87a8fc commit r14-11710-gbfed396d6a0e9c1450d5a9ccf63d38799e87a8fc Author: Francois-Xavier Coudert Date: Thu Jun 27 18:55:22 2024 +0200 fixincludes: adjust stdio fix for macOS 15 headers fixincludes/ChangeLog: * fixincl.x: Regenerate. * inclhack.def (apple_local_stdio_fn_deprecation): Also apply to _stdio.h. (cherry picked from commit 1dc143181550573c9c902fb7a3b495e9b409d0b0) Diff: --- fixincludes/fixincl.x| 6 +++--- fixincludes/inclhack.def | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/fixincludes/fixincl.x b/fixincludes/fixincl.x index e52f11d8460f..45d65f4872ab 100644 --- a/fixincludes/fixincl.x +++ b/fixincludes/fixincl.x @@ -2,11 +2,11 @@ * * DO NOT EDIT THIS FILE (fixincl.x) * - * It has been AutoGen-ed August 17, 2023 at 10:16:38 AM by AutoGen 5.18.12 + * It has been AutoGen-ed April 1, 2025 at 03:28:07 PM by AutoGen 5.18.16 * From the definitionsinclhack.def * and the template file fixincl */ -/* DO NOT SVN-MERGE THIS FILE, EITHER Thu Aug 17 10:16:38 CEST 2023 +/* DO NOT SVN-MERGE THIS FILE, EITHER Tue Apr 1 15:28:07 BST 2025 * * You must regenerate it. Use the ./genfixes script. * @@ -2619,7 +2619,7 @@ tSCC zApple_Local_Stdio_Fn_DeprecationName[] = * File name selection pattern */ tSCC zApple_Local_Stdio_Fn_DeprecationList[] = - "stdio.h\0"; + "stdio.h\0_stdio.h\0"; /* * Machine/OS name selection pattern */ diff --git a/fixincludes/inclhack.def b/fixincludes/inclhack.def index 19e0ea2df662..67a1082f9268 100644 --- a/fixincludes/inclhack.def +++ b/fixincludes/inclhack.def @@ -1273,6 +1273,7 @@ fix = { hackname = apple_local_stdio_fn_deprecation; mach = "*-*-*darwin2*"; files = stdio.h; +files = _stdio.h; select= "__deprecated_msg([^\n]*)$"; c_fix = format; c_fix_arg = "#if defined(__APPLE_LOCAL_DEPRECATIONS)\n"
[gcc r14-11709] libgcc, Darwin: Drop the legacy library build for macOS >= 10.12 [PR116809].
https://gcc.gnu.org/g:cae584bddd0e348d9ac6f9bd917b47255a26458e commit r14-11709-gcae584bddd0e348d9ac6f9bd917b47255a26458e Author: Mark Mentovai Date: Tue Sep 24 16:11:14 2024 -0400 libgcc, Darwin: Drop the legacy library build for macOS >= 10.12 [PR116809]. From macOSX15 SDK, the unwinder no longer exports some of the symbols used in that library which (a) causes bootstrap fail and (b) means that the legacy library is no longer useful. No open branch of GCC emits references to this library - and any already -built code that depends on the symbols would need rework anyway. We have been asked to extend this back to the earliest OS vesion supported by the SDK (10.12). PR target/116809 libgcc/ChangeLog: * config.host: Build legacy libgcc_s.1 on hosts before macOS 10.12. * config/i386/t-darwin: Remove reference to legacy libgcc_s.1 * config/rs6000/t-darwin: Likewise. * config/t-darwin-libgccs1: New file. Signed-off-by: Iain Sandoe (cherry picked from commit d9cafa0c4f0a81304d9b95a78ccc8e9003c6d7a3) Diff: --- libgcc/config.host | 9 ++--- libgcc/config/i386/t-darwin | 3 --- libgcc/config/rs6000/t-darwin | 3 --- libgcc/config/t-darwin-libgccs1 | 3 +++ 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/libgcc/config.host b/libgcc/config.host index 8ad2f4047867..ee10e99b0a66 100644 --- a/libgcc/config.host +++ b/libgcc/config.host @@ -242,16 +242,19 @@ case ${host} in *-*-darwin1[89]*) tmake_file="t-darwin-min-8 $tmake_file" ;; -*-*-darwin9* | *-*-darwin1[0-7]*) +*-*-darwin1[67]]*) tmake_file="t-darwin-min-5 $tmake_file" ;; +*-*-darwin9* | *-*-darwin1[0-5]*) + tmake_file="t-darwin-min-5 t-darwin-libgccs1 $tmake_file" + ;; *-*-darwin[4-8]*) - tmake_file="t-darwin-min-1 $tmake_file" + tmake_file="t-darwin-min-1 t-darwin-libgccs1 $tmake_file" ;; *) # Fall back to configuring for the oldest system known to work with # all archs and the current sources. - tmake_file="t-darwin-min-5 $tmake_file" + tmake_file="t-darwin-min-5 t-darwin-libgccs1 $tmake_file" echo "Warning: libgcc configured to support macOS 10.5" 1>&2 ;; esac diff --git a/libgcc/config/i386/t-darwin b/libgcc/config/i386/t-darwin index 4c18da1efbfd..c6b3acaaca28 100644 --- a/libgcc/config/i386/t-darwin +++ b/libgcc/config/i386/t-darwin @@ -4,6 +4,3 @@ LIB2FUNCS_EXCLUDE = _fixtfdi _fixunstfdi _floatditf _floatunditf # Extra symbols for this port. SHLIB_MAPFILES += $(srcdir)/config/i386/libgcc-darwin.ver - -# Build a legacy libgcc_s.1 -BUILD_LIBGCCS1 = YES diff --git a/libgcc/config/rs6000/t-darwin b/libgcc/config/rs6000/t-darwin index 183d0df92ce9..8b513bdb1d78 100644 --- a/libgcc/config/rs6000/t-darwin +++ b/libgcc/config/rs6000/t-darwin @@ -56,6 +56,3 @@ unwind-dw2_s.o: HOST_LIBGCC2_CFLAGS += -maltivec unwind-dw2.o: HOST_LIBGCC2_CFLAGS += -maltivec LIB2ADDEH += $(srcdir)/config/rs6000/darwin-fallback.c - -# Build a legacy libgcc_s.1 -BUILD_LIBGCCS1 = YES diff --git a/libgcc/config/t-darwin-libgccs1 b/libgcc/config/t-darwin-libgccs1 new file mode 100644 index ..b88b1a5bba8a --- /dev/null +++ b/libgcc/config/t-darwin-libgccs1 @@ -0,0 +1,3 @@ + +# Build a legacy libgcc_s.1 +BUILD_LIBGCCS1 = YES
[gcc r14-11713] includes, Darwin: Handle modular use for macOS SDKs [PR116827].
https://gcc.gnu.org/g:623aaebc7d755ef8696834bebd14f8eddd88200e commit r14-11713-g623aaebc7d755ef8696834bebd14f8eddd88200e Author: Iain Sandoe Date: Sun Dec 29 23:06:54 2024 + includes, Darwin: Handle modular use for macOS SDKs [PR116827]. Recent changes to the OS SDKs have altered the way in which include guards are used for a number of headers when C++ modules are enabled. Instead of placing the guards in the included header, they are being placed in the including header. This breaks the assumptions in the current GCC stddef.h specifically, that the presence of __PTRDIFF_T and __SIZE_T means that the relevant defs are already made. However in the case of the module-enabled C++ with these SDKs, that is no longer true. stddef.h has a large body of special-cases already, but it seems that the only viable solution here is to add a new one specifically for __APPLE__ and modular code. This fixes around 280 new fails in the modules test-suite; it is needed on all open branches that support modules. PR target/116827 gcc/ChangeLog: * ginclude/stddef.h: Undefine __PTRDIFF_T and __SIZE_T for module- enabled c++ on Darwin/macOS platforms. Signed-off-by: Iain Sandoe (cherry picked from commit 9cf6b52d04df22726d88eef113211b3cc08515de) Diff: --- gcc/ginclude/stddef.h | 15 +++ 1 file changed, 15 insertions(+) diff --git a/gcc/ginclude/stddef.h b/gcc/ginclude/stddef.h index 88730867eebe..244397b26c08 100644 --- a/gcc/ginclude/stddef.h +++ b/gcc/ginclude/stddef.h @@ -89,6 +89,21 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #undef _PTRDIFF_T_ #endif +/* When modular code is enabled with macOS SDKs from version 15, the + include guards are set in the includers of this code, rather than as + part of it. This means the we must unset them or the intended code + here will be bypassed (resulting in undefined values). */ +#if defined (__APPLE__) +# if defined(__has_feature) && __has_feature(modules) +# if defined (__need_ptrdiff_t) +# undef __PTRDIFF_T +# endif +# if defined (__need_size_t) +# undef __SIZE_T +# endif +# endif +#endif + /* On VxWorks, may have defined macros like _TYPE_size_t which will typedef size_t. fixincludes patched the vxTypesBase.h so that this macro is only defined if _GCC_SIZE_T is
[gcc r14-11714] configure, Darwin: Recognise new naming for Xcode ld.
https://gcc.gnu.org/g:dbba3c9008e35ba45966945baf816886c5520196 commit r14-11714-gdbba3c9008e35ba45966945baf816886c5520196 Author: Iain Sandoe Date: Tue Apr 15 14:02:21 2025 +0100 configure, Darwin: Recognise new naming for Xcode ld. The latest editions of XCode have altered the identify reported by 'ld -v' (again). This means that GCC configure no longer detects the version. Fixed by adding the new name to the set checked. gcc/ChangeLog: * configure: Regenerate. * configure.ac: Recognise PROJECT:ld-.nn.aa as an identifier for Darwin's static linker. Signed-off-by: Iain Sandoe (cherry picked from commit 7f56a8e8ad1c33d358e9e09fcbaf263c2caba1b9) Diff: --- gcc/configure| 7 --- gcc/configure.ac | 7 --- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/gcc/configure b/gcc/configure index 4e9c65225d34..a4dcd1317834 100755 --- a/gcc/configure +++ b/gcc/configure @@ -3940,7 +3940,7 @@ if test x"${DEFAULT_LINKER+set}" = x"set"; then as_fn_error $? "cannot execute: $DEFAULT_LINKER: check --with-ld or env. var. DEFAULT_LINKER" "$LINENO" 5 elif $DEFAULT_LINKER -v < /dev/null 2>&1 | grep GNU > /dev/null; then gnu_ld_flag=yes - elif $DEFAULT_LINKER -v < /dev/null 2>&1 | grep ld64- > /dev/null; then + elif $DEFAULT_LINKER -v < /dev/null 2>&1 | grep 'PROJECT:ld\(64\)*-' > /dev/null; then ld64_flag=yes fi @@ -32781,8 +32781,9 @@ $as_echo "$gcc_cv_ld64_major" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking linker version" >&5 $as_echo_n "checking linker version... " >&6; } if test x"${gcc_cv_ld64_version}" = x; then - gcc_cv_ld64_version=`$gcc_cv_ld -v 2>&1 | $EGREP 'ld64|dyld' \ - | sed -e 's/.*ld64-//' -e 's/.*dyld-//'| awk '{print $1}'` + gcc_cv_ld64_version=`$gcc_cv_ld -v 2>&1 | $EGREP 'ld64|dyld|PROJECT:ld' \ + | sed -e 's/.*ld64-//' -e 's/.*dyld-//' -e 's/.*PROJECT:ld-//' \ + | awk '{print $1}'` fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_ld64_version" >&5 $as_echo "$gcc_cv_ld64_version" >&6; } diff --git a/gcc/configure.ac b/gcc/configure.ac index 89d927cf0ac2..cb743b5a875a 100644 --- a/gcc/configure.ac +++ b/gcc/configure.ac @@ -358,7 +358,7 @@ if test x"${DEFAULT_LINKER+set}" = x"set"; then AC_MSG_ERROR([cannot execute: $DEFAULT_LINKER: check --with-ld or env. var. DEFAULT_LINKER]) elif $DEFAULT_LINKER -v < /dev/null 2>&1 | grep GNU > /dev/null; then gnu_ld_flag=yes - elif $DEFAULT_LINKER -v < /dev/null 2>&1 | grep ld64- > /dev/null; then + elif $DEFAULT_LINKER -v < /dev/null 2>&1 | grep 'PROJECT:ld\(64\)*-' > /dev/null; then ld64_flag=yes fi AC_DEFINE_UNQUOTED(DEFAULT_LINKER,"$DEFAULT_LINKER", @@ -6467,8 +6467,9 @@ if test x"$ld64_flag" = x"yes"; then # If the version was not specified, try to find it. AC_MSG_CHECKING(linker version) if test x"${gcc_cv_ld64_version}" = x; then - gcc_cv_ld64_version=`$gcc_cv_ld -v 2>&1 | $EGREP 'ld64|dyld' \ - | sed -e 's/.*ld64-//' -e 's/.*dyld-//'| awk '{print $1}'` + gcc_cv_ld64_version=`$gcc_cv_ld -v 2>&1 | $EGREP 'ld64|dyld|PROJECT:ld' \ + | sed -e 's/.*ld64-//' -e 's/.*dyld-//' -e 's/.*PROJECT:ld-//' \ + | awk '{print $1}'` fi AC_MSG_RESULT($gcc_cv_ld64_version)
[gcc r14-11712] testsuite, gm2: Use -B option for libstdc++ where required.
https://gcc.gnu.org/g:84ac2f46612ee928f0089f615ab6c03f895f80e3 commit r14-11712-g84ac2f46612ee928f0089f615ab6c03f895f80e3 Author: Iain Sandoe Date: Mon Mar 10 08:44:41 2025 + testsuite, gm2: Use -B option for libstdc++ where required. We need to add testsuite options to locate gm2 libs and libstdc++. Usually '-L' options are added to point to the relevant directories for the uninstalled libraries. In cases where libraries are available as both shared and convenience some additional checks are made. For some targets -static- options are handled by specs substitution and need a '-B' option rather than '-L'. For Darwin, when embedded runpaths are in use (the default for all versions after macOS 10.11), '-B' is also needed to provide the runpath. When '-B' is used, this results in a '-L' for each path that exists (so that appending a '-L' as well is a needless duplicate). There are also cases where tools warn for duplicates, leading to spurious fails. Therefore the objective of the code here is to add just one '-L' or '-B' for each of the libraries. Currently, we are forcing the full paths to each of the gm2 convenience libs onto the link line and therefore the B/L logic is not needed there. It would need to be added if/when gm2 is tested with shared libraries gcc/testsuite/ChangeLog: * lib/gm2.exp: Arrange for a '-B' option to be added for the libstdc++ paths on targets that need it. Signed-off-by: Iain Sandoe (cherry picked from commit 6b9ceac9e4e2be304c39e6bc8744edf21faac4fb) Diff: --- gcc/testsuite/lib/gm2.exp | 46 -- 1 file changed, 36 insertions(+), 10 deletions(-) diff --git a/gcc/testsuite/lib/gm2.exp b/gcc/testsuite/lib/gm2.exp index 64d44494e484..8a6e2d6236ba 100644 --- a/gcc/testsuite/lib/gm2.exp +++ b/gcc/testsuite/lib/gm2.exp @@ -254,12 +254,35 @@ proc gm2_link_flags { paths } { if [istarget "powerpc-*-*"] { lappend flags "-mabi=ieeelongdouble" } + +# We need to add options to locate gm2 libs and libstdc++ +# Usually '-L' options are added to point to the relevant directories for +# the uninstalled libraries. + +# In cases where libraries are available as both shared and convenience +# some additional checks are made. + +# For some targets -static- options are handled by specs substitution +# and need a '-B' option rather than '-L'. For Darwin, when embedded +# runpaths are in use (the default for all versions after macOS 10.11), +# '-B' is also needed to provide the runpath. +# When '-B' is used, this results in a '-L' for each path that exists (so +# that appending a '-L' as well is a needless duplicate). There are also +# cases where tools warn for duplicates, leading to spurious fails. +# Therefore the objective of the code below is to add just one '-L' or +# '-B' for each of the libraries. + +set target_wants_B_option 0 +if { [istarget *-*-darwin9* ] || [istarget *-*-darwin\[12\]* ] } { + set target_wants_B_option 1 +} + if { $gccpath == "" } { global tool_root_dir set libstdcpp [lookfor_file ${tool_root_dir} libstdc++] if { $libstdcpp != "" } { - append flags "-L${libstdcpp} " + append flags " -L${libstdcpp} " append ld_library_path ":${libstdcpp}" } } else { @@ -267,19 +290,22 @@ proc gm2_link_flags { paths } { append ld_library_path ":${gccpath}/lib" } if [file exists "${gccpath}/libstdc++/libstdc++.a"] { - append flags "-L${gccpath}/libstdc++ " + append flags " -L${gccpath}/libstdc++ " append ld_library_path ":${gccpath}/libstdc++" } - if [file exists "${gccpath}/libstdc++-v3/src/.libs/libstdc++.a"] { - append flags " -L${gccpath}/libstdc++-v3/src/.libs " - append ld_library_path ":${gccpath}/libstdc++-v3/src/.libs" - } - # Look for libstdc++.${shlib_ext}. - if [file exists "${gccpath}/libstdc++-v3/src/.libs/libstdc++.${shlib_ext}"] { - append flags " -L${gccpath}/libstdc++-v3/src/.libs " + # Look for libstdc++.. +if { [file exists "${gccpath}/libstdc++-v3/src/.libs/libstdc++.a"] \ +|| [file exists "${gccpath}/libstdc++-v3/src/.libs/libstdc++.${shlib_ext}"] } { +if { $target_wants_B_option } { + append flags " -B${gccpath}/libstdc++-v3/src/.libs " +} else { + append flags " -L${gccpath}/libstdc++-v3/src/.libs " +} append ld_library_path ":${gccpath}/libstdc++-v3/src/.libs" } + # Here we are forcing the static libraries, with complete paths so + # there's no -L/-B logic needed # puts stderr "${gm2_link_libraries} before foreach" foreach d [list
[gcc r16-330] c++: more overeager use of deleted function before ADL [PR119034]
https://gcc.gnu.org/g:1fb5abc3919f376f3dedccad636eba4a4ad7e4a7 commit r16-330-g1fb5abc3919f376f3dedccad636eba4a4ad7e4a7 Author: Patrick Palka Date: Thu May 1 10:58:50 2025 -0400 c++: more overeager use of deleted function before ADL [PR119034] The PR68942 fix used the tf_conv flag to disable mark_used when substituting a FUNCTION_DECL callee of an ADL-enabled call. In this slightly more elaborate testcase, we end up prematurely calling mark_used anyway on the FUNCTION_DECL directly from the CALL_EXPR case of tsubst_expr during partial instantiation, leading to a bogus "use of deleted function" error. This patch fixes the general problem in a more robust way by ensuring the callee of an ADL-enabled call is wrapped in an OVERLOAD, so that tsubst_expr leaves it alone. PR c++/119034 PR c++/68942 gcc/cp/ChangeLog: * pt.cc (tsubst_expr) : Revert PR68942 fix. * semantics.cc (finish_call_expr): Ensure the callee of an ADL-enabled call is wrapped in an OVERLOAD. gcc/testsuite/ChangeLog: * g++.dg/template/koenig13.C: New test. Reviewed-by: Jason Merrill Diff: --- gcc/cp/pt.cc | 8 +--- gcc/cp/semantics.cc | 8 gcc/testsuite/g++.dg/template/koenig13.C | 16 3 files changed, 25 insertions(+), 7 deletions(-) diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc index b45af9360ade..7b296d14a09b 100644 --- a/gcc/cp/pt.cc +++ b/gcc/cp/pt.cc @@ -21335,13 +21335,7 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl) /* Avoid error about taking the address of a constructor. */ function = TREE_OPERAND (function, 0); - tsubst_flags_t subcomplain = complain; - if (koenig_p && TREE_CODE (function) == FUNCTION_DECL) - /* When KOENIG_P, we don't want to mark_used the callee before -augmenting the overload set via ADL, so during this initial -substitution we disable mark_used by setting tf_conv (68942). */ - subcomplain |= tf_conv; - function = tsubst_expr (function, args, subcomplain, in_decl); + function = tsubst_expr (function, args, complain, in_decl); if (BASELINK_P (function)) qualified_p = true; diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc index 1aa35d3861ea..43a0eabfa127 100644 --- a/gcc/cp/semantics.cc +++ b/gcc/cp/semantics.cc @@ -3325,6 +3325,14 @@ finish_call_expr (tree fn, vec **args, bool disallow_virtual, if (type_dependent_expression_p (fn) || any_type_dependent_arguments_p (*args)) { + if (koenig_p + && TREE_CODE (orig_fn) == FUNCTION_DECL + && !fndecl_built_in_p (orig_fn)) + /* For an ADL-enabled call where unqualified lookup found a + single non-template function, wrap it in an OVERLOAD so that + later substitution doesn't overeagerly mark the function as + used. */ + orig_fn = ovl_make (orig_fn, NULL_TREE); result = build_min_nt_call_vec (orig_fn, *args); SET_EXPR_LOCATION (result, cp_expr_loc_or_input_loc (fn)); KOENIG_LOOKUP_P (result) = koenig_p; diff --git a/gcc/testsuite/g++.dg/template/koenig13.C b/gcc/testsuite/g++.dg/template/koenig13.C new file mode 100644 index ..364bc929579e --- /dev/null +++ b/gcc/testsuite/g++.dg/template/koenig13.C @@ -0,0 +1,16 @@ +// PR c++/119034 +// { dg-do compile { target c++14 } } +// A version of koenig12.C involving partial instantiation via a generic lambda. + +void foo(...) = delete; + +template void lookup(T t) { [](auto u) { foo(u); }(t); } + +namespace N { + struct A { }; + int foo(A); +} + +int main() { + lookup(N::A{}); +}
[gcc r14-11720] c++, coroutines: check for members we use in handle_types [PR105475]
https://gcc.gnu.org/g:d3389c96234eb3c259867edc91876571b5254392 commit r14-11720-gd3389c96234eb3c259867edc91876571b5254392 Author: Iain Sandoe Date: Wed Jul 24 20:59:10 2024 +0100 c++, coroutines: check for members we use in handle_types [PR105475] Currently, it is possible to ICE GCC by giving it sufficiently broken code, where sufficiently broken means a std::coroutine_handle missing a default on the promise_type template argument, and missing members. As the code generator relies on lookups in the coroutine_handle never failing (and has no way to signal that error), lets do it ahead of time, save the result, and use that. This saves us some lookups and allows us to propagate an error. PR c++/105475 - coroutines: ICE in coerce_template_parms, at cp/pt.cc:9183 This includes refactoring from 370a0dee55569, ffd521d8dcddcd4 and 00019b88e714c29c387. gcc/cp/ChangeLog: PR c++/105475 * coroutines.cc (struct coroutine_info): Add from_address. Carries the from_address member we looked up earlier. (coro_resume_identifier): Remove. Unused. (coro_init_identifiers): Do not initialize the above. (struct susp_frame_data): Remove unused members, provide a CTOR. (void_coro_handle_address): New variable. Contains the baselink for the std::coroutine_handle::address() instance method. (get_handle_type_address): New function. Looks up and validates handle_type::address in a given handle_type. (get_handle_type_from_address): New function. Looks up and validates handle_type::from_address in a given handle_type. (coro_promise_type_found_p): Remove reliance on coroutine_handle<> defaulting the promise type to void. Store get_handle_type_* results where appropriate. (struct local_vars_frame_data): Add a CTOR. (replace_continue): Look up expression type. (get_coroutine_from_address): New helper. Gets the handle_type::from_address BASELINK from a coroutine_info. (morph_fn_to_coro): Use susp_frame_data CTOR, and make the suspend state hash map local to the morph function. Use CTOR for local_vars_frame_data instead of brace init. (build_actor_fn): Use the get_coroutine_from_address helper and void_coro_handle_address. gcc/testsuite/ChangeLog: PR c++/105475 * g++.dg/coroutines/pr103868.C: Add std::coroutine_handle members we check for now. * g++.dg/coroutines/pr105287.C: Ditto. * g++.dg/coroutines/pr105301.C: Ditto. * g++.dg/coroutines/pr94528.C: Ditto. * g++.dg/coroutines/pr94879-folly-1.C: Ditto. * g++.dg/coroutines/pr94883-folly-2.C: Ditto. * g++.dg/coroutines/pr98118.C: Ditto. * g++.dg/coroutines/pr105475.C: New test. * g++.dg/coroutines/pr105475-1.C: New test. * g++.dg/coroutines/pr105475-2.C: New test. * g++.dg/coroutines/pr105475-3.C: New test. * g++.dg/coroutines/pr105475-4.C: New test. * g++.dg/coroutines/pr105475-5.C: New test. * g++.dg/coroutines/pr105475-6.C: New test. * g++.dg/coroutines/pr105475-broken-spec.C: New test. * g++.dg/coroutines/pr105475-broken-spec-2.C: New test. Co-authored-by: Arsen Arsenović (cherry picked from commit 5b4476a165565cb20729c0a97a3f43b060595209) Diff: --- gcc/cp/coroutines.cc | 219 - gcc/testsuite/g++.dg/coroutines/pr103868.C | 2 + gcc/testsuite/g++.dg/coroutines/pr105287.C | 2 + gcc/testsuite/g++.dg/coroutines/pr105301.C | 5 +- gcc/testsuite/g++.dg/coroutines/pr105475-1.C | 27 +++ gcc/testsuite/g++.dg/coroutines/pr105475-2.C | 29 +++ gcc/testsuite/g++.dg/coroutines/pr105475-3.C | 29 +++ gcc/testsuite/g++.dg/coroutines/pr105475-4.C | 41 gcc/testsuite/g++.dg/coroutines/pr105475-5.C | 29 +++ gcc/testsuite/g++.dg/coroutines/pr105475-6.C | 29 +++ .../g++.dg/coroutines/pr105475-broken-spec-2.C | 33 .../g++.dg/coroutines/pr105475-broken-spec.C | 29 +++ gcc/testsuite/g++.dg/coroutines/pr105475.C | 28 +++ gcc/testsuite/g++.dg/coroutines/pr94528.C | 11 +- gcc/testsuite/g++.dg/coroutines/pr94879-folly-1.C | 10 +- gcc/testsuite/g++.dg/coroutines/pr94883-folly-2.C | 10 +- gcc/testsuite/g++.dg/coroutines/pr98118.C | 10 +- 17 files changed, 481 insertions(+), 62 deletions(-) diff --git a/gcc/cp/coroutines.cc b/gcc/cp/coroutines.cc index c4f4843cf216..3774e5595a0d 100644 --- a/gcc/cp/coroutines.cc +++ b/gcc/cp/coroutines.cc @@ -91,6 +91,7 @@ struct GTY((for_user)) coroutine_info on
[gcc r16-341] get_known_nonzero_bits_1 should use wi::bit_and_not [PR118659]
https://gcc.gnu.org/g:adefadda3e87f693f20f0b2b34bced00aa525207 commit r16-341-gadefadda3e87f693f20f0b2b34bced00aa525207 Author: Andrew Pinski Date: Thu May 1 00:14:27 2025 -0700 get_known_nonzero_bits_1 should use wi::bit_and_not [PR118659] While looking into bitwise optimizations, I noticed that get_known_nonzero_bits_1 does `bm.value () & ~bm.mask ()` which is ok except it creates a temporary wide_int. Instead if we use wi::bit_and_not, we can avoid the temporary and on some targets use the andn/bic instruction. Bootstrapped and tested on x86_64-linux-gnu. gcc/ChangeLog: PR tree-optimization/118659 * tree-ssanames.cc (get_known_nonzero_bits_1): Use wi::bit_and_not instead of `a & ~b`. Signed-off-by: Andrew Pinski Diff: --- gcc/tree-ssanames.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gcc/tree-ssanames.cc b/gcc/tree-ssanames.cc index d7865f29f0bd..de7b9b79f948 100644 --- a/gcc/tree-ssanames.cc +++ b/gcc/tree-ssanames.cc @@ -576,7 +576,7 @@ get_known_nonzero_bits_1 (const_tree name) if (tmp.undefined_p ()) return wi::shwi (0, precision); irange_bitmask bm = tmp.get_bitmask (); - return bm.value () & ~bm.mask (); + return wi::bit_and_not (bm.value (), bm.mask ()); } /* Return a wide_int with known non-zero bits in SSA_NAME
[gcc r16-340] expand: Remove unsignedp argument from get_compare_parts [PR118090]
https://gcc.gnu.org/g:5d5bed0caef4570c255f35343be00e314dd8a08d commit r16-340-g5d5bed0caef4570c255f35343be00e314dd8a08d Author: Andrew Pinski Date: Thu May 1 08:31:18 2025 -0700 expand: Remove unsignedp argument from get_compare_parts [PR118090] While helping Eikansh with a patch to ccmp, it was noticed that the result stored in the up pointer that gets passed to get_compare_parts was unused on all call sites. It was always unused since get_compare_parts was added in r8-1717-gf580a969d7fbab. It looks it was not noticed it became unused when rcode was set via get_compare_parts and in RTL, the signedness is part of the comparison. PR middle-end/118090 gcc/ChangeLog: * ccmp.cc (get_compare_parts): Remove the up argument. (expand_ccmp_next): Update call to get_compare_parts. (expand_ccmp_expr_1): Likewise. Signed-off-by: Andrew Pinski Diff: --- gcc/ccmp.cc | 15 ++- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/gcc/ccmp.cc b/gcc/ccmp.cc index 67efe7d4f5a6..e49bafa85c5f 100644 --- a/gcc/ccmp.cc +++ b/gcc/ccmp.cc @@ -133,23 +133,22 @@ ccmp_candidate_p (gimple *g, bool outer = false) /* Extract the comparison we want to do from the tree. */ void -get_compare_parts (tree t, int *up, rtx_code *rcode, +get_compare_parts (tree t, rtx_code *rcode, tree *rhs1, tree *rhs2) { tree_code code; gimple *g = get_gimple_for_ssa_name (t); if (g && is_gimple_assign (g)) { - *up = TYPE_UNSIGNED (TREE_TYPE (gimple_assign_rhs1 (g))); + int up = TYPE_UNSIGNED (TREE_TYPE (gimple_assign_rhs1 (g))); code = gimple_assign_rhs_code (g); - *rcode = get_rtx_code (code, *up); + *rcode = get_rtx_code (code, up); *rhs1 = gimple_assign_rhs1 (g); *rhs2 = gimple_assign_rhs2 (g); } else { /* If g is not a comparison operator create a compare to zero. */ - *up = 1; *rcode = NE; *rhs1 = t; *rhs2 = build_zero_cst (TREE_TYPE (t)); @@ -167,10 +166,9 @@ expand_ccmp_next (tree op, tree_code code, rtx prev, rtx_insn **prep_seq, rtx_insn **gen_seq) { rtx_code rcode; - int unsignedp; tree rhs1, rhs2; - get_compare_parts(op, &unsignedp, &rcode, &rhs1, &rhs2); + get_compare_parts (op, &rcode, &rhs1, &rhs2); return targetm.gen_ccmp_next (prep_seq, gen_seq, prev, rcode, rhs1, rhs2, get_rtx_code (code, 0)); } @@ -204,7 +202,6 @@ expand_ccmp_expr_1 (gimple *g, rtx_insn **prep_seq, rtx_insn **gen_seq) { if (ccmp_tree_comparison_p (op1, bb)) { - int unsignedp0, unsignedp1; rtx_code rcode0, rcode1; tree logical_op0_rhs1, logical_op0_rhs2; tree logical_op1_rhs1, logical_op1_rhs2; @@ -214,10 +211,10 @@ expand_ccmp_expr_1 (gimple *g, rtx_insn **prep_seq, rtx_insn **gen_seq) unsigned cost1 = MAX_COST; unsigned cost2 = MAX_COST; - get_compare_parts (op0, &unsignedp0, &rcode0, + get_compare_parts (op0, &rcode0, &logical_op0_rhs1, &logical_op0_rhs2); - get_compare_parts (op1, &unsignedp1, &rcode1, + get_compare_parts (op1, &rcode1, &logical_op1_rhs1, &logical_op1_rhs2); rtx_insn *prep_seq_1, *gen_seq_1;
[gcc r16-342] vect: Use internal storage for converts for call into supportable_indirect_convert_operation [PR1186
https://gcc.gnu.org/g:69bcf1d6aa52a531f7bc4976e407325fe9742cf6 commit r16-342-g69bcf1d6aa52a531f7bc4976e407325fe9742cf6 Author: Andrew Pinski Date: Thu May 1 09:05:47 2025 -0700 vect: Use internal storage for converts for call into supportable_indirect_convert_operation [PR118617] While looking into PR 118616, I noticed that supportable_indirect_convert_operation only pushes up to 2 into its vec. And the 2 places which call supportable_indirect_convert_operation, use an auto_vec but without an internal storage. In this case an internal storage of 2 elements would save both memory and slight compile time performance. Bootstrapped and tested on x86_64-linux-gnu. PR tree-optimization/118617 gcc/ChangeLog: * tree-vect-generic.cc (expand_vector_conversion): Have 2 elements as internal storage for converts. * tree-vect-stmts.cc (vectorizable_conversion): Likewise. Signed-off-by: Andrew Pinski Diff: --- gcc/tree-vect-generic.cc | 2 +- gcc/tree-vect-stmts.cc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/gcc/tree-vect-generic.cc b/gcc/tree-vect-generic.cc index 80c2d31776bb..3c68361870bf 100644 --- a/gcc/tree-vect-generic.cc +++ b/gcc/tree-vect-generic.cc @@ -1754,7 +1754,7 @@ expand_vector_conversion (gimple_stmt_iterator *gsi) else if (ret_elt_bits > arg_elt_bits) modifier = WIDEN; - auto_vec > converts; + auto_vec, 2> converts; if (supportable_indirect_convert_operation (code, ret_type, arg_type, converts)) { diff --git a/gcc/tree-vect-stmts.cc b/gcc/tree-vect-stmts.cc index 42b6059520ac..537ae6c2f614 100644 --- a/gcc/tree-vect-stmts.cc +++ b/gcc/tree-vect-stmts.cc @@ -5706,7 +5706,7 @@ vectorizable_conversion (vec_info *vinfo, scalar_mode lhs_mode = SCALAR_TYPE_MODE (lhs_type); scalar_mode rhs_mode = SCALAR_TYPE_MODE (rhs_type); opt_scalar_mode rhs_mode_iter; - auto_vec > converts; + auto_vec, 2> converts; /* Supportable by target? */ switch (modifier)
[gcc r16-337] config-list.mk: Update FreeBSD targets to version 13
https://gcc.gnu.org/g:262a89fae6344e5c4e410da1dd5ffafbcee49fc0 commit r16-337-g262a89fae6344e5c4e410da1dd5ffafbcee49fc0 Author: Gerald Pfeifer Date: Fri May 2 00:06:59 2025 +0200 config-list.mk: Update FreeBSD targets to version 13 contrib: * config-list.mk: Update FreeBSD targets to version 13. Diff: --- contrib/config-list.mk | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/contrib/config-list.mk b/contrib/config-list.mk index 58bb4c5c186b..27aabf421b18 100644 --- a/contrib/config-list.mk +++ b/contrib/config-list.mk @@ -35,7 +35,7 @@ OPT_IN_LANGUAGES= # LIST = \ - aarch64-elf aarch64-freebsd13 aarch64-linux-gnu aarch64-rtems \ + aarch64-elf aarch64-freebsd14 aarch64-linux-gnu aarch64-rtems \ alpha-linux-gnu alpha-netbsd alpha-openbsd \ alpha64-dec-vms alpha-dec-vms \ amdgcn-amdhsa \ @@ -54,7 +54,7 @@ LIST = \ hppa64-hpux11.3 \ hppa64-hpux11.0OPT-enable-sjlj-exceptions=yes \ i686-apple-darwin9 i686-apple-darwin13 i686-apple-darwin17 \ - i686-freebsd13 i686-kfreebsd-gnu \ + i686-freebsd14 i686-kfreebsd-gnu \ i686-netbsdelf9 \ i686-openbsd i686-elf i686-kopensolaris-gnu i686-gnu \ i686-pc-linux-gnu i686-pc-msdosdjgpp i686-lynxos i686-nto-qnx \ @@ -82,7 +82,7 @@ LIST = \ or1k-elf or1k-linux-uclibc or1k-linux-musl or1k-rtems \ pdp11-aout \ powerpc-apple-darwin9 powerpc64-apple-darwin9 powerpc-apple-darwin8 \ - powerpc-freebsd13 powerpc-netbsd \ + powerpc-freebsd14 powerpc-netbsd \ powerpc-eabisimaltivec powerpc-eabisim ppc-elf \ powerpc-eabialtivec powerpc-xilinx-eabi powerpc-eabi \ powerpc-rtems \ @@ -105,7 +105,7 @@ LIST = \ vax-netbsdelf visium-elf \ x86_64-apple-darwin10 x86_64-apple-darwin15 x86_64-apple-darwin21 \ x86_64-gnu x86_64-pc-linux-gnuOPT-with-fpmath=avx \ - x86_64-elfOPT-with-fpmath=sse x86_64-freebsd13 x86_64-netbsd \ + x86_64-elfOPT-with-fpmath=sse x86_64-freebsd14 x86_64-netbsd \ x86_64-w64-mingw32 \ x86_64-mingw32OPT-enable-sjlj-exceptions=yes x86_64-rtems \ xstormy16-elf xtensa-elf \
[gcc r16-335] c++: add missing -fabi-version docs
https://gcc.gnu.org/g:87c4460024dadef0aa1c767be146ad3831857ebe commit r16-335-g87c4460024dadef0aa1c767be146ad3831857ebe Author: Jason Merrill Date: Thu May 1 16:04:29 2025 -0400 c++: add missing -fabi-version docs Looks like I've forgotten to update the docs for -fabi-version for a couple of my changes. gcc/ChangeLog: * doc/invoke.texi: Add -fabi-version detail. * common.opt: Likewise. Diff: --- gcc/doc/invoke.texi | 9 +++-- gcc/common.opt | 2 +- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index d1925c98c2f3..e7a9a03bace5 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -3006,12 +3006,17 @@ in C++14 and up. Version 18, which first appeared in G++ 13, fixes manglings of lambdas that have additional context. -Version 19, which first appeared in G++ 14, fixes manglings of structured -bindings to include ABI tags. +Version 19, which first appeared in G++ 14, fixes manglings of +structured bindings to include ABI tags, handling of cv-qualified +[[no_unique_address]] members, and adds mangling of C++20 constraints +on function templates. Version 20, which first appeared in G++ 15, fixes manglings of lambdas in static data member initializers. +Version 21, which first appeared in G++ 16, fixes unnecessary captures +in noexcept lambdas (c++/119764). + See also @option{-Wabi}. @opindex fabi-compat-version diff --git a/gcc/common.opt b/gcc/common.opt index 3edc5907ec85..8a5b69d0767c 100644 --- a/gcc/common.opt +++ b/gcc/common.opt @@ -1055,7 +1055,7 @@ Driver Undocumented ; 20: Fix mangling of lambdas in static data member initializers. ; Default in G++ 15. ; -; 21: +; 21: Fix noexcept lambda capture pruning. ; Default in G++ 16. ; ; Additional positive integers will be assigned as new versions of
[gcc r16-339] Regenerate opt-urls
https://gcc.gnu.org/g:99f186bac14febca9de9ee048eb16183ffd2c86a commit r16-339-g99f186bac14febca9de9ee048eb16183ffd2c86a Author: Richard Biener Date: Fri May 2 08:02:41 2025 +0200 Regenerate opt-urls * common.opt.urls: Regenerate. Diff: --- gcc/common.opt.urls | 3 +++ 1 file changed, 3 insertions(+) diff --git a/gcc/common.opt.urls b/gcc/common.opt.urls index 00775118e6f4..c10856087357 100644 --- a/gcc/common.opt.urls +++ b/gcc/common.opt.urls @@ -502,6 +502,9 @@ UrlSuffix(gcc/Optimize-Options.html#index-fcse-follow-jumps) fcse-skip-blocks UrlSuffix(gcc/Optimize-Options.html#index-fcse-skip-blocks) +fcx-method= +UrlSuffix(gcc/Optimize-Options.html#index-fcx-method) + fcx-limited-range UrlSuffix(gcc/Optimize-Options.html#index-fcx-limited-range)
[gcc r16-336] Fix BZ 119317: named loops (C2y) with debug info
https://gcc.gnu.org/g:25921d664242f651ed8a25b3db55093a19a5ae7b commit r16-336-g25921d664242f651ed8a25b3db55093a19a5ae7b Author: Christopher Bazley Date: Thu May 1 22:00:42 2025 +0100 Fix BZ 119317: named loops (C2y) with debug info Named loops (C2y) could not previously be compiled with -O1 and -ggdb2 or higher because the label preceding a loop (or switch) could not be found when using such command lines. This could be observed by compiling gcc/gcc/testsuite/gcc.dg/c2y-named-loops-1.c with the provoking command line (or any minimal example such as that cited in the bug report). The fix was simply to ignore the tree nodes inserted for debugging information. Base commit is 79aa2a283a8d3327ff4d6dca77e81d5b1ac3a01e PR c/119317 gcc/c/ChangeLog: * c-decl.cc (c_get_loop_names): Do not prematurely end the search for a label that names a loop or switch statement upon encountering a DEBUG_BEGIN_STMT. Instead, ignore any instances of DEBUG_BEGIN_STMT. gcc/testsuite/ChangeLog: * gcc.dg/c2y-named-loops-8.c: New test. Diff: --- gcc/c/c-decl.cc | 3 ++- gcc/testsuite/gcc.dg/c2y-named-loops-8.c | 5 + 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc index 4e200f91107b..ad66d7d258b8 100644 --- a/gcc/c/c-decl.cc +++ b/gcc/c/c-decl.cc @@ -13861,7 +13861,8 @@ c_get_loop_names (tree before_labels, bool switch_p, tree *last_p) ++ret; } } - else if (TREE_CODE (stmt) != CASE_LABEL_EXPR) + else if (TREE_CODE (stmt) != CASE_LABEL_EXPR + && TREE_CODE (stmt) != DEBUG_BEGIN_STMT) break; } if (last) diff --git a/gcc/testsuite/gcc.dg/c2y-named-loops-8.c b/gcc/testsuite/gcc.dg/c2y-named-loops-8.c new file mode 100644 index ..8d69db45f772 --- /dev/null +++ b/gcc/testsuite/gcc.dg/c2y-named-loops-8.c @@ -0,0 +1,5 @@ +/* PR c/119317 - Named loops (C2y) did not compile with -O1 and -ggdb2 or higher */ +/* { dg-do compile } */ +/* { dg-options "-std=c2y -O1 -ggdb2" } */ + +#include "c2y-named-loops-1.c"