http://gcc.gnu.org/bugzilla/show_bug.cgi?id=56988



             Bug #: 56988

           Summary: ipa-cp incorrectly propagates a field of an aggregate

    Classification: Unclassified

           Product: gcc

           Version: 4.9.0

            Status: UNCONFIRMED

          Severity: normal

          Priority: P3

         Component: middle-end

        AssignedTo: unassig...@gcc.gnu.org

        ReportedBy: era...@google.com





Created attachment 29890

  --> http://gcc.gnu.org/bugzilla/attachment.cgi?id=29890

Reduced test case



$ trunk_g++ --version

trunk_g++ (GCC) 4.9.0 20130416 (experimental)





$ trunk_g++ -S -O2  -std=c++11 -fno-exceptions upstream_test_case.ii && grep

"mov.* _ZTVN12_GLOBAL__N_18RCTesterE" upstream_test_case.s

    movq    %rax, _ZTVN12_GLOBAL__N_18RCTesterE+24(%rip)



The generated assembly attempts to write into RCTester class's vtable.



>From the dump generated by -fdump-ipa-whole-program-all (just before ipa-cp),

the caller has the following code:



  # .MEM_11 = VDEF <.MEM_10>

  obj_3->D.2045._vptr.ReferenceCountedD.2013 = &MEM[(voidD.45

*)&_ZTVN12_GLOBAL__N_18RCTesterED.2049 + 16B];

  # .MEM_12 = VDEF <.MEM_11>

  obj_3->destructed_D.2025 = 0B;

  # .MEM_13 = VDEF <.MEM_12>

  obj_3->owner_D.2026 = 0B;

  # .MEM_5 = VDEF <.MEM_13>

  # USE = nonlocal null { D.2015 D.2049 } (glob)

  # CLB = nonlocal null { D.2015 D.2049 } (glob)

  _ZN12_GLOBAL__N_19TestResetEPNS_8RCTesterED.2068 (obj_3);





At the callee, we see:



void {anonymous}::TestReset({anonymous}::RCTester*) (struct RCTesterD.2017 *

objD.2067)

{

  const struct AssertionResultD.1962 gtest_arD.2071;

  boolD.1899 destructedD.2070;

  struct RCTesterD.2017 * obj.3D.2179;



  # .MEM_2 = VDEF <.MEM_1(D)>

  destructedD.2070 = 0;

  # VUSE <.MEM_2>

  # PT = nonlocal escaped 

  obj.3_3 = objD.2067;

  # .MEM_8 = VDEF <.MEM_2>

  MEM[(boolD.1899 * *)obj.3_3 + 8B] = &destructedD.2070;



ipa-cp mistakenly thinks that the move statement

 obj.3_3 = objD.2067;



actually loads from offset 0 of objD.2067 and hence propagates &MEM[(voidD.45

*)&_ZTVN12_GLOBAL__N_18RCTesterED.2049 + 16B] into obj.3_3 which then

subsequently gets propagated to the store of &destructedD.2070. 



The following patch fixes this, but not sure if this could be too restrictive:

Index: gcc/ipa-prop.c

===================================================================

--- gcc/ipa-prop.c    (revision 197495)

+++ gcc/ipa-prop.c    (working copy)

@@ -3892,7 +3892,7 @@ ipcp_transform_function (struct cgraph_node *node)

       {

     struct ipa_agg_replacement_value *v;

     gimple stmt = gsi_stmt (gsi);

-    tree rhs, val, t;

+    tree rhs, lhs, val, t;

     HOST_WIDE_INT offset;

     int index;

     bool by_ref, vce;

@@ -3900,6 +3900,7 @@ ipcp_transform_function (struct cgraph_node *node)

     if (!gimple_assign_load_p (stmt))

       continue;

     rhs = gimple_assign_rhs1 (stmt);

+    lhs = gimple_assign_lhs (stmt);

     if (!is_gimple_reg_type (TREE_TYPE (rhs)))

       continue;



@@ -3924,7 +3925,8 @@ ipcp_transform_function (struct cgraph_node *node)

       continue;

     for (v = aggval; v; v = v->next)

       if (v->index == index

-          && v->offset == offset)

+          && v->offset == offset

+              && TREE_TYPE (v->value) == TREE_TYPE (lhs))

         break;

     if (!v)

       continue;

Reply via email to