Hi, This patch follow Richard Henderson's advice to tighten up CANNOT_CHANGE_MODE_CLASS for AArch64 to avoid a simplification bug in the middle-end. There is nothing AArch64-specific about the testcase which triggers this, so I'll put it in the testcase for other targets. If you see a regression, the explanation in the PR is much more thorough and correct than I can reproduce here, so I'd recommend starting there. In short, target maintainers need to: > forbid BITS_PER_WORD (64-bit) subregs of hard registers > > BITS_PER_WORD. See the verbiage I added to the i386 backend for this. We removed the CANNOT_CHANGE_MODE_CLASS macro back in January 2015. Before then, we used it to workaround bugs in big-endian vector support ( https://gcc.gnu.org/ml/gcc-patches/2014-12/msg01216.html ). Ideally, we'd not need to bring this macro back, but if we can't fix the middle-end bug this exposes, we need the workaround. For AArch64, doing this runs in to some trouble with two of our instruction patterns - we end up with: (truncate:DI (reg:TF)) Which fails if it ever make it through to the simplify routines with something nasty like: (and:DI (truncate:DI (reg:TF 32 v0 [ a ])) (const_int 2305843009213693951 [0x1fffffffffffffff])) The simplify routines want to turn this around to look like: (truncate:DI (and:TF (reg:TF 32 v0 [ a ]) (const_int 2305843009213693951 [0x1fffffffffffffff]))) Which then wants to further simplify the expression by first building the constant in TF mode, and trunc_int_for_mode barfs: 0x7a38a5 trunc_int_for_mode(long, machine_mode) .../gcc/explow.c:53 We can fix that by changing the patterns to use a zero_extract, which seems more in line with what they actually express (extracting the two 64-bit halves of a 128-bit value). Bootstrapped on aarch64-none-linux-gnu, and tested on aarch64-none-elf and aarch64_be-none-elf without seeing any correctness regressions. OK? If so, we ought to get this backported to the release branches, the gcc-5 backport applies clean (testing ongoing but looks OK so far) if the release managers and AArch64 maintainers agree this is something that should be backported this late in the 5.3 release cycle. Thanks, James --- 2015-11-27 James Greenhalgh * config/aarch64/aarch64-protos.h (aarch64_cannot_change_mode_class): Bring back. * config/aarch64/aarch64.c (aarch64_cannot_change_mode_class): Likewise. * config/aarch64/aarch64.h (CANNOT_CHANGE_MODE_CLASS): Likewise. * config/aarch64/aarch64.md (aarch64_movdi_low): Use zero_extract rather than truncate. (aarch64_movdi_high): Likewise. 2015-11-27 James Greenhalgh * gcc.dg/torture/pr67609.c: New.