Message ID | 5306D4F9.6040901@linaro.org |
---|---|
State | New |
Headers | show |
On 21 February 2014 04:24, Kugan <kugan.vivekanandarajah@linaro.org> wrote: > Compiling inline asm results in ICE (PR60034). Alignment calculation in > aarch64_classify_address for (symbol_ref:DI ("*.LANCHOR4") [flags > 0x182])) seems wrong here. Hi Kugan, + else if (SYMBOL_REF_FLAGS (sym)) + align = GET_MODE_ALIGNMENT (GET_MODE (sym)); This is inserted into the LO_SUM handling in the function aarch64_classify_address(), the code in question is checking the alignment of the object to ensure that a scaled address instruction would be valid. The proposed code is testing if any of a bunch of unrelated predicate flags have been set on the symbol and using that to gate whether GET_MODE_ALIGNMENT would give accurate alignment information on the symbol. I'm not convinced that the presence of SYMBOL_REF_FLAGS states anything definitive about the relevance of GET_MODE_ALIGNMENT. The test looks like it fails because a section anchor has been introduced and we fail to determine anything sensible about the alignment of a section anchor. How about this instead? if (SYMBOL_REF_BLOCK (sym)) align = SYMBOL_REF_BLOCK (sym)->alignment; > > Fixing this also caused a regression for pr38151.c, which is due to > complex type being allocated with wrong alignment. Attached patch fixes > these issues. It ~might~ be beneficial to increase data_alignment here as suggest for performance reasons, but the existing alignment should not cause breakage... this issue suggest to me that the SYMBOL_REF_FLAGS approach is at fault. Cheers /Marcus
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c index ea90311..89187c0 100644 --- a/gcc/config/aarch64/aarch64.c +++ b/gcc/config/aarch64/aarch64.c @@ -3203,6 +3203,8 @@ aarch64_classify_address (struct aarch64_address_info *info, } else if (SYMBOL_REF_DECL (sym)) align = DECL_ALIGN (SYMBOL_REF_DECL (sym)); + else if (SYMBOL_REF_FLAGS (sym)) + align = GET_MODE_ALIGNMENT (GET_MODE (sym)); else align = BITS_PER_UNIT; diff --git a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h index 13c424c..b93e9da 100644 --- a/gcc/config/aarch64/aarch64.h +++ b/gcc/config/aarch64/aarch64.h @@ -132,6 +132,7 @@ ((((ALIGN) < BITS_PER_WORD) \ && (TREE_CODE (EXP) == ARRAY_TYPE \ || TREE_CODE (EXP) == UNION_TYPE \ + || TREE_CODE (EXP) == COMPLEX_TYPE \ || TREE_CODE (EXP) == RECORD_TYPE)) \ ? BITS_PER_WORD : (ALIGN)) diff --git a/gcc/testsuite/gcc.target/aarch64/pr60034.c b/gcc/testsuite/gcc.target/aarch64/pr60034.c index e69de29..99c821d 100644 --- a/gcc/testsuite/gcc.target/aarch64/pr60034.c +++ b/gcc/testsuite/gcc.target/aarch64/pr60034.c @@ -0,0 +1,10 @@ +/* { dg-do compile } */ +/* { dg-options "-std=gnu99 -fgnu89-inline -O -Wall -Winline -Wwrite-strings -fmerge-all-constants -frounding-math -g -Wstrict-prototypes" } */ + +static unsigned long global_max_fast; + +int __libc_mallopt (int param_number, int value) +{ + __asm__ __volatile__ ("# %[_SDT_A21]" :: [_SDT_A21] "nr" ((global_max_fast))); + global_max_fast = 1; +}