diff options
Diffstat (limited to 'gcc/testsuite/gcc.dg/tree-ssa')
111 files changed, 3732 insertions, 0 deletions
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20030530-2.c b/gcc/testsuite/gcc.dg/tree-ssa/20030530-2.c new file mode 100644 index 00000000000..408e2464e96 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/20030530-2.c @@ -0,0 +1,26 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -fdump-tree-dom3" } */ + + +typedef struct rs6000_stack { + int first_gp_reg_save; +} rs6000_stack_t; +extern char regs_ever_live[113]; +extern rs6000_stack_t *rs6000_stack_info (void); +void +rs6000_emit_prologue (int i, rs6000_stack_t *info) +{ + if (regs_ever_live[info->first_gp_reg_save + i] || i+info->first_gp_reg_save) + gen_rtx_REG (info->first_gp_reg_save + i); +} + +/* There should be precisely one load of first_gp_reg_save. If there is + more than one, then the dominator optimizations failed. */ +/* { dg-final { scan-tree-dump-times "first_gp_reg_save" 1 "dom3"} } */ + +/* There should be precisely one addition. If there is more than one, then + the dominator optimizations failed, most likely due to not handling + commutative operands correctly. */ +/* { dg-final { scan-tree-dump-times "\\+" 1 "dom3"} } */ + + diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20030611-1.c b/gcc/testsuite/gcc.dg/tree-ssa/20030611-1.c new file mode 100644 index 00000000000..d16bda4c1f1 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/20030611-1.c @@ -0,0 +1,13 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -fdump-tree-dom3" } */ + +extern int square (int) __attribute__ ((__const__)); +shit(int a) +{ + return square (a) + square (a); + +} + +/* There should be precisely one call to square. If there is more than one, + then the dominator optimizations failed to remove the redundant call. */ +/* { dg-final { scan-tree-dump-times "square" 1 "dom3"} } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20030703-1.c b/gcc/testsuite/gcc.dg/tree-ssa/20030703-1.c new file mode 100644 index 00000000000..f5b3db3460d --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/20030703-1.c @@ -0,0 +1,21 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -fdump-tree-dom3" } */ + + +extern int blah[]; + +foo(int index) +{ + if (blah [(unsigned int)index] != 0) + abort (); + if (blah [(unsigned int)index] != 0) + abort (); +} + +/* There should be precisely one load of blah. If there is + more than one, then the dominator optimizations failed. */ +/* { dg-final { scan-tree-dump-times "blah" 1 "dom3"} } */ + +/* There should be exactly one IF conditional. */ +/* { dg-final { scan-tree-dump-times "if " 1 "dom3"} } */ + diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20030703-2.c b/gcc/testsuite/gcc.dg/tree-ssa/20030703-2.c new file mode 100644 index 00000000000..a73150a06a3 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/20030703-2.c @@ -0,0 +1,41 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -fdump-tree-dom3" } */ + +union tree_node; +typedef union tree_node *tree; +extern const char tree_code_type[]; + +union tree_node +{ + int code; + long pointer_alias_set; +}; + +long +get_alias_set (t) + tree t; +{ + if (tree_code_type[t->code]) + abort (); + if (t->pointer_alias_set) + { + tree __t = t; + if (tree_code_type[__t->code]) + abort (); + } +} + +/* There should be precisely one load of {t,__t}->code. If there is + more than one, then the dominator optimizations failed. */ +/* { dg-final { scan-tree-dump-times "->code" 1 "dom3"} } */ + +/* There should be precisely one load of tree_code_type. If there is + more than one, then the dominator optimizations failed. */ +/* { dg-final { scan-tree-dump-times "tree_code_type" 1 "dom3"} } */ + +/* There should be one IF conditional. If 'tree_code_type[t->code]' is + zero, then the third if() conditional is unnecessary. That should cause + the call to abort() to be removed, which in turn causes the whole second + if() to disappear. */ +/* { dg-final { scan-tree-dump-times "if " 1 "dom3"} } */ + diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20030708-1.c b/gcc/testsuite/gcc.dg/tree-ssa/20030708-1.c new file mode 100644 index 00000000000..a94f2a7c6c9 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/20030708-1.c @@ -0,0 +1,41 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -fdump-tree-dom3" } */ +struct rtx_def; +typedef struct rtx_def *rtx; +enum rtx_code +{ + CALL_INSN, + EXPR_LIST, + NOTE +}; + +struct rtx_def +{ + + enum rtx_code code:16; +}; + +static int +nonlocal_mentioned_p (x) + rtx x; +{ + if (x->code == CALL_INSN) + { + rtx const _rtx = ((x)); + if (_rtx->code != CALL_INSN + && _rtx->code != NOTE + && _rtx->code != EXPR_LIST) + abort (); + } + + blah (&x); +} + +/* There should be no casts to a short unsigned int since the entire + set of conditionals should optimize away. */ +/* { dg-final { scan-tree-dump-times "\\(short unsigned int\\)" 0 "dom3"} } */ + +/* There should be no IF conditionals. */ +/* { dg-final { scan-tree-dump-times "if " 0 "dom3"} } */ + + diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20030709-1.c b/gcc/testsuite/gcc.dg/tree-ssa/20030709-1.c new file mode 100644 index 00000000000..dc45cbd73a2 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/20030709-1.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -fdump-tree-optimized" } */ + +static int copying_arguments; +static int +foo () +{ + unsigned int regno; + if (regno < 53 && copying_arguments) + if (regno >= 53) + return 1; +} + +/* There should be no IF conditionals. */ +/* { dg-final { scan-tree-dump-times "if " 0 "optimized"} } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20030709-2.c b/gcc/testsuite/gcc.dg/tree-ssa/20030709-2.c new file mode 100644 index 00000000000..ffa7f477622 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/20030709-2.c @@ -0,0 +1,53 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-cddce" } */ + +struct rtx_def; +typedef struct rtx_def *rtx; +union tree_node; +typedef union tree_node *tree; +typedef struct mem_attrs +{ + int foo; + +} mem_attrs; +union rtunion_def +{ + mem_attrs *rtmem; +}; +typedef union rtunion_def rtunion; +struct rtx_def +{ + rtunion fld[1]; +}; +struct tree_decl +{ + rtx rtl; +}; +union tree_node +{ + struct tree_decl decl; +}; +void * +get_alias_set (t) + tree t; +{ + long set; + if (t->decl.rtl) + return (t->decl.rtl->fld[1].rtmem + ? 0 + : (((t->decl.rtl ? t->decl.rtl: (make_decl_rtl (t, 0), t->decl.rtl)))->fld[1]).rtmem); + return (void*)-1; +} + +/* There should be precisely one load of ->decl.rtl. If there is + more than, then the dominator optimizations failed. */ +/* { dg-final { scan-tree-dump-times "->decl\\.rtl" 1 "cddce"} } */ + +/* There should be no loads of .rtmem since the complex return statement + is just "return 0". */ +/* { dg-final { scan-tree-dump-times ".rtmem" 0 "cddce"} } */ + +/* There should be one IF statement (the complex return statement should + collapse down to a simple return 0 without any conditionals). */ +/* { dg-final { scan-tree-dump-times "if " 1 "cddce"} } */ + diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20030709-3.c b/gcc/testsuite/gcc.dg/tree-ssa/20030709-3.c new file mode 100644 index 00000000000..98681c088c9 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/20030709-3.c @@ -0,0 +1,45 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -fdump-tree-dom3" } */ + + +union tree_node; +typedef union tree_node *tree; +enum tree_code +{ + TREE_VEC = 20, +}; +struct tree_common +{ + int code; +}; +struct tree_type +{ + tree binfo; +}; +union tree_node +{ + struct tree_common common; + struct tree_type type; +}; +void +record_component_aliases (type) + tree type; +{ + const tree __z = type->type.binfo; + if (type->type.binfo->common.code != TREE_VEC) + abort (); + + if (__z->common.code != TREE_VEC) + abort (); +} + +/* There should be precisely one load of type.binfo. If there is + more than one, then the dominator optimizations failed. */ +/* { dg-final { scan-tree-dump-times "type\\.binfo" 1 "dom3"} } */ + +/* There should be precisely one load of common.code. If there is + more than one, then the dominator optimizations failed. */ +/* { dg-final { scan-tree-dump-times "common\\.code" 1 "dom3"} } */ + +/* There should be one IF conditional. */ +/* { dg-final { scan-tree-dump-times "if " 1 "dom3"} } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20030710-1.c b/gcc/testsuite/gcc.dg/tree-ssa/20030710-1.c new file mode 100644 index 00000000000..53e3d5992cf --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/20030710-1.c @@ -0,0 +1,53 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -fdump-tree-dom3" } */ + +union tree_node; +typedef union tree_node *tree; +struct tree_vec +{ + int length; + tree a[1]; +}; +struct tree_type +{ + tree binfo; +}; +union tree_node +{ + struct tree_type type; + struct tree_vec vec; +}; +void +record_component_aliases (type) + tree type; +{ + if (type->type.binfo->vec.length) + abort (); + for (; (( + { + const tree __z = type->type.binfo; + if (type->type.binfo->vec.length) + abort (); + type->type.binfo->vec.a[4];} + )->vec.length);) + { + if (4 >= type->type.binfo->vec.length) + abort (); + blah (); + } +} + +/* The call to blah should have been eliminated. If the call is not + eliminated, then dominator optimizations failed and it'll be + impossible to delete other unnecessary code. */ +/* { dg-final { scan-tree-dump-not "blah \\(\\)" "dom3" } } */ + +/* There should be two IF conditionals. */ +/* { dg-final { scan-tree-dump-times "if " 2 "dom3"} } */ + +/* There should be a single load of type.binfo. */ +/* { dg-final { scan-tree-dump-times "type\\.binfo" 1 "dom3"} } */ + +/* There should be two loads of vec.length. */ +/* { dg-final { scan-tree-dump-times "vec.length" 2 "dom3"} } */ + diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20030711-1.c b/gcc/testsuite/gcc.dg/tree-ssa/20030711-1.c new file mode 100644 index 00000000000..eba207a25e5 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/20030711-1.c @@ -0,0 +1,53 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -fdump-tree-dom3" } */ + + +union tree_node; +typedef union tree_node *tree; +struct tree_vec +{ + int length; + tree a[1]; +}; +struct tree_type +{ + tree binfo; +}; +union tree_node +{ + struct tree_type type; + struct tree_vec vec; +}; + +void +record_component_aliases (type) + tree type; +{ + int i; + if (4 >= type->type.binfo->vec.length) + abort (); + for (; i < (( + { + const tree __t = type->type.binfo; + if (4 >= __t->vec.length) + abort (); type->type.binfo->vec.a[4];} + )->vec.length);) + { + if (4 >= type->type.binfo->vec.length) + abort (); + blah (); + } +} + +/* The call to blah can not be eliminated. */ +/* { dg-final { scan-tree-dump-times "blah \\(\\)" 1 "dom3" } } */ + +/* There should be four IF conditionals. */ +/* { dg-final { scan-tree-dump-times "if " 4 "dom3"} } */ + +/* There should be two loads of type.binfo. */ +/* { dg-final { scan-tree-dump-times "type\\.binfo" 2 "dom3"} } */ + +/* There should be four loads of vec.length. */ +/* { dg-final { scan-tree-dump-times "vec.length" 4 "dom3"} } */ + diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20030711-2.c b/gcc/testsuite/gcc.dg/tree-ssa/20030711-2.c new file mode 100644 index 00000000000..2fd47f753cf --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/20030711-2.c @@ -0,0 +1,67 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -fdump-tree-dom3" } */ + + +struct rtx_def; +typedef struct rtx_def *rtx; +struct rtvec_def; +typedef struct rtvec_def *rtvec; +union tree_node; +typedef union tree_node *tree; +typedef struct mem_attrs +{ + long alias; +} +mem_attrs; +union rtunion_def +{ + mem_attrs *rtmem; +}; +typedef union rtunion_def rtunion; +struct rtx_def +{ + int code; + rtunion fld[1]; +}; +struct tree_decl +{ + rtx rtl; +}; +union tree_node +{ + struct tree_decl decl; +}; +long +get_alias_set (t,z) + tree t; + rtx z; +{ + if (t->decl.rtl && (((t->decl.rtl ? z + : (make_decl_rtl (t, 0), t->decl.rtl)))->code)) + return (((((t->decl.rtl ? z : (make_decl_rtl (t, 0), t->decl.rtl)))-> + fld[1]).rtmem) == 0 ? 0 : ((((( + { + t;} + )->decl. + rtl ? z : (make_decl_rtl (t, 0), + t->decl.rtl)))-> + fld[1]).rtmem)->alias); +} + +/* The calls to make_decl_rtl should be eliminated +/* { dg-final { scan-tree-dump-not "make_decl_rtl \\(\\)" "dom3" } } */ + +/* There should be three IF conditionals. */ +/* { dg-final { scan-tree-dump-times "if " 3 "dom3"} } */ + +/* There should be one loads of decl.rtl. */ +/* { dg-final { scan-tree-dump-times "decl\\.rtl" 1 "dom3"} } */ + +/* There should be one load of code. */ +/* { dg-final { scan-tree-dump-times "code" 1 "dom3"} } */ + +/* There should be one load of rtmem. */ +/* { dg-final { scan-tree-dump-times "rtmem" 1 "dom3"} } */ + +/* There should be one load of alias. */ +/* { dg-final { scan-tree-dump-times "->alias" 1 "dom3"} } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20030711-3.c b/gcc/testsuite/gcc.dg/tree-ssa/20030711-3.c new file mode 100644 index 00000000000..515f3609f70 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/20030711-3.c @@ -0,0 +1,59 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -fdump-tree-dom3" } */ + + +struct rtx_def; +typedef struct rtx_def *rtx; +struct rtvec_def; +typedef struct rtvec_def *rtvec; +union tree_node; +typedef union tree_node *tree; +typedef struct mem_attrs +{ + long alias; +} +mem_attrs; +union rtunion_def +{ + mem_attrs *rtmem; +}; +typedef union rtunion_def rtunion; +struct rtx_def +{ + int code; + rtunion fld[1]; +}; +struct tree_decl +{ + rtx rtl; +}; +union tree_node +{ + struct tree_decl decl; +}; +long +get_alias_set (t) + tree t; +{ + if (t->decl.rtl != (void *) 0) + return (((t->decl.rtl->fld[1]).rtmem) == + 0 ? 0 + : ((((t->decl. + rtl ? 0 : (make_decl_rtl (t, ((void *) 0)), + t->decl.rtl)))->fld[1]).rtmem)->alias); +} + +/* The calls to make_decl_rtl should be eliminated. */ +/* { dg-final { scan-tree-dump-not "make_decl_rtl \\(\\)" "dom3" } } */ + +/* There should be two IF conditionals. */ +/* { dg-final { scan-tree-dump-times "if " 2 "dom3"} } */ + +/* There should be one load of decl.rtl. */ +/* { dg-final { scan-tree-dump-times "decl\\.rtl" 1 "dom3"} } */ + +/* There should be two loads of rtmem. */ +/* { dg-final { scan-tree-dump-times "rtmem" 2 "dom3"} } */ + +/* There should be one load of alias. */ +/* { dg-final { scan-tree-dump-times "->alias" 1 "dom3"} } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20030714-1.c b/gcc/testsuite/gcc.dg/tree-ssa/20030714-1.c new file mode 100644 index 00000000000..936df5371c4 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/20030714-1.c @@ -0,0 +1,44 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -fdump-tree-dom3" } */ + +struct rtx_def; +typedef struct rtx_def *rtx; +enum rtx_code +{ + REG, + LAST_AND_UNUSED_RTX_CODE +}; +typedef union rtunion_def rtunion; +struct rtx_def +{ + enum rtx_code code:16; + unsigned frame_related:1; +}; +static rtx +find_base_value (src) + rtx src; +{ + rtx temp; + rtx src_0; + rtx src_1; + + if ((src_0->code == REG) && (({src_0;})->frame_related)) + return find_base_value (src_0); + if ((src_1->code == REG) && (({ src_1;})->frame_related)) + return find_base_value (src_1); + if (src_0->code == REG) + find_base_value (src_0); + if (src_1->code == REG) + find_base_value (src_1); +} + + +/* There should be six IF conditionals. */ +/* { dg-final { scan-tree-dump-times "if " 6 "dom3"} } */ + +/* There should be no casts to short unsigned int. */ +/* { dg-final { scan-tree-dump-times "\\(short unsigned int\\)" 0 "dom3"} } */ + +/* There should be three loads of ->code. */ +/* { dg-final { scan-tree-dump-times "->code" 3 "dom3"} } */ + diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20030714-2.c b/gcc/testsuite/gcc.dg/tree-ssa/20030714-2.c new file mode 100644 index 00000000000..6a43360b07f --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/20030714-2.c @@ -0,0 +1,39 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -fdump-tree-dom3" } */ + + +union tree_node; +typedef union tree_node *tree; +extern const char tree_code_type[]; +struct tree_common +{ + int code; + tree type; +}; +struct tree_exp +{ + tree operands[1]; +}; +union tree_node +{ + struct tree_common common; + struct tree_exp exp; +}; +long +get_alias_set (t) + tree t; +{ + if (tree_code_type[t->common.code] != 't' && t->common.type == 0) + return 0; + if (tree_code_type[t->common.code] != 't') + { + while (t->exp.operands[0]) + t = t->exp.operands[0]; + } +} + +/* There should be exactly four IF conditionals if we thread jumps + properly. */ +/* { dg-final { scan-tree-dump-times "if " 4 "dom3"} } */ + + diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20030728-1.c b/gcc/testsuite/gcc.dg/tree-ssa/20030728-1.c new file mode 100644 index 00000000000..4bc04bc4da4 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/20030728-1.c @@ -0,0 +1,47 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ + + +union tree_node; +typedef union tree_node *tree; + +enum tree_code +{ + ARRAY_TYPE, + LAST_AND_UNUSED_TREE_CODE +}; + +struct tree_common +{ + enum tree_code code:8; +}; + + + + + +union tree_node +{ + struct tree_common common; +}; + + + + +int +objects_must_conflict_p (t1, t2) + tree t1, t2; +{ + + if ((t1->common.code == ARRAY_TYPE) != (t2 + && t2->common.code == ARRAY_TYPE)) + return 0; + + + return foo (t2 ? get_alias_set (t2) : 0); +} + +/* There should be three assignments of variables to the value zero. */ +/* { dg-final { scan-tree-dump-times " = 0" 3 "optimized"} } */ + + diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20030729-1.c b/gcc/testsuite/gcc.dg/tree-ssa/20030729-1.c new file mode 100644 index 00000000000..b4b1a819ff4 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/20030729-1.c @@ -0,0 +1,51 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -fdump-tree-dom3" } */ + +union tree_node; +typedef union tree_node *tree; + + +enum tree_code +{ + SET_TYPE, + RECORD_TYPE, + LAST_AND_UNUSED_TREE_CODE +}; +extern const char tree_code_type[]; + +struct tree_common +{ + + enum tree_code code:8; +}; + + + + + +union tree_node +{ + struct tree_common common; +}; + +readonly_fields_p (type) + tree type; +{ + + if (type->common.code != RECORD_TYPE) + return; + + if (tree_code_type[type->common.code] != 't') + abort (); + + return; +} + +/* A good optimizer would realize that the cast to (unsigned int) is + useless as the earlier cast of the same value of (unsigned char) will + always produce the same result. */ +/* { dg-final { scan-tree-dump-times "\\(unsigned int\\)" 0 "dom3"} } */ + +/* There should be one load of ->common.code. We currently fail this + because we load from ->common.code using different types. */ +/* { dg-final { scan-tree-dump-times "common\.code" 1 "dom3"} } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20030730-1.c b/gcc/testsuite/gcc.dg/tree-ssa/20030730-1.c new file mode 100644 index 00000000000..643b5e79271 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/20030730-1.c @@ -0,0 +1,23 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-dom3" } */ + +extern void *ggc_alloc (__SIZE_TYPE__); +typedef struct dw_attr_struct *dw_attr_ref; +typedef struct dw_attr_struct +{ + int dw_attr; +} +dw_attr_node; +void +foo (int attr_kind, unsigned long offset) +{ + dw_attr_ref attr = (dw_attr_ref) ggc_alloc (sizeof (dw_attr_node)); + attr->dw_attr = attr_kind; + if (attr != 0) + exit (0); +} + +/* There should be no IF conditionals. */ +/* { dg-final { scan-tree-dump-times "if " 0 "dom3"} } */ + + diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20030730-2.c b/gcc/testsuite/gcc.dg/tree-ssa/20030730-2.c new file mode 100644 index 00000000000..06b5710f65f --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/20030730-2.c @@ -0,0 +1,22 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-dom3" } */ + +extern void *ggc_alloc (__SIZE_TYPE__); +typedef struct dw_attr_struct *dw_attr_ref; +typedef struct dw_attr_struct +{ + int dw_attr; +} +dw_attr_node; +void +foo (int attr_kind, unsigned long offset) +{ + dw_attr_ref attr = (dw_attr_ref) ggc_alloc (sizeof (dw_attr_node)); + attr->dw_attr = attr_kind; + if (attr != ((void *)0)) + exit (0); +} + +/* There should be no IF conditionals. */ +/* { dg-final { scan-tree-dump-times "if " 0 "dom3"} } */ + diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20030731-1.c b/gcc/testsuite/gcc.dg/tree-ssa/20030731-1.c new file mode 100644 index 00000000000..82634da1c5b --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/20030731-1.c @@ -0,0 +1,65 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -fdump-tree-dom3" } */ + + +struct rtx_def; +typedef struct rtx_def *rtx; +struct rtvec_def; +typedef struct rtvec_def *rtvec; +union tree_node; +typedef union tree_node *tree; +struct rtx_def +{ + int code; + int mode; + unsigned int in_struct:1; +}; +struct tree_common +{ + int code; +}; +struct tree_decl +{ + rtx rtl; +}; +union tree_node +{ + struct tree_common common; + struct tree_decl decl; +}; +rtx +store_expr (exp, target, want_value) + tree exp; + rtx target; + int want_value; +{ + if (exp->common.code == 42) + abort (); + else if (queued_subexp_p (target)) + { + blah (target->mode); + if (target->code) + abort (); + } + else + { + if (target->code && (__extension__({target;})->in_struct)); + } + + if ((target != (exp->decl.rtl + ? (exp->decl.rtl + ? exp->decl.rtl + : (make_decl_rtl (exp, 0), exp->decl.rtl)) + : 0)) + && expr_size (exp)) + ; +} + +/* All paths to the test "target != 0" occuring in the final IF statement + dereference target. Thus target can not have the value zero at that + point and the test should have been eliminated. */ +/* ??? The dominator walker (A) doesn't merge this data at joins and + (B) only looks at immediate dominators, and only queued_subexp_p + immediately dominates the comparison in question. We need something + stronger. */ +/* { dg-final { scan-tree-dump-times "target.*!= 0" 0 "dom3" { xfail *-*-* } } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20030731-2.c b/gcc/testsuite/gcc.dg/tree-ssa/20030731-2.c new file mode 100644 index 00000000000..b088f007447 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/20030731-2.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -fdump-tree-ccp" } */ + + +bar (int i, int partial, int args_addr) +{ + int offset = 0; + if (args_addr == 0) + offset = 0; + if (i >= offset) + foo (); +} + +/* There should be only one IF conditional since the first does nothing + useful. */ +/* { dg-final { scan-tree-dump-times "if " 1 "ccp"} } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20030807-1.c b/gcc/testsuite/gcc.dg/tree-ssa/20030807-1.c new file mode 100644 index 00000000000..ab013d3d9fc --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/20030807-1.c @@ -0,0 +1,46 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -fdump-tree-dom3" } */ + +struct rtx_def; +typedef struct rtx_def *rtx; + + + +union rtunion_def +{ + int rtint; +}; +typedef union rtunion_def rtunion; + + + +struct rtx_def +{ + rtunion fld[1]; + +}; + +static int *uid_cuid; +static int max_uid_cuid; + +static rtx +bar (rtx r) +{ + rtx place = r; + + if (place->fld[0].rtint <= max_uid_cuid + && (place->fld[0].rtint > max_uid_cuid ? insn_cuid (place) : + uid_cuid[place->fld[0].rtint])) + return r; + + return 0; +} + +/* There should be two IF conditionals. One tests <= max_uid_cuid, the + other tets the value in uid_cuid. If either is false the jumps + are threaded to the return 0. Which in turn means the path + which combines the result of those two tests into a new test + must always be true and it is optimized appropriately. */ +/* { dg-final { scan-tree-dump-times "if " 2 "dom3"} } */ + + diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20030807-10.c b/gcc/testsuite/gcc.dg/tree-ssa/20030807-10.c new file mode 100644 index 00000000000..709395511a4 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/20030807-10.c @@ -0,0 +1,25 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -fdump-tree-dom3" } */ + + +extern const unsigned char mode_size[]; +unsigned int +subreg_highpart_offset (outermode, innermode) + int outermode, innermode; +{ + unsigned int offset = 0; + int difference = (mode_size[innermode] - mode_size[outermode]); + if (difference > 0) + { + offset += difference % (0 ? 8 : 4); + offset += difference / 4 * 4; + } + return offset; +} + +/* There should be one mask with the value 3. */ +/* { dg-final { scan-tree-dump-times " \& 3" 1 "dom3"} } */ + +/* There should be one right shift by 2 places. */ +/* { dg-final { scan-tree-dump-times " >> 2" 1 "dom3"} } */ + diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20030807-11.c b/gcc/testsuite/gcc.dg/tree-ssa/20030807-11.c new file mode 100644 index 00000000000..6296346095d --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/20030807-11.c @@ -0,0 +1,19 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -fdump-tree-dom3" } */ + +struct rtx_def; +typedef struct rtx_def *rtx; +struct rtx_def +{ + int code; +}; +foo (reg) + rtx reg; +{ + reg->code = 42; + if (reg->code != 42) + abort (); +} + +/* There should be no IF conditionals. */ +/* { dg-final { scan-tree-dump-times "if " 0 "dom3"} } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20030807-2.c b/gcc/testsuite/gcc.dg/tree-ssa/20030807-2.c new file mode 100644 index 00000000000..e9837d38814 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/20030807-2.c @@ -0,0 +1,26 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -fdump-tree-dom3" } */ + + +oof () +{ + int live_head; + int * live = &live_head; + + if (live) + bitmap_clear (live); +} + +foo(int n) +{ + int *space = (int *)__builtin_alloca (n); + + if (space == 0) + abort (); + else + bar (space); +} + + +/* There should be no IF conditionals. */ +/* { dg-final { scan-tree-dump-times "if " 0 "dom3"} } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20030807-3.c b/gcc/testsuite/gcc.dg/tree-ssa/20030807-3.c new file mode 100644 index 00000000000..7e10d382c4e --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/20030807-3.c @@ -0,0 +1,27 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -fdump-tree-dom3" } */ + +typedef unsigned int cppchar_t; +cppchar_t +cpp_parse_escape (pstr, limit, wide) + const unsigned char **pstr; + const unsigned char *limit; + int wide; +{ + cppchar_t i = 0; + int overflow = 0; + cppchar_t mask = ~0; + + while (*pstr < limit) + { + overflow |= i ^ (i << 4 >> 4); + i = oof (); + } + if (overflow | (i != (i & mask))) + foo(); +} + +/* There should be precisely three IF statements. If there is + more than two, then the dominator optimizations failed. */ +/* { dg-final { scan-tree-dump-times "if " 3 "dom3"} } */ + diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20030807-5.c b/gcc/testsuite/gcc.dg/tree-ssa/20030807-5.c new file mode 100644 index 00000000000..b530c841a7f --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/20030807-5.c @@ -0,0 +1,36 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -fdump-tree-dom3" } */ + +struct rtx_def; +typedef struct rtx_def *rtx; + + +struct rtx_def +{ + + int code; + unsigned int unchanging:1; + +}; +static rtx current_sym_addr; + +static int +foo () +{ + if (current_sym_addr->code == 42 + && (({ + rtx _rtx = current_sym_addr; + if (((_rtx)->code) != 42) + abort (); + _rtx;} + )->unchanging)) + return 0; +} + +/* There should be precisely one load of ->code. If there is + more than, then the dominator optimizations failed. */ +/* { dg-final { scan-tree-dump-times "->code" 1 "dom3"} } */ + +/* There should be two IF statements. One for 'current_sym_addr->code == 42'. + The other one for '(EXPR)->unchanging'. */ +/* { dg-final { scan-tree-dump-times "if " 2 "dom3"} } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20030807-6.c b/gcc/testsuite/gcc.dg/tree-ssa/20030807-6.c new file mode 100644 index 00000000000..3b24bcaf662 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/20030807-6.c @@ -0,0 +1,44 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -fdump-tree-dom3" } */ + + +static void +foo (distance, i, j) + int distance[13][13]; + int i, j; +{ + if (distance[i][j] < 0) + distance[i][0] = ((distance[i][j]) < 0 ? -(distance[i][j]) : (distance[i][j])); +} + +static void +foo2 (distance, i, j) + int distance[13][13]; + int i, j; +{ + if (distance[i][j] <= 0) + distance[i][0] = ((distance[i][j]) < 0 ? -(distance[i][j]) : (distance[i][j])); +} + +static void +foo3 (distance, i, j) + int distance[13][13]; + int i, j; +{ + if (distance[i][j] > 0) + distance[i][0] = ((distance[i][j]) < 0 ? -(distance[i][j]) : (distance[i][j])); +} + +static void +foo4 (distance, i, j) + double distance[13][13]; + int i, j; +{ + if (distance[i][j] >= 0) + distance[i][0] = ((distance[i][j]) < 0 ? -(distance[i][j]) : (distance[i][j])); +} + +/* There should be no ABS_EXPR. */ +/* { dg-final { scan-tree-dump-times "ABS_EXPR " 0 "dom3"} } */ + + diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20030807-7.c b/gcc/testsuite/gcc.dg/tree-ssa/20030807-7.c new file mode 100644 index 00000000000..7f31578307a --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/20030807-7.c @@ -0,0 +1,37 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-dom3" } */ + + + +union tree_node; +typedef union tree_node *tree; +struct tree_common +{ + int code; +}; +struct tree_list +{ + tree purpose; +}; +union tree_node +{ + struct tree_common common; + struct tree_list list; +}; +void +simplify_condition (cond_p) + tree *cond_p; +{ + tree decl; + tree cond = *cond_p; + if (cond->common.code != 42) + abort (); + decl = cond->list.purpose; + if (cond->common.code != 42) + abort (); + c_simplify_stmt (&decl); +} + +/* There should be exactly one IF conditional. TBAA is not able to + determine that 'decl' and 'cond' can't alias. */ +/* { dg-final { scan-tree-dump-times "if " 1 "dom3"} } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20030807-8.c b/gcc/testsuite/gcc.dg/tree-ssa/20030807-8.c new file mode 100644 index 00000000000..1241f32a7f8 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/20030807-8.c @@ -0,0 +1,52 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -fdump-tree-dom3" } */ + +struct die_struct; +typedef struct die_struct *dw_die_ref; +typedef struct dw_loc_list_struct *dw_loc_list_ref; +enum dw_val_class +{ + dw_val_class_loc_list, +}; +typedef struct dw_val_struct +{ + enum dw_val_class val_class; + union dw_val_struct_union + { + dw_loc_list_ref val_loc_list; + } + v; +} +dw_val_node; +typedef struct dw_attr_struct *dw_attr_ref; +typedef struct dw_attr_struct +{ + dw_val_node dw_attr_val; +} +dw_attr_node; + +extern __inline__ enum dw_val_class +AT_class (a) + dw_attr_ref a; +{ + return a->dw_attr_val.val_class; +} +extern __inline__ dw_loc_list_ref +AT_loc_list (a) + dw_attr_ref a; +{ + if (AT_class (a) == dw_val_class_loc_list) + return a->dw_attr_val.v.val_loc_list; +} +static void +output_location_lists (die) + dw_die_ref die; +{ + dw_die_ref c; + dw_attr_ref d_attr; + if (AT_class (d_attr) == dw_val_class_loc_list) + output_loc_list (AT_loc_list (d_attr)); +} + +/* There should be exactly one IF conditional, in output_location_lists. */ +/* { dg-final { scan-tree-dump-times "if " 1 "dom3"} } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20030807-9.c b/gcc/testsuite/gcc.dg/tree-ssa/20030807-9.c new file mode 100644 index 00000000000..6144bd187ed --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/20030807-9.c @@ -0,0 +1,19 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -fdump-tree-dom3" } */ + +static void +bar () +{ + const char *label2 = (*"*.L_sfnames_b" == '*') + "*.L_sfnames_b"; + oof (label2); +} + +void +ooof () +{ + if (""[0] == 0) + foo(); +} + +/* There should be no IF conditionals. */ +/* { dg-final { scan-tree-dump-times "if " 0 "dom3"} } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20030808-1.c b/gcc/testsuite/gcc.dg/tree-ssa/20030808-1.c new file mode 100644 index 00000000000..9a20a3040c5 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/20030808-1.c @@ -0,0 +1,39 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -fdump-tree-cddce" } */ + + +struct rtx_def; +typedef struct rtx_def *rtx; +enum rtx_code +{ + UNKNOWN, + CODE_LABEL, + NOTE, + LAST_AND_UNUSED_RTX_CODE +}; +typedef union rtunion_def rtunion; +struct rtx_def +{ + enum rtx_code code:16; +}; +void +delete_dead_jumptables () +{ + rtx insn, next; + if (insn->code == CODE_LABEL) + { + rtx const _rtx = insn; + if (_rtx->code != CODE_LABEL && _rtx->code != NOTE) + abort (); + } + ; +} + +/* There should be no loads of ->code. If any exist, then we failed to + optimize away all the IF statements and the statements feeding + their conditions. */ +/* { dg-final { scan-tree-dump-times "->code" 0 "cddce"} } */ + +/* There should be no IF statements. */ +/* { dg-final { scan-tree-dump-times "if " 0 "cddce"} } */ + diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20030814-1.c b/gcc/testsuite/gcc.dg/tree-ssa/20030814-1.c new file mode 100644 index 00000000000..d165b19bfda --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/20030814-1.c @@ -0,0 +1,20 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -fdump-tree-dom3" } */ + + +com(int *blah) +{ + int z = *blah; + if (z == 256) + { + oof (z); + abort (); + } + return *blah; +} + +/* There should be precisely one load of blah. If there is + more than one, then the dominator optimizations failed. */ +/* { dg-final { scan-tree-dump-times "\\*blah" 1 "dom3"} } */ + + diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20030814-2.c b/gcc/testsuite/gcc.dg/tree-ssa/20030814-2.c new file mode 100644 index 00000000000..a3f2ae6b70b --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/20030814-2.c @@ -0,0 +1,21 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -fdump-tree-dom3" } */ + + +void +foo (int value) +{ + switch (value) + { + case 42: + if (value != 42) + abort (); + case 50: + blah (); + } +} + +/* There should be no IF conditionals. */ +/* { dg-final { scan-tree-dump-times "if " 0 "dom3"} } */ + + diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20030814-3.c b/gcc/testsuite/gcc.dg/tree-ssa/20030814-3.c new file mode 100644 index 00000000000..2058c0c987a --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/20030814-3.c @@ -0,0 +1,22 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -fdump-tree-dom3" } */ + + +void +foo (int value) +{ + switch (value) + { + case 40: + case 42: + if (value != 42) + abort (); + case 50: + blah (); + } +} + +/* There should be one IF conditional. */ +/* { dg-final { scan-tree-dump-times "if " 1 "dom3"} } */ + + diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20030814-4.c b/gcc/testsuite/gcc.dg/tree-ssa/20030814-4.c new file mode 100644 index 00000000000..81711dd75cd --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/20030814-4.c @@ -0,0 +1,40 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -fdump-tree-dom3 -fdump-tree-optimized" } */ + +union tree_node; +typedef union tree_node *tree; +extern const char tree_code_type[]; +struct tree_common +{ + int code; +}; +struct tree_decl +{ + long pointer_alias_set; +}; +union tree_node +{ + struct tree_common common; + struct tree_decl decl; +}; +long +blah (decl, set) + tree decl; + long set; +{ + decl->decl.pointer_alias_set = set; + if (tree_code_type[decl->common.code] != 'd') + abort (); + record_alias_subset (decl->decl.pointer_alias_set); + if (set != -1) + set = 0; + return set; +} + +/* There should be precisely one reference to pointer_alias_set. If there is + more than one, then the dominator optimizations failed. */ +/* { dg-final { scan-tree-dump-times "pointer_alias_set" 1 "dom3"} } */ + +/* The assignment set = -1 in the ELSE clause of the last IF + statement should be removed by the final cleanup phase. */ +/* { dg-final { scan-tree-dump-times "set = -1" 0 "optimized"} } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20030814-5.c b/gcc/testsuite/gcc.dg/tree-ssa/20030814-5.c new file mode 100644 index 00000000000..bab21a3cae8 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/20030814-5.c @@ -0,0 +1,40 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -fdump-tree-dom3 -fdump-tree-optimized" } */ + +union tree_node; +typedef union tree_node *tree; +extern const char tree_code_type[]; +struct tree_common +{ + int code; +}; +struct tree_decl +{ + long pointer_alias_set; +}; +union tree_node +{ + struct tree_common common; + struct tree_decl decl; +}; +long +blah (decl, set) + tree decl; + long set; +{ + decl->decl.pointer_alias_set = oof(); + if (tree_code_type[decl->common.code] != 'd') + abort (); + record_alias_subset (decl->decl.pointer_alias_set); + if (set != -1) + set = 0; + return set; +} + +/* There should be precisely one reference to pointer_alias_set. If there is + more than one, then the dominator optimizations failed. */ +/* { dg-final { scan-tree-dump-times "pointer_alias_set" 1 "dom3"} } */ + +/* The assignment set = -1 in the ELSE clause of the last IF + statement should be removed by the final cleanup phase. */ +/* { dg-final { scan-tree-dump-times "set = -1" 0 "optimized"} } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20030814-6.c b/gcc/testsuite/gcc.dg/tree-ssa/20030814-6.c new file mode 100644 index 00000000000..c16fda9155c --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/20030814-6.c @@ -0,0 +1,43 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -fdump-tree-dom3" } */ + +union tree_node; +typedef union tree_node *tree; +enum tree_code +{ + LAST_AND_UNUSED_TREE_CODE +}; +extern const char tree_code_type[]; +struct tree_common +{ + enum tree_code code:8; +}; +struct tree_type +{ + double alias_set; +}; +union tree_node +{ + struct tree_common common; + struct tree_type type; +}; +long +foo (t, set) + tree t; + double set; +{ + if (tree_code_type[t->common.code] != 't') + abort (); + + t->type.alias_set = set; + + if (t->common.code == 42) + return 1; + else + return 0; +} +/* There should be precisely one load of common.code. If there is + more than one, then the dominator optimizations failed. */ +/* ??? Will fail until we properly distinguish member stores. At + present the write to type.alias_set kills the previous load. */ +/* { dg-final { scan-tree-dump-times "common.code" 1 "dom3" { xfail *-*-* } } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20030814-7.c b/gcc/testsuite/gcc.dg/tree-ssa/20030814-7.c new file mode 100644 index 00000000000..cbefbb33c1a --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/20030814-7.c @@ -0,0 +1,40 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -fdump-tree-dom3" } */ + +struct rtx_def; +typedef struct rtx_def *rtx; +struct rtvec_def; +typedef struct rtvec_def *rtvec; +union tree_node; +typedef union tree_node *tree; +struct tree_common +{ + int code; +}; +union tree_node +{ + struct tree_common common; +}; +extern tree current_function_decl; +struct cgraph_rtl_info +{ + _Bool pure_function; +}; +struct cgraph_rtl_info *cgraph_rtl_info (tree); +void +mark_constant_function (void) +{ + rtx insn; + int nonlocal_memory_referenced; + + if (current_function_decl->common.code != 42) + abort (); + + cgraph_rtl_info (current_function_decl)->pure_function = 1; +} + +/* current_function_decl should be loaded once into a temporary + and the temporary used as the argument to cgraph_rtl_info. + This if we find current_function_decl used as an argument, then + we have failed. */ +/* { dg-final { scan-tree-dump-times "\\(current_function_decl\\)" 0 "dom3"} } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20030815-1.c b/gcc/testsuite/gcc.dg/tree-ssa/20030815-1.c new file mode 100644 index 00000000000..13a4917e912 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/20030815-1.c @@ -0,0 +1,42 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -fdump-tree-dom3" } */ + +typedef unsigned int size_t; +struct rtx_def; +typedef struct rtx_def *rtx; +typedef union varray_data_tag +{ + struct reg_info_def *reg[1]; +} varray_data; +struct varray_head_tag +{ + size_t num_elements; + varray_data data; +}; +typedef struct varray_head_tag *varray_type; +typedef struct reg_info_def +{ +} reg_info; +extern varray_type reg_n_info; +static rtx *reg_base_value; +static rtx *new_reg_base_value; +static rtx +blah (unsigned int regno) +{ + if (new_reg_base_value[regno] && ((*( + { + if (regno >= + reg_n_info-> + num_elements) + abort (); + ®_n_info->data.reg[regno];} + )))) + return reg_base_value[regno]; +} + +/* If we have more than 1 cast to a struct rtx_def * *, then we failed to + eliminate some useless typecasting. The first type cast is needed + to convert the unsigned int regno parameter into a struct rtx_def **. */ +/* { dg-final { scan-tree-dump-times "\\(struct rtx_def \\* \\*\\)" 1 "dom3"} } */ + + diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20030820-1.c b/gcc/testsuite/gcc.dg/tree-ssa/20030820-1.c new file mode 100644 index 00000000000..4b659ca3411 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/20030820-1.c @@ -0,0 +1,24 @@ +/* { dg-do compile } */ +/* { dg-options "-O1" } */ + +/* A test for unreachable blocks removal -- bind_expr whose entry is + unreachable, but it contains reachable statements. */ + +void foo(void) +{ + if (1) + { + goto bla; + } + else + { +xxx: + { +bla: + bar (); + return; + } + goto xxx; + } +} + diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20030820-2.c b/gcc/testsuite/gcc.dg/tree-ssa/20030820-2.c new file mode 100644 index 00000000000..9ca9fbb59c6 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/20030820-2.c @@ -0,0 +1,24 @@ +/* { dg-do compile } */ +/* { dg-options "-O1" } */ + +/* A test for variables getting out of their scope in copy propagation. */ + +void foo(void) +{ + int k; + + goto forward; +back: + bla (k); + return; + +forward: + { + int i = bar (); + + k = i; + + goto back; + } +} + diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20030821-1.c b/gcc/testsuite/gcc.dg/tree-ssa/20030821-1.c new file mode 100644 index 00000000000..2d1e9e78df2 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/20030821-1.c @@ -0,0 +1,23 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -fdump-tree-optimized" } */ + +void foo(int k) +{ + int i = 1; + void *label; + + label = k ? &&x : &&y; + + if (k == 1) + goto *label; + + i = 0; + goto z; +z: +x: + if (i) + dont_remove (); +y: ; +} + +/* { dg-final { scan-tree-dump-times "dont_remove \\(\\)" 1 "optimized"} } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20030824-1.c b/gcc/testsuite/gcc.dg/tree-ssa/20030824-1.c new file mode 100644 index 00000000000..328d33d1243 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/20030824-1.c @@ -0,0 +1,22 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -fdump-tree-optimized" } */ + +struct A +{ + int a,b; +}; + +int foo (int x, int y) +{ + int i, j; + struct A a,b; + + a.a = x; + b.b = y; + j = a.a; + i = b.b; + return i + j; +} + +/* The addition should be optimized into 'y+x'. */ +/* { dg-final { scan-tree-dump-times "y \\+ x" 1 "optimized"} } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20030824-2.c b/gcc/testsuite/gcc.dg/tree-ssa/20030824-2.c new file mode 100644 index 00000000000..5ed66d094a0 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/20030824-2.c @@ -0,0 +1,22 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -fdump-tree-optimized" } */ + +struct A +{ + int a,b; +}; + +int foo (int x, int y) +{ + int i, j; + struct A a; + + a.a = x; + a.b = y; + j = a.a; + i = a.b; + return i + j; +} + +/* This function should be optimized into 'return y+x'. */ +/* { dg-final { scan-tree-dump-times "return y \\+ x" 1 "optimized"} } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20030825-1.c b/gcc/testsuite/gcc.dg/tree-ssa/20030825-1.c new file mode 100644 index 00000000000..440f75571d4 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/20030825-1.c @@ -0,0 +1,28 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -fdump-tree-optimized" } */ + +void bla(void); + +void +foo(int c, int d) +{ + goto skip; + +ebef: + goto xxx; + +skip: + + if (c) + { +xxx:; + if (!c) + bla (); + } + + if (d) + goto ebef; +} + +/* Bla should not be optimized away. */ +/* { dg-final { scan-tree-dump-times "bla" 1 "optimized"} } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20030907-1.c b/gcc/testsuite/gcc.dg/tree-ssa/20030907-1.c new file mode 100644 index 00000000000..3bc5557cf00 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/20030907-1.c @@ -0,0 +1,26 @@ +/* PR optimization/12198 + + This was a miscompilation of a switch expressions because + the "Case Ranges" extension wasn't handled in tree-cfg.c. */ + +/* { dg-do compile } */ +/* { dg-options "-O -fdump-tree-optimized" } */ + +int main() +{ + int i; + i = 2; + switch (i) + { + case 1 ... 5: + goto L1; + default: + abort (); + goto L1; + } + L1: + exit(0); +} + +/* The abort() call clearly is unreachable. */ +/* { dg-final { scan-tree-dump-times "abort" 0 "optimized"} } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20030907-2.c b/gcc/testsuite/gcc.dg/tree-ssa/20030907-2.c new file mode 100644 index 00000000000..47d60946e0c --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/20030907-2.c @@ -0,0 +1,30 @@ +/* PR optimization/12109 + + This would ICE in tree-ssa-dce.c:process_worklist() when + the function was expecting an SSA_NAME but found a VAR_DECL. */ + +/* { dg-do compile } */ +/* { dg-options "-O -ftree-dce" } */ + +void *do_it(void * dest, const void * src); +double *create_float(void); + +void parse_rvalue(void **DataPtr) +{ + double local = 0.0; + int terms = 1; + + *DataPtr = create_float(); + + switch (terms) + { + case 1: + *((double *)*DataPtr) = local; + break; + + case 2: + do_it(*DataPtr, &local); + break; + } +} + diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20030917-1.c b/gcc/testsuite/gcc.dg/tree-ssa/20030917-1.c new file mode 100644 index 00000000000..1b1441f0f9b --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/20030917-1.c @@ -0,0 +1,20 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -fdump-tree-ccp" } */ + + +extern int board[]; + +void +findbestextension (int blah, int blah2) +{ + int defval; + defval = def_val (board[blah2]); + if (blah) + defval = 0; + foo (defval); +} + +/* The argument to "foo" should be a variable, not a constant. */ +/* { dg-final { scan-tree-dump-times "foo .defval" 1 "ccp"} } */ + + diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20030917-2.c b/gcc/testsuite/gcc.dg/tree-ssa/20030917-2.c new file mode 100644 index 00000000000..2c08050c975 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/20030917-2.c @@ -0,0 +1,40 @@ +/* This test was causing an ICE in DCE because we were allowing void * + pointers to have a memory tag, which we were copying when doing copy + propagation. Since void * can never be de-referenced, its memory tag + was never renamed. */ + +/* { dg-do compile } */ +/* { dg-options "-O -ftree-dominator-opts" } */ + +typedef __SIZE_TYPE__ size_t; +typedef union tree_node *tree; +struct operands_d +{ + tree *def_op; +}; + +void +gt_ggc_mx_operands_d (void *x_p) +{ + struct operands_d *const x = (struct operands_d *) x_p; + if ((*x).def_op != ((void *) 0)) + { + size_t i0; + do + { + const void *const a__ = ((*x).def_op); + if (a__ != ((void *) 0) && a__ != (void *) 1) + ggc_set_mark (a__); + } + while (0); + for (i0 = 0; i0 < (size_t) (1); i0++) + { + do + { + if ((void *) (*x).def_op[i0] != ((void *) 0)) + gt_ggc_mx_lang_tree_node ((*x).def_op[i0]); + } + while (0); + } + } +} diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20030917-3.c b/gcc/testsuite/gcc.dg/tree-ssa/20030917-3.c new file mode 100644 index 00000000000..f7fabe5008c --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/20030917-3.c @@ -0,0 +1,24 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -fno-tree-dominator-opts -fdump-tree-ccp" } */ + + +main () +{ + int variable = 0; + int p = 1; + while (1) + { + if (p) + break; + variable = variable + 1; + if (variable == 10) + break; + } + printf("%d\n", variable); +} + + +/* The argument to "printf" should be a constant, not a variable. */ +/* { dg-final { scan-tree-dump-times "printf.*, 0" 1 "ccp"} } */ + + diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20030918-1.c b/gcc/testsuite/gcc.dg/tree-ssa/20030918-1.c new file mode 100644 index 00000000000..719ea65f5bf --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/20030918-1.c @@ -0,0 +1,15 @@ +/* The compiler was failing to adjust pointer dereferences into array + references after propagating &equot[0] into p. */ + +/* { dg-do compile } */ +/* { dg-options "-O -ftree-dominator-opts" } */ + +static unsigned short equot[(6 +3)]; +int +foo (num) + unsigned short num[]; +{ + unsigned short *p = &equot[0]; + *p++ = num[0]; + *p++ = num[1]; +} diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20030920-1.c b/gcc/testsuite/gcc.dg/tree-ssa/20030920-1.c new file mode 100644 index 00000000000..e27764aecda --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/20030920-1.c @@ -0,0 +1,112 @@ +/* Jump threading was creating FALLTHRU edges out of blocks ending in + GOTO_EXPR. */ + +extern int frame_pointer_needed; + +struct value_data_entry +{ + unsigned int mode; + unsigned int oldest_regno; + unsigned int next_regno; +}; + +struct value_data +{ + struct value_data_entry e[53]; + unsigned int max_value_regs; +}; + +struct rtx_def +{ + unsigned int code: 16; + unsigned int mode : 8; + unsigned int jump : 1; + unsigned int call : 1; + unsigned int unchanging : 1; + unsigned int volatil : 1; + unsigned int in_struct : 1; + unsigned int used : 1; + unsigned integrated : 1; + unsigned frame_related : 1; + int fld[1]; +}; + +typedef struct rtx_def *rtx; + +enum machine_mode { VOIDmode, BImode, QImode, HImode, SImode, DImode, + TImode, OImode, PQImode, PHImode, PSImode, PDImode, QFmode, HFmode, + TQFmode, SFmode, DFmode, XFmode, TFmode, QCmode, HCmode, SCmode, + DCmode, XCmode, TCmode, CQImode, CHImode, CSImode, CDImode, CTImode, + COImode, V1DImode, V2QImode, V2HImode, V2SImode, V2DImode, V4QImode, + V4HImode, V4SImode, V4DImode, V8QImode, V8HImode, V8SImode, V8DImode, + V16QImode, V2HFmode, V2SFmode, V2DFmode, V4HFmode, V4SFmode, V4DFmode, + V8HFmode, V8SFmode, V8DFmode, V16SFmode, BLKmode, CCmode, CCGCmode, + CCGOCmode, CCNOmode, CCZmode, CCFPmode, CCFPUmode, MAX_MACHINE_MODE }; + +enum mode_class { MODE_RANDOM, MODE_INT, MODE_FLOAT, MODE_PARTIAL_INT, MODE_CC, + MODE_COMPLEX_INT, MODE_COMPLEX_FLOAT, + MODE_VECTOR_INT, MODE_VECTOR_FLOAT, + MAX_MODE_CLASS}; + +extern const unsigned char mode_size[(int) MAX_MACHINE_MODE]; +extern const enum mode_class mode_class[(int) MAX_MACHINE_MODE]; + +extern int target_flags; + +static void +copy_value (rtx dest, rtx src, struct value_data *vd) +{ + unsigned int dr = (((dest)->fld[0])); + unsigned int sr = (((src)->fld[0])); + unsigned int dn, sn; + unsigned int i; + + + + if (sr == dr) + return; + + + + if (dr == 7) + return; + + + if (frame_pointer_needed && dr == 6) + return; + + + dn = (((dr) >= 8 && (dr) <= (8 + 7)) || (((dr) >= (20 + 1) && (dr) <= ((20 + 1) + 7)) || ((dr) >= (((((((20 + 1) + 7) + 1) + 7) + 1) + 7) + 1) && (dr) <= ((((((((20 + 1) + 7) + 1) + 7) + 1) + 7) + 1) + 7))) || ((dr) >= (((20 + 1) + 7) + 1) && (dr) <= ((((20 + 1) + 7) + 1) + 7)) ? (((mode_class[(int) (((enum machine_mode) (dest)->mode))]) == MODE_COMPLEX_INT || (mode_class[(int) (((enum machine_mode) (dest)->mode))]) == MODE_COMPLEX_FLOAT) ? 2 : 1) : ((((enum machine_mode) (dest)->mode)) == TFmode ? ((target_flags & 0x00100000) ? 2 : 3) : (((enum machine_mode) (dest)->mode)) == TCmode ? ((target_flags & 0x00100000) ? 4 : 6) : (((mode_size[(int) (((enum machine_mode) (dest)->mode))]) + ((target_flags & 0x00100000) ? 8 : 4) - 1) / ((target_flags & 0x00100000) ? 8 : 4)))); + sn = (((sr) >= 8 && (sr) <= (8 + 7)) || (((sr) >= (20 + 1) && (sr) <= ((20 + 1) + 7)) || ((sr) >= (((((((20 + 1) + 7) + 1) + 7) + 1) + 7) + 1) && (sr) <= ((((((((20 + 1) + 7) + 1) + 7) + 1) + 7) + 1) + 7))) || ((sr) >= (((20 + 1) + 7) + 1) && (sr) <= ((((20 + 1) + 7) + 1) + 7)) ? (((mode_class[(int) (((enum machine_mode) (dest)->mode))]) == MODE_COMPLEX_INT || (mode_class[(int) (((enum machine_mode) (dest)->mode))]) == MODE_COMPLEX_FLOAT) ? 2 : 1) : ((((enum machine_mode) (dest)->mode)) == TFmode ? ((target_flags & 0x00100000) ? 2 : 3) : (((enum machine_mode) (dest)->mode)) == TCmode ? ((target_flags & 0x00100000) ? 4 : 6) : (((mode_size[(int) (((enum machine_mode) (dest)->mode))]) + ((target_flags & 0x00100000) ? 8 : 4) - 1) / ((target_flags & 0x00100000) ? 8 : 4)))); + if ((dr > sr && dr < sr + sn) + || (sr > dr && sr < dr + dn)) + return; + + + + + if (vd->e[sr].mode == VOIDmode) + set_value_regno (sr, vd->e[dr].mode, vd); + else if (sn < (unsigned int) (((sr) >= 8 && (sr) <= (8 + 7)) || (((sr) >= (20 + 1) && (sr) <= ((20 + 1) + 7)) || ((sr) >= (((((((20 + 1) + 7) + 1) + 7) + 1) + 7) + 1) && (sr) <= ((((((((20 + 1) + 7) + 1) + 7) + 1) + 7) + 1) + 7))) || ((sr) >= (((20 + 1) + 7) + 1) && (sr) <= ((((20 + 1) + 7) + 1) + 7)) ? (((mode_class[(int) (vd->e[sr].mode)]) == MODE_COMPLEX_INT || (mode_class[(int) (vd->e[sr].mode)]) == MODE_COMPLEX_FLOAT) ? 2 : 1) : ((vd->e[sr].mode) == TFmode ? ((target_flags & 0x00100000) ? 2 : 3) : (vd->e[sr].mode) == TCmode ? ((target_flags & 0x00100000) ? 4 : 6) : (((mode_size[(int) (vd->e[sr].mode)]) + ((target_flags & 0x00100000) ? 8 : 4) - 1) / ((target_flags & 0x00100000) ? 8 : 4)))) + && ((mode_size[(int) (vd->e[sr].mode)]) > ((target_flags & 0x00100000) ? 8 : 4) + ? 0 : 0)) + return; + + + + + else if (sn > (unsigned int) (((sr) >= 8 && (sr) <= (8 + 7)) || (((sr) >= (20 + 1) && (sr) <= ((20 + 1) + 7)) || ((sr) >= (((((((20 + 1) + 7) + 1) + 7) + 1) + 7) + 1) && (sr) <= ((((((((20 + 1) + 7) + 1) + 7) + 1) + 7) + 1) + 7))) || ((sr) >= (((20 + 1) + 7) + 1) && (sr) <= ((((20 + 1) + 7) + 1) + 7)) ? (((mode_class[(int) (vd->e[sr].mode)]) == MODE_COMPLEX_INT || (mode_class[(int) (vd->e[sr].mode)]) == MODE_COMPLEX_FLOAT) ? 2 : 1) : ((vd->e[sr].mode) == TFmode ? ((target_flags & 0x00100000) ? 2 : 3) : (vd->e[sr].mode) == TCmode ? ((target_flags & 0x00100000) ? 4 : 6) : (((mode_size[(int) (vd->e[sr].mode)]) + ((target_flags & 0x00100000) ? 8 : 4) - 1) / ((target_flags & 0x00100000) ? 8 : 4))))) + return; + + + + vd->e[dr].oldest_regno = vd->e[sr].oldest_regno; + + for (i = sr; vd->e[i].next_regno != (~(unsigned int) 0); i = vd->e[i].next_regno) + continue; + vd->e[i].next_regno = dr; + + + validate_value_data (vd); + +} diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20030922-1.c b/gcc/testsuite/gcc.dg/tree-ssa/20030922-1.c new file mode 100644 index 00000000000..8876071c81f --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/20030922-1.c @@ -0,0 +1,32 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -fdump-tree-dom3" } */ + + +union tree_node; +typedef union tree_node *tree; +enum tree_code +{ + BIND_EXPR, +}; +struct tree_common +{ + enum tree_code code:8; +}; +union tree_node +{ + struct tree_common common; +}; +tree +voidify_wrapper_expr (tree wrapper) +{ + switch (wrapper->common.code) + { + case BIND_EXPR: + if (wrapper->common.code != BIND_EXPR) + abort (); + } +} + + +/* There should be no IF conditionals. */ +/* { dg-final { scan-tree-dump-times "if " 0 "dom3"} } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20030922-2.c b/gcc/testsuite/gcc.dg/tree-ssa/20030922-2.c new file mode 100644 index 00000000000..322f3ab3891 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/20030922-2.c @@ -0,0 +1,22 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -fdump-tree-dom1" } */ + +struct rtx_def; +typedef struct rtx_def *rtx; +struct rtx_def +{ + int bb; +}; +static int *block_to_bb; +static int target_bb; +static int +rgn_rank (rtx insn1, rtx insn2) +{ + if (block_to_bb[insn1->bb] != block_to_bb[insn2->bb]) + if (block_to_bb[insn2->bb] == target_bb + && block_to_bb[insn1->bb] != target_bb) + return 1; +} + +/* There should be two IF conditionals. */ +/* { dg-final { scan-tree-dump-times "if " 2 "dom1" { xfail *-*-* } } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20031015-1.c b/gcc/testsuite/gcc.dg/tree-ssa/20031015-1.c new file mode 100644 index 00000000000..62772b7b939 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/20031015-1.c @@ -0,0 +1,16 @@ +/* With tree-ssa, gcc.dg/20000724-1.c failed because we missed + a VOP of x in the asm statement. */ +/* { dg-do compile } */ +/* { dg-options "-O1 -fdump-tree-alias-vops" } */ + +struct s { int a; }; + +int +main(void) +{ + struct s x = { 0 }; + asm volatile ("" : : "r" (&x) : "memory"); + return 0; +} + +/* { dg-final { scan-tree-dump-times "VDEF" 2 "alias" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20031021-1.c b/gcc/testsuite/gcc.dg/tree-ssa/20031021-1.c new file mode 100644 index 00000000000..4534ef34fc8 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/20031021-1.c @@ -0,0 +1,20 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -fdump-tree-optimized" } */ + +struct A +{ + int i : 8; +}; + +signed char c1, c2; +struct A a; + +int main() +{ + a.i = c1; + c2 = a.i; + return a.i; +} + +/* We should only store to a.i, not load from it. */ +/* { dg-final { scan-tree-dump-times "a.i" 1 "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20031022-1.c b/gcc/testsuite/gcc.dg/tree-ssa/20031022-1.c new file mode 100644 index 00000000000..546e6b00759 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/20031022-1.c @@ -0,0 +1,27 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -fdump-tree-dom1" } */ + +typedef struct edge_def +{ + int z; +} *edge; +typedef struct basic_block_def +{ + edge pred; +} *basic_block; +extern struct basic_block_def entry_exit_blocks[2]; +void +blah (int arf) +{ + edge e; + e = (&entry_exit_blocks[1])->pred; + for ( ; ;) + if (arf) + break; + commit_edge_insertions (); + e = (&entry_exit_blocks[1])->pred; + foo (e); +} + +/* There should be two loads from entry_exit_blocks[1].pred. */ +/* { dg-final { scan-tree-dump-times "entry_exit_blocks.1..pred" 2 "dom1"} } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20031031-1.c b/gcc/testsuite/gcc.dg/tree-ssa/20031031-1.c new file mode 100644 index 00000000000..baca2a00a94 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/20031031-1.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ +/* { dg-options "-O1" } */ + +/* This program requires the SSA renamer to be run after the second DOM + pass. Test provided by Falk Hueffner as Bugzilla #12825. */ + +struct floppy_raw_cmd { + int flags, track; +} *raw_cmd, default_raw_cmd; + +void +setup_format_params (void) +{ + raw_cmd = &default_raw_cmd; + raw_cmd->track = 0; + raw_cmd->flags = 0; +} diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20031106-1.c b/gcc/testsuite/gcc.dg/tree-ssa/20031106-1.c new file mode 100644 index 00000000000..eb312cea1e2 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/20031106-1.c @@ -0,0 +1,20 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -fdump-tree-optimized" } */ + +extern void link_error (void); + +/* Check for dead stores to an array. */ + +void foo (int testarray[]) +{ + testarray[0] = 0; + testarray[0]++; + if (testarray[0] != 1) + link_error (); +} + +/* There should be only one reference to "testarray". */ +/* { dg-final { scan-tree-dump-times "testarray" 1 "optimized" { xfail *-*-* } } } */ + +/* There should be no link_error calls. */ +/* { dg-final { scan-tree-dump-times "link_error" 0 "optimized"} } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20031106-2.c b/gcc/testsuite/gcc.dg/tree-ssa/20031106-2.c new file mode 100644 index 00000000000..da430dc5813 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/20031106-2.c @@ -0,0 +1,27 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -fdump-tree-optimized" } */ + +extern void link_error (void); + +/* Check for dead stores to a struct. */ + +struct s +{ + char d; + int a, b; + double m; +}; + +void foo (struct s* teststruct) +{ + teststruct->a = 0; + teststruct->a++; + if (teststruct->a != 1) + link_error (); +} + +/* There should be only one reference to "teststruct". */ +/* { dg-final { scan-tree-dump-times "teststruct" 1 "optimized" { xfail *-*-* } } } */ + +/* There should be no link_error calls. */ +/* { dg-final { scan-tree-dump-times "link_error" 0 "optimized"} } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20031106-3.c b/gcc/testsuite/gcc.dg/tree-ssa/20031106-3.c new file mode 100644 index 00000000000..ee7cb8a009d --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/20031106-3.c @@ -0,0 +1,21 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -fdump-tree-optimized" } */ + +extern void link_error (void); + +/* Check for cprop on array elements. */ + +void foo (int testarray[]) +{ + testarray[0] = 0; + testarray[1] = 1; + testarray[0]++; + testarray[1]++; + if (testarray[0] != 1) + link_error (); + if (testarray[1] != 2) + link_error (); +} + +/* There should be no link_error calls. */ +/* { dg-final { scan-tree-dump-times "link_error" 0 "optimized" { xfail *-*-* } } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20031106-4.c b/gcc/testsuite/gcc.dg/tree-ssa/20031106-4.c new file mode 100644 index 00000000000..a288dacee47 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/20031106-4.c @@ -0,0 +1,29 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -fdump-tree-optimized" } */ + +extern void link_error (void); + +/* Check for cprop on fields of the same struct. */ + +struct s +{ + char d; + int a, b; + double m; +}; + + +void foo (struct s* r) +{ + r->a = 0; + r->b = 1; + r->a++; + r->b++; + if (r->a != 1) + link_error (); + if (r->b != 2) + link_error (); +} + +/* There should be no link_error calls. */ +/* { dg-final { scan-tree-dump-times "link_error" 0 "optimized" { xfail *-*-* } } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20031106-5.c b/gcc/testsuite/gcc.dg/tree-ssa/20031106-5.c new file mode 100644 index 00000000000..e543939c77b --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/20031106-5.c @@ -0,0 +1,28 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -fdump-tree-optimized" } */ + +extern void link_error (void); + +/* Check for cprop on different fields of same type structs. */ + +struct s +{ + char d; + int a, b; + double m; +}; + +void foo2 (struct s* r, struct s* p) +{ + r->a = 0; + p->b = 1; + r->a++; + p->b++; + if (r->a != 1) + link_error (); + if (p->b != 2) + link_error (); +} + +/* There should be no link_error calls. */ +/* { dg-final { scan-tree-dump-times "link_error" 0 "optimized" { xfail *-*-* } } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20031106-6.c b/gcc/testsuite/gcc.dg/tree-ssa/20031106-6.c new file mode 100644 index 00000000000..39fb08b032a --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/20031106-6.c @@ -0,0 +1,28 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -fdump-tree-optimized" } */ + +extern void link_error (void); + +/* Check for copyprop on structs. */ + +struct s +{ + char d; + int a, b; + double m; +}; + +struct s foo (struct s r) +{ + struct s temp_struct1; + struct s temp_struct2; + struct s temp_struct3; + temp_struct1 = r; + temp_struct2 = temp_struct1; + temp_struct3 = temp_struct2; + return temp_struct3; +} + +/* There should be no references to any of "temp_struct*" + temporaries. */ +/* { dg-final { scan-tree-dump-times "temp_struct" 0 "optimized" { xfail *-*-* } } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20031113-1.c b/gcc/testsuite/gcc.dg/tree-ssa/20031113-1.c new file mode 100644 index 00000000000..a114379a7ad --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/20031113-1.c @@ -0,0 +1,30 @@ +/* PR optimization/12640 + + We used to get into an infinite loop while trying to + figure out `strlen (resultString)'. This showed up as + a stack overflow while compiling tk. */ + +/* { dg-do compile } */ +/* { dg-options "-O1" } */ + +int i; + +static void +SendEventProc (char *resultString) +{ + char *p; + + resultString = ""; + while (*p == '-') + { + if (p[2] == ' ') + { + resultString = p + 3; + } + } + for (;;) + { + i = strlen (resultString) + 1; + } +} + diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20031216-1.c b/gcc/testsuite/gcc.dg/tree-ssa/20031216-1.c new file mode 100644 index 00000000000..d3d39df3b11 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/20031216-1.c @@ -0,0 +1,19 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -fdump-tree-optimized" } */ + +extern void link_error (void); + +void +foo (int b) +{ + int a; + a = b + 2; + a--; + a--; + if (a != b) + link_error (); +} + +/* The comparison should be eliminated, there should be no reference + to link_error. */ +/* { dg-final { scan-tree-dump-times "link_error" 0 "optimized"} } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20040121-1.c b/gcc/testsuite/gcc.dg/tree-ssa/20040121-1.c new file mode 100644 index 00000000000..6987e17d907 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/20040121-1.c @@ -0,0 +1,27 @@ + + +/* 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(); +} diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20040204-1.c b/gcc/testsuite/gcc.dg/tree-ssa/20040204-1.c new file mode 100644 index 00000000000..426e2eab51a --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/20040204-1.c @@ -0,0 +1,36 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -fdump-tree-optimized" } */ + +extern void link_error (void); + +/* + test that a condition is propagated inside an if +*/ + +void test5 (int x) +{ + extern int foo (int); + if (x == 0) + foo (x); + else if (x == 0 ) + link_error (); +} + +void test55 (int x, int y) +{ + int u; + if (x == 5 && y) + { + u = x + 22; + if (u != 27) + link_error (); + } +} + +/* There should be not link_error calls, if there is any the + optimization has failed */ +/* ??? Ug. This one may or may not fail based on how fold decides + that the && should be emitted (based on BRANCH_COST). Fix this + by teaching dom to look through && and register all components + as true. */ +/* { dg-final { scan-tree-dump-times "link_error" 0 "optimized" { xfail *-*-* } } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20040209-1.c b/gcc/testsuite/gcc.dg/tree-ssa/20040209-1.c new file mode 100644 index 00000000000..087715322b7 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/20040209-1.c @@ -0,0 +1,52 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -Wuninitialized" } */ + +typedef union tree_node *tree; + +struct tree_common +{ + tree chain; +}; + +struct tree_decl +{ + struct tree_common common; + tree name; +}; + + +union tree_node +{ + struct tree_common common; + struct tree_decl decl; +}; + +int pedantic; + +void +finish_struct (tree t, tree fieldlist, tree attributes) +{ + union tree_node * x; + + if (pedantic) + { + x = fieldlist; + if (x->decl.name == 0) + { + while (x) + x = x->common.chain; + foo (fieldlist); + } + } + + x = fieldlist; + if (x) + { + do + { + x = x->common.chain; + } while (x != 0); + } + + bar1 (&fieldlist); +} diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20040210-1.c b/gcc/testsuite/gcc.dg/tree-ssa/20040210-1.c new file mode 100644 index 00000000000..9eb7905aef0 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/20040210-1.c @@ -0,0 +1,32 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -fdump-tree-phiopt1-details" } */ + + +void abort(void); +void exit(int); + +int x, y; + +static void +init_xy(void) +{ + x = 3; + y = 2; +} + +void +test4(void) +{ + init_xy(); + if ((x < y ? x++ : y++) != 2) + abort (); +} + +int +main(){ + test4 (); + exit (0); +} + +/* Should have no more than two ifs left after straightening. */ +/* { dg-final { scan-tree-dump-times "if " 2 "phiopt1"} } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20040211-1.c b/gcc/testsuite/gcc.dg/tree-ssa/20040211-1.c new file mode 100644 index 00000000000..5d6e07940a5 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/20040211-1.c @@ -0,0 +1,40 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-cddce" } */ + + + + +struct rtx_def; +typedef struct rtx_def *rtx; +extern const char rtx_class[]; +union rtunion_def +{ + rtx rtx; +}; +typedef union rtunion_def rtunion; +struct rtx_def +{ + int code; + rtunion fld[1]; +}; +static int +can_move_up (rtx insn, int n_insns) +{ + while (n_insns > 0) + { + insn = (((insn)->fld[1]).rtx); + if (((rtx_class[(int) (((insn)->code))]) == 'i')) + n_insns--; + } + return n_insns <= 0; +} +int +com (rtx insn, int blah) +{ + if (!can_move_up (insn, blah)) + foo (); +} + +/* Cddce cannot remove possibly infinite loops and there is no way how to + determine whether the loop in can_move_up ends. */ +/* { dg-final { scan-tree-dump "if " "cddce"} } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20040216-1.c b/gcc/testsuite/gcc.dg/tree-ssa/20040216-1.c new file mode 100644 index 00000000000..7585905a4da --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/20040216-1.c @@ -0,0 +1,18 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -fdump-tree-dse1-details" } */ + +foo(int *z, int *y, int xx) +{ + *z = 1; + if (xx) + xx = 20; + else + xx = 30; + *z = 2; + *z = 3; + return xx; +} + +/* We should convert two COND_EXPRs into straightline code. */ +/* { dg-final { scan-tree-dump-times "Deleted dead store" 2 "dse1"} } */ + diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20040302-1.c b/gcc/testsuite/gcc.dg/tree-ssa/20040302-1.c new file mode 100644 index 00000000000..ef59b041030 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/20040302-1.c @@ -0,0 +1,8 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 --param global-var-threshold=0" } */ + +/* Test for .GLOBAL_VAR not being renamed into SSA after alias analysis. + provided by Dale Johannesen in PR 14266. */ + +void foo() { bar (); } +main () { foo (); } diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20040305-1.c b/gcc/testsuite/gcc.dg/tree-ssa/20040305-1.c new file mode 100644 index 00000000000..2d098d50e1d --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/20040305-1.c @@ -0,0 +1,30 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-cddce -fdump-tree-forwprop1-details" } */ + +int abarney[2]; +int afred[1]; + +void foo(int edx, int eax) +{ + if (eax == 100) + { + if (edx == 1) + { + abarney[0] = 5; + abarney[1] = 6; + } + } + if (eax == 100) + { + if (-- edx == 0) + afred[0] = 2; + } +} + + +/* Verify that we did a forward propagation. */ +/* { dg-final { scan-tree-dump-times "Replaced" 1 "forwprop1"} } */ + +/* After cddce we should have two IF statements remaining as the other + two tests can be threaded. */ +/* { dg-final { scan-tree-dump-times "if " 2 "cddce"} } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20040313-1.c b/gcc/testsuite/gcc.dg/tree-ssa/20040313-1.c new file mode 100644 index 00000000000..0ad144c03dd --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/20040313-1.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ +/* { dg-options "-O3" } */ + +/* Test provided by Volker Reichelt in PR 14553. The redundant PHI + node elimination pass was not using the right API functions to + propagate pointers, which resulted in dereferenced pointers that + did not have memory tags associated with them. */ + +void foo(int* p) +{ + int i; + for (i=1; i>0; --i, ++p) + *p=0; +} + +void bar(int* p) { foo(p); } diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20040319-1.c b/gcc/testsuite/gcc.dg/tree-ssa/20040319-1.c new file mode 100644 index 00000000000..571c2aeabad --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/20040319-1.c @@ -0,0 +1,25 @@ +/* { dg-do run } */ +/* { dg-options "-O2" } */ + +/* Test derived from PR 14643. When a function has no addressable + variables but 2 or more pointers have conflicting memory tags, they + were not being processed by the type based alias analyzer, + resulting in optimizations removing a non-redundant load. */ + +struct bar { int count; int *arr;}; + +void foo (struct bar *b) +{ + b->count = 0; + *(b->arr) = 2; + if (b->count == 0) /* b->count can't be assumed to be 0 here. */ + abort (); +} + +main () +{ + struct bar x; + x.arr = &x.count; + foo (&x); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20040324-1.c b/gcc/testsuite/gcc.dg/tree-ssa/20040324-1.c new file mode 100644 index 00000000000..15eb0d62381 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/20040324-1.c @@ -0,0 +1,31 @@ +/* { dg-do run } */ +/* { dg-options "-O2" } */ + +/* Ensure that BIT_FIELD_REFs gets the appropriate VUSE. + Contributed by Paolo Bonzini <bonzini@gnu.org>. + + This testcase actually never triggered in the CVS repo, but it did + in my local tree and it seems worth testing. In this test, the if's + are folded to BIT_FIELD_REFs but the VUSEs were erroneously left out. + Therefore, DOM did not see that i was modified between the two ifs + and optimized away the second if. */ + +struct x +{ + unsigned b:1; + unsigned c:1; +}; + +struct x i = { 1, 1 }; + +int +main () +{ + i.b = 1; + if (i.b == 1 && i.c == 0) + exit (0); + i.c = 0; + if (i.b == 1 && i.c == 0) + exit (0); + abort (); +} diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20040326-1.c b/gcc/testsuite/gcc.dg/tree-ssa/20040326-1.c new file mode 100644 index 00000000000..c29655a24fd --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/20040326-1.c @@ -0,0 +1,29 @@ +/* { dg-options "-O2 -fno-inline-functions" } */ +/* { dg-do run } */ +/* When there are no call-clobbered variables, we should still create + a .GLOBAL_VAR to model the side effects of functions. Without it, + we were moving the call to Faref() inside the second call to + Faset(). */ +main () +{ + int table, c, elt; + int tem = Faref (table, elt); + Faset (table, elt, c); + Faset (table, c, tem);/* tem cannot be replaced with Faref (table, elt) */ + exit (0); +} + +int j = 0; + +int __attribute__ ((noinline)) Faref (table, elt) +{ + j = 1; + return 0; +} + +int __attribute__ ((noinline)) Faset (table, elt, c) +{ + if (j != 1) + abort (); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20040326-2.c b/gcc/testsuite/gcc.dg/tree-ssa/20040326-2.c new file mode 100644 index 00000000000..a3e16ad451e --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/20040326-2.c @@ -0,0 +1,63 @@ +/* { dg-options "-O2 -fno-inline-functions" } */ +/* { dg-do run } */ + +/* Gimplification problem exposed by zsh. All the side-effects in + function arguments and in the called expression should happen + before the actual function call. */ +int A; + +typedef void (*fnptr) (void); +fnptr *F; + +void +foo (int x) +{ + if (A == x) + abort (); +} + +void +bar (int x, int y) +{ + if (x == 5 || y != 3) + abort (); +} + +void +boz (void) +{ + abort (); +} + +void +baz (void) +{ + if (*F != boz) + abort (); +} + +fnptr B[2] = { baz, boz }; + +main () +{ + int b, c; + + /* The gimplifier was emitting A++ after the call to foo. */ + A = 5; + foo (A++); + + /* The increment to 'b' and 'c' must happen before the call. However, + the first argument to bar() must be the original value of 'b', while + the second argument must be the new value of 'c'. */ + b = 4; + c = 2; + bar (b++, ++c); + + /* This call via function pointer *F should go to baz, but F should + be incremented before the actual call (i.e., right before the + call F should be pointing to boz). */ + F = &B[0]; + (*F++) (); + + return 0; +} diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20040408-1.c b/gcc/testsuite/gcc.dg/tree-ssa/20040408-1.c new file mode 100644 index 00000000000..6578be543a0 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/20040408-1.c @@ -0,0 +1,51 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ +/* Make sure that when a variable with an NMT is marked for renaming + that the NMT's aliases are also marked for renaming. */ + +static int eiisnan (short unsigned int *x) +{ + int i; + + if( x[i] != 0 ) + return(1); +} + +static int eiisinf (unsigned short *x) +{ + if (eiisnan (x)) + return (0); + + if ((x[1] & 0x7fff) == 0x7fff) + return (1); +} + +static void toe64(short unsigned int *a, short unsigned int *b) +{ + register unsigned short *p, *q; + unsigned short i; + + q = b + 4; + + if (eiisinf (a)); + + for( i=0; i<4; i++ ) + *q-- = *p++; +} + +static int asctoeg(short unsigned int *y, int oprec) +{ + unsigned short yy[13]; + char *s; + + while( *s == ' ' ) + ++s; + + toe64( yy, y ); +} + +long double _strtold (char *s, char **se) +{ + long double x; + asctoeg( (unsigned short *)&x, 64 ); +} diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20040430-1.c b/gcc/testsuite/gcc.dg/tree-ssa/20040430-1.c new file mode 100644 index 00000000000..73ee8da85a6 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/20040430-1.c @@ -0,0 +1,25 @@ +/* PR middle-end/14470. Similar to + gcc.c-torture/execute/20040313-1.c, but with a compile time test to + make sure the second if() is removed. We should actually get rid + of the first if() too, but we're not that smart yet. */ + +/* { dg-do run } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ + + +extern void abort(void); + +int main() +{ + int t[1025] = { 1024 }, d; + + d = 0; + d = t[d]++; + if (t[0] != 1025) + abort(); + if (d != 1024) + abort(); + return 0; +} + +/* { dg-final { scan-tree-dump-times "if " 1 "optimized"} } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/asm-1.c b/gcc/testsuite/gcc.dg/tree-ssa/asm-1.c new file mode 100644 index 00000000000..ad92408f170 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/asm-1.c @@ -0,0 +1,16 @@ +/* Make sure that gcc understands that an in/out operand is a use as well + as a def. */ + +/* { dg-do compile } */ +/* { dg-options "-O -fdump-tree-optimized" } */ + +void f() +{ + int i = 42; + int j = 63; + + asm ("": "=m"(i), "+r"(j) : "m"(i)); +} + +/* { dg-final { scan-tree-dump-times "42" 1 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "63" 1 "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/cfgcleanup-1.c b/gcc/testsuite/gcc.dg/tree-ssa/cfgcleanup-1.c new file mode 100644 index 00000000000..4d22a42814a --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/cfgcleanup-1.c @@ -0,0 +1,18 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-dce1" } */ +void +cleanup (int a, int b) +{ + if (a) + if (b) + a = 1; + else + b = 1; + else if (a) + a = 1; + else + b = 1; + return; +} +/* Dce should get rid of the initializers and cfgcleanup should elliminate ifs */ +/* { dg-final { scan-tree-dump-times "if " 0 "dce1"} } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/copy-headers.c b/gcc/testsuite/gcc.dg/tree-ssa/copy-headers.c new file mode 100644 index 00000000000..efe831beab5 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/copy-headers.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-ch-details" } */ + +extern int foo (int); + +void bla (void) +{ + int i, n = foo (0); + + for (i = 0; i < n; i++) + foo (i); +} + +/* There should be a header scheduled for duplication. */ +/* { dg-final { scan-tree-dump-times "Scheduled" 1 "ch"} } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/sra-1.c b/gcc/testsuite/gcc.dg/tree-ssa/sra-1.c new file mode 100644 index 00000000000..652f402dc83 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/sra-1.c @@ -0,0 +1,72 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -fdump-tree-optimized" } */ + +/* Tests for SRA. */ + +typedef struct teststruct +{ + double d; + char f1; +} teststruct; + +void +copystruct1 (teststruct param) +{ + teststruct local; + param.f1 = 0; + local = param; + if (local.f1 != 0) + link_error (); +} + +void +copystruct11 (teststruct *param) +{ + teststruct local; + param->f1 = 0; + local = *param; + if (local.f1 != 0) + link_error (); +} + +void +copystruct111 (teststruct param) +{ + teststruct *local = ¶m; + param.f1 = 0; + if (local->f1 != 0) + link_error (); +} + +teststruct globf; +void +copystruct1111 (void) +{ + teststruct local; + globf.f1 = 0; + local = globf; + if (local.f1 != 0) + link_error (); +} + +void +copystruct11111 (void) +{ + teststruct *local = &globf; + globf.f1 = 0; + if (local->f1 != 0) + link_error (); +} + +void +copystruct111111 (teststruct param) +{ + static teststruct local; + param.f1 = 0; + local = param; + if (local.f1 != 0) + link_error (); +} + +/* There should be no referenc to link_error. */ +/* { dg-final { scan-tree-dump-times "link_error" 0 "optimized"} } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/sra-2.c b/gcc/testsuite/gcc.dg/tree-ssa/sra-2.c new file mode 100644 index 00000000000..fa8bea51bc7 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/sra-2.c @@ -0,0 +1,25 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -fdump-tree-optimized" } */ + +/* Test for SRA. */ + +typedef struct teststruct +{ + double d; + char f1; +} teststruct; + + +void +copystruct11 (teststruct *param) +{ + static teststruct local; + param->f1 = 0; + local = *param; + if (local.f1 != 0) + link_error (); +} + + +/* There should be no reference to link_error. */ +/* { dg-final { scan-tree-dump-times "link_error" 0 "optimized" { xfail *-*-* } } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/sra-3.c b/gcc/testsuite/gcc.dg/tree-ssa/sra-3.c new file mode 100644 index 00000000000..f6ffc575938 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/sra-3.c @@ -0,0 +1,27 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -fdump-tree-optimized" } */ + +/* Test for SRA. */ + +typedef struct teststruct +{ + double d; + char f1; +} teststruct; + +teststruct *globf1; + +extern void link_error (void); + +void +copystruct1 (void) +{ + teststruct local; + globf1->f1 = 0; + local = *globf1; + if (local.f1 != 0) + link_error (); +} + +/* There should be no reference to link_error. */ +/* { dg-final { scan-tree-dump-times "link_error" 0 "optimized" { xfail *-*-* } } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-1.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-1.c new file mode 100644 index 00000000000..419cc95c71e --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-1.c @@ -0,0 +1,74 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -fdump-tree-ccp" } */ + +extern void link_error (void); + +/* check folding */ + +void test1 (void) +{ + unsigned int l = 3 * 4 - 5 / 2; + if (l != 10) + link_error (); +} + +void test11 (void) +{ + unsigned int l = (((((((3 / 2 + 2) * 4) & 7) ^ 3) % 8) << 2) + 1) >> 2; + if (l != 7) + link_error (); +} + +/* cprop in a basic block */ +void test111 (void) +{ + unsigned int l0 = 3 / 2 + 2; + unsigned int l1 = l0 * 4; + unsigned int l2 = 7; + unsigned int l3 = l1 & l2; + unsigned int l4 = 3; + unsigned int l5 = l3 ^ l4; + unsigned int l6 = 8; + unsigned int l7 = l5 % l6; + unsigned int l8 = 2; + unsigned int l9 = l7 << l8; + unsigned int l10 = l9 + 1; + unsigned int l11 = l10 >> 2; + if (l11 != 7) + link_error (); +} + + +/* cprop after an if statement */ +void test1111 (int p) +{ + int l = 53; + if (p) + { + if ((67 + l - 25) != 95) + link_error (); + } + else + { + if ((93 - l + 25) != 65) + link_error (); + } +} + +/* cprop after a loop */ +void test11111 (int p, int q, int r) +{ + int l = 53; + while (p < r) + { + if ((67 + l - 25) != 95) + link_error (); + p -= q; + } +} + + + +/* There should be not link_error calls, if there is any the + optimization has failed */ +/* { dg-final { scan-tree-dump-times "link_error" 0 "ccp"} } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-10.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-10.c new file mode 100644 index 00000000000..091703a1017 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-10.c @@ -0,0 +1,31 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -fdump-tree-fab" } */ + +/* Check that we fold strlen of equally long strings, and that we do not + fail to terminate when there is a nontrivial cycle in the corresponding + ssa graph. */ + +void foo(int i) +{ + char *s = "abcde"; + + if (i) + { + s = "defgh"; + goto middle; + } + +start: + + bla (); + +middle: + + if (bla ()) + goto start; + + bar (strlen (s)); +} + +/* There should be no calls to strlen. */ +/* { dg-final { scan-tree-dump-times "strlen" 0 "fab"} } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-11.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-11.c new file mode 100644 index 00000000000..b7f307964a6 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-11.c @@ -0,0 +1,41 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -fdump-tree-optimized" } */ + +/* Test for CPROP across a DAG. */ + +int test111 (int param) +{ + int a, b, c; + if (param) { + a = 3; + b = 2; + } + else { + a = 2; + b = 3; + } + c = a + b; + if (c != 5) + return 2; + return 0; +} + +int test1111 (int param) +{ + _Bool a, b, c; + if (param) { + a = 1; + b = 0; + } + else { + a = 0; + b = 1; + } + c = a && b; + if (c) + return 2; + return 0; +} + +/* All ifs should be eliminated. */ +/* { dg-final { scan-tree-dump-times "if" 0 "optimized" { xfail *-*-* } } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-2.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-2.c new file mode 100644 index 00000000000..b3c87fdc7b3 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-2.c @@ -0,0 +1,171 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -fdump-tree-ccp" } */ + +extern void link_error (void); + + +/* check that cprop for variables of different types still works even + if function calls or assignments to different types of data are + interposed. */ + +int test7 (int *intarr) +{ + extern int foo7 (int); + int u = 7, v1; + foo7 (u); + v1 = u; + if (v1 != 7) + link_error (); + return v1; +} + +int test77 (int *arr) +{ + int u = 7, v1; + arr[0] = 4; + v1 = u; + if (v1 != 7) + link_error (); + return v1 + arr[0]; +} + +int test777 (void) +{ + extern int foo(int *); + int u = 7, v1; + static int sarr[10]; + sarr[0] = 4; + v1 = u; + if (v1 != 7) + link_error (); + foo (sarr); + return v1 + sarr[0]; +} + +int garr[10]; +int test7777 (void) +{ + int u = 7, v1; + garr[0] = 4; + v1 = u; + if (v1 != 7) + link_error (); + return v1 + garr[0]; +} + +int test88 (int *arr) +{ + static int l; + int v1; + l = 8; + arr[0] = 4; + v1 = l; + if (v1 != 8) + link_error (); + l = foo88 (l); + return v1 + arr[0]; +} + +int test888 (void) +{ + static int l; + extern int foo(int *); + int v1; + static int sarr[10]; + l = 8; + sarr[0] = 4; + v1 = l; + if (v1 != 8) + link_error (); + foo (sarr); + l = foo88(l); + return v1 + sarr[0]; +} + +int test8888 (void) +{ + static int l; + int v1; + l = 8; + garr[0] = 4; + v1 = l; + if (v1 != 8) + link_error (); + return v1 + garr[0]; +} + + + +/* global var */ +int g9; +int garr9[10]; +int test9 (int *intarr) +{ + extern int foo9 (int) __attribute__ ((const)); + int h, v; + g9 = 9; + h = foo9 (g9); + v = g9; + if (v != 9) + link_error (); + return g9; +} + +int test99 (int *intarr) +{ + extern int foo9 (int) __attribute__ ((pure)); + int h, v; + g9 = 9; + h = foo9 (g9); + v = g9; + if (v != 9) + link_error (); + return g9; +} + +extern int foo99 (int); + +int test999 (int *arr) +{ + static int l; + int v1; + g9 = 9; + l = 4; + v1 = g9; + if (v1 != 9) + link_error (); + l = foo99 (l); + return v1 + l; +} + + +int test9999 (void) +{ + int v1; + static int sarr[10]; + g9 = 9; + sarr[0] = 4; + v1 = g9; + if (v1 != 9) + link_error (); + foo (sarr); + g9 = foo99 (g9); + return v1 + sarr[0]; +} + + +int test99999 (void) +{ + int v1; + g9 = 9; + garr9[0] = 4; + v1 = g9; + if (v1 != 9) + link_error (); + return v1 + garr9[0]; +} + + +/* There should be not link_error calls, if there is any the + optimization has failed */ +/* { dg-final { scan-tree-dump-times "link_error" 0 "ccp"} } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-3.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-3.c new file mode 100644 index 00000000000..15d43cb7ef7 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-3.c @@ -0,0 +1,134 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -fdump-tree-ccp" } */ + +extern void link_error (void); + +/* some addresses clearly cannot be equal, check that some address + expressions can be evaluated as constants */ + +char g1, g2; +void test6 (char p1, char p2) +{ + char l1 = 1, l2 = 2; + static char s1 = 5, s2 = 7; + if (&l1 == &l2) + link_error (); + + if (&p1 == &p2) + link_error (); + + if (&s1 == &s2) + link_error (); + + if (&g1 == &g2) + link_error (); + + if (&p1 == &l1) + link_error (); + + if (&p1 == &s1) + link_error (); + + if (&p1 == &l2) + link_error (); + + if (&p1 == &g1) + link_error (); + + if (&l1 == &g1) + link_error (); + + if (&s1 == &g1) + link_error (); +} + +extern void *alloc (int) __attribute__ ((malloc)); +char gca1[128]; +char* __restrict__ rgc1; +char* test66 (char * __restrict__ rp1, char * __restrict__ rp2, char *p1) +{ + char * __restrict__ rl1 = p1; + char * l1 = (char*) alloc (20); + + if (l1 == rgc1) + link_error (); + + if (l1 == rp1) + link_error (); + + if (l1 == rl1) + link_error (); + + if (l1 == gca1) + link_error (); + + if (rl1 == rgc1) + link_error (); + + if (rl1 == rp1) + link_error (); + + if (rl1 == gca1) + link_error (); + + if (rp1 == rp2) + link_error (); + + if (rp1 == rgc1) + link_error (); + + if (rp1 == gca1) + link_error (); + + if (gca1 == rgc1) + link_error (); + +} + +int gci1[128]; +int* __restrict__ rgi1; +int* test666 (int * __restrict__ rp1, int * __restrict__ rp2, int *p1) +{ + int * __restrict__ rl1 = p1; + int * l1 = (int*) alloc (20); + + if (l1 == rgi1) + link_error (); + + if (l1 == rp1) + link_error (); + + if (l1 == rl1) + link_error (); + + if (l1 == gci1) + link_error (); + + if (rl1 == rgi1) + link_error (); + + if (rl1 == rp1) + link_error (); + + if (rl1 == gci1) + link_error (); + + if (rp1 == rp2) + link_error (); + + if (rp1 == rgi1) + link_error (); + + if (rp1 == gci1) + link_error (); + + if (gci1 == rgi1) + link_error (); +} + + +/* There should be not link_error calls, if there is any the + optimization has failed */ +/* ??? While we indeed don't handle some of these, a couple of the + restrict tests are incorrect. */ +/* { dg-final { scan-tree-dump-times "link_error" 0 "ccp" { xfail *-*-* } } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-7.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-7.c new file mode 100644 index 00000000000..ba6db18e00e --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-7.c @@ -0,0 +1,27 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -fdump-tree-ccp" } */ + +extern void link_error (void); + +/* tests to check if cprop works when using non-return functions */ + +extern int not_returning (int) __attribute__ ((noreturn)); + +int b; +int test7 (int a) +{ + b = 7; + if (a) + { + not_returning (a); + } + if (b != 7) + link_error (); + return b; +} + + +/* There should be not link_error calls, if there is any the + optimization has failed */ +/* { dg-final { scan-tree-dump-times "link_error" 0 "ccp"} } */ + diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-9.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-9.c new file mode 100644 index 00000000000..4656558814e --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-9.c @@ -0,0 +1,54 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -fdump-tree-ccp" } */ + +/* Check that cprop works for assignments to array elements and structs. */ + +struct foo { + int a; +}; + +extern void link_error (void); + +void +test9 (struct foo f) +{ + f.a = 0; + if (f.a != 0) + link_error (); +} + +void +test99 (struct foo *f) +{ + f->a = 0; + if (f->a != 0) + link_error (); +} + +void +test999 (int *arr) +{ + *arr = 0; + if (*arr != 0) + link_error (); +} + +void +test9999 (int *arr) +{ + arr[13] = 0; + if (arr[13] != 0) + link_error (); +} + +void +test99999 (int *arr, int j) +{ + arr[j] = 0; + if (arr[j] != 0) + link_error (); +} + +/* There should be no link_error calls, if there is any, the + optimization has failed */ +/* { dg-final { scan-tree-dump-times "link_error" 0 "ccp"} } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dce-1.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dce-1.c new file mode 100644 index 00000000000..e95cf67cde0 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dce-1.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -fdump-tree-dce3" } */ + +int t() __attribute__ ((const)); +q() +{ + int i = t(); + if (!i) + i = t(); +} +/* There should be no IF conditionals. */ +/* { dg-final { scan-tree-dump-times "if " 0 "dce3"} } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dce-2.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dce-2.c new file mode 100644 index 00000000000..64525141beb --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dce-2.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -fdump-tree-dce3" } */ + +/* We should notice constantness of this function. */ +int t(int a) +{ + return a+1; +} +q() +{ + int i = t(1); + if (!i) + i = t(1); +} +/* There should be no IF conditionals. */ +/* { dg-final { scan-tree-dump-times "if " 0 "dce3"} } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dce-3.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dce-3.c new file mode 100644 index 00000000000..efaa3affaf6 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dce-3.c @@ -0,0 +1,29 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-cddce" } */ + +int main(void) +{ + unsigned i, j; + + for (i = 1, j = 0; i != 0; i+=2) + { + j += 500; + if (j % 7) + { + j++; + } + else + { + j--; + } + } + + return 0; +} + +/* We should eliminate the inner condition, but the loop must be preserved + as it is infinite. Therefore there should be just one phi node (for i): */ +/* { dg-final { scan-tree-dump-times "PHI " 1 "cddce"} } */ + +/* And one if (for the exit condition of the loop): */ +/* { dg-final { scan-tree-dump-times "if " 1 "cddce"} } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-ccp-1.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-ccp-1.c new file mode 100644 index 00000000000..db7b4b49ed2 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-ccp-1.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-dom1-details" } */ +int t(int a) __attribute__ ((const)); +void abort (void); +int +ccp(int b) +{ + int a=1; + a++; + a++; + a++; + if (b) + abort(); + return a; +} +/* We should propagate constant 4 into return. */ +/* { dg-final { scan-tree-dump-times "Replaced.*with constant '4'" 1 "dom1"} } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-cse-1.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-cse-1.c new file mode 100644 index 00000000000..4e4ed8c912f --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-cse-1.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-dom2-details" } */ +int t(int a) __attribute__ ((const)); +void q (void); +void +threading(int a,int b) +{ + if (t(a)) + { + if (t(a)) + q(); + } +} +/* We should thread the jump twice and eliminate it. Test this in + DOM2, after aliases have been computed. */ +/* { dg-final { scan-tree-dump-times "Replaced.* t " 1 "dom2"} } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-1.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-1.c new file mode 100644 index 00000000000..e4ae8ea0b92 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-1.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-dom1-details" } */ +void t(void); +void q(void); +void q1(void); +void +threading(int a,int b) +{ + if (a>b) + t(); + else + q(); + if (a<=b) + q1(); +} +/* We should thread the jump twice and elliminate it. */ +/* { dg-final { scan-tree-dump-times "Threaded" 2 "dom1"} } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-1.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-1.c new file mode 100644 index 00000000000..43eb6e0848f --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-1.c @@ -0,0 +1,19 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-pre-stats" } */ +int main(int argc, char **argv) +{ + int a; + int b; + int c; + b = argc + 1; + c = argc + 2; + a = b + c; + if (argc * 2) + { + c = argc + 3; + } + printf ("%d, %d\n", a, b + c); +} +/* We should eliminate one evaluation of b + c along the main path, + causing one reload. */ +/* { dg-final { scan-tree-dump-times "Reloads:1" 1 "pre"} } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-2.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-2.c new file mode 100644 index 00000000000..e264c50f920 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-2.c @@ -0,0 +1,20 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-pre-stats" } */ +int motion_test1(int data, int data_0, int data_3, int v) +{ + int i; + int t, u; + + if (data) + i = data_0 + data_3; + else { + v = 2; + i = 5; + } + t = data_0 + data_3; + u = i; + return v * t * u; +} +/* We should eliminate one computation of data_0 + data_3 along the + main path, causing one reload. */ +/* { dg-final { scan-tree-dump-times "Reloads:1" 1 "pre"} } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/tailcall-1.c b/gcc/testsuite/gcc.dg/tree-ssa/tailcall-1.c new file mode 100644 index 00000000000..c2a85940a30 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/tailcall-1.c @@ -0,0 +1,18 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-tailc-details" } */ +int q(int a); +int *v; +int +t(int a) +{ + int r,r1; + if (a) + r1=r = q(a-1); + else + return 0; + /* Dead alloca should not disturb us. */ + if (r!=r1) + v=alloca(r); + return r; +} +/* { dg-final { scan-tree-dump-times "Found tail call" 1 "tailc"} } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/tailcall-2.c b/gcc/testsuite/gcc.dg/tree-ssa/tailcall-2.c new file mode 100644 index 00000000000..7f3415444ff --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/tailcall-2.c @@ -0,0 +1,23 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-tailc-details" } */ +/* Test provided by Richard Earnshaw in PR 14312. */ + +void bar (int i); +void baz (int *); + +void +foo (int *x) +{ + if (*x < 0) + { + baz (x); + return; + } + bar (*x); +} + +/* The test has no local call-clobbered variables. Only the memory + tag for 'x' is call-clobbered. And since tags are not real + variables, they ought to be ignored. There should be two tail + calls here. */ +/* { dg-final { scan-tree-dump-times "Found tail call" 2 "tailc"} } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/tailrecursion-1.c b/gcc/testsuite/gcc.dg/tree-ssa/tailrecursion-1.c new file mode 100644 index 00000000000..dc61c1324bd --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/tailrecursion-1.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -fdump-tree-tailr-details" } */ +int +t(int a) +{ + if (a) + return t(a-1); + else + return 0; +} +/* { dg-final { scan-tree-dump-times "Eliminated tail recursion" 1 "tailr"} } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/tailrecursion-2.c b/gcc/testsuite/gcc.dg/tree-ssa/tailrecursion-2.c new file mode 100644 index 00000000000..095993bc133 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/tailrecursion-2.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -fdump-tree-tailr-details" } */ +int +t(char *a) +{ + static char p[100]; + if (a) + return t(p); + else + return 0; +} +/* { dg-final { scan-tree-dump-times "Eliminated tail recursion" 1 "tailr"} } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/tailrecursion-3.c b/gcc/testsuite/gcc.dg/tree-ssa/tailrecursion-3.c new file mode 100644 index 00000000000..097a1de0e4e --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/tailrecursion-3.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -fdump-tree-tailr-details" } */ +int +t(int a) +{ + int r; + if (a) + r = t(a-1); + else + return 0; + if (r) + r=r; + return r; +} +/* { dg-final { scan-tree-dump-times "Eliminated tail recursion" 1 "tailr"} } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/tailrecursion-4.c b/gcc/testsuite/gcc.dg/tree-ssa/tailrecursion-4.c new file mode 100644 index 00000000000..71a4f6716a1 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/tailrecursion-4.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -fdump-tree-tailr-details" } */ +int +t(int a) +{ + int r; + if (a&1) + r = t(a-1); + else if (a) + r = t(a-2); + else + return 0; + if (r) + r=r; + return r; +} +/* { dg-final { scan-tree-dump-times "Eliminated tail recursion" 2 "tailr"} } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/tailrecursion-5.c b/gcc/testsuite/gcc.dg/tree-ssa/tailrecursion-5.c new file mode 100644 index 00000000000..2940a5019bd --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/tailrecursion-5.c @@ -0,0 +1,72 @@ +/* { dg-do run } */ +/* { dg-options "-O1 -fdump-tree-optimized" } */ + +int sum (int n) +{ + if (n == 0) + return 0; + + return n + sum (n - 1); +} + +int fac (int n) +{ + if (n == 0) + return 1; + + return n * fac (n - 1); +} + +int sq_sum (int n) +{ + if (n == 0) + return 0; + + return n * n + sq_sum (n - 1); +} + +int pow2m1 (int n) +{ + if (n == 0) + return 0; + + return 2 * pow2m1 (n - 1) + 1; +} + +int fib (int n) +{ + if (n <= 1) + return 1; + + return fib (n - 2) + fib (n - 1); +} + +int main(void) +{ + if (sum (5) != 15) + abort (); + + if (fac (5) != 120) + abort (); + + if (sq_sum (5) != 55) + abort (); + + if (pow2m1 (5) != 31) + abort (); + + if (fib (5) != 8) + abort (); + + exit (0); +} + +/* There is one call of sum in main and then 2 instances of the word in + ;; Function sum (sum) and one in the function header. */ +/* { dg-final { scan-tree-dump-times "\\msum\\M" 4 "optimized"} } */ +/* { dg-final { scan-tree-dump-times "\\mfac\\M" 4 "optimized"} } */ +/* { dg-final { scan-tree-dump-times "\\msq_sum\\M" 4 "optimized"} } */ +/* { dg-final { scan-tree-dump-times "\\mpow2m1\\M" 4 "optimized"} } */ + +/* There is one recursive call to fib. */ +/* { dg-final { scan-tree-dump-times "\\mfib\\M" 5 "optimized"} } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/tree-ssa.exp b/gcc/testsuite/gcc.dg/tree-ssa/tree-ssa.exp new file mode 100644 index 00000000000..7b3403c957d --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/tree-ssa.exp @@ -0,0 +1,36 @@ +# Copyright (C) 1997,2002,2003 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +# GCC testsuite that uses the `dg.exp' driver. + +# Load support procs. +load_lib gcc-dg.exp + +# If a testcase doesn't have special options, use these. +global DEFAULT_CFLAGS +if ![info exists DEFAULT_CFLAGS] then { + set DEFAULT_CFLAGS " -ansi -pedantic-errors" +} + +# Initialize `dg'. +dg-init + +# Main loop. +dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cS\]]] \ + "" $DEFAULT_CFLAGS + +# All done. +dg-finish diff --git a/gcc/testsuite/gcc.dg/tree-ssa/useless-1.c b/gcc/testsuite/gcc.dg/tree-ssa/useless-1.c new file mode 100644 index 00000000000..3274998d1fc --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/useless-1.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -fdump-tree-useless" } */ + +void +foo (void) +{ + int i, a; + for (i = 0; i < 10; i++) + { a = i; } +} + +/* There should be three gotos in the dump. If one was removed + in the loop exit condition, it would be re-introduced during + GIMPLE lowering, at the cost of an extra statement, label, + and basic block. */ +/* { dg-final { scan-tree-dump-times "goto" 3 "useless"} } */ |