[Bug inline-asm/100785] [9/10/11/12 Regression] ICE: in expand_asm_stmt with "m" and bitfield
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100785 --- Comment #9 from CVS Commits --- The releases/gcc-11 branch has been updated by Jakub Jelinek : https://gcc.gnu.org/g:b6e4453172e6502318d31517b7d3771b157ae71a commit r11-8642-gb6e4453172e6502318d31517b7d3771b157ae71a Author: Jakub Jelinek Date: Mon Jun 21 13:30:42 2021 +0200 inline-asm: Fix ICE with bitfields in "m" operands [PR100785] Bitfields, while they live in memory, aren't something inline-asm can easily operate on. For C and "=m" or "+m", we were diagnosing bitfields in the past in the FE, where c_mark_addressable had: case COMPONENT_REF: if (DECL_C_BIT_FIELD (TREE_OPERAND (x, 1))) { error ("cannot take address of bit-field %qD", TREE_OPERAND (x, 1)); return false; } but that check got moved in GCC 6 to build_unary_op instead and now we emit an error during expansion and ICE afterwards (i.e. error-recovery). For "m" it used to be diagnosed in c_mark_addressable too, but since GCC 6 it is ice-on-invalid. For C++, this was never diagnosed in the FE, but used to be diagnosed in the gimplifier and/or during expansion before 4.8. The following patch does multiple things: 1) diagnoses it in the FEs 2) simplifies during expansion the inline asm if any errors have been reported (similarly how e.g. vregs pass if it detects errors on inline-asm either deletes them or simplifies to bare minimum - just labels), so that we don't have error-recovery ICEs there 2021-06-11 Jakub Jelinek PR inline-asm/100785 gcc/ * cfgexpand.c (expand_asm_stmt): If errors are emitted, remove all inputs, outputs and clobbers from the asm and set template to "". gcc/c/ * c-typeck.c (c_mark_addressable): Diagnose trying to make bit-fields addressable. gcc/cp/ * typeck.c (cxx_mark_addressable): Diagnose trying to make bit-fields addressable. gcc/testsuite/ * c-c++-common/pr100785.c: New test. (cherry picked from commit 644c2cc5f2c09506a7bfef293a7f90efa8d7e5fa)
[Bug inline-asm/100785] [9/10/11/12 Regression] ICE: in expand_asm_stmt with "m" and bitfield
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100785 --- Comment #8 from CVS Commits --- The master branch has been updated by Jakub Jelinek : https://gcc.gnu.org/g:644c2cc5f2c09506a7bfef293a7f90efa8d7e5fa commit r12-1696-g644c2cc5f2c09506a7bfef293a7f90efa8d7e5fa Author: Jakub Jelinek Date: Mon Jun 21 13:30:42 2021 +0200 inline-asm: Fix ICE with bitfields in "m" operands [PR100785] Bitfields, while they live in memory, aren't something inline-asm can easily operate on. For C and "=m" or "+m", we were diagnosing bitfields in the past in the FE, where c_mark_addressable had: case COMPONENT_REF: if (DECL_C_BIT_FIELD (TREE_OPERAND (x, 1))) { error ("cannot take address of bit-field %qD", TREE_OPERAND (x, 1)); return false; } but that check got moved in GCC 6 to build_unary_op instead and now we emit an error during expansion and ICE afterwards (i.e. error-recovery). For "m" it used to be diagnosed in c_mark_addressable too, but since GCC 6 it is ice-on-invalid. For C++, this was never diagnosed in the FE, but used to be diagnosed in the gimplifier and/or during expansion before 4.8. The following patch does multiple things: 1) diagnoses it in the FEs 2) stops emitting a redundant diagnostic in the gimplifier using the usual way, if we already see error_mark_node, we assume error has been emitted already and only diagnose if it wasn't error_mark_node; this helps diagnosing the same bug with multiple different errors 3) simplifies during expansion the inline asm if any errors have been reported (similarly how e.g. vregs pass if it detects errors on inline-asm either deletes them or simplifies to bare minimum - just labels), so that we don't have error-recovery ICEs there 2021-06-11 Jakub Jelinek PR inline-asm/100785 gcc/ * gimplify.c (gimplify_asm_expr): Don't diagnose errors if output or input operands were already error_mark_node. * cfgexpand.c (expand_asm_stmt): If errors are emitted, remove all inputs, outputs and clobbers from the asm and set template to "". gcc/c/ * c-typeck.c (c_mark_addressable): Diagnose trying to make bit-fields addressable. gcc/cp/ * typeck.c (cxx_mark_addressable): Diagnose trying to make bit-fields addressable. gcc/testsuite/ * c-c++-common/pr100785.c: New test. * gcc.dg/pr48552-1.c: Don't expect invalid lvalue errors. * gcc.dg/pr48552-2.c: Likewise.
[Bug inline-asm/100785] [9/10/11/12 Regression] ICE: in expand_asm_stmt with "m" and bitfield
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100785 Jakub Jelinek changed: What|Removed |Added Assignee|unassigned at gcc dot gnu.org |jakub at gcc dot gnu.org Status|NEW |ASSIGNED --- Comment #7 from Jakub Jelinek --- Created attachment 50904 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=50904&action=edit gcc12-pr100785.patch Untested fix.
[Bug inline-asm/100785] [9/10/11/12 Regression] ICE: in expand_asm_stmt with "m" and bitfield
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100785 Richard Biener changed: What|Removed |Added Target Milestone|9.4 |9.5 --- Comment #6 from Richard Biener --- GCC 9.4 is being released, retargeting bugs to GCC 9.5.
[Bug inline-asm/100785] [9/10/11/12 Regression] ICE: in expand_asm_stmt with "m" and bitfield
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100785 Jakub Jelinek changed: What|Removed |Added Priority|P4 |P2 --- Comment #5 from Jakub Jelinek --- With: --- gcc/cfgexpand.c.jj 2021-05-20 09:03:54.147700369 +0200 +++ gcc/cfgexpand.c 2021-05-31 20:48:28.078548261 +0200 @@ -3082,6 +3082,7 @@ expand_asm_stmt (gasm *stmt) unsigned ninputs = gimple_asm_ninputs (stmt); unsigned nlabels = gimple_asm_nlabels (stmt); unsigned i; + bool error_seen = false; /* ??? Diagnose during gimplification? */ if (ninputs + noutputs + nlabels > MAX_RECOG_OPERANDS) @@ -3140,6 +3141,7 @@ expand_asm_stmt (gasm *stmt) { /* ??? Diagnose during gimplification? */ error ("unknown register name %qs in %", regname); + error_seen = true; } else if (j == -4) { @@ -3202,7 +3204,10 @@ expand_asm_stmt (gasm *stmt) && REG_P (DECL_RTL (output_tvec[j])) && HARD_REGISTER_P (DECL_RTL (output_tvec[j])) && output_hregno == REGNO (DECL_RTL (output_tvec[j]))) - error ("invalid hard register usage between output operands"); + { + error ("invalid hard register usage between output operands"); + error_seen = true; + } /* Verify matching constraint operands use the same hard register and that the non-matching constraint operands do not use the same @@ -3225,13 +3230,19 @@ expand_asm_stmt (gasm *stmt) } if (i == match && output_hregno != input_hregno) - error ("invalid hard register usage between output operand " -"and matching constraint operand"); + { + error ("invalid hard register usage between output " + "operand and matching constraint operand"); + error_seen = true; + } else if (early_clobber_p && i != match && output_hregno == input_hregno) - error ("invalid hard register usage between earlyclobber " -"operand and input operand"); + { + error ("invalid hard register usage between " + "earlyclobber operand and input operand"); + error_seen = true; + } } } @@ -3307,7 +3318,10 @@ expand_asm_stmt (gasm *stmt) op = validize_mem (op); if (! allows_reg && !MEM_P (op)) - error ("output number %d not directly addressable", i); + { + error ("output number %d not directly addressable", i); + error_seen = true; + } if ((! allows_mem && MEM_P (op) && GET_MODE (op) != BLKmode) || GET_CODE (op) == CONCAT) { @@ -3347,6 +3361,19 @@ expand_asm_stmt (gasm *stmt) inout_opnum.safe_push (i); } + const char *str = gimple_asm_string (stmt); + if (error_seen) +{ + ninputs = 0; + noutputs = 0; + inout_opnum.truncate (0); + output_rvec.truncate (0); + clobber_rvec.truncate (0); + constraints.truncate (0); + CLEAR_HARD_REG_SET (clobbered_regs); + str = ""; +} + auto_vec input_rvec; auto_vec input_mode; @@ -3405,7 +3432,7 @@ expand_asm_stmt (gasm *stmt) } /* For in-out operands, copy output rtx to input rtx. */ - unsigned ninout = inout_opnum.length(); + unsigned ninout = inout_opnum.length (); for (i = 0; i < ninout; i++) { int j = inout_opnum[i]; @@ -3459,7 +3486,7 @@ expand_asm_stmt (gasm *stmt) rtx body = gen_rtx_ASM_OPERANDS ((noutputs == 0 ? VOIDmode : GET_MODE (output_rvec[0])), - ggc_strdup (gimple_asm_string (stmt)), + ggc_strdup (str), "", 0, argvec, constraintvec, labelvec, locus); MEM_VOLATILE_P (body) = gimple_asm_volatile_p (stmt); ICEs on: /* PR inline-asm/100785 */ struct S { int a : 1; }; void foo (struct S *x) { __asm__ ("" : "+m" (x->a)); /* { dg-error "not directly addressable" } */ } void bar (struct S *x) { __asm__ ("" : "=m" (x->a)); /* { dg-error "not directly addressable" } */ } void baz (struct S *x) { __asm__ ("" : : "m" (x->a)); /* { dg-error "not directly addressable" } */ } in foo and bar are fixed, but baz is actually not diagnosed at all and just ICEs. So bumping priority to P2, as this isn't error-recovery in the baz case anymore.
[Bug inline-asm/100785] [9/10/11/12 Regression] ICE: in expand_asm_stmt with "m" and bitfield
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100785 Jakub Jelinek changed: What|Removed |Added CC||ebotcazou at gcc dot gnu.org --- Comment #4 from Jakub Jelinek --- In particular it is the + * c-typeck.c (build_unary_op) : Remove left-overs. Issue + errors on bit-fields and reverse SSO here and not... + (c_mark_addressable): ...here. change here, when handling inline asm constraints that don't allow registers the FEs call *mark_addressable: 9265 /* If the operand is going to end up in memory, 9266 mark it addressable. */ 9267 if (!allows_reg && !c_mark_addressable (output)) 9268output = error_mark_node; and previously that would diagnose the bitfields but now it doesn't. So, one way to fix this is restore the error also in c_mark_addressable (and guess C++ FE too), or at the spots where for inline asm c_mark_addressable is called also check for bit-fields and diagnose there, or fix the ICE during expansion where it is diagnosed right now. E.g. instantiate_virtual_regs_in_insn when seeing errors in inline asm will do: /* For asm goto, instead of fixing up all the edges just clear the template and clear input and output operands and strip away clobbers. */ if (JUMP_P (insn)) { rtx asm_op = extract_asm_operands (PATTERN (insn)); PATTERN (insn) = asm_op; PUT_MODE (asm_op, VOIDmode); ASM_OPERANDS_TEMPLATE (asm_op) = ggc_strdup (""); ASM_OPERANDS_OUTPUT_CONSTRAINT (asm_op) = ""; ASM_OPERANDS_OUTPUT_IDX (asm_op) = 0; ASM_OPERANDS_INPUT_VEC (asm_op) = rtvec_alloc (0); ASM_OPERANDS_INPUT_CONSTRAINT_VEC (asm_op) = rtvec_alloc (0); } else delete_insn (insn); so perhaps expansion when it detects errors should treat it similarly, don't emit anything unless it is asm goto and trivialize asm goto. Note, the cfgexpand.c and FE fixes can be done both.
[Bug inline-asm/100785] [9/10/11/12 Regression] ICE: in expand_asm_stmt with "m" and bitfield
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100785 --- Comment #3 from Jakub Jelinek --- That revision changed already the original dump: - __asm__("":"+m" <<< error >>>:); + __asm__("":"+m" x->a:); and during gimplification the asm stmt used to be removed instead of being kept.
[Bug inline-asm/100785] [9/10/11/12 Regression] ICE: in expand_asm_stmt with "m" and bitfield
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100785 Jakub Jelinek changed: What|Removed |Added Priority|P3 |P4 CC||jakub at gcc dot gnu.org --- Comment #2 from Jakub Jelinek --- Started with r6-4623-gee45a32dae253f7daa966573eb8cb64b2cf7bf52
[Bug inline-asm/100785] [9/10/11/12 Regression] ICE: in expand_asm_stmt with "m" and bitfield
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100785 Andrew Pinski changed: What|Removed |Added Known to work||4.8.5 Severity|normal |minor Status|UNCONFIRMED |NEW Summary|ICE: in expand_asm_stmt |[9/10/11/12 Regression] |with "m" and bitfield |ICE: in expand_asm_stmt ||with "m" and bitfield Target Milestone|--- |9.4 Ever confirmed|0 |1 Last reconfirmed||2021-05-27 --- Comment #1 from Andrew Pinski --- Confirmed, a regression from at least 4.8.5 where there was no ICE (or "confused by earlier errors, bailing out"). At least GCC 7.5.0 has the bug. Minor issue as there was an error emitted before the ICE happens.