http://gcc.gnu.org/bugzilla/show_bug.cgi?id=48377
--- Comment #26 from Jakub Jelinek <jakub at gcc dot gnu.org> 2011-04-07 12:48:12 UTC --- int a = __alignof__ (double); struct A { int b; double c; int d; } e; int f = __alignof__ (e.c); double *p; int g = __alignof__ (*p); int a2 = __alignof__ (long long); struct A2 { int b; long long c; int d; } e2; int f2 = __alignof__ (e2.c); long long *p2; int g2 = __alignof__ (*p2); on powerpc64-linux unfortunately shows that the target hook is needed, at least with -m64 -malign-power. Though, what the target hook does is definitely weird: if (TARGET_32BIT) { if (rs6000_alignment_flags == MASK_ALIGN_NATURAL) return true; if (rs6000_alignment_flags == MASK_ALIGN_POWER) return true; return false; } else { if (TARGET_MACHO) return false; /* Assuming that all other types are naturally aligned. CHECKME! */ return true; } I believe rs6000_alignment_flags can be either MASK_ALIGN_NATURAL, or MASK_ALIGN_POWER, nothing else, so wonder why it just doesn't return true for TARGET_32BIT. And, for TARGET_64BIT && !TARGET_MACHO, clearly DFmode types aren't naturally aligned with rs6000_alignment_flags == MASK_ALIGN_POWER. Therefore I'd say it should return false for TYPE_MODE (strip_array_types (type)) == DFmode && !TARGET_ALIGN_NATURAL, at least for Linux (rs6000 has unfortunately way too many ABIs and even more target switches). For TARGET_MACHO, ADJUST_FIELD_ALIGN is darwin.h:#define ADJUST_FIELD_ALIGN(FIELD, COMPUTED) \ darwin.h- (TARGET_ALIGN_NATURAL ? (COMPUTED) \ darwin.h- : (COMPUTED) == 128 ? 128 \ darwin.h- : MIN ((COMPUTED), 32)) thus I think it could use ADJUST_FIELD_ALIGN (NULL, TYPE_ALIGN (type)) == TYPE_ALIGN (type). And AIX is the same as Linux TARGET_64BIT, probably even for 32-bit AIX though. So, I think you want the compare_tree_int check in generic code (not sure if is_packed isn't redundant with that check), plus a hook which will sometimes tell you peeling won't necessarily align either.