This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] Fix PR34099, wrong-code with CCP


On Fri, 16 Nov 2007, Richard Guenther wrote:

> On Fri, 16 Nov 2007, Joseph S. Myers wrote:
> 
> > On Fri, 16 Nov 2007, Richard Guenther wrote:
> > 
> > > + 	case MULT_EXPR:
> > > + 	case TRUNC_DIV_EXPR:
> > > + 	case CEIL_DIV_EXPR:
> > > + 	case FLOOR_DIV_EXPR:
> > > + 	case ROUND_DIV_EXPR:
> > > + 	case TRUNC_MOD_EXPR:
> > > + 	case CEIL_MOD_EXPR:
> > > + 	case FLOOR_MOD_EXPR:
> > > + 	case ROUND_MOD_EXPR:
> > > + 	case EQ_EXPR:
> > > + 	case NE_EXPR:
> > > + 	case LT_EXPR:
> > > + 	case GT_EXPR:
> > > + 	  /* Not MIN_EXPR, MAX_EXPR.  One VARYING operand may be selected.
> > > + 	     Not bitwise operators, one VARYING operand may specify the
> > > + 	     result completely.  Not logical operators for the same reason.
> > > + 	     Not LE/GE comparisons or unordered comparisons.  Not
> > > + 	     COMPLEX_EXPR as one VARYING operand makes the result partly
> > > + 	     not UNDEFINED.  */
> > 
> > x * 0 and x % 1 are always 0 (for integer x).  Comparisons may be always 0 
> > or always 1 for one operand outside the range of the unsigned char from 
> > which the original operand was promoted; likewise the results of 
> > divisions, or shifts.
> 
> Right.  That'll shrink down the list to nearly zero operands.  Unless
> we start to tell apart which of the operands is undefined.  I'll do a
> followup patch.

Like this one.  Bootstrap / regtest in progress.

Richard.

2007-11-18  Richard Guenther  <rguenther@suse.de>

	PR tree-optimization/34
	* tree-ssa-ccp.c (likely_value): Exclude all but PLUS_EXPR,
	MINUS_EXPR and POINTER_PLUS_EXPR from handling as UNDEFINED
	if only one operand is undefined.

	* gcc.c-torture/execute/pr34099-2.c: New testcase.

Index: tree-ssa-ccp.c
===================================================================
*** tree-ssa-ccp.c	(revision 130268)
--- tree-ssa-ccp.c	(working copy)
*************** likely_value (tree stmt)
*** 582,613 ****
  	/* Unary operators are handled with all_undefined_operands.  */
  	case PLUS_EXPR:
  	case MINUS_EXPR:
- 	case MULT_EXPR:
  	case POINTER_PLUS_EXPR:
- 	case TRUNC_DIV_EXPR:
- 	case CEIL_DIV_EXPR:
- 	case FLOOR_DIV_EXPR:
- 	case ROUND_DIV_EXPR:
- 	case TRUNC_MOD_EXPR:
- 	case CEIL_MOD_EXPR:
- 	case FLOOR_MOD_EXPR:
- 	case ROUND_MOD_EXPR:
- 	case RDIV_EXPR:
- 	case EXACT_DIV_EXPR:
- 	case LSHIFT_EXPR:
- 	case RSHIFT_EXPR:
- 	case LROTATE_EXPR:
- 	case RROTATE_EXPR:
- 	case EQ_EXPR:
- 	case NE_EXPR:
- 	case LT_EXPR:
- 	case GT_EXPR:
  	  /* Not MIN_EXPR, MAX_EXPR.  One VARYING operand may be selected.
  	     Not bitwise operators, one VARYING operand may specify the
  	     result completely.  Not logical operators for the same reason.
! 	     Not LE/GE comparisons or unordered comparisons.  Not
! 	     COMPLEX_EXPR as one VARYING operand makes the result partly
! 	     not UNDEFINED.  */
  	  return UNDEFINED;
  
  	default:
--- 582,594 ----
  	/* Unary operators are handled with all_undefined_operands.  */
  	case PLUS_EXPR:
  	case MINUS_EXPR:
  	case POINTER_PLUS_EXPR:
  	  /* Not MIN_EXPR, MAX_EXPR.  One VARYING operand may be selected.
  	     Not bitwise operators, one VARYING operand may specify the
  	     result completely.  Not logical operators for the same reason.
! 	     Not COMPLEX_EXPR as one VARYING operand makes the result partly
! 	     not UNDEFINED.  Not *DIV_EXPR, comparisons and shifts because
! 	     the undefined operand may be promoted.  */
  	  return UNDEFINED;
  
  	default:
Index: testsuite/gcc.c-torture/execute/pr34099-2.c
===================================================================
*** testsuite/gcc.c-torture/execute/pr34099-2.c	(revision 0)
--- testsuite/gcc.c-torture/execute/pr34099-2.c	(revision 0)
***************
*** 0 ****
--- 1,47 ----
+ int test1 (int b, int c)
+ {
+   char x;
+   if (b)
+     return x / c;
+   else
+     return 1;
+ }
+ int test2 (int b, int c)
+ {
+   int x;
+   if (b)
+     return x * c;
+   else
+     return 1;
+ }
+ int test3 (int b, int c)
+ {
+   int x;
+   if (b)
+     return x % c;
+   else
+     return 1;
+ }
+ int test4 (int b, int c)
+ {
+   char x;
+   if (b)
+     return x == c;
+   else
+     return 1;
+ }
+ 
+ extern void abort (void);
+ int main()
+ {
+   if (test1(1, 1000) != 0)
+     abort ();
+   if (test2(1, 0) != 0)
+     abort ();
+   if (test3(1, 1) != 0)
+     abort ();
+   if (test4(1, 1000) != 0)
+     abort ();
+   return 0;
+ }
+ 


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]