aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2024-11-19 10:26:44 +0100
committerJakub Jelinek <jakub@gcc.gnu.org>2024-11-19 10:26:44 +0100
commit694613a7f9adfa9c87e733adc63839c8801f2b5c (patch)
treef7d004f02c82aefd12ae28a2af06d497961ac653 /gcc
parent600cab162c561c3061317c998972b0ed1b681d5b (diff)
downloadgcc-694613a7f9adfa9c87e733adc63839c8801f2b5c.zip
gcc-694613a7f9adfa9c87e733adc63839c8801f2b5c.tar.gz
gcc-694613a7f9adfa9c87e733adc63839c8801f2b5c.tar.bz2
expand: Fix up ICE on VCE from _Complex types to _BitInt [PR117458]
extract_bit_field can't handle extraction of non-mode precision from complex mode operands which don't live in memory, e.g. gen_lowpart crashes on those. The following patch in that case defers the extract_bit_field call until op0 is forced into memory. 2024-11-19 Jakub Jelinek <jakub@redhat.com> PR middle-end/117458 * expr.cc (expand_expr_real_1) <case VIEW_CONVERT_EXPR>: Don't call extract_bit_field if op0 has complex mode and isn't a MEM, instead first force op0 into memory and then call extract_bit_field. * gcc.dg/bitint-116.c: New test.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/expr.cc9
-rw-r--r--gcc/testsuite/gcc.dg/bitint-116.c11
2 files changed, 19 insertions, 1 deletions
diff --git a/gcc/expr.cc b/gcc/expr.cc
index caa1a72..aa6ee85 100644
--- a/gcc/expr.cc
+++ b/gcc/expr.cc
@@ -12505,7 +12505,9 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode tmode,
op0 = convert_modes (mode, GET_MODE (op0), op0,
TYPE_UNSIGNED (TREE_TYPE (treeop0)));
/* If the output type is a bit-field type, do an extraction. */
- else if (reduce_bit_field && mode != BLKmode)
+ else if (reduce_bit_field
+ && mode != BLKmode
+ && (MEM_P (op0) || !COMPLEX_MODE_P (GET_MODE (op0))))
return extract_bit_field (op0, TYPE_PRECISION (type), 0,
TYPE_UNSIGNED (type), NULL_RTX,
mode, mode, false, NULL);
@@ -12529,6 +12531,11 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode tmode,
emit_move_insn (target, op0);
op0 = target;
+
+ if (reduce_bit_field && mode != BLKmode)
+ return extract_bit_field (op0, TYPE_PRECISION (type), 0,
+ TYPE_UNSIGNED (type), NULL_RTX,
+ mode, mode, false, NULL);
}
/* If OP0 is (now) a MEM, we need to deal with alignment issues. If the
diff --git a/gcc/testsuite/gcc.dg/bitint-116.c b/gcc/testsuite/gcc.dg/bitint-116.c
new file mode 100644
index 0000000..9af5d72
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/bitint-116.c
@@ -0,0 +1,11 @@
+/* PR middle-end/117458 */
+/* { dg-do compile { target bitint } } */
+/* { dg-options "-std=c23 -O2" } */
+
+typedef _BitInt(33) B __attribute__((may_alias));
+
+_BitInt(33)
+foo (_Complex float x)
+{
+ return *(B *)&x;
+}