diff mbox

[GIMPLE,FE] Avoid ICE with __builtin_abs

Message ID CAAgBjMk43ewF+CjrCKnEr60WuvhvAWppsRpfJS4kMg74BEr1wQ@mail.gmail.com
State New
Headers show

Commit Message

Prathamesh Kulkarni Feb. 4, 2017, 11:45 a.m. UTC
Hi,
The following test-case ICE's with -fgimple:

int __GIMPLE foo(int a)
{
  int t1;
  t1_1 = __builtin_abs (a);
  return t1_1;
}

gimplefe-2.c:4:3: internal compiler error: in get_callee_fndecl, at tree.c:9500
   t1_1 = __builtin_abs (a);
   ^~~~
0xe96e8d get_callee_fndecl(tree_node const*)
../../gcc/gcc/tree.c:9500
0x924d75 gimple_build_call_from_tree(tree_node*)
../../gcc/gcc/gimple.c:351
0x6c86b3 c_parser_gimple_statement
../../gcc/gcc/c/gimple-parser.c:393
0x6c86b3 c_parser_gimple_compound_statement
../../gcc/gcc/c/gimple-parser.c:216
0x6c86b3 c_parser_parse_gimple_body(c_parser*)
../../gcc/gcc/c/gimple-parser.c:93
0x6b04f1 c_parser_declaration_or_fndef
../../gcc/gcc/c/c-parser.c:2081
0x6b883b c_parser_external_declaration
../../gcc/gcc/c/c-parser.c:1464
0x6b92a1 c_parser_translation_unit
../../gcc/gcc/c/c-parser.c:1344
0x6b92a1 c_parse_file()
../../gcc/gcc/c/c-parser.c:18141
0x717832 c_common_parse_file()
../../gcc/gcc/c-family/c-opts.c:1102

This happens because __builtin_abs(a) gets folded to <nop_expr<abs_expr<a>>
and get_callee_fndecl expects CALL_EXPR.

The attached patch tries to fix the issue by building gimple_assign
with appropriate subcode
for functions that get folded to expression instead of trying to build
it as a function-call.
Is it OK to commit after bootstrap+test ?

Thanks,
Prathamesh
2017-02-04  Prathamesh Kulkarni  <prathamesh.kulkarni@linaro.org>

	* gimple-pretty-print.c (dump_unary_rhs): Change dump format for
	ABS_EXPR for gimple dump.
	* tree-pretty-print.c (dump_generic_node): Likewise.

c/
	* gimple-parser.c (c_parser_gimple_statement): Check if rhs.value is
	CALL_EXPR and build gimple_assign if it isn't.

testsuite/
	* gcc.dg/gimplefe-23.c: New test-case.

Comments

Richard Biener Feb. 6, 2017, 7:58 a.m. UTC | #1
On Sat, 4 Feb 2017, Prathamesh Kulkarni wrote:

> Hi,
> The following test-case ICE's with -fgimple:
> 
> int __GIMPLE foo(int a)
> {
>   int t1;
>   t1_1 = __builtin_abs (a);
>   return t1_1;
> }
> 
> gimplefe-2.c:4:3: internal compiler error: in get_callee_fndecl, at tree.c:9500
>    t1_1 = __builtin_abs (a);
>    ^~~~
> 0xe96e8d get_callee_fndecl(tree_node const*)
> ../../gcc/gcc/tree.c:9500
> 0x924d75 gimple_build_call_from_tree(tree_node*)
> ../../gcc/gcc/gimple.c:351
> 0x6c86b3 c_parser_gimple_statement
> ../../gcc/gcc/c/gimple-parser.c:393
> 0x6c86b3 c_parser_gimple_compound_statement
> ../../gcc/gcc/c/gimple-parser.c:216
> 0x6c86b3 c_parser_parse_gimple_body(c_parser*)
> ../../gcc/gcc/c/gimple-parser.c:93
> 0x6b04f1 c_parser_declaration_or_fndef
> ../../gcc/gcc/c/c-parser.c:2081
> 0x6b883b c_parser_external_declaration
> ../../gcc/gcc/c/c-parser.c:1464
> 0x6b92a1 c_parser_translation_unit
> ../../gcc/gcc/c/c-parser.c:1344
> 0x6b92a1 c_parse_file()
> ../../gcc/gcc/c/c-parser.c:18141
> 0x717832 c_common_parse_file()
> ../../gcc/gcc/c-family/c-opts.c:1102
> 
> This happens because __builtin_abs(a) gets folded to <nop_expr<abs_expr<a>>
> and get_callee_fndecl expects CALL_EXPR.
> 
> The attached patch tries to fix the issue by building gimple_assign
> with appropriate subcode
> for functions that get folded to expression instead of trying to build
> it as a function-call.
> Is it OK to commit after bootstrap+test ?

