Bug 83660

Summary: ICE with vec_extract inside expression statement
Product: gcc Reporter: Zoltan Hidvegi <zoltan>
Component: targetAssignee: acsawdey
Status: RESOLVED FIXED    
Severity: normal CC: acsawdey, jakub, kelvin, meissner, rguenth, segher, willschm, wschmidt
Priority: P3 Keywords: ice-on-valid-code
Version: 7.2.1   
Target Milestone: 8.0   
Host: Target: powerpc*-*-*
Build: Known to work:
Known to fail: Last reconfirmed: 2018-01-03 00:00:00

Description Zoltan Hidvegi 2018-01-03 06:47:35 UTC
Compile the following with g++ -mcpu=power7 -S ppc_vec_extract_ice.C
This probably happens with ppc64le as well. -mcpu=power7 is needed to make the move go through memory, with power8 direct move instruction is used and there is no coredump.

#include <altivec.h>

typedef __vector unsigned int  uvec32_t  __attribute__((__aligned__(16)));

unsigned get_word(uvec32_t v)
{
    return ({const unsigned _B1 = 32;
            vec_extract((uvec32_t)v, 2);});
}
Comment 1 Bill Schmidt 2018-01-03 14:22:31 UTC
Confirmed on trunk with ppc64le.  I don't think the direct move instruction is involved since the problem occurs during gimplification, though it's mystifying to me why the target CPU should matter.  Note that vec_extract has special handling during parsing, in gcc/config/rs6000/rs6000-c.c, and this is probably at fault.  That's old code, so I imagine this bug has been out there forever.

wschmidt@pike:~/src$ $GCC_INSTALL/bin/g++ -mcpu=power7 -S pr83660.C
pr83660.C: In function 'unsigned int get_word(__vector(4) unsigned int)':
pr83660.C:5:10: internal compiler error: in verify_gimple_stmt, at tree-cfg.c:5085
 unsigned get_word(uvec32_t v)
          ^~~~~~~~
0x10c5e54f verify_gimple_stmt
	/home/wschmidt/gcc/gcc-mainline-base/gcc/tree-cfg.c:5085
0x10c5f467 verify_gimple_in_seq_2
	/home/wschmidt/gcc/gcc-mainline-base/gcc/tree-cfg.c:5200
0x10c5f427 verify_gimple_in_seq_2
	/home/wschmidt/gcc/gcc-mainline-base/gcc/tree-cfg.c:5168
0x10c66237 verify_gimple_in_seq(gimple*)
	/home/wschmidt/gcc/gcc-mainline-base/gcc/tree-cfg.c:5239
0x108a8047 gimplify_body(tree_node*, bool)
	/home/wschmidt/gcc/gcc-mainline-base/gcc/gimplify.c:12694
0x108a84a3 gimplify_function_tree(tree_node*)
	/home/wschmidt/gcc/gcc-mainline-base/gcc/gimplify.c:12784
0x10663557 cgraph_node::analyze()
	/home/wschmidt/gcc/gcc-mainline-base/gcc/cgraphunit.c:670
0x10667763 analyze_functions
	/home/wschmidt/gcc/gcc-mainline-base/gcc/cgraphunit.c:1131
0x1066913b symbol_table::finalize_compilation_unit()
	/home/wschmidt/gcc/gcc-mainline-base/gcc/cgraphunit.c:2690
Please submit a full bug report,
with preprocessed source if appropriate.
Please include the complete backtrace with any bug report.
See <https://gcc.gnu.org/bugs/> for instructions.
Comment 2 Bill Schmidt 2018-01-03 14:24:55 UTC
Also fails with -mcpu=power6 -maltivec.

Also succeeds with -mcpu=power9.
Comment 3 Segher Boessenkool 2018-01-03 15:34:07 UTC
Doesn't fail as C, only as C++.  Also fails on 32-bit.
Comment 4 kelvin 2018-01-09 20:51:02 UTC
Author: kelvin
Date: Tue Jan  9 20:50:30 2018
New Revision: 256394

URL: https://gcc.gnu.org/viewcvs?rev=256394&root=gcc&view=rev
Log:

Use this branch to reproduce and resolve PR 83660.


Added:
    branches/ibm/pr83660/
      - copied from r256393, trunk/
