Bug 80382 - ICE with error: unrecognizable insn
Summary: ICE with error: unrecognizable insn
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: target (show other bugs)
Version: 7.0
: P3 normal
Target Milestone: ---
Assignee: Segher Boessenkool
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2017-04-10 12:21 UTC by Marek Polacek
Modified: 2017-06-29 09:38 UTC (History)
5 users (show)

See Also:
Host:
Target: powerpc64*-*-*
Build:
Known to work:
Known to fail: 5.3.1, 6.1.0
Last reconfirmed: 2017-04-10 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Marek Polacek 2017-04-10 12:21:48 UTC
This testcase (which took ~5 days of reducing) ICEs with -O3 -std=c++11 -mtune=power8 -mcpu=power8 -mno-lra:

test.C: In constructor ‘sbis::rpc::ProcessPool::ProcessPool(const String&, sbis::rpc::ProcessPoolType, sbis::EventLoopService*, sbis::EventReactionService*, const String&)’:
test.C:195:37: error: unrecognizable insn:
       mSemaphore(U(G()), edCREATE) {}
                                     ^
(insn 16 15 17 2 (set (reg:PTI 169)
        (unspec:PTI [
                (mem/v:TI (plus:DI (reg/f:DI 160 [ this ])
                        (const_int 8 [0x8])) [-1  S16 A128])
            ] UNSPEC_LSQ)) "test.C":47 -1
     (nil))
test.C:195:37: internal compiler error: in extract_insn, at recog.c:2311
0xcca398 _fatal_insn(char const*, rtx_def const*, char const*, int, char const*)
	/home/marek/src/gcc/gcc/rtl-error.c:108
0xcca3c9 _fatal_insn_not_found(rtx_def const*, char const*, int, char const*)
	/home/marek/src/gcc/gcc/rtl-error.c:116
0xc9bcf1 extract_insn(rtx_insn*)
	/home/marek/src/gcc/gcc/recog.c:2311
0xa689f3 instantiate_virtual_regs_in_insn
	/home/marek/src/gcc/gcc/function.c:1589
0xa689f3 instantiate_virtual_regs
	/home/marek/src/gcc/gcc/function.c:1957
0xa689f3 execute
	/home/marek/src/gcc/gcc/function.c:2006
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.

namespace std {
template <typename> class allocator;
template <class> struct char_traits;
}
typedef int size_t;
namespace std {
template <typename, typename, typename> class basic_string {};
}

namespace mpl_ {}
namespace boost {
namespace mpl {
using namespace mpl_;
}
}
namespace mpl_ {
struct void_;
template <bool> struct bool_;
typedef bool_<false> false_;
template <bool C_> struct bool_ { static const bool value = C_; };
}
namespace boost {
namespace mpl {
template <bool, typename, typename> struct if_c;
template <typename T1, typename T2> struct if_c<false, T1, T2> {
  typedef T2 type;
};
template <typename> struct is_not_void_ : false_ {};
}
}
namespace {
typedef std::basic_string<wchar_t, std::char_traits<wchar_t>,
                          std::allocator<wchar_t>>
    String;
}

namespace mpl_ {
template <size_t N> struct size_t { static const ::size_t value = N; };
}
namespace std {
typedef enum { memory_order_relaxed } memory_order;
template <typename _Tp> struct atomic {
  _Tp _M_i;
  atomic(_Tp) {}
  _Tp load(memory_order _m) {
    _Tp tmp;
    __atomic_load(&_M_i, &tmp, _m);
  }
};
}

