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 <union type> (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 <VIEW_CONVERT <...>, ...> 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.
This commit is contained in:
parent
cacf65d744
commit
a94dcac59e
2 changed files with 45 additions and 2 deletions
|
@ -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);
|
||||
|
|
40
gcc/testsuite/gcc.dg/torture/pr109652.c
Normal file
40
gcc/testsuite/gcc.dg/torture/pr109652.c
Normal file
|
@ -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;
|
||||
}
|
Loading…
Add table
Reference in a new issue