Comment 5 kelvin 2018-01-19 19:13:38 UTC
The ICE in verify_gimple_stmt apparently occurs because gimplification wants to produce an "<<< Unknown GIMPLE statement: gimple_with_cleanup_expr >>>".  The cleanup expression is a CLOBBER directive on a temporary variable that is introduced with a match_scratch pattern in the expansion for this built-in.

The Power9 version of the expansion does not introduce the scratch operand, nor the CLOBBER directive, which explains why it does not exhibit this problem.

Based on other observations captured in the comments of this problem report, it appears that the problem is introduced by the C++ parser and its handling of the compound statement nested within the return expression.

I'm going to unassign myself from this task for now.
Comment 6 kelvin 2018-01-23 01:26:39 UTC
For what it's worth, I reconfigured my build with --enable-checking=yes,tree in hopes that this would help us find the C++ parser code that is responsible for creating the problematic syntax tree.  The resulting compiler produces the exact same ICE with the same backtrace as has been captured already in these comments.
Comment 7 Will Schmidt 2018-03-20 17:01:25 UTC
The ICE is triggered on the gcc_unreachable() at the bottom of the switch(gimple_code(stmt)) clause in gimple-low.c: lower_stmt().

We enter the switch with our gimple_code(stmt) == GIMPLE_WITH_CLEANUP_EXPR.

# cfun at this point is:
(gdb) pcfun
get_word (__vector __bool int v)
{
  unsigned int D.3236;

  {
    const unsigned int _B2;

    _B2 = 32;
    D.3235 = v;
    <<< Unknown GIMPLE statement: gimple_with_cleanup_expr >>>

    retval.0 = BIT_FIELD_REF <D.3235, 32, 64>;
  }
  D.3236 = retval.0;
  return D.3236;
}


Doing some code-browsing, I see some logic to handle GIMPLE_WITH_CLEANUP_EXPR in remap_gimple_stmt() and in gimple_copy() , but not in lower_stmt().

However, at gimplify.c: gimplify_cleanup_point_expr() i see the comment:

