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

> 


-- 
Richard Biener <rguenther@suse.de>
SUSE LINUX GmbH, GF: Felix Imendoerffer, Jane Smithard, Graham Norton, HRB 21284 (AG Nuernberg)
Richard Biener Feb. 6, 2017, 3:26 p.m. UTC | #2
On Mon, 6 Feb 2017, Richard Biener wrote:

> 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.


Sth as simple as


for example fixes the bogus promotions inserted for

short int __GIMPLE ()
foo (short int s)
{
  short int D_1803;

  bb_2:
  D_1803 = s;

L0:
  return D_1803;

}


int __GIMPLE ()
main (int argc, char * * argv)
{
  short int s;
  int D_1805;
  int _1;
  short _2;

  bb_2:
  s = (short int) argc;
  _1 = (int) s;
  _2 = foo (_1);
  D_1805 = (int) _2;

L0:
  return D_1805;

}

it should also fix the folding you see.  Otherwise untested, of course
(and we shouldn't build a CALL_EXPR but instead refactor this so we
can build a GIMPLE_CALL directly)

Richard.Index: gcc/c/gimple-parser.c
===================================================================
--- gcc/c/gimple-parser.c	(revision 245203)
+++ gcc/c/gimple-parser.c	(working copy)
@@ -946,17 +946,11 @@
 	    orig_expr = expr;
 	    start = expr.get_start ();
 	    finish = c_parser_tokens_buf (parser, 0)->get_finish ();
-	    expr.value = c_build_function_call_vec (expr_loc, arg_loc,
-						    expr.value,
-						    exprlist, origtypes);
+	    expr.value = build_call_vec (TREE_TYPE (TREE_TYPE (expr.value)),
+					 expr.value, exprlist);
+	    SET_EXPR_LOCATION (expr.value, expr_loc);
 	    set_c_expr_source_range (&expr, start, finish);
-
 	    expr.original_code = ERROR_MARK;
-	    if (TREE_CODE (expr.value) == INTEGER_CST
-		&& TREE_CODE (orig_expr.value) == FUNCTION_DECL
-		&& DECL_BUILT_IN_CLASS (orig_expr.value) == BUILT_IN_NORMAL
-		&& DECL_FUNCTION_CODE (orig_expr.value) == BUILT_IN_CONSTANT_P)
-	      expr.original_code = C_MAYBE_CONST_EXPR;
 	    expr.original_type = NULL;
 	    if (exprlist)
 	      {

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: