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

--- Comment #5 from Jeffrey A. Law <law at redhat dot com> ---
I've pondered just killing that pattern, but I'm pretty sure there'll be
notable regressions.  There was a clear regression we fixed in gcc-6 due to not
handling QImode operands in that pattern.

What I'm playing with is looking at pos + len and if it hits the sign bit in
the operand's mode, then widening the mode.  Something like this:

+  /* If the mask is going to have the sign bit set in the mode
+     we want to do the comparison, then we must widen the target
+     mode.  Otherwise the flags will be incorrect when we split
+     this into a (compare (and (op0) (mask))) and a subsequent
+     test like LE will get the wrong result.  */
+  if (mode < E_DImode
+      && pos + len == GET_MODE_PRECISION (mode))
+    {
+      mode = GET_MODE_WIDER_MODE (mode).require ();
+      val = gen_lowpart (mode, val);
+    }
+

Which I think is roughly what you were suggesting.  Mine does it with a SUBREG,
so it matches existing patterns...  A ZERO_EXTEND may well require new
patterns.

Reply via email to