Index: ChangeLog
===================================================================
--- ChangeLog	(revision 229592)
+++ ChangeLog	(working copy)
@@ -1,3 +1,12 @@
+2015-10-30  Vladimir Makarov  <vmakarov@redhat.com>
+
+	PR rtl-optimization/68106
+	* lra-remat.c (input_regno_present_p): Process hard regs
+	explicitly present in machine description insns.
+	(call_used_input_regno_present_p): Ditto.
+	(calculate_gen_cands): Ditto.
+	(do_remat): Ditto.
+
 2015-10-30  Jim Wilson  <jim.wilson@linaro.org>
 
 	* config/arm/neon-testgen.ml: Fix comment typo.
Index: lra-remat.c
===================================================================
--- lra-remat.c	(revision 229592)
+++ lra-remat.c	(working copy)
@@ -695,12 +695,17 @@ calculate_local_reg_remat_bb_data (void)
 static bool
 input_regno_present_p (rtx_insn *insn, int regno)
 {
+  int iter;
   lra_insn_recog_data_t id = lra_get_insn_recog_data (insn);
+  struct lra_static_insn_data *static_id = id->insn_static_data;
   struct lra_insn_reg *reg;
-
-  for (reg = id->regs; reg != NULL; reg = reg->next)
-    if (reg->type == OP_IN && reg->regno == regno)
-      return true;
+  
+  for (iter = 0; iter < 2; iter++)
+    for (reg = (iter == 0 ? id->regs : static_id->hard_regs);
+	 reg != NULL;
+	 reg = reg->next)
+      if (reg->type == OP_IN && reg->regno == regno)
+	return true;
   return false;
 }
 