/* Gimplify a CLEANUP_POINT_EXPR.  Currently this works by adding
   GIMPLE_WITH_CLEANUP_EXPRs to the prequeue as we encounter cleanups while
   gimplifying the body, and converting them to TRY_FINALLY_EXPRs when we
   return to this function.

Debug on the logic there...
  for (iter = gsi_start (body_sequence); !gsi_end_p (iter); )
    {
      gimple *wce = gsi_stmt (iter);
      if (gimple_code (wce) == GIMPLE_WITH_CLEANUP_EXPR)

does not show any matches with GIMPLE_WITH_CLEANUP_EXPR. (one GIMPLE_ASSIGN, 3 GIMPLE_BIND).  so we're not catching and generating TRY_FINALLY_EXPRS on the way out like we want or need to.

(I can scratch and dig around some more,.. but could use a hint or do a hand-off to someone..  :-)   



Additional debug, possibly not relevant:
During (first?) gimple pass, we get to gimple_build_wce by way of multiple calls through ..  hard to paraphrase, heres the bt. 

(gdb) bt
#0  0x000000001088da08 in gimple_build_wce (cleanup=0x1000009e00f0) at gimple.c:742
#1  0x00000000108e9984 in gimple_push_cleanup (var=0x100000080a20, cleanup=<optimized out>, eh_only=false, pre_p=0x3fffffffd7a0, force_uncond=true) at gimplify.c:6528
#2  0x00000000108f7cbc in gimplify_target_expr (expr_p=0x1000006b0d38, pre_p=0x3fffffffd7a0, post_p=0x3fffffffd390) at gimplify.c:6611
#3  0x00000000108e3410 in gimplify_expr (expr_p=0x1000006b0d38, pre_p=0x3fffffffd7a0, post_p=0x3fffffffd390, gimple_test_f=0x1089b130 <is_gimple_lvalue(tree_node*)>, 
    fallback=<optimized out>) at gimplify.c:11815
#4  0x00000000108e2f28 in gimplify_expr (expr_p=0x1000008c8e50, pre_p=0x3fffffffd7a0, post_p=0x3fffffffd390, gimple_test_f=0x108d1660 <is_gimple_reg_rhs_or_call(tree)>, 
    fallback=1) at gimplify.c:11739
#5  0x00000000108f9cdc in gimplify_modify_expr (expr_p=0x1000006ff598, pre_p=0x3fffffffd7a0, post_p=0x3fffffffd390, want_value=false) at gimplify.c:5626
#6  0x00000000108e3430 in gimplify_expr (expr_p=0x1000006ff598, pre_p=0x3fffffffd7a0, post_p=0x3fffffffd390, gimple_test_f=0x108d6cc0 <is_gimple_stmt(tree)>, fallback=0)
    at gimplify.c:11435
#7  0x00000000108e7288 in gimplify_stmt (stmt_p=<optimized out>, seq_p=0x3fffffffd7a0) at gimplify.c:6658
#8  0x00000000108e402c in gimplify_statement_list (pre_p=<optimized out>, expr_p=0x1000006b0c80) at gimplify.c:1767
#9  gimplify_expr (expr_p=0x1000006b0c80, pre_p=0x3fffffffd7a0, post_p=0x3fffffffd5c0, gimple_test_f=0x108d6cc0 <is_gimple_stmt(tree)>, fallback=0) at gimplify.c:11863
#10 0x00000000108e72dc in gimplify_stmt (stmt_p=0x1000006b0c80, seq_p=0x3fffffffd7a0) at gimplify.c:6658
#11 0x00000000108e8b8c in gimplify_bind_expr (expr_p=0x1000008c8e00, pre_p=0x3fffffffe0d0) at gimplify.c:1335
#12 0x00000000108e31ec in gimplify_expr (expr_p=0x1000008c8e00, pre_p=0x3fffffffe0d0, post_p=0x3fffffffdc20, gimple_test_f=0x108d1660 <is_gimple_reg_rhs_or_call(tree)>, 
    fallback=1) at gimplify.c:11635
#13 0x00000000108f9cdc in gimplify_modify_expr (expr_p=0x3fffffffde70, pre_p=0x3fffffffe0d0, post_p=0x3fffffffdc20, want_value=false) at gimplify.c:5626
#14 0x00000000108e3430 in gimplify_expr (expr_p=0x3fffffffde70, pre_p=0x3fffffffe0d0, post_p=0x3fffffffdc20, gimple_test_f=0x108d6cc0 <is_gimple_stmt(tree)>, fallback=0)
    at gimplify.c:11435
#15 0x00000000108e72dc in gimplify_stmt (stmt_p=0x3fffffffde70, seq_p=0x3fffffffe0d0) at gimplify.c:6658
#16 0x00000000108e3cc0 in gimplify_and_add (seq_p=0x3fffffffe0d0, t=<optimized out>) at gimplify.c:441
#17 gimplify_return_expr (pre_p=0x3fffffffe0d0, stmt=<optimized out>) at gimplify.c:1571
#18 gimplify_expr (expr_p=0x1000009b4bd8, pre_p=0x3fffffffe0d0, post_p=0x3fffffffde50, gimple_test_f=0x108d6cc0 <is_gimple_stmt(tree)>, fallback=0) at gimplify.c:11695
#19 0x00000000108e72dc in gimplify_stmt (stmt_p=<optimized out>, seq_p=0x3fffffffe0d0) at gimplify.c:6658
#20 0x00000000108e3050 in gimplify_cleanup_point_expr (pre_p=<optimized out>, expr_p=0x1000006b0cb0) at gimplify.c:6400
#21 gimplify_expr (expr_p=0x1000006b0cb0, pre_p=0x3fffffffe260, post_p=0x3fffffffe080, gimple_test_f=0x108d6cc0 <is_gimple_stmt(tree)>, fallback=0) at gimplify.c:11811
#22 0x00000000108e72dc in gimplify_stmt (stmt_p=0x1000006b0cb0, seq_p=0x3fffffffe260) at gimplify.c:6658
#23 0x00000000108e8b8c in gimplify_bind_expr (expr_p=0x100000965dc0, pre_p=0x3fffffffe5a0) at gimplify.c:1335
#24 0x00000000108e31ec in gimplify_expr (expr_p=0x100000965dc0, pre_p=0x3fffffffe5a0, post_p=0x3fffffffe3c0, gimple_test_f=0x108d6cc0 <is_gimple_stmt(tree)>, fallback=0)
    at gimplify.c:11635
#25 0x00000000108e72dc in gimplify_stmt (stmt_p=0x100000965dc0, seq_p=0x3fffffffe5a0) at gimplify.c:6658
#26 0x00000000108e9ba0 in gimplify_body (fndecl=0x100000965d00, do_parms=true) at gimplify.c:12635
#27 0x00000000108ea490 in gimplify_function_tree (fndecl=0x100000965d00) at gimplify.c:12800
#28 0x00000000106cf058 in cgraph_node::analyze (this=0x1000009d2b20) at cgraphunit.c:670


As we enter the gimple_build_wce() function,:
Breakpoint 15, 0x000000001088da08 in gimple_build_wce (cleanup=0x1000009e00f0) at gimple.c:742
742	{
"gimple_build_wce():"
"p cleanup" 
$5 = (gimple_seq) 0x1000009e00f0
"pgq cleanup"
warning: Expression is not an assignment (and might have no effect)
D.3235 = {CLOBBER};
"pcfun"
"
 get_word (__vector __bool int v)
 {
   <<cleanup_point return D.3236 = {
     const unsigned int _B2;
  
      retval.0 = BIT_FIELD_REF <TARGET_EXPR <D.3235, NON_LVALUE_EXPR <v>>, 32, 64>;
    }>>;
  }
  void
"

And at the end of the pass(?), our cfun reads:

get_word (__vector __bool int v)
{
  unsigned int D.3236;
  __bool int retval.0;
  __vector __bool int D.3235;

  {
    const unsigned int _B2;

    _B2 = 32;
    D.3235 = v;
    <<< Unknown GIMPLE statement: gimple_with_cleanup_expr >>>

    retval.0 = BIT_FIELD_REF <D.3235, 32, 64>;
  }
  D.3236 = retval.0;
  return D.3236;
}


void
Comment 8 Will Schmidt 2018-03-21 14:32:25 UTC
Per top half of comment 7, could use insights from someone with better understanding of the gimplify code, particularly gimplify_cleanup_point_expr().

Adding Richi and Jakub to cc.
Comment 9 Richard Biener 2018-03-21 15:38:25 UTC
I think the issue is that gimplify_cleanup_point_expr when walking the body_sequence to look for WCE stmts doesn't traverse GIMPLE_BIND sub-stmts.

Or it is not supposed to do that and the GENERIC is at fault, mis-matching
cleanup_points somehow:

 <<cleanup_point return <retval> = {
    const unsigned int _B1 = 32;

    <<cleanup_point     const unsigned int _B1 = 32;>>;
    *((unsigned int *) &TARGET_EXPR <D.3230, NON_LVALUE_EXPR <v>> + 8);
  }>>;

here the outer cleanup_point is relevant, and the stmt expression generating
the GIMPLE_BIND.  Is there a cleanup_point missing in that scope?

Other than that I don't know very much of this logic.
Comment 10 Jakub Jelinek 2018-03-21 16:21:28 UTC
--- gcc/config/rs6000/rs6000-c.c.jj	2018-03-15 08:36:26.526776571 +0100
+++ gcc/config/rs6000/rs6000-c.c	2018-03-21 17:10:04.340935624 +0100
@@ -6649,6 +6649,14 @@ altivec_resolve_overloaded_builtin (loca
       stmt = convert (innerptrtype, stmt);
       stmt = build_binary_op (loc, PLUS_EXPR, stmt, arg2, 1);
       stmt = build_indirect_ref (loc, stmt, RO_NULL);
+      if (c_dialect_cxx ())
+	{
+	  /* Add a CLEANUP_POINT_EXPR for the above TARGET_EXPR, as it doesn't
+	     need to live after the INDIRECT_REF.  Force side-effects, so that
+	     it isn't optimized away.  */
+	  TREE_SIDE_EFFECTS (stmt) = 1;
+	  stmt = build1_loc (loc, CLEANUP_POINT_EXPR, TREE_TYPE (stmt), stmt);
+	}
 
       return stmt;
     }

