diff mbox

canonicalize_condition vs zero_extract

Message ID 201007010317.o613HmhD016051@greed.delorie.com
State New
Headers show

Commit Message

DJ Delorie July 1, 2010, 3:17 a.m. UTC
If you have an insn that does "test <const>,<reg>", gcc will look for
a pattern that uses zero_extract to generate the "condition" when
<const> is a power of two.  However, canincalize_condition gets passed
this condition, and only expects the RTL at this point to have two
subexpressions.  Zero_extract has three, so it blows up:

  return gen_rtx_fmt_ee (code, VOIDmode, op0, op1);

This is a simple check for this case, but is it the right solution?
Would it be better to:

* Check for a generic "this rtl has more than 2 xexp's"?
* Check for the codes we know, and return 0 for the rest?
* Find out why a zero_extract is getting this far in the first place?

Comments

Paolo Bonzini July 1, 2010, 8:06 a.m. UTC | #1
On 07/01/2010 05:17 AM, DJ Delorie wrote:
> If you have an insn that does "test<const>,<reg>", gcc will look for
> a pattern that uses zero_extract to generate the "condition" when
> <const>  is a power of two.  However, canincalize_condition gets passed
> this condition, and only expects the RTL at this point to have two
> subexpressions.  Zero_extract has three, so it blows up:
>
>    return gen_rtx_fmt_ee (code, VOIDmode, op0, op1);
>
> This is a simple check for this case, but is it the right solution?
> Would it be better to:
>
> * Check for a generic "this rtl has more than 2 xexp's"?

This is better done...

> * Check for the codes we know, and return 0 for the rest?

... by simply checking for COMPARISON_P.

> * Find out why a zero_extract is getting this far in the first place?

This also sounds like a good idea.  Maybe a small testcase and a 
backtrace will be enough?

Paolo
diff mbox

Patch

Index: rtlanal.c
===================================================================
--- rtlanal.c      (revision 161641)
+++ rtlanal.c   (working copy)
@@ -4699,12 +4699,15 @@  canonicalize_condition (rtx insn, rtx co
 
   code = GET_CODE (cond);
   mode = GET_MODE (cond);
   op0 = XEXP (cond, 0);
   op1 = XEXP (cond, 1);
 
+  if (code == ZERO_EXTRACT)
+    return 0;
+
   if (reverse)
     code = reversed_comparison_code (cond, insn);
   if (code == UNKNOWN)
     return 0;
 
   if (earliest)