No.  The proper fix is to not use the C frontend call-expr parsing
and building -- it does have many more issues I think.

Richard.

> Thanks,
> Prathamesh
>
diff mbox

Patch

diff --git a/gcc/c/gimple-parser.c b/gcc/c/gimple-parser.c
index 7feb6d0..4e2ae37 100644
--- a/gcc/c/gimple-parser.c
+++ b/gcc/c/gimple-parser.c
@@ -401,10 +401,22 @@  c_parser_gimple_statement (c_parser *parser, gimple_seq *seq)
       rhs = c_parser_gimple_unary_expression (parser);
       if (rhs.value != error_mark_node)
 	{
-	  gimple *call = gimple_build_call_from_tree (rhs.value);
-	  gimple_call_set_lhs (call, lhs.value);
-	  gimple_seq_add_stmt (seq, call);
-	  gimple_set_location (call, loc);
+	  if (TREE_CODE (rhs.value) == CALL_EXPR)
+	    {
+	      gimple *call = gimple_build_call_from_tree (rhs.value);
+	      gimple_call_set_lhs (call, lhs.value);
+	      gimple_seq_add_stmt (seq, call);
+	      gimple_set_location (call, loc);
+	    }
+	  else
+	    {
+	      tree value = tree_strip_nop_conversions (rhs.value);
+	      gcc_assert (get_gimple_rhs_class (TREE_CODE (value))
+			  != GIMPLE_INVALID_RHS);
+	      gassign *assign = gimple_build_assign (lhs.value, value);
+	      gimple_seq_add_stmt (seq, assign);
+	      gimple_set_location (assign, loc);
+	    }
 	}
       return;
     }
diff --git a/gcc/gimple-pretty-print.c b/gcc/gimple-pretty-print.c
index 91c839d..f773d85 100644
--- a/gcc/gimple-pretty-print.c
+++ b/gcc/gimple-pretty-print.c
@@ -323,9 +323,18 @@  dump_unary_rhs (pretty_printer *buffer, gassign *gs, int spc, int flags)
       break;
 
     case ABS_EXPR:
-      pp_string (buffer, "ABS_EXPR <");
-      dump_generic_node (buffer, rhs, spc, flags, false);
-      pp_greater (buffer);
+      if (flags & TDF_GIMPLE)
+	{
+	  pp_string (buffer, "__builtin_abs (");
+	  dump_generic_node (buffer, rhs, spc, flags, false);
+	  pp_right_paren (buffer);
+	}
+      else
+	{
+	  pp_string (buffer, "ABS_EXPR <");
+	  dump_generic_node (buffer, rhs, spc, flags, false);
+	  pp_greater (buffer);
+	}
       break;
 
     default:
diff --git a/gcc/testsuite/gcc.dg/gimplefe-23.c b/gcc/testsuite/gcc.dg/gimplefe-23.c
new file mode 100644
index 0000000..1448030
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/gimplefe-23.c
@@ -0,0 +1,11 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O -fgimple -fdump-tree-ssa-gimple" } */
+
+int __GIMPLE foo(int a)
+{
+  int t1;
+  t1_1 = __builtin_abs (a);
+  return t1_1;
+}
+
+/* { dg-final { scan-tree-dump "__builtin_abs" "ssa" } } */
diff --git a/gcc/tree-pretty-print.c b/gcc/tree-pretty-print.c
index d823c2e..f1a5bdd 100644
--- a/gcc/tree-pretty-print.c
+++ b/gcc/tree-pretty-print.c
@@ -2441,9 +2441,18 @@  dump_generic_node (pretty_printer *pp, tree node, int spc, int flags,
       break;
 
     case ABS_EXPR:
-      pp_string (pp, "ABS_EXPR <");
-      dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false);
-      pp_greater (pp);
+      if (flags & TDF_GIMPLE)
+	{
+	  pp_string (pp, "__builtin_abs (");
+	  dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false);
+	  pp_right_paren (pp);
+	}
+      else
+	{
+	  pp_string (pp, "ABS_EXPR <");
+          dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false);
+          pp_greater (pp);
+	}
       break;
 
     case RANGE_EXPR: