aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorAndrew Pinski <andrew.pinski@oss.qualcomm.com>2026-02-03 19:20:48 -0800
committerAndrew Pinski <andrew.pinski@oss.qualcomm.com>2026-02-04 10:19:46 -0800
commit7c6cb40a44498991ed93d3dd19d128105e8b64b8 (patch)
tree9909617bb35ab960bf5d540f6c96e3ad6870fae6 /gcc
parent1e71ff87c97fcd37b8b98c76b684f23a17bae973 (diff)
downloadgcc-master.zip
gcc-master.tar.gz
gcc-master.tar.bz2
complex: Directly emit gimple from extract_component [PR121661]HEADtrunkmaster
Currently extract_component uses force_gimple_operand_gsi to emit gimple including loads. The problem with that decls that have DECL_EXPR_DECL set on it will change over to use the DECL_EXPR_DECL instead. Normally this is ok except for nested functions where the original decl is a PARAM_DECL, there is a copy from the param decl to the new frame based location. Well instead we should just create the gimple ourselves. The only special case that needs to be handled is BIT_FIELD_REF and a VCE of SSA_NAME. BIT_FIELD_REF was already handled specially so we can just emit the load there. VCE of SSA_NAME on the other hand needed some extra code. Note VCE of s SSA_NAME case could be optimized, I filed PR 123968 for that. Since that is not a regression at this point and we are now producing the same code as before. Bootstrapped and tested on x86_64-linux-gnu. PR middle-end/121661 gcc/ChangeLog: * tree-complex.cc (extract_component): Create gimple assign statements directly rather than call force_gimple_operand_gsi. gcc/testsuite/ChangeLog: * gcc.dg/torture/pr121661-1.c: New test. Signed-off-by: Andrew Pinski <andrew.pinski@oss.qualcomm.com>
Diffstat (limited to 'gcc')
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr121661-1.c21
-rw-r--r--gcc/tree-complex.cc46
2 files changed, 60 insertions, 7 deletions
diff --git a/gcc/testsuite/gcc.dg/torture/pr121661-1.c b/gcc/testsuite/gcc.dg/torture/pr121661-1.c
new file mode 100644
index 0000000..3bc2a8e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr121661-1.c
@@ -0,0 +1,21 @@
+/* { dg-do run } */
+/* { dg-options "" } */
+/* PR middle-end/121661 */
+
+static void fun1(_Complex int val)
+{
+ __attribute__((unused))
+ void nfun()
+ {
+ if (__real__ val != 1)
+ __builtin_abort();
+ }
+ (void)&val;
+ if (__real__ val != 1)
+ __builtin_abort();
+}
+
+int main(int argc, char* [])
+{
+ fun1(1);
+}
diff --git a/gcc/tree-complex.cc b/gcc/tree-complex.cc
index d2a3ed3..9040192 100644
--- a/gcc/tree-complex.cc
+++ b/gcc/tree-complex.cc
@@ -652,28 +652,60 @@ extract_component (gimple_stmt_iterator *gsi, tree t, bool imagpart_p,
if (imagpart_p)
TREE_OPERAND (t, 2) = size_binop (PLUS_EXPR, TREE_OPERAND (t, 2),
TYPE_SIZE (inner_type));
+
if (gimple_p)
- t = force_gimple_operand_gsi (gsi, t, true, NULL, true,
- GSI_SAME_STMT);
+ {
+ tree new_lhs = make_ssa_name (inner_type);
+ gimple *new_load = gimple_build_assign (new_lhs, t);
+ gsi_insert_before (gsi, new_load, GSI_SAME_STMT);
+ t = new_lhs;
+ }
return t;
}
+ case VIEW_CONVERT_EXPR:
+ /* Getting the real/imag parts of a VCE of a ssa-name requires
+ to place the complex into a ssa name before getting the
+ 2 parts.
+ As `IMAGPART_EXPR<VIEW_CONVERT_EXPR<a_BN>>` is an invalid
+ gimple. This will only show up when gimplifying it.
+ Note this creates an extra copy. The call to
+ force_gimple_operand_gsi would create one too. */
+ if (TREE_CODE (TREE_OPERAND (t, 0)) == SSA_NAME)
+ {
+ gcc_assert (gimple_p);
+ tree new_cplx = make_ssa_name (TREE_TYPE (t));
+ gimple *vce = gimple_build_assign (new_cplx, unshare_expr (t));
+ gsi_insert_before (gsi, vce, GSI_SAME_STMT);
+
+ tree new_lhs = make_ssa_name (TREE_TYPE (TREE_TYPE (t)));
+ t = build1 ((imagpart_p ? IMAGPART_EXPR : REALPART_EXPR),
+ TREE_TYPE (TREE_TYPE (t)), new_cplx);
+ gimple *new_ri = gimple_build_assign (new_lhs, t);
+ gsi_insert_before (gsi, new_ri, GSI_SAME_STMT);
+ t = new_lhs;
+ return t;
+ }
+ /* FALLTHRU */
case VAR_DECL:
case RESULT_DECL:
case PARM_DECL:
case COMPONENT_REF:
case ARRAY_REF:
- case VIEW_CONVERT_EXPR:
case MEM_REF:
{
tree inner_type = TREE_TYPE (TREE_TYPE (t));
- t = build1 ((imagpart_p ? IMAGPART_EXPR : REALPART_EXPR),
- inner_type, unshare_expr (t));
+ t = fold_build1 ((imagpart_p ? IMAGPART_EXPR : REALPART_EXPR),
+ inner_type, unshare_expr (t));
if (gimple_p)
- t = force_gimple_operand_gsi (gsi, t, true, NULL, true,
- GSI_SAME_STMT);
+ {
+ tree new_lhs = make_ssa_name (inner_type);
+ gimple *new_load = gimple_build_assign (new_lhs, t);
+ gsi_insert_before (gsi, new_load, GSI_SAME_STMT);
+ t = new_lhs;
+ }
return t;
}