diff --git a/gcc/expr.cc b/gcc/expr.cc index 348ac3c777a356450865a2947dbfcf8dd864abf3..caa1a72ba0bef6c7c33c854b422cced771b90d1e 100644 --- a/gcc/expr.cc +++ b/gcc/expr.cc @@ -12468,7 +12468,7 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode tmode, if (!op0) op0 = expand_expr_real (treeop0, NULL_RTX, VOIDmode, modifier, - NULL, inner_reference_p); + NULL, inner_reference_p || mode == BLKmode); /* If the input and output modes are both the same, we are done. */ if (mode == GET_MODE (op0)) @@ -12505,7 +12505,7 @@ 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) + else if (reduce_bit_field && mode != BLKmode) return extract_bit_field (op0, TYPE_PRECISION (type), 0, TYPE_UNSIGNED (type), NULL_RTX, mode, mode, false, NULL); diff --git a/gcc/testsuite/gcc.dg/bitint-113.c b/gcc/testsuite/gcc.dg/bitint-113.c new file mode 100644 index 0000000000000000000000000000000000000000..3c934a62fb47ed7f48f530cab5db5c794bc3b4e8 --- /dev/null +++ b/gcc/testsuite/gcc.dg/bitint-113.c @@ -0,0 +1,40 @@ +/* PR middle-end/117354 */ +/* { dg-do compile { target bitint } } */ +/* { dg-options "-O2" } */ +/* { dg-additional-options "-mavx2" { target x86_64-*-* i?86-*-* } } */ + +#if __BITINT_MAXWIDTH__ >= 256 +#define N 256 +#else +#define N 64 +#endif + +struct S { + unsigned char y; + _BitInt(N) x; +} s; + +__attribute__((noipa)) static void +foo (const char *, _BitInt(N)) +{ +} + +__attribute__((noipa)) static void +bar (_BitInt(N)) +{ +} + +static void +baz (void *p) +{ + foo ("bazbazbazb", s.x); + __builtin_memcpy (p, &s.x, sizeof s.x); +} + +int +main () +{ + void *ptr = &s.x; + baz (&s.x); + bar (*(_BitInt(N) *) ptr); +}