aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2023-04-28 08:40:07 +0200
committerRichard Biener <rguenther@suse.de>2023-04-28 13:35:22 +0200
commita94dcac59ee4c99b523ae593cb1c0ad43d4a110b (patch)
treed91a1169d3d009e4b782b4bef5e2850a734a10a6
parentcacf65d74463600815773255e8b82b4043432bd7 (diff)
downloadgcc-a94dcac59ee4c99b523ae593cb1c0ad43d4a110b.zip
gcc-a94dcac59ee4c99b523ae593cb1c0ad43d4a110b.tar.gz
gcc-a94dcac59ee4c99b523ae593cb1c0ad43d4a110b.tar.bz2
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.
-rw-r--r--gcc/ipa-param-manipulation.cc7
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr109652.c40
2 files changed, 45 insertions, 2 deletions
diff --git a/gcc/ipa-param-manipulation.cc b/gcc/ipa-param-manipulation.cc
index 33dcab9..a286af7 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 0000000..8a6524d
--- /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;
+}