diff mbox

[COMMITTED] Fix target/64669 -- aarch64 profilebootstrap failure

Message ID 54BFD6A7.2000305@redhat.com
State New
Headers show

Commit Message

Richard Henderson Jan. 21, 2015, 4:41 p.m. UTC
As discussed in the PR, we're committing a layering violation here.
Removing that violation fixes the ICE, which is the most important
thing for the moment.

Reviewing objdump of the stage3 cc1plus, about 90% of the instances
of ccmp instruction are followed by a conditional branch, so combine
is usually performing the optimization that the code being removed
indended.  But there are some instances that aren't optimized, so I
opened pr64713 to track that.


r~
PR target/64669
	* ccmp.c (used_in_cond_stmt_p): Remove.
	(expand_ccmp_expr): Don't use it.
diff mbox

Patch

diff --git a/gcc/ccmp.c b/gcc/ccmp.c
index 903d5a8..5d17554 100644
--- a/gcc/ccmp.c
+++ b/gcc/ccmp.c
@@ -90,9 +90,8 @@  along with GCC; see the file COPYING3.  If not see
 	 - gen_ccmp_first expands the first compare in CCMP.
 	 - gen_ccmp_next expands the following compares.
 
-     * If the final result is not used in a COND_EXPR (checked by function
-       used_in_cond_stmt_p), it calls cstorecc4 pattern to store the CC to a
-       general register.
+     * We use cstorecc4 pattern to convert the CCmode intermediate to
+       the integer mode result that expand_normal is expecting.
 
    Since the operands of the later compares might clobber CC reg, we do not
    emit the insns during expand.  We keep the insn sequences in two seq
@@ -156,31 +155,6 @@  ccmp_candidate_p (gimple g)
   return false;
 }
 
-/* Check whether EXP is used in a GIMPLE_COND statement or not.  */
-static bool
-used_in_cond_stmt_p (tree exp)
-{
-  bool expand_cond = false;
-  imm_use_iterator ui;
-  gimple use_stmt;
-  FOR_EACH_IMM_USE_STMT (use_stmt, ui, exp)
-    if (gimple_code (use_stmt) == GIMPLE_COND)
-      {
-	tree op1 = gimple_cond_rhs (use_stmt);
-	if (integer_zerop (op1))
-	  expand_cond = true;
-	BREAK_FROM_IMM_USE_STMT (ui);
-      }
-    else if (gimple_code (use_stmt) == GIMPLE_ASSIGN
-	     && gimple_expr_code (use_stmt) == COND_EXPR)
-      {
-	if (gimple_assign_rhs1 (use_stmt) == exp)
-	  expand_cond = true;
-      }
-
-  return expand_cond;
-}
-
 /* PREV is the CC flag from precvious compares.  The function expands the
    next compare based on G which ops previous compare with CODE.
    PREP_SEQ returns all insns to prepare opearands for compare.
@@ -301,20 +275,9 @@  expand_ccmp_expr (gimple g)
       enum machine_mode cc_mode = CCmode;
       tree lhs = gimple_assign_lhs (g);
 
-      /* TMP should be CC.  If it is used in a GIMPLE_COND, just return it.
-	 Note: Target needs to define "cbranchcc4".  */
-      if (used_in_cond_stmt_p (lhs))
-	{
-	  emit_insn (prep_seq);
-	  emit_insn (gen_seq);
-	  return tmp;
-	}
-
 #ifdef SELECT_CC_MODE
       cc_mode = SELECT_CC_MODE (NE, tmp, const0_rtx);
 #endif
-      /* If TMP is not used in a GIMPLE_COND, store it with a csctorecc4_optab.
-	 Note: Target needs to define "cstorecc4".  */
       icode = optab_handler (cstore_optab, cc_mode);
       if (icode != CODE_FOR_nothing)
 	{
diff --git a/gcc/testsuite/g++.dg/torture/pr64669.C b/gcc/testsuite/g++.dg/torture/pr64669.C
new file mode 100644
index 0000000..b207739
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/pr64669.C
@@ -0,0 +1,63 @@ 
+typedef unsigned int source_location;
+typedef source_location location_t;
+extern void error_at (location_t, const char *, ...)
+  __attribute__ ((__format__ (__gcc_tdiag__, 2, 3)))
+  __attribute__ ((__nonnull__ (2)));
+
+class Lex
+{
+  static int fetch_char (const char *str, unsigned int *value);
+  location_t location () const;
+  const char *advance_one_utf8_char (const char *, unsigned int *, bool *);
+  const char *advance_one_char (const char *, bool, unsigned int *, bool *);
+  int lineoff_;
+  int lineno_;
+};
+
+int
+Lex::fetch_char (const char *p, unsigned int *value)
+{
+  unsigned char c = *p;
+  if (c <= 0x7f)
+    {
+      return 1;
+    }
+  else if ((c & 0xe0) == 0xc0 && (p[1] & 0xc0) == 0x80)
+    {
+      *value = (((c & 0x1f) << 6) + (p[1] & 0x3f));
+    }
+  {
+    *value = (((c & 0xf) << 12) + (p[2] & 0x3f));
+  }
+}
+
+const char *
+Lex::advance_one_utf8_char (const char *p, unsigned int *value,
+			    bool * issued_error)
+{
+  *issued_error = false;
+  if (*p == '\0')
+    {
+      *issued_error = true;
+      return p + 1;
+    }
+  int adv = Lex::fetch_char (p, value);
+  if (*value == 0xfeff && (this->lineno_ != 1 || this->lineoff_ != 0))
+    {
+      *issued_error = true;
+    }
+  return p + adv;
+}
+
+const char *
+Lex::advance_one_char (const char *p, bool is_single_quote,
+		       unsigned int *value, bool * is_character)
+{
+  {
+    bool issued_error;
+    const char *ret = this->advance_one_utf8_char (p, value, &issued_error);
+    if (is_single_quote
+	&& (*value == '\'' || *value == '\n') && !issued_error)
+      error_at (this->location (), "invalid character literal");
+  }
+}