This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] PR41661, fold compare in IPCP
- From: Chung-Lin Tang <cltang at pllab dot cs dot nthu dot edu dot tw>
- To: gcc-patches at gcc dot gnu dot org
- Date: Sun, 11 Oct 2009 22:51:25 +0800
- Subject: [PATCH] PR41661, fold compare in IPCP
Hi,
this seems to be caused by using the type of the constant operand for
folding the binary expression in ipcp_lattice_from_jfunc(), while it
should actually pass the type of the whole expression. In this case for
example, for a compare expression of two doubles, a 'double' type is
passed instead of 'int'.
The correct type to pass should be the type of the whole argument at the
call-site when computing the jump function, so a 'type' field was added
to struct ipa_pass_through_data to record this.
Here's my proposed fix. The testcase is further simplified from the one
on bugzilla.
C.L.
gcc/
2009-10-11 Chung-Lin Tang <cltang@pllab.cs.nthu.edu.tw>
PR tree-optimization/41661
* ipa-prop.h (struct ipa_pass_through_data): Add 'tree type' field.
* ipa-prop.c (compute_complex_pass_through): Record type of call arg.
(compute_scalar_jump_functions): Same.
(compute_pass_through_member_ptrs): Same.
* ipa-cp.c (ipcp_lattice_from_jfunc): Change to pass saved arg type
to fold_binary().
gcc/testsuite/
2009-10-11 Chung-Lin Tang <cltang@pllab.cs.nthu.edu.tw>
PR tree-optimization/41661
* gcc.dg/pr41661.c: New test.
diff -Nru --exclude='*.svn*' trunk.orig/gcc/gcc/ipa-cp.c trunk/gcc/gcc/ipa-cp.c
--- trunk.orig/gcc/gcc/ipa-cp.c 2009-10-08 00:24:02.975897120 +0800
+++ trunk/gcc/gcc/ipa-cp.c 2009-10-11 20:32:33.914896553 +0800
@@ -300,7 +300,7 @@
if (jfunc->value.pass_through.operation != NOP_EXPR)
cst = fold_binary (jfunc->value.pass_through.operation,
- TREE_TYPE (cst), cst,
+ jfunc->value.pass_through.type, cst,
jfunc->value.pass_through.operand);
if (!cst || !is_gimple_ip_invariant (cst))
lat->type = IPA_BOTTOM;
diff -Nru --exclude='*.svn*' trunk.orig/gcc/gcc/ipa-prop.c trunk/gcc/gcc/ipa-prop.c
--- trunk.orig/gcc/gcc/ipa-prop.c 2009-10-11 21:01:09.912896320 +0800
+++ trunk/gcc/gcc/ipa-prop.c 2009-10-11 22:16:51.242896325 +0800
@@ -367,6 +367,7 @@
jfunc->value.pass_through.formal_id = index;
jfunc->value.pass_through.operation = gimple_assign_rhs_code (stmt);
jfunc->value.pass_through.operand = op2;
+ jfunc->value.pass_through.type = TREE_TYPE (name);
}
return;
}
@@ -432,6 +433,7 @@
functions[num].type = IPA_JF_PASS_THROUGH;
functions[num].value.pass_through.formal_id = index;
functions[num].value.pass_through.operation = NOP_EXPR;
+ functions[num].value.pass_through.type = TREE_TYPE (arg);
}
}
else
@@ -504,6 +506,7 @@
functions[num].type = IPA_JF_PASS_THROUGH;
functions[num].value.pass_through.formal_id = index;
functions[num].value.pass_through.operation = NOP_EXPR;
+ functions[num].value.pass_through.type = TREE_TYPE (arg);
}
else
undecided_members = true;
diff -Nru --exclude='*.svn*' trunk.orig/gcc/gcc/ipa-prop.h trunk/gcc/gcc/ipa-prop.h
--- trunk.orig/gcc/gcc/ipa-prop.h 2009-10-08 00:24:04.467896674 +0800
+++ trunk/gcc/gcc/ipa-prop.h 2009-10-11 20:48:50.993896286 +0800
@@ -84,6 +84,8 @@
arithmetic operation where the caller's parameter is the first operand and
operand field from this structure is the second one. */
enum tree_code operation;
+ /* Tree type of the whole passed expression. */
+ tree type;
};
/* Structure holding data required to describe and ancestor pass throu
diff -Nru --exclude='*.svn*' trunk.orig/gcc/gcc/testsuite/gcc.dg/pr41661.c trunk/gcc/gcc/testsuite/gcc.dg/pr41661.c
--- trunk.orig/gcc/gcc/testsuite/gcc.dg/pr41661.c 1970-01-01 08:00:00.000000000 +0800
+++ trunk/gcc/gcc/testsuite/gcc.dg/pr41661.c 2009-10-11 22:22:23.268896320 +0800
@@ -0,0 +1,20 @@
+/* PR tree-optimization/41661 */
+/* { dg-do compile } */
+/* { dg-options "-O1 -fipa-cp -fipa-cp-clone" } */
+
+int g;
+
+void foo (int x)
+{
+ g = x;
+}
+
+void bar (double d)
+{
+ foo (d == 1);
+}
+
+void baz (int a)
+{
+ bar (1);
+}