namespace boost {
namespace {
namespace detail {
using std::atomic;
using std::memory_order_relaxed;
}
using detail::atomic;
using detail::memory_order_relaxed;
}
namespace parameter {
struct void_;
template <class> struct optional;
template <class> struct parameters { template <class = void_> struct bind; };
template <class, class, class> struct binding;
}
namespace lockfree {
namespace tag {
struct fixed_sized;
struct capacity;
}
namespace detail {
template <typename bound_args, typename tag_type> struct has_arg {
  typedef parameter::binding<bound_args, tag_type, mpl::void_> type;
  static const bool value = mpl::is_not_void_<type>::value;
};
template <typename bound_args> struct extract_capacity {
  static const bool has_capacity = has_arg<bound_args, tag::capacity>::value;
  typedef typename mpl::if_c<has_capacity,
                             typename has_arg<bound_args, tag::capacity>::type,
                             mpl::size_t<0>>::type capacity_t;
  static const size_t capacity = capacity_t::value;
};
template <typename, typename> struct extract_allocator;
template <typename bound_args, bool default_ = false>
struct extract_fixed_sized {
  static const bool has_fixed_sized =
      has_arg<bound_args, tag::fixed_sized>::value;
  typedef
      typename mpl::if_c<has_fixed_sized,
                         typename has_arg<bound_args, tag::fixed_sized>::type,
                         mpl::bool_<default_>>::type type;
  static const bool value = type::value;
};
template <class T> class tagged_ptr {
  typedef size_t tag_t;
  T *ptr;
  tag_t tag;
};
template <typename T> class freelist_stack {
public:
  typedef tagged_ptr<T> tagged_node_handle;
  template <typename Allocator> freelist_stack(Allocator);
};
template <typename, size_t> struct compiletime_sized_freelist_storage;
template <typename> struct runtime_sized_freelist_storage;
template <typename, typename> class fixed_size_freelist;
template <typename T, typename Alloc, bool IsCompileTimeSized, bool IsFixedSize,
          size_t Capacity>
struct select_freelist {
  typedef mpl::if_c<IsCompileTimeSized,
                    compiletime_sized_freelist_storage<T, Capacity>,
                    runtime_sized_freelist_storage<Alloc>>
      fixed_sized_storage_type;
  typedef typename mpl::if_c<IsFixedSize,
                             fixed_size_freelist<T, fixed_sized_storage_type>,
                             freelist_stack<Alloc>>::type type;
};
typedef parameter::parameters<parameter::optional<tag::capacity>>
    queue_signature;
}
template <class = parameter::void_> class queue {
  typedef detail::queue_signature::bind<> bound_args;
  static const bool has_capacity =
      detail::extract_capacity<bound_args>::has_capacity;
  static const size_t capacity = detail::extract_capacity<bound_args>::capacity;
  static const bool fixed_sized =
      detail::extract_fixed_sized<bound_args>::value;
  static const bool compile_time_sized = has_capacity;
  struct node;
  typedef detail::extract_allocator<bound_args, node> node_allocator;
  typedef
      typename detail::select_freelist<node, node_allocator, compile_time_sized,
                                       fixed_sized, capacity>::type pool_t;
  typedef typename pool_t::tagged_node_handle tagged_node_handle;
  struct implementation_defined {
    typedef size_t size_type;
  };

public:
  typedef typename implementation_defined::size_type size_type;
  queue(size_type)
      : head_(tagged_node_handle()), tail_(tagged_node_handle()), pool(1) {
    head_.load(memory_order_relaxed);
  }
  atomic<tagged_node_handle> head_;
  atomic<tagged_node_handle> tail_;
  pool_t pool;
};
}
}