seems to fix this, maybe in some cases it would be enough to force TREE_SIDE_EFFECTS, e.g. on this testcase finish_stmt_expr_expr has:
          /* Wrap it in a CLEANUP_POINT_EXPR and add it to the list like a
             normal statement, but don't convert to void or actually add
             the EXPR_STMT.  */
          if (TREE_CODE (expr) != CLEANUP_POINT_EXPR)
            expr = maybe_cleanup_point_expr (expr);

Without TREE_SIDE_EFFECTS though maybe_cleanup_point_expr doesn't add anything, and even if we add it ourselves (e.g. the above patch with TREE_SIDE_EFFECTS (stmt) = 1; removed), then cp_fold will optimize the CLEANUP_POINT_EXPR away.  And the CLEANUP_POINT_EXPR is essential during gimplification, so that we know where the TARGET_EXPR decl rs6000 has added actually dies and where we can emit the clobber.

Note, for ALTIVEC_BUILTIN_VEC_INSERT it contains similar code, but I'm afraid I have no idea where to insert that CLEANUP_POINT_EXPR, because it does:
      stmt = build_indirect_ref (loc, stmt, RO_NULL);
      stmt = build2 (MODIFY_EXPR, TREE_TYPE (stmt), stmt,
                     convert (TREE_TYPE (stmt), arg0));
      stmt = build2 (COMPOUND_EXPR, arg1_type, stmt, decl);
