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: [email protected]
ReportedBy: [email protected]
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;