namespace sbis {
namespace rpc {
enum ProcessPoolType : int;
}
class EventLoopService;
class EventReactionService;
namespace rpc {
enum ExchangeDirection : int;
class NamedSemaphore {
public:
  NamedSemaphore(String, ExchangeDirection);
};
class ProcessPool {
  ProcessPool(const String &, ProcessPoolType, EventLoopService *,
              EventReactionService *, const String &);
  boost::atomic<bool> mStarted;
  boost::lockfree::queue<> mNotifies;
  boost::atomic<size_t> mNumberOfProcesses;
  boost::atomic<size_t> mNumberOfThreads;
  boost::atomic<size_t> mNumberOfExtraProcesses;
  boost::atomic<int> mMaximumQueueSize;
  boost::atomic<size_t> mRequestQueueSize;
  NamedSemaphore mSemaphore;
};
}
}
namespace boost {
namespace uuids {
struct uuid {};
}
}
namespace sbis {
namespace rpc {
enum ExchangeDirection : int { edCREATE };
}
boost::uuids::uuid G();
String U(boost::uuids::uuid);
namespace rpc {
ProcessPool::ProcessPool(const String &, ProcessPoolType, EventLoopService *,
                         EventReactionService *, const String &)
    : mStarted(false), mNotifies(0), mNumberOfProcesses(0), mNumberOfThreads(1),
      mNumberOfExtraProcesses(0), mMaximumQueueSize(0), mRequestQueueSize(0),
      mSemaphore(U(G()), edCREATE) {}
}
}
Comment 1 Bill Schmidt 2017-04-10 17:18:26 UTC
You didn't fill in the target.  32/64-bit, little-/big-endian?
Comment 2 Marek Polacek 2017-04-10 17:21:01 UTC
(In reply to Bill Schmidt from comment #1)
> You didn't fill in the target.  32/64-bit, little-/big-endian?

64-bit, and I think it ICEs on both BE and LE.
Comment 3 Peter Bergner 2017-04-10 17:33:09 UTC
I'll have a look.
Comment 4 Peter Bergner 2017-04-10 17:34:00 UTC
(In reply to Marek Polacek from comment #0)
> This testcase (which took ~5 days of reducing) ICEs with -O3 -std=c++11
> -mtune=power8 -mcpu=power8 -mno-lra:

Did you use creduce or delta or ??? to reduce the test case?
Comment 5 Marek Polacek 2017-04-10 17:36:30 UTC
(In reply to Peter Bergner from comment #4)
> (In reply to Marek Polacek from comment #0)
> > This testcase (which took ~5 days of reducing) ICEs with -O3 -std=c++11
> > -mtune=power8 -mcpu=power8 -mno-lra:
> 
> Did you use creduce or delta or ??? to reduce the test case?

Just creduce.  I think it'd be possible to reduce it a bit more, first manually and then run creduce again, but it needs a bit of knowledge of C++.
Comment 6 Peter Bergner 2017-04-10 17:41:37 UTC
(In reply to Marek Polacek from comment #5)
> Just creduce.  I think it'd be possible to reduce it a bit more, first
> manually and then run creduce again, but it needs a bit of knowledge of C++.

Ok, in that case, I'll leave it as is.  Was just making sure you hadn't used delta.
Comment 7 Jakub Jelinek 2017-04-10 17:59:36 UTC
Note it might be nicer to replace typedef int size_t; with something not that wrong, say typedef __SIZE_TYPE__ size_t; if it still reproduces with that (or replace size_t with int everywhere).
Comment 8 Peter Bergner 2017-04-10 20:46:55 UTC
Confirmed.  The (const_int 8) offset needs to be a multiple of 16, so I'll track down why rs6000_legitimize_reload_address() doesn't catch this.
Comment 9 Peter Bergner 2017-04-11 21:07:36 UTC
It seems you can call creduce multiple times and see some reduction.  Here's a reduced test case:

bergner@pike:~/gcc/BUGS/PR80382$ cat bug.ii
namespace a {
typedef enum {} b;
template <typename c> struct g {
  c d;
  g(c) {}
  b f;
  void i() {
    c a;
    __atomic_load(&d, &a, f);
  }
};
}
namespace ad {
using a::g;
}
using ad::g;
class k {
  int *ak;
  int h;
};
class l {
public:
  template <typename j> l(j);
};
class m {
public:
  m() : as(k()), au(1) { as.i(); }
  g<k> as;
  l au;
};
enum av : int;
class n {
public:
  n(int, av);
};
class G {
  G();
  bool ay;
  m e;
  n bf;
};
enum av : int { bg };
int bh();
G::G() : bf(bh(), bg) {}
bergner@pike:~/gcc/BUGS/PR80382$ /home/bergner/gcc/build/gcc-fsf-mainline-pr80382-debug/gcc/xg++ -B/home/bergner/gcc/build/gcc-fsf-mainline-pr80382-debug/gcc -O3 -std=c++11 -mtune=power8 -mcpu=power8 -mno-lra -S bug.ii
bug.ii: In constructor ‘G::G()’:
bug.ii:44:24: error: unrecognizable insn:
 G::G() : bf(bh(), bg) {}
                        ^
(insn 12 11 13 2 (set (reg:PTI 165)
        (unspec:PTI [
                (mem/v:TI (plus:DI (reg/f:DI 161 [ this ])
                        (const_int 8 [0x8])) [-1  S16 A128])
            ] UNSPEC_LSQ)) "bug.ii":9 -1
     (nil))
bug.ii:44:24: internal compiler error: in extract_insn, at recog.c:2311
0x110c3cf7 _fatal_insn(char const*, rtx_def const*, char const*, int, char const*)
	/home/bergner/gcc/gcc-fsf-mainline-pr80382/gcc/rtl-error.c:108
0x110c3d6b _fatal_insn_not_found(rtx_def const*, char const*, int, char const*)
	/home/bergner/gcc/gcc-fsf-mainline-pr80382/gcc/rtl-error.c:116
0x1104ac5b extract_insn(rtx_insn*)
	/home/bergner/gcc/gcc-fsf-mainline-pr80382/gcc/recog.c:2311
0x10c0063f instantiate_virtual_regs_in_insn
	/home/bergner/gcc/gcc-fsf-mainline-pr80382/gcc/function.c:1589
0x10c0260f instantiate_virtual_regs
	/home/bergner/gcc/gcc-fsf-mainline-pr80382/gcc/function.c:1957
0x10c027af execute
	/home/bergner/gcc/gcc-fsf-mainline-pr80382/gcc/function.c:2006
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 10 Segher Boessenkool 2017-04-12 01:08:25 UTC
I have a patch.
Comment 11 Segher Boessenkool 2017-04-12 08:40:31 UTC
Fixed on trunk (I forgot the marker in the checkin comment, oops):

rs6000: Enforce quad_address_p in TImode atomic_load/store (PR80382)

Whatever expand expands to should be valid instructions.  The defined
instructions here have a quad_memory_operand predicate, which boils
down to quad_address_p on the address, so let's test for that instead
of only disallowing indexed addresses.


        PR target/80382
        * config/rs6000/sync.md (atomic_load<mode>, atomic_store<mode): Test
        for quad_address_p for TImode, instead of just not indexed_address.
Comment 12 Peter Bergner 2017-05-12 18:06:14 UTC
With a GCC 6 and GCC 5 builds I had laying around, the reduce test case ICEs with those versions.  I assume it ICEs on GCC 7 as well. Therefore, we should back port this fix to the release branches as well.
Comment 13 Segher Boessenkool 2017-06-27 17:11:34 UTC
Author: segher
Date: Tue Jun 27 17:11:01 2017
New Revision: 249700

URL: https://gcc.gnu.org/viewcvs?rev=249700&root=gcc&view=rev
Log:
	Backports from trunk:

	2016-08-15  Segher Boessenkool  <segher@kernel.crashing.org>
	PR rtl-optimization/73650
	* lra-constraints.c (simple_move_p): If the insn is multiple_sets
	it is not a simple move.

	2017-01-20  Segher Boessenkool  <segher@kernel.crashing.org>
	PR target/61729
	PR target/77850
	* config/rs6000/rs6000.c (rs6000_gimplify_va_arg): Adjust address to
	read from, for big endian.

	2017-04-04  Segher Boessenkool  <segher@kernel.crashing.org>
	PR rtl-optimization/60818
	* simplify-rtx.c (simplify_binary_operation_1): Do not replace
	a compare of comparisons with the thing compared if this results
	in a different machine mode.

	2017-04-12  Segher Boessenkool  <segher@kernel.crashing.org>
	PR target/80382
	* config/rs6000/sync.md (atomic_load<mode>, atomic_store<mode): Test
	for quad_address_p for TImode, instead of just not indexed_address.

	2017-04-19  Segher Boessenkool  <segher@kernel.crashing.org>
	PR rtl-optimization/80429
	* ira.c (split_live_ranges_for_shrink_wrap): Don't split regs that
	are only used in debug insns.

	2017-05-17  Segher Boessenkool  <segher@kernel.crashing.org>
	PR middle-end/80692
	* real.c (do_compare): Give decimal_do_compare preference over
	comparing just the signs.

	2017-05-31  Segher Boessenkool  <segher@kernel.crashing.org>
	PR target/80618
	* config/rs6000/vector.md (*vector_uneq<mode>): Write the nor in the
	splitter result in the canonical way.

	2017-06-09  Segher Boessenkool  <segher@kernel.crashing.org>
	PR target/80966
	* config/rs6000/rs6000.c (rs6000_emit_allocate_stack): Assert that
	gen_add3_insn did not fail.
	* config/rs6000/rs6000.md (add<mode>3): If asked to add a constant to
	r0, construct that number in a temporary reg and add that reg to r0.
	If asked to put the result in r0 as well, fail.

	2017-06-23  Segher Boessenkool  <segher@kernel.crashing.org>
	PR middle-end/80902
	* builtins.c (expand_builtin_atomic_fetch_op): If emitting code after
	a call, force the call to not be a tail call.

gcc/testsuite/
	Backports from trunk:

	2017-04-04  Segher Boessenkool  <segher@kernel.crashing.org>
	PR rtl-optimization/60818
	* gcc.c-torture/compile/pr60818.c: New testcase.

	2017-05-17  Segher Boessenkool  <segher@kernel.crashing.org>
	PR middle-end/80692
	* gcc.c-torture/execute/pr80692.c: New testcase.

	2017-06-09  Segher Boessenkool  <segher@kernel.crashing.org>
	PR target/80966
	* gcc.target/powerpc/stack-limit.c: New testcase.

Added:
    branches/gcc-6-branch/gcc/testsuite/gcc.c-torture/compile/pr60818.c
    branches/gcc-6-branch/gcc/testsuite/gcc.c-torture/execute/pr80692.c
    branches/gcc-6-branch/gcc/testsuite/gcc.target/powerpc/stack-limit.c
Modified:
    branches/gcc-6-branch/gcc/ChangeLog
    branches/gcc-6-branch/gcc/builtins.c
    branches/gcc-6-branch/gcc/config/rs6000/rs6000.c
    branches/gcc-6-branch/gcc/config/rs6000/rs6000.md
    branches/gcc-6-branch/gcc/config/rs6000/sync.md
    branches/gcc-6-branch/gcc/config/rs6000/vector.md
    branches/gcc-6-branch/gcc/ira.c
    branches/gcc-6-branch/gcc/lra-constraints.c
    branches/gcc-6-branch/gcc/real.c
    branches/gcc-6-branch/gcc/simplify-rtx.c
    branches/gcc-6-branch/gcc/testsuite/ChangeLog
Comment 14 Segher Boessenkool 2017-06-27 18:25:29 UTC
Author: segher
Date: Tue Jun 27 18:24:51 2017
New Revision: 249707

URL: https://gcc.gnu.org/viewcvs?rev=249707&root=gcc&view=rev
Log:
	Backports from trunk:

	2016-08-15  Segher Boessenkool  <segher@kernel.crashing.org>
	PR rtl-optimization/73650
	* lra-constraints.c (simple_move_p): If the insn is multiple_sets
	it is not a simple move.

	2017-01-20  Segher Boessenkool  <segher@kernel.crashing.org>
	PR target/61729
	PR target/77850
	* config/rs6000/rs6000.c (rs6000_gimplify_va_arg): Adjust address to
	read from, for big endian.

	2017-04-12  Segher Boessenkool  <segher@kernel.crashing.org>
	PR target/80382
	* config/rs6000/sync.md (atomic_load<mode>, atomic_store<mode): Test
	for quad_address_p for TImode, instead of just not indexed_address.

	2017-05-17  Segher Boessenkool  <segher@kernel.crashing.org>
	PR middle-end/80692
	* real.c (do_compare): Give decimal_do_compare preference over
	comparing just the signs.

	2017-05-31  Segher Boessenkool  <segher@kernel.crashing.org>
	PR target/80618
	* config/rs6000/vector.md (*vector_uneq<mode>): Write the nor in the
	splitter result in the canonical way.

	2017-06-09  Segher Boessenkool  <segher@kernel.crashing.org>
	PR target/80966
	* config/rs6000/rs6000.c (rs6000_emit_allocate_stack): Assert that
	gen_add3_insn did not fail.
	* config/rs6000/rs6000.md (add<mode>3): If asked to add a constant to
	r0, construct that number in a temporary reg and add that reg to r0.
	If asked to put the result in r0 as well, fail.

	2017-06-23  Segher Boessenkool  <segher@kernel.crashing.org>
	PR middle-end/80902
	* builtins.c (expand_builtin_atomic_fetch_op): If emitting code after
	a call, force the call to not be a tail call.

gcc/testsuite/
	Backports from trunk:

	2017-05-17  Segher Boessenkool  <segher@kernel.crashing.org>
	PR middle-end/80692
	* gcc.c-torture/execute/pr80692.c: New testcase.

	2017-06-09  Segher Boessenkool  <segher@kernel.crashing.org>
	PR target/80966
	* gcc.target/powerpc/stack-limit.c: New testcase.

Added:
    branches/gcc-5-branch/gcc/testsuite/gcc.c-torture/execute/pr80692.c
    branches/gcc-5-branch/gcc/testsuite/gcc.target/powerpc/stack-limit.c
Modified:
    branches/gcc-5-branch/gcc/ChangeLog
    branches/gcc-5-branch/gcc/builtins.c
    branches/gcc-5-branch/gcc/config/rs6000/rs6000.c
    branches/gcc-5-branch/gcc/config/rs6000/rs6000.md
    branches/gcc-5-branch/gcc/config/rs6000/sync.md
    branches/gcc-5-branch/gcc/config/rs6000/vector.md
    branches/gcc-5-branch/gcc/lra-constraints.c
    branches/gcc-5-branch/gcc/real.c
    branches/gcc-5-branch/gcc/testsuite/ChangeLog
Comment 15 Segher Boessenkool 2017-06-27 21:46:27 UTC
Author: segher
Date: Tue Jun 27 21:45:45 2017
New Revision: 249711

URL: https://gcc.gnu.org/viewcvs?rev=249711&root=gcc&view=rev
Log:
Those two changes aren't actually applicable to 5.  Sorry for the noise.


	Revert:
	Backports from trunk:

	2017-04-12  Segher Boessenkool  <segher@kernel.crashing.org>
	PR target/80382
	* config/rs6000/sync.md (atomic_load<mode>, atomic_store<mode): Test
	for quad_address_p for TImode, instead of just not indexed_address.

	2017-06-09  Segher Boessenkool  <segher@kernel.crashing.org>
	PR target/80966
	* config/rs6000/rs6000.c (rs6000_emit_allocate_stack): Assert that
	gen_add3_insn did not fail.
	* config/rs6000/rs6000.md (add<mode>3): If asked to add a constant to
	r0, construct that number in a temporary reg and add that reg to r0.
	If asked to put the result in r0 as well, fail.


	Revert:
	Backport from trunk:

	2017-06-09  Segher Boessenkool  <segher@kernel.crashing.org>
	PR target/80966
	* gcc.target/powerpc/stack-limit.c: New testcase.

Removed:
    branches/gcc-5-branch/gcc/testsuite/gcc.target/powerpc/stack-limit.c
Modified:
    branches/gcc-5-branch/gcc/ChangeLog
    branches/gcc-5-branch/gcc/config/rs6000/rs6000.c
    branches/gcc-5-branch/gcc/config/rs6000/rs6000.md
    branches/gcc-5-branch/gcc/config/rs6000/sync.md
    branches/gcc-5-branch/gcc/testsuite/ChangeLog
Comment 16 Segher Boessenkool 2017-06-29 09:38:07 UTC
Fixed on 6 and later.