@@ -708,13 +713,18 @@ input_regno_present_p (rtx_insn *insn, i
 static bool
 call_used_input_regno_present_p (rtx_insn *insn)
 {
+  int iter;
   lra_insn_recog_data_t id = lra_get_insn_recog_data (insn);
+  struct lra_static_insn_data *static_id = id->insn_static_data;
   struct lra_insn_reg *reg;
 
-  for (reg = id->regs; reg != NULL; reg = reg->next)
-    if (reg->type == OP_IN && reg->regno <= FIRST_PSEUDO_REGISTER
-	&& TEST_HARD_REG_BIT (call_used_reg_set, reg->regno))
-      return true;
+  for (iter = 0; iter < 2; iter++)
+    for (reg = (iter == 0 ? id->regs : static_id->hard_regs);
+	 reg != NULL;
+	 reg = reg->next)
+      if (reg->type == OP_IN && reg->regno <= FIRST_PSEUDO_REGISTER
+	  && TEST_HARD_REG_BIT (call_used_reg_set, reg->regno))
+	return true;
   return false;
 }
 
@@ -761,11 +771,13 @@ calculate_gen_cands (void)
 	if (INSN_P (insn))
 	  {
 	    lra_insn_recog_data_t id = lra_get_insn_recog_data (insn);
+	    struct lra_static_insn_data *static_id = id->insn_static_data;
 	    struct lra_insn_reg *reg;
 	    unsigned int uid;
 	    bitmap_iterator bi;
 	    cand_t cand;
 	    rtx set;
+	    int iter;
 	    int src_regno = -1, dst_regno = -1;
 
 	    if ((set = single_set (insn)) != NULL
@@ -777,26 +789,29 @@ calculate_gen_cands (void)
 
 	    /* Update gen_cands:  */
 	    bitmap_clear (&temp_bitmap);
-	    for (reg = id->regs; reg != NULL; reg = reg->next)
-	      if (reg->type != OP_IN
-		  || find_regno_note (insn, REG_DEAD, reg->regno) != NULL)
-		EXECUTE_IF_SET_IN_BITMAP (&gen_insns, 0, uid, bi)
-		  {
-		    rtx_insn *insn2 = lra_insn_recog_data[uid]->insn;
-
-		    cand = insn_to_cand[INSN_UID (insn2)];
-		    gcc_assert (cand != NULL);
-		    /* Ignore the reload insn.  */
-		    if (src_regno == cand->reload_regno
-			&& dst_regno == cand->regno)
-		      continue;
-		    if (cand->regno == reg->regno
-			|| input_regno_present_p (insn2, reg->regno))
-		      {
-			bitmap_clear_bit (gen_cands, cand->index);
-			bitmap_set_bit (&temp_bitmap, uid);
-		      }
-		  }
+	    for (iter = 0; iter < 2; iter++)
+	      for (reg = (iter == 0 ? id->regs : static_id->hard_regs);
+		   reg != NULL;
+		   reg = reg->next)
+		if (reg->type != OP_IN
+		    || find_regno_note (insn, REG_DEAD, reg->regno) != NULL)
+		  EXECUTE_IF_SET_IN_BITMAP (&gen_insns, 0, uid, bi)
+		    {
+		      rtx_insn *insn2 = lra_insn_recog_data[uid]->insn;
+		      
+		      cand = insn_to_cand[INSN_UID (insn2)];
+		      gcc_assert (cand != NULL);
+		      /* Ignore the reload insn.  */
+		      if (src_regno == cand->reload_regno
+			  && dst_regno == cand->regno)
+			continue;
+		      if (cand->regno == reg->regno
+			  || input_regno_present_p (insn2, reg->regno))
+			{
+			  bitmap_clear_bit (gen_cands, cand->index);
+			  bitmap_set_bit (&temp_bitmap, uid);
+			}
+		    }
 	    
 	    if (CALL_P (insn))
 	      EXECUTE_IF_SET_IN_BITMAP (&gen_insns, 0, uid, bi)
@@ -1070,6 +1085,7 @@ do_remat (void)
 	  unsigned int cid;
 	  bitmap_iterator bi;
 	  rtx set;
+	  int iter;
 	  int src_regno = -1, dst_regno = -1;
 
 	  if ((set = single_set (insn)) != NULL
@@ -1155,21 +1171,24 @@ do_remat (void)
 	  bitmap_clear (&temp_bitmap);
 	  /* Update avail_cands (see analogous code for
 	     calculate_gen_cands).  */
-	  for (reg = id->regs; reg != NULL; reg = reg->next)
-	    if (reg->type != OP_IN
-		|| find_regno_note (insn, REG_DEAD, reg->regno) != NULL)
-	      EXECUTE_IF_SET_IN_BITMAP (&avail_cands, 0, cid, bi)
-		{
-		  cand = all_cands[cid];
-
-		  /* Ignore the reload insn.  */
-		  if (src_regno == cand->reload_regno
-		      && dst_regno == cand->regno)
-		    continue;
-		  if (cand->regno == reg->regno
-		      || input_regno_present_p (cand->insn, reg->regno))
-		    bitmap_set_bit (&temp_bitmap, cand->index);
-		}
+	  for (iter = 0; iter < 2; iter++)
+	    for (reg = (iter == 0 ? id->regs : static_id->hard_regs);
+		 reg != NULL;
+		 reg = reg->next)
+	      if (reg->type != OP_IN
+		  || find_regno_note (insn, REG_DEAD, reg->regno) != NULL)
+		EXECUTE_IF_SET_IN_BITMAP (&avail_cands, 0, cid, bi)
+		  {
+		    cand = all_cands[cid];
+		    
+		    /* Ignore the reload insn.  */
+		    if (src_regno == cand->reload_regno
+			&& dst_regno == cand->regno)
+		      continue;
+		    if (cand->regno == reg->regno
+			|| input_regno_present_p (cand->insn, reg->regno))
+		      bitmap_set_bit (&temp_bitmap, cand->index);
+		  }
 
 	  if (CALL_P (insn))
 	    EXECUTE_IF_SET_IN_BITMAP (&avail_cands, 0, cid, bi)
Index: testsuite/ChangeLog
===================================================================
--- testsuite/ChangeLog	(revision 229592)
+++ testsuite/ChangeLog	(working copy)
@@ -1,3 +1,8 @@
+2015-10-30  Vladimir Makarov  <vmakarov@redhat.com>
+
+	PR rtl-optimization/68106
+	* testsuite/gcc.target/aarch64/pr68106.c: New.
+
 2015-10-30  Steven G. Kargl  <kargl@gcc.gnu.org>
 
 	PR fortran/36192
Index: testsuite/gcc.target/aarch64/pr68106.c
===================================================================
--- testsuite/gcc.target/aarch64/pr68106.c	(revision 0)
+++ testsuite/gcc.target/aarch64/pr68106.c	(working copy)
@@ -0,0 +1,50 @@
+/* { dg-do run { target aarch64*-*-* } } */
+/* { dg-options "-O" } */
+
+typedef signed long long int S;
+typedef unsigned long long int U;
+typedef __int128 W;
+__attribute__ ((noinline, noclone))
+U upseu (U x, S y, int *ovf)
+{
+  U res;
+  *ovf = __builtin_add_overflow (x, y, &res);
+  return res;
+}
+U
+usueu (U x, U y, int *ovf)
+{
+  U res;
+  *ovf = __builtin_sub_overflow (x, y, &res);
+  return res;
+}
+U
+usseu (U x, S y, int *ovf)
+{
+  U res;
+  *ovf = __builtin_sub_overflow (x, y, &res);
+  return res;
+}
+int
+main ()
+{
+  int i, j;
+  for (i = 0; i < ((unsigned char) ~0); i++)
+    for (j = 0; j < ((unsigned char) ~0); j++)
+      {
+	U u1 = ((W) i << ((8 - 1) * 8));
+	S s2 = ((W) j << ((8 - 1) * 8)) + (-0x7fffffffffffffffLL - 1);
+	U u2 = ((W) j << ((8 - 1) * 8));
+	W w;
+	int ovf;
+	w = ((W) u1) + ((W) s2);
+	if (upseu (u1, s2, &ovf) != (U) w || ovf != (w != (U) w))
+	  __builtin_abort ();
+	w = ((W) u1) - ((W) u2);
+	if (usueu (u1, u2, &ovf) != (U) w || ovf != (w != (U) w))
+	  __builtin_abort ();
+	w = ((W) u1) - ((W) s2);
+	if (usseu (u1, s2, &ovf) != (U) w || ovf != (w != (U) w))
+	  __builtin_abort ();
+      }
+}
