Hi! The following patch ensures we don't access bytes beyond the original MEM, those might not be mapped etc., or for big endian the offset computation computes the offset incorrectly.
Bootstrapped/regtested on powerpc64{,-le}-linux, Wilco has tested it on aarch64_be-*, preapproved by Segher in the PR, committed to trunk. 2019-02-05 Jakub Jelinek <ja...@redhat.com> PR rtl-optimization/89195 * combine.c (make_extraction): For MEMs, don't extract bytes outside of the original MEM. * gcc.c-torture/execute/pr89195.c: New test. --- gcc/combine.c.jj 2019-02-01 23:52:24.701025057 +0100 +++ gcc/combine.c 2019-02-05 12:51:17.813658725 +0100 @@ -7687,6 +7687,7 @@ make_extraction (machine_mode mode, rtx /* We can't do this if we are widening INNER_MODE (it may not be aligned, for one thing). */ && !paradoxical_subreg_p (tmode, inner_mode) + && known_le (pos + len, GET_MODE_PRECISION (is_mode)) && (inner_mode == tmode || (! mode_dependent_address_p (XEXP (inner, 0), MEM_ADDR_SPACE (inner)) --- gcc/testsuite/gcc.c-torture/execute/pr89195.c.jj 2019-02-05 12:55:40.856362136 +0100 +++ gcc/testsuite/gcc.c-torture/execute/pr89195.c 2019-02-05 12:55:09.920853996 +0100 @@ -0,0 +1,22 @@ +/* PR rtl-optimization/89195 */ +/* { dg-require-effective-target int32plus } */ + +struct S { unsigned i : 24; }; + +volatile unsigned char x; + +__attribute__((noipa)) int +foo (struct S d) +{ + return d.i & x; +} + +int +main () +{ + struct S d = { 0x123456 }; + x = 0x75; + if (foo (d) != (0x56 & 0x75)) + __builtin_abort (); + return 0; +} Jakub