diff mbox

Fix PR65758

Message ID alpine.LSU.2.11.1504141020130.6786@zhemvz.fhfr.qr
State New
Headers show

Commit Message

Richard Biener April 14, 2015, 8:21 a.m. UTC
This fixes PR65758 - the patch is mostly a split-out from the
patch unifying CCP and copyprop where I noticed the bitmask
comparisons against -1 are not working as expected and thus we
get invalid CONSTANT -> CONSTANT transitions because that first
CONSTANT should have been VARYING...

Bootstrap and regtest in progress on x86_64-unknown-linux-gnu.

Probably need to backport this at some point as this is a latent
issue from the wide-int merge.

Richard.

2015-04-14  Richard Biener  <rguenther@suse.de>

	PR tree-optimization/65758
	* tree-ssa-ccp.c (get_value_from_alignment): Adjust mask test
	against -1.
	(ccp_lattice_meet): Likewise.
	(bit_value_unop): Likewise.
	(bit_value_binop): Likewise.
	(bit_value_assume_aligned): Likewise.

	* gfortran.fortran-torture/compile/pr65758.f90: New testcase.
diff mbox

Patch

Index: gcc/tree-ssa-ccp.c
===================================================================
--- gcc/tree-ssa-ccp.c	(revision 222076)
+++ gcc/tree-ssa-ccp.c	(working copy)
@@ -585,7 +585,8 @@  get_value_from_alignment (tree expr)
   val.mask = (POINTER_TYPE_P (type) || TYPE_UNSIGNED (type)
 	      ? wi::mask <widest_int> (TYPE_PRECISION (type), false)
 	      : -1).and_not (align / BITS_PER_UNIT - 1);
-  val.lattice_val = val.mask == -1 ? VARYING : CONSTANT;
+  val.lattice_val
+    = wi::sext (val.mask, TYPE_PRECISION (type)) == -1 ? VARYING : CONSTANT;
   if (val.lattice_val == CONSTANT)
     val.value = build_int_cstu (type, bitpos / BITS_PER_UNIT);
   else
@@ -990,7 +991,7 @@  ccp_lattice_meet (ccp_prop_value_t *val1
       val1->mask = (val1->mask | val2->mask
 		    | (wi::to_widest (val1->value)
 		       ^ wi::to_widest (val2->value)));
-      if (val1->mask == -1)
+      if (wi::sext (val1->mask, TYPE_PRECISION (TREE_TYPE (val1->value))) == -1)
 	{
 	  val1->lattice_val = VARYING;
 	  val1->value = NULL_TREE;
@@ -1499,10 +1500,10 @@  bit_value_unop (enum tree_code code, tre
 
   gcc_assert ((rval.lattice_val == CONSTANT
 	       && TREE_CODE (rval.value) == INTEGER_CST)
-	      || rval.mask == -1);
+	      || wi::sext (rval.mask, TYPE_PRECISION (TREE_TYPE (rhs))) == -1);
   bit_value_unop_1 (code, type, &value, &mask,
 		    TREE_TYPE (rhs), value_to_wide_int (rval), rval.mask);
-  if (mask != -1)
+  if (wi::sext (mask, TYPE_PRECISION (type)) != -1)
     {
       val.lattice_val = CONSTANT;
       val.mask = mask;
@@ -1540,14 +1541,16 @@  bit_value_binop (enum tree_code code, tr
 
   gcc_assert ((r1val.lattice_val == CONSTANT
 	       && TREE_CODE (r1val.value) == INTEGER_CST)
-	      || r1val.mask == -1);
+	      || wi::sext (r1val.mask,
+			   TYPE_PRECISION (TREE_TYPE (rhs1))) == -1);
   gcc_assert ((r2val.lattice_val == CONSTANT
 	       && TREE_CODE (r2val.value) == INTEGER_CST)
-	      || r2val.mask == -1);
+	      || wi::sext (r2val.mask,
+			   TYPE_PRECISION (TREE_TYPE (rhs2))) == -1);
   bit_value_binop_1 (code, type, &value, &mask,
 		     TREE_TYPE (rhs1), value_to_wide_int (r1val), r1val.mask,
 		     TREE_TYPE (rhs2), value_to_wide_int (r2val), r2val.mask);
-  if (mask != -1)
+  if (wi::sext (mask, TYPE_PRECISION (type)) != -1)
     {
       val.lattice_val = CONSTANT;
       val.mask = mask;
@@ -1596,7 +1599,7 @@  bit_value_assume_aligned (gimple stmt, t
     return ptrval;
   gcc_assert ((ptrval.lattice_val == CONSTANT
 	       && TREE_CODE (ptrval.value) == INTEGER_CST)
-	      || ptrval.mask == -1);
+	      || wi::sext (ptrval.mask, TYPE_PRECISION (type)) == -1);
   if (attr == NULL_TREE)
     {
       /* Get aligni and misaligni from __builtin_assume_aligned.  */
@@ -1648,7 +1651,7 @@  bit_value_assume_aligned (gimple stmt, t
   bit_value_binop_1 (BIT_AND_EXPR, type, &value, &mask,
 		     type, value_to_wide_int (ptrval), ptrval.mask,
 		     type, value_to_wide_int (alignval), alignval.mask);
-  if (mask != -1)
+  if (wi::sext (mask, TYPE_PRECISION (type)) != -1)
     {
       val.lattice_val = CONSTANT;
       val.mask = mask;
Index: gcc/testsuite/gfortran.fortran-torture/compile/pr65758.f90
===================================================================
--- gcc/testsuite/gfortran.fortran-torture/compile/pr65758.f90	(revision 0)
+++ gcc/testsuite/gfortran.fortran-torture/compile/pr65758.f90	(working copy)
@@ -0,0 +1,20 @@ 
+      SUBROUTINE USER_MESSAGE (MESSAGE)
+      CHARACTER MSGL*1
+      CHARACTER, INTENT(IN) :: MESSAGE*(*)
+      CHARACTER(21)  :: LEADER(4)
+      CHARACTER(132) :: MSG_TEXT*132
+      LOGICAL, SAVE  :: FIRST
+ 100  IR = MIN (LM, IL+INDEX(MESSAGE(MIN(LM,IL+1):LM)//MSGL,MSGL))
+      IF (FIRST) THEN
+        IF (INDEX(MESSAGE(IL:IR),'WARN') .NE. 0) THEN
+          K = 2
+        ELSE IF (INDEX(MESSAGE(IL:IR),'INFORM') .NE. 0) THEN
+          K = 3
+          GO TO 100
+        ENDIF
+      ELSE
+        IF (MESSAGE(IR:IR) .EQ. MSGL) THEN
+          MSG_TEXT = LEADER(K)//MESSAGE(IL+1:IR-1)
+        ENDIF
+      ENDIF
+      END