aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2009-10-16 12:43:18 +0200
committerJakub Jelinek <jakub@gcc.gnu.org>2009-10-16 12:43:18 +0200
commitd02a5a4b9abb043ff6a243bb4f9a9aaac2fb8656 (patch)
tree6eba8425535818cb1b7315f03e20aef3130b2545
parent200ab6fd4b218b3e9f5617bcf1d36857b68e0c1e (diff)
downloadgcc-d02a5a4b9abb043ff6a243bb4f9a9aaac2fb8656.zip
gcc-d02a5a4b9abb043ff6a243bb4f9a9aaac2fb8656.tar.gz
gcc-d02a5a4b9abb043ff6a243bb4f9a9aaac2fb8656.tar.bz2
re PR debug/41717 (internal compiler error: in expand_debug_expr)
PR debug/41717 * cfgexpand.c (expand_debug_expr): Handle CONJ_EXPR. * dwarf2out.c (mem_loc_descriptor): Don't handle POST_INT/POST_DEC/POST_MODIFY like SUBREG. For SUBREG punt if it is not lowpart subreg or if inner mode isn't MODE_INT. * gcc.dg/debug/pr41717.c: New test. From-SVN: r152897
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/cfgexpand.c40
-rw-r--r--gcc/dwarf2out.c30
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/debug/pr41717.c10
5 files changed, 83 insertions, 11 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index dea1011..2c8dff8 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,12 @@
+2009-10-15 Jakub Jelinek <jakub@redhat.com>
+
+ PR debug/41717
+ * cfgexpand.c (expand_debug_expr): Handle CONJ_EXPR.
+ * dwarf2out.c (mem_loc_descriptor): Don't handle
+ POST_INT/POST_DEC/POST_MODIFY like SUBREG. For SUBREG
+ punt if it is not lowpart subreg or if inner mode isn't
+ MODE_INT.
+
2009-10-16 Andreas Krebbel <Andreas.Krebbel@de.ibm.com>
* config/s390/s390.c (s390_z10_optimize_cmp): Skip notes when
diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c
index 4f317d9..acd70c1 100644
--- a/gcc/cfgexpand.c
+++ b/gcc/cfgexpand.c
@@ -2869,6 +2869,46 @@ expand_debug_expr (tree exp)
op1 = gen_rtx_CONST (GET_MODE_INNER (mode), op1);
return gen_rtx_CONCAT (mode, op0, op1);
+ case CONJ_EXPR:
+ if (GET_CODE (op0) == CONCAT)
+ return gen_rtx_CONCAT (mode, XEXP (op0, 0),
+ gen_rtx_NEG (GET_MODE_INNER (mode),
+ XEXP (op0, 1)));
+ else
+ {
+ enum machine_mode imode = GET_MODE_INNER (mode);
+ rtx re, im;
+
+ if (MEM_P (op0))
+ {
+ re = adjust_address_nv (op0, imode, 0);
+ im = adjust_address_nv (op0, imode, GET_MODE_SIZE (imode));
+ }
+ else
+ {
+ enum machine_mode ifmode = int_mode_for_mode (mode);
+ enum machine_mode ihmode = int_mode_for_mode (imode);
+ rtx halfsize;
+ if (ifmode == BLKmode || ihmode == BLKmode)
+ return NULL;
+ halfsize = GEN_INT (GET_MODE_BITSIZE (ihmode));
+ re = op0;
+ if (mode != ifmode)
+ re = gen_rtx_SUBREG (ifmode, re, 0);
+ re = gen_rtx_ZERO_EXTRACT (ihmode, re, halfsize, const0_rtx);
+ if (imode != ihmode)
+ re = gen_rtx_SUBREG (imode, re, 0);
+ im = copy_rtx (op0);
+ if (mode != ifmode)
+ im = gen_rtx_SUBREG (ifmode, im, 0);
+ im = gen_rtx_ZERO_EXTRACT (ihmode, im, halfsize, halfsize);
+ if (imode != ihmode)
+ im = gen_rtx_SUBREG (imode, im, 0);
+ }
+ im = gen_rtx_NEG (imode, im);
+ return gen_rtx_CONCAT (mode, re, im);
+ }
+
case ADDR_EXPR:
op0 = expand_debug_expr (TREE_OPERAND (exp, 0));
if (!op0 || !MEM_P (op0))
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index 791ecd3..b67bab3 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -12894,10 +12894,7 @@ mem_loc_descriptor (rtx rtl, enum machine_mode mode,
case POST_INC:
case POST_DEC:
case POST_MODIFY:
- /* POST_INC and POST_DEC can be handled just like a SUBREG. So we
- just fall into the SUBREG code. */
-
- /* ... fall through ... */
+ return mem_loc_descriptor (XEXP (rtl, 0), mode, initialized);
case SUBREG:
/* The case of a subreg may arise when we have a local (register)
@@ -12905,9 +12902,13 @@ mem_loc_descriptor (rtx rtl, enum machine_mode mode,
up an entire register. For now, just assume that it is
legitimate to make the Dwarf info refer to the whole register which
contains the given subreg. */
- rtl = XEXP (rtl, 0);
+ if (!subreg_lowpart_p (rtl))
+ break;
+ rtl = SUBREG_REG (rtl);
if (GET_MODE_SIZE (GET_MODE (rtl)) > DWARF2_ADDR_SIZE)
break;
+ if (GET_MODE_CLASS (GET_MODE (rtl)) != MODE_INT)
+ break;
mem_loc_result = mem_loc_descriptor (rtl, mode, initialized);
break;
@@ -13392,12 +13393,19 @@ mem_loc_descriptor (rtx rtl, enum machine_mode mode,
if (BITS_BIG_ENDIAN)
shift = GET_MODE_BITSIZE (GET_MODE (XEXP (rtl, 0)))
- shift - size;
- add_loc_descr (&mem_loc_result,
- int_loc_descriptor (DWARF2_ADDR_SIZE - shift - size));
- add_loc_descr (&mem_loc_result, new_loc_descr (DW_OP_shl, 0, 0));
- add_loc_descr (&mem_loc_result,
- int_loc_descriptor (DWARF2_ADDR_SIZE - size));
- add_loc_descr (&mem_loc_result, new_loc_descr (op, 0, 0));
+ if (shift + size != DWARF2_ADDR_SIZE)
+ {
+ add_loc_descr (&mem_loc_result,
+ int_loc_descriptor (DWARF2_ADDR_SIZE
+ - shift - size));
+ add_loc_descr (&mem_loc_result, new_loc_descr (DW_OP_shl, 0, 0));
+ }
+ if (size != DWARF2_ADDR_SIZE)
+ {
+ add_loc_descr (&mem_loc_result,
+ int_loc_descriptor (DWARF2_ADDR_SIZE - size));
+ add_loc_descr (&mem_loc_result, new_loc_descr (op, 0, 0));
+ }
}
break;
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 7e16631..587f153 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2009-10-15 Jakub Jelinek <jakub@redhat.com>
+
+ PR debug/41717
+ * gcc.dg/debug/pr41717.c: New test.
+
2009-10-16 Paul Thomas <pault@gcc.gnu.org>
PR fortran/41648
diff --git a/gcc/testsuite/gcc.dg/debug/pr41717.c b/gcc/testsuite/gcc.dg/debug/pr41717.c
new file mode 100644
index 0000000..2125088
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/debug/pr41717.c
@@ -0,0 +1,10 @@
+/* PR debug/41717 */
+/* { dg-do compile } */
+
+void
+foo (void)
+{
+ _Complex float v[1], w;
+ v[1] = 0.0f + 0.8fi;
+ w = __builtin_conjf (v[1] * v[1]);
+}