ipa/109652 - ICE in modification phase of IPA SRA
Checks
Commit Message
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.
Bootstrapped and tested on x86_64-unknown-linux-gnu, pushed.
Richard.
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
@@ -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);
new file mode 100644
@@ -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;
+}