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.