[backport from gcc-4.8/trunk r195318 <mikpe@it.uu.se>]

gcc/

2013-01-19  Andrew Pinski  <apinski@cavium.com>

	PR tree-optimization/52631
	* tree-ssa-sccvn (visit_use): Before looking up the original
	statement, try looking up the simplified expression.

gcc/testsuite/

2013-01-19  Jeff Law  <law@redhat.com>

	PR tree-optimization/52631
	* tree-ssa/pr52631.c: New test.
	* tree-ssa/ssa-fre-9: Update expected output.

--- gcc-4.7.2/gcc/testsuite/gcc.dg/tree-ssa/pr52631.c.~1~	1970-01-01 01:00:00.000000000 +0100
+++ gcc-4.7.2/gcc/testsuite/gcc.dg/tree-ssa/pr52631.c	2013-01-20 11:25:29.330923258 +0100
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-fre1-details" } */
+
+unsigned f(unsigned a)
+{
+  unsigned b = a >> 31;
+  return b&1;
+}
+
+/* We want to verify that we replace the b & 1 with b.  */
+/* { dg-final { scan-tree-dump-times "Replaced b_\[0-9\]+ & 1 with b_\[0-9\]+ in" 1 "fre1"} } */
+ 
+/* { dg-final { cleanup-tree-dump "fre1" } } */
+
--- gcc-4.7.2/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-9.c.~1~	2011-03-25 12:59:19.000000000 +0100
+++ gcc-4.7.2/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-9.c	2013-01-20 11:25:29.330923258 +0100
@@ -23,6 +23,6 @@ void __frame_state_for1 (volatile char *
     }
 }
 
-/* { dg-final { scan-tree-dump-times "Eliminated: 1" 2 "fre1" } } */
+/* { dg-final { scan-tree-dump-times "Eliminated: 2" 2 "fre1" } } */
 /* { dg-final { scan-tree-dump-times "Insertions: 1" 2 "fre1" } } */
 /* { dg-final { cleanup-tree-dump "fre1" } } */
--- gcc-4.7.2/gcc/tree-ssa-sccvn.c.~1~	2012-08-21 15:34:19.000000000 +0200
+++ gcc-4.7.2/gcc/tree-ssa-sccvn.c	2013-01-20 11:24:49.941026366 +0100
@@ -3299,6 +3299,28 @@ visit_use (tree use)
 		}
 	      else
 		{
+		  /* First try to lookup the simplified expression.  */
+		  if (simplified)
+		    {
+		      enum gimple_rhs_class rhs_class;
+
+
+		      rhs_class = get_gimple_rhs_class (TREE_CODE (simplified));
+		      if ((rhs_class == GIMPLE_UNARY_RHS
+			   || rhs_class == GIMPLE_BINARY_RHS
+			   || rhs_class == GIMPLE_TERNARY_RHS)
+			  && valid_gimple_rhs_p (simplified))
+			{
+			  tree result = vn_nary_op_lookup (simplified, NULL);
+			  if (result)
+			    {
+			      changed = set_ssa_val_to (lhs, result);
+			      goto done;
+			    }
+			}
+		    }
+
+		  /* Otherwise visit the original statement.  */
 		  switch (get_gimple_rhs_class (code))
 		    {
 		    case GIMPLE_UNARY_RHS:
