The CRIS port seems to have made a minor goof in a conditional guarding a call to copy_to_mode_reg.
copy_to_mode_reg always allocates a new pseudo, so calling it when !can_create_pseudo_p is going to result in an ICE.
The attached patch fixes the ICE. But I don't know enough about the CRIS port to know if other adjustments are necessary.
Jeff
diff --git a/gcc/config/cris/cris.md b/gcc/config/cris/cris.md index 59a3862..13279b5 100644 --- a/gcc/config/cris/cris.md +++ b/gcc/config/cris/cris.md @@ -499,7 +499,8 @@ { if (MEM_P (operands[0]) && operands[1] != const0_rtx - && (!TARGET_V32 || (!REG_P (operands[1]) && can_create_pseudo_p ()))) + && can_create_pseudo_p () + && (!TARGET_V32 || !REG_P (operands[1]))) operands[1] = copy_to_mode_reg (DImode, operands[1]); /* Some other ports (as of 2001-09-10 for example mcore and romp) also diff --git a/gcc/testsuite/gcc.c-torture/compile/pr68538.c b/gcc/testsuite/gcc.c-torture/compile/pr68538.c new file mode 100644 index 0000000..2822cdb --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/compile/pr68538.c @@ -0,0 +1,52 @@ +struct percpu_counter { + signed long long count; +}; +struct blkg_rwstat { + struct percpu_counter cpu_cnt[4]; +}; +struct cfq_group { + struct blkg_rwstat service_time; +}; +struct cfq_queue { + struct cfq_group *group; +}; +struct request { + struct cfq_queue *active_queue; + unsigned long long cmd_flags; + void *priv; +}; +static void blkg_rwstat_add(struct blkg_rwstat *rwstat, int rw, unsigned long long val) +{ + struct percpu_counter *cnt; + if (rw & 1) + cnt = &rwstat->cpu_cnt[1]; + else + cnt = &rwstat->cpu_cnt[0]; + cnt->count += val; + if (rw & 2) + cnt = &rwstat->cpu_cnt[2]; + else + cnt = &rwstat->cpu_cnt[3]; + cnt->count += val; +} +extern unsigned long long rq_start_time_ns(void); +extern unsigned long long rq_io_start_time_ns(void); +extern int rq_is_sync(void); +extern void cfq_arm_slice_timer(void); +void cfq_completed_request(struct request *rq) +{ + struct cfq_queue *queue = rq->priv; + int sync = rq_is_sync(); + struct cfq_group *group = queue->group; + long long start_time = rq_start_time_ns(); + long long io_start_time = rq_io_start_time_ns(); + int rw = rq->cmd_flags; + + if (io_start_time < 1) + blkg_rwstat_add(&group->service_time, rw, 1 - io_start_time); + blkg_rwstat_add(0, rw, io_start_time - start_time); + + if (rq->active_queue == queue && sync) + cfq_arm_slice_timer(); +} +