and decl is the TARGET_EXPRs temporary.  The return value of the builtin is non-lvalue though, right?  So maybe just wrapping that similarly to the above would work, or wrap the last argument of the COMPOUND_EXPR into NON_LVALUE_EXPR or something similar first?
Comment 11 acsawdey 2018-04-12 21:58:43 UTC
Looking at the dump of an analogous test case for vec_insert:

#include <altivec.h>

typedef __vector unsigned int  uvec32_t  __attribute__((__aligned__(16)));

uvec32_t get_word(uvec32_t v)
{ 
  return({const unsigned _B1 = 32;
      vec_insert(10, (uvec32_t)v, 2);});
}

It seems that we do get an additional cleanup_point like you are proposing to add for vec_extract, which is maybe why that does not get into trouble:

;; Function __vector(4) unsigned int get_word(__vector(4) unsigned int) (null)
;; enabled by -tree-original


{
  <<cleanup_point return <retval> = {
    const unsigned int _B1 = 32;

    <<cleanup_point     const unsigned int _B1 = 32;>>;
    <<cleanup_point *((unsigned int *) &TARGET_EXPR <D.3231, NON_LVALUE_EXPR <v>> + 8) = 10;, D.3231>>;
  }>>;
}

I've gotten as far as seeing that something is calling fold_build_cleanup_point_expr an additional time compared to the vec_extract example.
Comment 12 acsawdey 2018-04-13 16:57:51 UTC
This function is called from cp/semantics.c maybe_cleanup_point_expr()

tree
fold_build_cleanup_point_expr (tree type, tree expr)
{
  /* If the expression does not have side effects then we don't have to wrap
     it with a cleanup point expression.  */
  if (!TREE_SIDE_EFFECTS (expr))
    return expr;

In the vec_extract case it bails out due to no side effects and does not put in the cleanup point.

So in fact a more minimal version of Jakub's patch also works. If you mark that this has side effects, then the cleanup point is added for us by the existing code:

Index: config/rs6000/rs6000-c.c
===================================================================
--- config/rs6000/rs6000-c.c    (revision 259353)
+++ config/rs6000/rs6000-c.c    (working copy)
@@ -6704,6 +6704,8 @@
       stmt = convert (innerptrtype, stmt);
       stmt = build_binary_op (loc, PLUS_EXPR, stmt, arg2, 1);
       stmt = build_indirect_ref (loc, stmt, RO_NULL);
+      if (c_dialect_cxx ())
+       TREE_SIDE_EFFECTS (stmt) = 1;
 
       return stmt;
     }

