From: Richard Biener Date: Tue, 28 Jan 2025 15:20:30 +0000 (+0100) Subject: middle-end/118684 - wrongly aligned stack local during expansion X-Git-Tag: basepoints/gcc-16~2296 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=54bdeca3c6214485d15454df30183a56ad3e473b;p=thirdparty%2Fgcc.git middle-end/118684 - wrongly aligned stack local during expansion The following fixes a not properly aligned stack temporary created during RTL expansion of a MEM_REF that we handle as a BIT_FIELD_REF whose base was allocated to a register but which was originally aligned to allow a larger load not trapping. While probably UB in C the vectorizer creates aligned accesses that might overread a (static) allocation because it is then known not to trap. PR middle-end/118684 * expr.cc (expand_expr_real_1): When expanding a reference based on a register and we end up needing a MEM make sure that's aligned as the original reference required. * gcc.dg/pr118684.c: New testcase. --- diff --git a/gcc/expr.cc b/gcc/expr.cc index a06411e1c27..95f41f69fcf 100644 --- a/gcc/expr.cc +++ b/gcc/expr.cc @@ -12148,7 +12148,11 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode tmode, and need be, put it there. */ else if (CONSTANT_P (op0) || (!MEM_P (op0) && must_force_mem)) { - memloc = assign_temp (TREE_TYPE (tem), 1, 1); + poly_int64 size; + if (!poly_int_tree_p (TYPE_SIZE_UNIT (TREE_TYPE (tem)), &size)) + size = max_int_size_in_bytes (TREE_TYPE (tem)); + memloc = assign_stack_local (TYPE_MODE (TREE_TYPE (tem)), size, + get_object_alignment (tem)); emit_move_insn (memloc, op0); op0 = memloc; clear_mem_expr = true; diff --git a/gcc/testsuite/gcc.dg/pr118684.c b/gcc/testsuite/gcc.dg/pr118684.c new file mode 100644 index 00000000000..08cc24dc061 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr118684.c @@ -0,0 +1,12 @@ +/* { dg-do run } */ +/* { dg-options "-O2" } */ + +typedef int v4si __attribute__((vector_size(16))); +v4si x; +int main () +{ + int b __attribute__((aligned(16))); + b = 0; + x = *(v4si *)&b; + return 0; +}