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);
+}