https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69557

            Bug ID: 69557
           Summary: [ARM] revsh instruction not being conditionalised for
                    Thumb2
           Product: gcc
           Version: 6.0
            Status: UNCONFIRMED
          Keywords: missed-optimization
          Severity: normal
          Priority: P3
         Component: rtl-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: ktkachov at gcc dot gnu.org
  Target Milestone: ---
            Target: arm*

While doing some of the testcase splitting work for PR 65578
I saw that we don't use conditional execution as much as we should for Thumb2.

The testcase:

extern short foos16 (short);
/* revshne */
short swaps16_cond (short x, int y)
{
  short z = x;
  if (y)
    z = __builtin_bswap16 (x);
  return foos16 (z);
}

for -march=armv6t2 -mthumb -O2 I get:
swaps16_cond:
        @ args = 0, pretend = 0, frame = 0
        @ frame_needed = 0, uses_anonymous_args = 0
        @ link register save eliminated.
        cbz     r1, .L2
        revsh   r0, r0
.L2:
        b

whereas for -march=armv6t2 -mthumb -O2 we get conditional execution:
swaps16_cond:
        @ args = 0, pretend = 0, frame = 0
        @ frame_needed = 0, uses_anonymous_args = 0
        @ link register save eliminated.
        cmp     r1, #0
        revshne r0, r0
.L2:
        b

Note that the -marm version gets conditionalised at the very end in
arm_final_prescan_insn which we don't perform for Thumb2.

The ce3 pass doesn't create the COND_EXEC forms like I'd expect.
For the testcase above it refuses to perform any transformations in
cond_exec_find_if_block (from ifcvt.c) where it fails the check:

  /* The edges of the THEN and ELSE blocks cannot have complex edges.  */
  FOR_EACH_EDGE (cur_edge, ei, then_bb->preds)
    {
      if (cur_edge->flags & EDGE_COMPLEX)
        return FALSE;
    }

Seems the edge is deemed complex so ifconversion bails out.

Reply via email to