From a94dcac59ee4c99b523ae593cb1c0ad43d4a110b Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Fri, 28 Apr 2023 08:40:07 +0200 Subject: [PATCH] ipa/109652 - ICE in modification phase of IPA SRA There's another questionable IL transform by IPA SRA, replacing foo (p_1(D)->x) with foo (VIEW_CONVERT (ISRA.PARM.1)) where ISRA.PARM.1 is a register. Conversion of a register to an aggregate type is questionable but not entirely unreasonable and not within the set of IL I am rejecting when fixing PR109644. The following lets this slip through in IPA SRA transform by restricting re-gimplification to the case of register type results. To not break the previous testcase again we need to optimize the BIT_FIELD_REF , ...> case to elide the conversion. PR ipa/109652 * ipa-param-manipulation.cc (ipa_param_body_adjustments::modify_expression): Allow conversion of a register to a non-register type. Elide conversions inside BIT_FIELD_REFs. * gcc.dg/torture/pr109652.c: New testcase. --- gcc/ipa-param-manipulation.cc | 7 +++-- gcc/testsuite/gcc.dg/torture/pr109652.c | 40 +++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/torture/pr109652.c diff --git a/gcc/ipa-param-manipulation.cc b/gcc/ipa-param-manipulation.cc index 33dcab9c33c..a286af7f5d9 100644 --- a/gcc/ipa-param-manipulation.cc +++ b/gcc/ipa-param-manipulation.cc @@ -1836,9 +1836,11 @@ ipa_param_body_adjustments::modify_expression (tree *expr_p, bool convert, || TREE_CODE (expr) == IMAGPART_EXPR || TREE_CODE (expr) == REALPART_EXPR) { + /* For a BIT_FIELD_REF do not bother to VIEW_CONVERT the base, + instead reference the replacement directly. */ + convert = TREE_CODE (expr) != BIT_FIELD_REF; expr_p = &TREE_OPERAND (expr, 0); expr = *expr_p; - convert = true; } ipa_param_body_replacement *pbr = get_expr_replacement (expr, false); @@ -1861,7 +1863,8 @@ ipa_param_body_adjustments::modify_expression (tree *expr_p, bool convert, gcc_checking_assert (tree_to_shwi (TYPE_SIZE (TREE_TYPE (expr))) == tree_to_shwi (TYPE_SIZE (TREE_TYPE (repl)))); tree vce = build1 (VIEW_CONVERT_EXPR, TREE_TYPE (expr), repl); - if (is_gimple_reg (repl)) + if (is_gimple_reg (repl) + && is_gimple_reg_type (TREE_TYPE (expr))) { gcc_assert (extra_stmts); vce = force_gimple_operand (vce, extra_stmts, true, NULL_TREE); diff --git a/gcc/testsuite/gcc.dg/torture/pr109652.c b/gcc/testsuite/gcc.dg/torture/pr109652.c new file mode 100644 index 00000000000..8a6524d2212 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr109652.c @@ -0,0 +1,40 @@ +/* { dg-do compile } */ + +typedef int UInt; +UInt skeletal_RI5_instr; +__attribute__((__noreturn__)) void vex_assert_fail(); +typedef struct { + union { + struct { + UInt imm5; + } I5; + } ARMri5; +} ARMRI5; +typedef enum { ARMin_Alu, ARMin_Shift } ARMInstrTag; +void iregEnc(); +static UInt skeletal_RI5(ARMRI5 *ri) { + UInt imm5 = ri->ARMri5.I5.imm5; + __builtin_expect(imm5, 1) ?: vex_assert_fail(); + iregEnc(ri->ARMri5); + return skeletal_RI5_instr; +} +ARMInstrTag emit_ARMInstr_i_0; +void *emit_ARMInstr_disp_cp_chain_me_to_slowEP() { + switch (emit_ARMInstr_i_0) { + case ARMin_Alu: + UInt instr, subopc; + UInt rD, rN; + goto bad; + instr |= subopc | rN; + case ARMin_Shift: + rD = 0; + UInt rM = 0; + ARMRI5 argR; + instr = skeletal_RI5(&argR); + instr |= rD | rM; + goto done; + } +bad: +done: + return 0; +}