https://gcc.gnu.org/g:6b56e645a7b481693fe6982f8f09ba2e07768bf8

commit r15-7284-g6b56e645a7b481693fe6982f8f09ba2e07768bf8
Author: Richard Biener <rguent...@suse.de>
Date:   Wed Jan 29 15:09:35 2025 +0100

    middle-end/118692 - ICE with out-of-bound ref expansion
    
    The following guards the BIT_FIELD_REF expansion fallback for
    MEM_REFs of entities expanded to register (or constant) further,
    avoiding large out-of-bound offsets by, when the access does not
    overlap the base object, expanding the offset as if it were zero.
    
            PR middle-end/118692
            * expr.cc (expand_expr_real_1): When expanding a MEM_REF
            as BIT_FIELD_REF avoid large offsets for accesses not
            overlapping the base object.
    
            * gcc.dg/pr118692.c: New testcase.

Diff:
---
 gcc/expr.cc                     |  8 ++++++++
 gcc/testsuite/gcc.dg/pr118692.c | 10 ++++++++++
 2 files changed, 18 insertions(+)

diff --git a/gcc/expr.cc b/gcc/expr.cc
index 7f3149b85eec..10467f82c0d2 100644
--- a/gcc/expr.cc
+++ b/gcc/expr.cc
@@ -11806,6 +11806,14 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode 
tmode,
                  set_mem_size (temp, int_size_in_bytes (type));
                return temp;
              }
+           /* When the access is fully outside of the underlying object
+              expand the offset as zero.  This avoids out-of-bound
+              BIT_FIELD_REFs and generates smaller code for these cases
+              with UB.  */
+           type_size = tree_to_poly_uint64 (TYPE_SIZE_UNIT (type));
+           if (!ranges_maybe_overlap_p (offset, type_size, 0,
+                                        GET_MODE_SIZE (DECL_MODE (base))))
+             offset = 0;
            exp = build3 (BIT_FIELD_REF, type, base, TYPE_SIZE (type),
                          bitsize_int (offset * BITS_PER_UNIT));
            REF_REVERSE_STORAGE_ORDER (exp) = reverse;
diff --git a/gcc/testsuite/gcc.dg/pr118692.c b/gcc/testsuite/gcc.dg/pr118692.c
new file mode 100644
index 000000000000..45fba560b35c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr118692.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+_Complex double cf;
+
+void
+foo(char c)
+{
+  cf += *(_Complex double *)__builtin_memcpy(8143523003042804629LL + &c, 0, 0);
+}

Reply via email to