https://gcc.gnu.org/g:98eabdaddc660906f59b8b3db53703588f72f39f

commit r14-11140-g98eabdaddc660906f59b8b3db53703588f72f39f
Author: Jakub Jelinek <ja...@redhat.com>
Date:   Tue Nov 19 10:26:44 2024 +0100

    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  <ja...@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.
    
    (cherry picked from commit 694613a7f9adfa9c87e733adc63839c8801f2b5c)

Diff:
---
 gcc/expr.cc                       |  9 ++++++++-
 gcc/testsuite/gcc.dg/bitint-116.c | 11 +++++++++++
 2 files changed, 19 insertions(+), 1 deletion(-)

diff --git a/gcc/expr.cc b/gcc/expr.cc
index 414b7fda7545..034d036b188c 100644
--- a/gcc/expr.cc
+++ b/gcc/expr.cc
@@ -12464,7 +12464,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);
@@ -12488,6 +12490,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 000000000000..9af5d723d058
--- /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;
+}

Reply via email to