This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[tree-ssa] PATCH: disallow const-prop when types don't match
- From: Dale Johannesen <dalej at apple dot com>
- To: GCC Patches <gcc-patches at gcc dot gnu dot org>
- Cc: Dale Johannesen <dalej at apple dot com>
- Date: Mon, 19 Jan 2004 16:48:53 -0800
- Subject: [tree-ssa] PATCH: disallow const-prop when types don't match
This revises my previous patch
http://gcc.gnu.org/ml/gcc-patches/2004-01/msg00597.html
based on Jeff Law's comments. Bootstrapped and tested on Darwin.
2004-01-19 Dale Johannesen <dalej@apple.com>
* tree-ssa-dom.c (cprop_into_stmt): Add convert() call
to prevent type mismatches.
Index: tree-ssa-dom.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-ssa-dom.c,v
retrieving revision 1.1.2.114
diff -u -d -b -w -c -3 -p -r1.1.2.114 tree-ssa-dom.c
cvs server: conflicting specifications of output style
*** tree-ssa-dom.c 16 Jan 2004 06:09:23 -0000 1.1.2.114
--- tree-ssa-dom.c 20 Jan 2004 00:48:38 -0000
*************** cprop_into_stmt (tree stmt)
*** 1948,1953 ****
--- 1948,1966 ----
|| TREE_CODE (val) != SSA_NAME))
continue;
+ /* Make sure basic types match. We cannot substitute a
+ boolean for an int for example, fold() doesn't
+ handle this as we would like. But don't create
+ non-gimple trees; if we would, just skip it. */
+ if (TREE_TYPE (*op_p) != TREE_TYPE (val)
+ && TREE_CODE (val) != SSA_NAME)
+ {
+ val = convert (TREE_TYPE (*op_p), val);
+ if (!is_gimple_min_invariant (val) &&
+ TREE_CODE (val) != SSA_NAME)
+ continue;
+ }
+
/* Certain operands are not allowed to be copy propagated
due
to their interaction with exception handling and some
GCC extensions. */
=====Testcase:
/* Test that (p!=0) + (q!=0) is computed as int,
not boolean */
/* { dg-options "-O3 } */
/* { dg-do run } */
char *foo(char *p, char *q) {
int x = (p !=0) + (q != 0);
if (x==2) return "a"; else return 0;
}
extern char *bar(char*, char*) __attribute__((noinline));
char *bar(char *first, char *last)
{
int y;
if (!first) return last;
if (!last) return first;
if (*first == 'a')
return foo(first, last);
return 0;
}
main() {
char *p = "a", *q = "b";
if (p)
if (bar(p,q))
return 0;
abort();
}