As mentioned in PR87511, the shift used in aarch64_mask_and_shift_for_ubfiz_p should be evaluated as a HOST_WIDE_INT rather than int.
Passes bootstrap, OK for commit and backport? ChangeLog: 2018-10-11 Wilco Dijkstra <wdijk...@arm.com> gcc/ * config/aarch64/aarch64.c (aarch64_mask_and_shift_for_ubfiz_p): Use HOST_WIDE_INT_1U for shift. testsuite/ * gcc.target/aarch64/pr87511.c: Add new test. -- diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c index 385272b8867317be4b2d10e56da25af306121214..86cfb92861eda652718b4e0be013688718d8f1b2 100644 --- a/gcc/config/aarch64/aarch64.c +++ b/gcc/config/aarch64/aarch64.c @@ -8549,7 +8549,8 @@ aarch64_mask_and_shift_for_ubfiz_p (scalar_int_mode mode, rtx mask, return CONST_INT_P (mask) && CONST_INT_P (shft_amnt) && INTVAL (shft_amnt) < GET_MODE_BITSIZE (mode) && exact_log2 ((INTVAL (mask) >> INTVAL (shft_amnt)) + 1) >= 0 - && (INTVAL (mask) & ((1 << INTVAL (shft_amnt)) - 1)) == 0; + && (INTVAL (mask) + & ((HOST_WIDE_INT_1U << INTVAL (shft_amnt)) - 1)) == 0; } /* Calculate the cost of calculating X, storing it in *COST. Result diff --git a/gcc/testsuite/gcc.target/aarch64/pr87511.c b/gcc/testsuite/gcc.target/aarch64/pr87511.c new file mode 100644 index 0000000000000000000000000000000000000000..98064701594caefa747c10d87924746f295ad8cd --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/pr87511.c @@ -0,0 +1,16 @@ +/* { dg-do assemble } */ +/* { dg-options "-Os" } */ + +int a, d; +struct { + signed f5 : 26; + signed f6 : 12; +} b; +signed char c; +void fn1() { + signed char *e = &c; + d = a * 10; + *e = d; + b.f6 = c; + b.f5 = 8 <= 3; +}