Any comments on whether this is the right way to fix this? I think the vec_insert case does not need to be changed because the MODIFY_EXPR used there will mark that there are side effects for us.
Comment 13 Jakub Jelinek 2018-04-13 17:05:07 UTC
(In reply to acsawdey from comment #12)
> This function is called from cp/semantics.c maybe_cleanup_point_expr()
> 
> tree
> fold_build_cleanup_point_expr (tree type, tree expr)
> {
>   /* If the expression does not have side effects then we don't have to wrap
>      it with a cleanup point expression.  */
>   if (!TREE_SIDE_EFFECTS (expr))
>     return expr;
> 
> In the vec_extract case it bails out due to no side effects and does not put
> in the cleanup point.
> 
> So in fact a more minimal version of Jakub's patch also works. If you mark
> that this has side effects, then the cleanup point is added for us by the
> existing code:
> 
> Index: config/rs6000/rs6000-c.c
> ===================================================================
> --- config/rs6000/rs6000-c.c    (revision 259353)
> +++ config/rs6000/rs6000-c.c    (working copy)
> @@ -6704,6 +6704,8 @@
>        stmt = convert (innerptrtype, stmt);
>        stmt = build_binary_op (loc, PLUS_EXPR, stmt, arg2, 1);
>        stmt = build_indirect_ref (loc, stmt, RO_NULL);
> +      if (c_dialect_cxx ())
> +       TREE_SIDE_EFFECTS (stmt) = 1;
>  
>        return stmt;
>      }
> 
> Any comments on whether this is the right way to fix this? I think the
> vec_insert case does not need to be changed because the MODIFY_EXPR used
> there will mark that there are side effects for us.

I think this is reasonable, but should have a comment why we do that.
Comment 14 acsawdey 2018-04-16 14:50:37 UTC
Author: acsawdey
Date: Mon Apr 16 14:50:06 2018
New Revision: 259403

URL: https://gcc.gnu.org/viewcvs?rev=259403&root=gcc&view=rev
Log:
2018-04-16  Aaron Sawdey  <acsawdey@linux.ibm.com>

	PR target/83660
	* config/rs6000/rs6000-c.c (altivec_resolve_overloaded_builtin): Mark
	vec_extract expression as having side effects to make sure it gets
	a cleanup point.

2018-04-16  Aaron Sawdey  <acsawdey@linux.ibm.com>

	PR target/83660
	* gcc.target/powerpc/pr83660.C: New test.



Added:
    trunk/gcc/testsuite/gcc.target/powerpc/pr83660.C
Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/config/rs6000/rs6000-c.c
    trunk/gcc/testsuite/ChangeLog
Comment 15 acsawdey 2018-04-16 14:52:02 UTC
Fixed in 259403.
Comment 16 acsawdey 2018-04-16 15:55:06 UTC
Possibly need backports to both 7 and 6.
Comment 17 acsawdey 2018-04-24 00:14:57 UTC
Author: acsawdey
Date: Tue Apr 24 00:14:21 2018
New Revision: 259586

URL: https://gcc.gnu.org/viewcvs?rev=259586&root=gcc&view=rev
Log:

2018-04-23  Aaron Sawdey  <acsawdey@linux.ibm.com>

	Backport from mainline
	2018-04-16  Aaron Sawdey  <acsawdey@linux.ibm.com>

	PR target/83660
	* config/rs6000/rs6000-c.c (altivec_resolve_overloaded_builtin): Mark
	vec_extract expression as having side effects to make sure it gets
	a cleanup point.

2018-04-23  Aaron Sawdey  <acsawdey@linux.ibm.com>

	Backport from mainline
	2018-04-16  Aaron Sawdey  <acsawdey@linux.ibm.com>

	PR target/83660
	* gcc.target/powerpc/pr83660.C: New test.


Added:
    branches/gcc-6-branch/gcc/testsuite/gcc.target/powerpc/pr83660.C
Modified:
    branches/gcc-6-branch/gcc/ChangeLog
    branches/gcc-6-branch/gcc/config/rs6000/rs6000-c.c
    branches/gcc-6-branch/gcc/testsuite/ChangeLog
Comment 18 acsawdey 2018-04-24 00:20:15 UTC
Author: acsawdey
Date: Tue Apr 24 00:19:43 2018
New Revision: 259590

URL: https://gcc.gnu.org/viewcvs?rev=259590&root=gcc&view=rev
Log:
2018-04-23  Aaron Sawdey  <acsawdey@linux.ibm.com>

	Backport from mainline
	2018-04-16  Aaron Sawdey  <acsawdey@linux.ibm.com>

	PR target/83660
	* config/rs6000/rs6000-c.c (altivec_resolve_overloaded_builtin): Mark
	vec_extract expression as having side effects to make sure it gets
	a cleanup point.

2018-04-23  Aaron Sawdey  <acsawdey@linux.ibm.com>

	Backport from mainline
	2018-04-16  Aaron Sawdey  <acsawdey@linux.ibm.com>

	PR target/83660
	* gcc.target/powerpc/pr83660.C: New test.



Added:
    branches/gcc-7-branch/gcc/testsuite/gcc.target/powerpc/pr83660.C
Modified:
    branches/gcc-7-branch/gcc/ChangeLog
    branches/gcc-7-branch/gcc/config/rs6000/rs6000-c.c
    branches/gcc-7-branch/gcc/testsuite/ChangeLog
Comment 19 acsawdey 2018-04-24 03:26:02 UTC
Backported to gcc 7 and 6. Closing again.