Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
DISCONTINUED:openSUSE:11.2
gcc43
pr40141.diff
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File pr40141.diff of Package gcc43
2009-05-15 Richard Guenther <rguenther@suse.de> Backport from gcc-4_4-branch 2008-11-25 Richard Guenther <rguenther@suse.de> PR middle-end/38151 PR middle-end/38236 * tree-ssa-alias.c (struct alias_info): Remove written_vars. Remove dereferenced_ptrs_store and dereferenced_ptrs_load in favor of dereferenced_ptrs. (init_alias_info): Adjust. (delete_alias_info): Likewise. (compute_flow_insensitive_aliasing): Properly include all aliased variables. (update_alias_info_1): Use dereferenced_ptrs. (setup_pointers_and_addressables): Likewise. (get_smt_for): Honor ref-all pointers and pointers with known alias set properly. * config/i386/i386.c (ix86_gimplify_va_arg): Use ref-all pointers. 2008-11-20 Uros Bizjak <ubizjak@gmail.com> PR target/38151 * config/i386/i386.c (classify_argument) [integer mode size <= 64bit]: Handle cases when integer argument crosses argument register boundary. 2008-04-29 Richard Guenther <rguenther@suse.de> * tree-ssa-alias.c (finalize_ref_all_pointers): Remove. (compute_may_aliases): Do not call finalize_ref_all_pointers. (compute_flow_insensitive_aliasing): Do not treat PTR_IS_REF_ALL pointers special. (get_smt_for): Likewise. (may_alias_p): Re-structure. (is_escape_site): A ref-all pointer conversion is not an escape site. * tree-ssa-structalias.c (find_what_p_points_to): Do not treat PTR_IS_REF_ALL pointers special. * tree-ssa-structalias.h (struct alias_info): Remove ref_all_symbol_mem_tag field. (PTR_IS_REF_ALL): Remove. Index: gcc/tree-ssa-structalias.c =================================================================== *** gcc/tree-ssa-structalias.c (revision 147534) --- gcc/tree-ssa-structalias.c (working copy) *************** update_alias_info (tree stmt, struct ali *** 3536,3548 **** all the variables OP points to. */ pi->is_dereferenced = 1; ! /* If this is a store operation, mark OP as being ! dereferenced to store, otherwise mark it as being ! dereferenced to load. */ ! if (num_stores > 0) ! pointer_set_insert (ai->dereferenced_ptrs_store, var); ! else ! pointer_set_insert (ai->dereferenced_ptrs_load, var); /* Update the frequency estimate for all the dereferences of pointer OP. */ --- 3536,3543 ---- all the variables OP points to. */ pi->is_dereferenced = 1; ! /* Mark OP as being dereferenced. */ ! pointer_set_insert (ai->dereferenced_ptrs, var); /* Update the frequency estimate for all the dereferences of pointer OP. */ *************** update_alias_info (tree stmt, struct ali *** 3567,3573 **** if (get_call_expr_in (stmt) || stmt_escape_type == ESCAPE_STORED_IN_GLOBAL) { ! pointer_set_insert (ai->dereferenced_ptrs_store, var); pi->is_dereferenced = 1; } } --- 3562,3568 ---- if (get_call_expr_in (stmt) || stmt_escape_type == ESCAPE_STORED_IN_GLOBAL) { ! pointer_set_insert (ai->dereferenced_ptrs, var); pi->is_dereferenced = 1; } } *************** update_alias_info (tree stmt, struct ali *** 3585,3613 **** mem_ref_stats->num_mem_stmts++; - /* Add all decls written to to the list of written variables. */ - if (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT - && TREE_CODE (GIMPLE_STMT_OPERAND (stmt, 0)) != SSA_NAME) - { - tree lhs = GIMPLE_STMT_OPERAND (stmt, 0); - while (handled_component_p (lhs)) - lhs = TREE_OPERAND (lhs, 0); - if (DECL_P (lhs)) - { - subvar_t svars; - if (var_can_have_subvars (lhs) - && (svars = get_subvars_for_var (lhs))) - { - unsigned int i; - tree subvar; - for (i = 0; VEC_iterate (tree, svars, i, subvar); ++i) - pointer_set_insert (ai->written_vars, subvar); - } - else - pointer_set_insert (ai->written_vars, lhs); - } - } - /* Notice that we only update memory reference stats for symbols loaded and stored by the statement if the statement does not contain pointer dereferences and it is not a call/asm site. --- 3580,3585 ---- *************** find_what_p_points_to (tree p) *** 5026,5042 **** /* Instead of using pt_anything, we merge in the SMT aliases for the underlying SMT. In addition, if they could have ! pointed to anything, they could point to global memory. ! But we cannot do that for ref-all pointers because these ! aliases have not been computed yet. */ if (was_pt_anything) { - if (PTR_IS_REF_ALL (p)) - { - pi->pt_anything = 1; - return false; - } - merge_smts_into (p, finished_solution); pi->pt_global_mem = 1; } --- 4998,5006 ---- /* Instead of using pt_anything, we merge in the SMT aliases for the underlying SMT. In addition, if they could have ! pointed to anything, they could point to global memory. */ if (was_pt_anything) { merge_smts_into (p, finished_solution); pi->pt_global_mem = 1; } Index: gcc/tree-ssa-structalias.h =================================================================== *** gcc/tree-ssa-structalias.h (revision 147534) --- gcc/tree-ssa-structalias.h (working copy) *************** *** 21,29 **** #ifndef TREE_SSA_STRUCTALIAS_H #define TREE_SSA_STRUCTALIAS_H - /* True if the data pointed to by PTR can alias anything. */ - #define PTR_IS_REF_ALL(PTR) TYPE_REF_CAN_ALIAS_ALL (TREE_TYPE (PTR)) - struct constraint; typedef struct constraint *constraint_t; --- 21,26 ---- *************** struct alias_info *** 48,65 **** struct alias_map_d **pointers; size_t num_pointers; ! /* Variables that have been written to directly (i.e., not through a ! pointer dereference). */ ! struct pointer_set_t *written_vars; ! ! /* Pointers that have been used in an indirect store operation. */ ! struct pointer_set_t *dereferenced_ptrs_store; ! ! /* Pointers that have been used in an indirect load operation. */ ! struct pointer_set_t *dereferenced_ptrs_load; ! ! /* Memory tag for all the PTR_IS_REF_ALL pointers. */ ! tree ref_all_symbol_mem_tag; }; /* In tree-ssa-alias.c. */ --- 45,52 ---- struct alias_map_d **pointers; size_t num_pointers; ! /* Pointers that have been used in an indirect load/store operation. */ ! struct pointer_set_t *dereferenced_ptrs; }; /* In tree-ssa-alias.c. */ Index: gcc/tree-ssa-alias.c =================================================================== *** gcc/tree-ssa-alias.c (revision 147534) --- gcc/tree-ssa-alias.c (working copy) *************** static bitmap_obstack alias_bitmap_obsta *** 196,202 **** /* Local functions. */ static void compute_flow_insensitive_aliasing (struct alias_info *); - static void finalize_ref_all_pointers (struct alias_info *); static void dump_alias_stats (FILE *); static bool may_alias_p (tree, alias_set_type, tree, alias_set_type, bool); static tree create_memory_tag (tree type, bool is_type_tag); --- 196,201 ---- *************** compute_may_aliases (void) *** 1894,1905 **** avoid invalid transformations on them. */ maybe_create_global_var (); - /* If the program contains ref-all pointers, finalize may-alias information - for them. This pass needs to be run after call-clobbering information - has been computed. */ - if (ai->ref_all_symbol_mem_tag) - finalize_ref_all_pointers (ai); - /* Compute memory partitions for every memory variable. */ compute_memory_partitions (); --- 1893,1898 ---- *************** init_alias_info (void) *** 2220,2228 **** ai->ssa_names_visited = sbitmap_alloc (num_ssa_names); sbitmap_zero (ai->ssa_names_visited); ai->processed_ptrs = VEC_alloc (tree, heap, 50); ! ai->written_vars = pointer_set_create (); ! ai->dereferenced_ptrs_store = pointer_set_create (); ! ai->dereferenced_ptrs_load = pointer_set_create (); /* Clear out all memory reference stats. */ init_mem_ref_stats (); --- 2213,2219 ---- ai->ssa_names_visited = sbitmap_alloc (num_ssa_names); sbitmap_zero (ai->ssa_names_visited); ai->processed_ptrs = VEC_alloc (tree, heap, 50); ! ai->dereferenced_ptrs = pointer_set_create (); /* Clear out all memory reference stats. */ init_mem_ref_stats (); *************** delete_alias_info (struct alias_info *ai *** 2269,2277 **** free (ai->pointers[i]); free (ai->pointers); ! pointer_set_destroy (ai->written_vars); ! pointer_set_destroy (ai->dereferenced_ptrs_store); ! pointer_set_destroy (ai->dereferenced_ptrs_load); free (ai); delete_mem_ref_stats (cfun); --- 2260,2266 ---- free (ai->pointers[i]); free (ai->pointers); ! pointer_set_destroy (ai->dereferenced_ptrs); free (ai); delete_mem_ref_stats (cfun); *************** compute_flow_insensitive_aliasing (struc *** 2518,2548 **** tree tag = symbol_mem_tag (p_map->var); tree var; - /* Call-clobbering information is not finalized yet at this point. */ - if (PTR_IS_REF_ALL (p_map->var)) - continue; - for (j = 0; j < ai->num_addressable_vars; j++) { struct alias_map_d *v_map; var_ann_t v_ann; - bool tag_stored_p, var_stored_p; v_map = ai->addressable_vars[j]; var = v_map->var; v_ann = var_ann (var); ! /* Skip memory tags and variables that have never been ! written to. We also need to check if the variables are ! call-clobbered because they may be overwritten by ! function calls. */ ! tag_stored_p = pointer_set_contains (ai->written_vars, tag) ! || is_call_clobbered (tag); ! var_stored_p = pointer_set_contains (ai->written_vars, var) ! || is_call_clobbered (var); ! if (!tag_stored_p && !var_stored_p) ! continue; ! if (may_alias_p (p_map->var, p_map->set, var, v_map->set, false)) { /* We should never have a var with subvars here, because --- 2507,2528 ---- tree tag = symbol_mem_tag (p_map->var); tree var; for (j = 0; j < ai->num_addressable_vars; j++) { struct alias_map_d *v_map; var_ann_t v_ann; v_map = ai->addressable_vars[j]; var = v_map->var; v_ann = var_ann (var); ! /* We used to skip variables that have never been written to ! if the memory tag has been never written to directly (or ! either of them were call clobbered). This is not enough ! though, as this misses writes through the tags aliases. ! So, for correctness we need to include any aliased ! variable here. */ ! if (may_alias_p (p_map->var, p_map->set, var, v_map->set, false)) { /* We should never have a var with subvars here, because *************** compute_flow_insensitive_aliasing (struc *** 2583,2600 **** tree tag1 = symbol_mem_tag (p_map1->var); bitmap may_aliases1 = MTAG_ALIASES (tag1); - if (PTR_IS_REF_ALL (p_map1->var)) - continue; - for (j = i + 1; j < ai->num_pointers; j++) { struct alias_map_d *p_map2 = ai->pointers[j]; tree tag2 = symbol_mem_tag (p_map2->var); bitmap may_aliases2 = may_aliases (tag2); - if (PTR_IS_REF_ALL (p_map2->var)) - continue; - /* If the pointers may not point to each other, do nothing. */ if (!may_alias_p (p_map1->var, p_map1->set, tag2, p_map2->set, true)) continue; --- 2563,2574 ---- *************** compute_flow_insensitive_aliasing (struc *** 2639,2687 **** } - /* Finalize may-alias information for ref-all pointers. Traverse all - the addressable variables found in setup_pointers_and_addressables. - - If flow-sensitive alias analysis has attached a name memory tag to - a ref-all pointer, we will use it for the dereferences because that - will have more precise aliasing information. But if there is no - name tag, we will use a special symbol tag that aliases all the - call-clobbered addressable variables. */ - - static void - finalize_ref_all_pointers (struct alias_info *ai) - { - size_t i; - - /* First add the real call-clobbered variables. */ - for (i = 0; i < ai->num_addressable_vars; i++) - { - tree var = ai->addressable_vars[i]->var; - if (is_call_clobbered (var)) - add_may_alias (ai->ref_all_symbol_mem_tag, var); - } - - /* Then add the call-clobbered pointer memory tags. See - compute_flow_insensitive_aliasing for the rationale. */ - for (i = 0; i < ai->num_pointers; i++) - { - tree ptr = ai->pointers[i]->var, tag; - /* Avoid adding to self and clean up. */ - if (PTR_IS_REF_ALL (ptr)) - { - struct ptr_info_def *pi = get_ptr_info (ptr); - if (pi->is_dereferenced) - pi->pt_anything = 0; - continue; - } - tag = symbol_mem_tag (ptr); - if (is_call_clobbered (tag)) - add_may_alias (ai->ref_all_symbol_mem_tag, tag); - } - - } - - /* Create a new alias set entry for VAR in AI->ADDRESSABLE_VARS. */ static void --- 2613,2618 ---- *************** setup_pointers_and_addressables (struct *** 2723,2729 **** /* Since we don't keep track of volatile variables, assume that these pointers are used in indirect store operations. */ if (TREE_THIS_VOLATILE (var)) ! pointer_set_insert (ai->dereferenced_ptrs_store, var); num_pointers++; } --- 2654,2660 ---- /* Since we don't keep track of volatile variables, assume that these pointers are used in indirect store operations. */ if (TREE_THIS_VOLATILE (var)) ! pointer_set_insert (ai->dereferenced_ptrs, var); num_pointers++; } *************** setup_pointers_and_addressables (struct *** 2821,2828 **** array and create a symbol memory tag for them. */ if (POINTER_TYPE_P (TREE_TYPE (var))) { ! if ((pointer_set_contains (ai->dereferenced_ptrs_store, var) ! || pointer_set_contains (ai->dereferenced_ptrs_load, var))) { tree tag, old_tag; var_ann_t t_ann; --- 2752,2758 ---- array and create a symbol memory tag for them. */ if (POINTER_TYPE_P (TREE_TYPE (var))) { ! if (pointer_set_contains (ai->dereferenced_ptrs, var)) { tree tag, old_tag; var_ann_t t_ann; *************** setup_pointers_and_addressables (struct *** 2848,2858 **** /* Associate the tag with pointer VAR. */ set_symbol_mem_tag (var, tag); - - /* If pointer VAR has been used in a store operation, - then its memory tag must be marked as written-to. */ - if (pointer_set_contains (ai->dereferenced_ptrs_store, var)) - pointer_set_insert (ai->written_vars, tag); } else { --- 2778,2783 ---- *************** may_alias_p (tree ptr, alias_set_type me *** 2966,3039 **** return false; } gcc_assert (TREE_CODE (mem) == SYMBOL_MEMORY_TAG); ! if (!DECL_NO_TBAA_P (ptr)) { ! alias_stats.tbaa_queries++; ! /* If the alias sets don't conflict then MEM cannot alias VAR. */ ! if (!alias_sets_conflict_p (mem_alias_set, var_alias_set)) ! { ! alias_stats.alias_noalias++; ! alias_stats.tbaa_resolved++; ! return false; ! } ! /* If VAR is a record or union type, PTR cannot point into VAR ! unless there is some explicit address operation in the ! program that can reference a field of the type pointed-to by ! PTR. This also assumes that the types of both VAR and PTR ! are contained within the compilation unit, and that there is ! no fancy addressing arithmetic associated with any of the ! types involved. */ ! if (mem_alias_set != 0 && var_alias_set != 0) ! { ! tree ptr_type = TREE_TYPE (ptr); ! tree var_type = TREE_TYPE (var); ! ! /* The star count is -1 if the type at the end of the ! pointer_to chain is not a record or union type. */ ! if ((!alias_set_only) && ! ipa_type_escape_star_count_of_interesting_type (var_type) >= 0) { ! int ptr_star_count = 0; ! ! /* ipa_type_escape_star_count_of_interesting_type is a ! little too restrictive for the pointer type, need to ! allow pointers to primitive types as long as those ! types cannot be pointers to everything. */ ! while (POINTER_TYPE_P (ptr_type)) ! { ! /* Strip the *s off. */ ! ptr_type = TREE_TYPE (ptr_type); ! ptr_star_count++; ! } ! ! /* There does not appear to be a better test to see if ! the pointer type was one of the pointer to everything ! types. */ ! if (ptr_star_count > 0) ! { ! alias_stats.structnoaddress_queries++; ! if (ipa_type_escape_field_does_not_clobber_p (var_type, ! TREE_TYPE (ptr))) ! { ! alias_stats.structnoaddress_resolved++; ! alias_stats.alias_noalias++; ! return false; ! } ! } ! else if (ptr_star_count == 0) { - /* If PTR_TYPE was not really a pointer to type, it cannot - alias. */ - alias_stats.structnoaddress_queries++; alias_stats.structnoaddress_resolved++; alias_stats.alias_noalias++; return false; } } } } --- 2891,2974 ---- return false; } + /* If the pointed to memory has alias set zero, or the pointer + is ref-all, or the pointer decl is marked that no TBAA is to + be applied, the MEM can alias VAR. */ + if (mem_alias_set == 0 + || DECL_POINTER_ALIAS_SET (ptr) == 0 + || TYPE_REF_CAN_ALIAS_ALL (TREE_TYPE (ptr)) + || DECL_NO_TBAA_P (ptr)) + { + alias_stats.alias_mayalias++; + alias_stats.simple_resolved++; + return true; + } + gcc_assert (TREE_CODE (mem) == SYMBOL_MEMORY_TAG); ! alias_stats.tbaa_queries++; ! ! /* If the alias sets don't conflict then MEM cannot alias VAR. */ ! if (!alias_sets_conflict_p (mem_alias_set, var_alias_set)) { ! alias_stats.alias_noalias++; ! alias_stats.tbaa_resolved++; ! return false; ! } ! /* If VAR is a record or union type, PTR cannot point into VAR ! unless there is some explicit address operation in the ! program that can reference a field of the type pointed-to by ! PTR. This also assumes that the types of both VAR and PTR ! are contained within the compilation unit, and that there is ! no fancy addressing arithmetic associated with any of the ! types involved. */ ! if (mem_alias_set != 0 && var_alias_set != 0) ! { ! tree ptr_type = TREE_TYPE (ptr); ! tree var_type = TREE_TYPE (var); ! ! /* The star count is -1 if the type at the end of the ! pointer_to chain is not a record or union type. */ ! if (!alias_set_only ! && ipa_type_escape_star_count_of_interesting_type (var_type) >= 0) ! { ! int ptr_star_count = 0; ! ! /* ipa_type_escape_star_count_of_interesting_type is a ! little too restrictive for the pointer type, need to ! allow pointers to primitive types as long as those ! types cannot be pointers to everything. */ ! while (POINTER_TYPE_P (ptr_type)) ! { ! /* Strip the *s off. */ ! ptr_type = TREE_TYPE (ptr_type); ! ptr_star_count++; ! } ! /* There does not appear to be a better test to see if ! the pointer type was one of the pointer to everything ! types. */ ! if (ptr_star_count > 0) { ! alias_stats.structnoaddress_queries++; ! if (ipa_type_escape_field_does_not_clobber_p (var_type, ! TREE_TYPE (ptr))) { alias_stats.structnoaddress_resolved++; alias_stats.alias_noalias++; return false; } } + else if (ptr_star_count == 0) + { + /* If PTR_TYPE was not really a pointer to type, it cannot + alias. */ + alias_stats.structnoaddress_queries++; + alias_stats.structnoaddress_resolved++; + alias_stats.alias_noalias++; + return false; + } } } *************** is_escape_site (tree stmt) *** 3139,3150 **** pointer escapes since we can't track the integer. */ if (POINTER_TYPE_P (from) && !POINTER_TYPE_P (to)) return ESCAPE_BAD_CAST; - - /* Same if the RHS is a conversion between a regular pointer and a - ref-all pointer since we can't track the SMT of the former. */ - if (POINTER_TYPE_P (from) && !TYPE_REF_CAN_ALIAS_ALL (from) - && POINTER_TYPE_P (to) && TYPE_REF_CAN_ALIAS_ALL (to)) - return ESCAPE_BAD_CAST; } /* If the LHS is an SSA name, it can't possibly represent a non-local --- 3074,3079 ---- *************** get_smt_for (tree ptr, struct alias_info *** 3248,3261 **** size_t i; tree tag; tree tag_type = TREE_TYPE (TREE_TYPE (ptr)); ! alias_set_type tag_set = get_alias_set (tag_type); ! /* We use a unique memory tag for all the ref-all pointers. */ ! if (PTR_IS_REF_ALL (ptr)) { ! if (!ai->ref_all_symbol_mem_tag) ! ai->ref_all_symbol_mem_tag = create_memory_tag (void_type_node, true); ! return ai->ref_all_symbol_mem_tag; } /* To avoid creating unnecessary memory tags, only create one memory tag --- 3177,3197 ---- size_t i; tree tag; tree tag_type = TREE_TYPE (TREE_TYPE (ptr)); ! alias_set_type tag_set; ! /* Get the alias set to be used for the pointed-to memory. If that ! differs from what we would get from looking at the type adjust ! the tag_type to void to make sure we get a proper alias set from ! just looking at the SMT we create. */ ! tag_set = get_alias_set (tag_type); ! if (TYPE_REF_CAN_ALIAS_ALL (TREE_TYPE (ptr)) ! /* This is overly conservative but we do not want to assign ! restrict alias sets here (which if they are not assigned ! are -2 but still "known"). */ ! || DECL_POINTER_ALIAS_SET_KNOWN_P (ptr)) { ! tag_set = 0; ! tag_type = void_type_node; } /* To avoid creating unnecessary memory tags, only create one memory tag *************** get_smt_for (tree ptr, struct alias_info *** 3287,3293 **** artificial variable representing the memory location pointed-to by PTR. */ tag = symbol_mem_tag (ptr); ! if (tag == NULL_TREE) tag = create_memory_tag (tag_type, true); /* Add PTR to the POINTERS array. Note that we are not interested in --- 3223,3230 ---- artificial variable representing the memory location pointed-to by PTR. */ tag = symbol_mem_tag (ptr); ! if (tag == NULL_TREE ! || tag_set != get_alias_set (tag)) tag = create_memory_tag (tag_type, true); /* Add PTR to the POINTERS array. Note that we are not interested in Index: gcc/config/i386/i386.c =================================================================== *** gcc/config/i386/i386.c (revision 147534) --- gcc/config/i386/i386.c (working copy) *************** ix86_gimplify_va_arg (tree valist, tree *** 5336,5341 **** --- 5336,5343 ---- enum machine_mode mode = GET_MODE (reg); tree piece_type = lang_hooks.types.type_for_mode (mode, 1); tree addr_type = build_pointer_type (piece_type); + tree daddr_type = build_pointer_type_for_mode (piece_type, + ptr_mode, true); tree src_addr, src; int src_offset; tree dest_addr, dest; *************** ix86_gimplify_va_arg (tree valist, tree *** 5355,5362 **** size_int (src_offset)); src = build_va_arg_indirect_ref (src_addr); ! dest_addr = fold_convert (addr_type, addr); ! dest_addr = fold_build2 (POINTER_PLUS_EXPR, addr_type, dest_addr, size_int (INTVAL (XEXP (slot, 1)))); dest = build_va_arg_indirect_ref (dest_addr); --- 5357,5364 ---- size_int (src_offset)); src = build_va_arg_indirect_ref (src_addr); ! dest_addr = fold_convert (daddr_type, addr); ! dest_addr = fold_build2 (POINTER_PLUS_EXPR, daddr_type, dest_addr, size_int (INTVAL (XEXP (slot, 1)))); dest = build_va_arg_indirect_ref (dest_addr); Index: gcc/testsuite/gcc.c-torture/execute/pr38151.c =================================================================== *** gcc/testsuite/gcc.c-torture/execute/pr38151.c (revision 0) --- gcc/testsuite/gcc.c-torture/execute/pr38151.c (revision 0) *************** *** 0 **** --- 1,46 ---- + void abort (void); + + struct S2848 + { + unsigned int a; + _Complex int b; + struct + { + } __attribute__ ((aligned)) c; + }; + + struct S2848 s2848; + + int fails; + + void __attribute__((noinline)) + check2848va (int z, ...) + { + struct S2848 arg; + __builtin_va_list ap; + + __builtin_va_start (ap, z); + + arg = __builtin_va_arg (ap, struct S2848); + + if (s2848.a != arg.a) + ++fails; + if (s2848.b != arg.b) + ++fails; + + __builtin_va_end (ap); + } + + int main (void) + { + s2848.a = 4027477739U; + s2848.b = (723419448 + -218144346 * __extension__ 1i); + + check2848va (1, s2848); + + if (fails) + abort (); + + return 0; + } + Index: gcc/testsuite/gcc.c-torture/execute/pr38236.c =================================================================== *** gcc/testsuite/gcc.c-torture/execute/pr38236.c (revision 0) --- gcc/testsuite/gcc.c-torture/execute/pr38236.c (revision 0) *************** *** 0 **** --- 1,22 ---- + struct X { int i; }; + + int __attribute__((noinline)) + foo (struct X *p, int *q, int a, int b) + { + struct X x, y; + if (a) + p = &x; + if (b) + q = &x.i; + else + q = &y.i; + *q = 1; + return p->i; + } + extern void abort (void); + int main() + { + if (foo((void *)0, (void *)0, 1, 1) != 1) + abort (); + return 0; + } Index: gcc/testsuite/gcc.c-torture/execute/pr40141.c =================================================================== *** gcc/testsuite/gcc.c-torture/execute/pr40141.c (revision 0) --- gcc/testsuite/gcc.c-torture/execute/pr40141.c (revision 0) *************** *** 0 **** --- 1,16 ---- + extern void abort (void); + typedef int __m128 __attribute__((vector_size(16),may_alias)); + typedef float floatA __attribute__((may_alias)); + + int main() + { + __m128 x = { 0, 0, 0, 0 }; + int i; + for (i = 0; i < 4; ++i) { + const float xx = ((floatA*)&x)[i]; + if (xx != 0.f) + abort (); + } + return 0; + } + Index: gcc/testsuite/gcc.target/i386/pr38151-1.c =================================================================== --- gcc/testsuite/gcc.target/i386/pr38151-1.c (revision 0) +++ gcc/testsuite/gcc.target/i386/pr38151-1.c (revision 142059) @@ -0,0 +1,29 @@ +/* { dg-do run } */ +/* { dg-options "-O2" } */ + +void abort (void); + +struct S2848 +{ + unsigned int a; + _Complex int b; +}; + +struct S2848 s2848; + +void __attribute__((noinline)) +check2848 (struct S2848 arg0) +{ + if (arg0.b != s2848.b) + abort (); +} + +int main() +{ + s2848.a = 4027477739U; + s2848.b = (723419448 + -218144346 * __extension__ 1i); + + check2848 (s2848); + + return 0; +} Index: gcc/config/i386/i386.c =================================================================== --- gcc/config/i386/i386.c (revision 142058) +++ gcc/config/i386/i386.c (revision 142059) @@ -5029,11 +5029,33 @@ classify_argument (enum machine_mode mod case CSImode: case CHImode: case CQImode: - if (bit_offset + GET_MODE_BITSIZE (mode) <= 32) - classes[0] = X86_64_INTEGERSI_CLASS; - else - classes[0] = X86_64_INTEGER_CLASS; - return 1; + { + int size = (bit_offset % 64)+ (int) GET_MODE_BITSIZE (mode); + + if (size <= 32) + { + classes[0] = X86_64_INTEGERSI_CLASS; + return 1; + } + else if (size <= 64) + { + classes[0] = X86_64_INTEGER_CLASS; + return 1; + } + else if (size <= 64+32) + { + classes[0] = X86_64_INTEGER_CLASS; + classes[1] = X86_64_INTEGERSI_CLASS; + return 2; + } + else if (size <= 64+64) + { + classes[0] = classes[1] = X86_64_INTEGER_CLASS; + return 2; + } + else + gcc_unreachable (); + } case CDImode: case TImode: classes[0] = classes[1] = X86_64_INTEGER_CLASS;
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor