Message ID | 201102091245.57413.ebotcazou@adacore.com |
---|---|
State | New |
Headers | show |
On 02/09/2011 07:45 PM, Eric Botcazou wrote: >> Maybe we can explicitly detect the nested COMPARE pattern in order to >> preserve the inner mode if nothing else changed. > > Like in the attached patch. > Thanks. I verified that this patch fixes my issue. I put your patch in a arm-none-linux-gnueabi target regression testing now. I will let you know the results when it's done. Regards,
> Like in the attached patch.
Sandra expressed an interest for it so I've installed it on the mainline after
bootstrapping and regtesting on x86_64-suse-linux.
2011-03-22 Eric Botcazou <ebotcazou@adacore.com>
* combine.c (simplify_set): Try harder to find the best CC mode when
simplifying a nested COMPARE on the RHS.
On Tue, 2011-03-22 at 21:00 +0100, Eric Botcazou wrote: > > Like in the attached patch. > > Sandra expressed an interest for it so I've installed it on the mainline after > bootstrapping and regtesting on x86_64-suse-linux. > > > 2011-03-22 Eric Botcazou <ebotcazou@adacore.com> > > * combine.c (simplify_set): Try harder to find the best CC mode when > simplifying a nested COMPARE on the RHS. > > So I've always suspected that the way the ARM port handles this is broken. I think this now confirms that suspicion. Taking a look at the x86 backend the code there looks far more sensible and more in-line with what I think ARM should be doing. For a floating point operation the code is: TARGET_IEEE_FP ? CCFPUmode : CCFPmode; That is, if generating IEEE compliant code, then use non-excepting comparisions, otherwise use exception raising ones. R.
Index: combine.c =================================================================== --- combine.c (revision 169914) +++ combine.c (working copy) @@ -6242,10 +6242,18 @@ simplify_set (rtx x) enum rtx_code new_code; rtx op0, op1, tmp; int other_changed = 0; + rtx inner_compare = NULL_RTX; enum machine_mode compare_mode = GET_MODE (dest); if (GET_CODE (src) == COMPARE) - op0 = XEXP (src, 0), op1 = XEXP (src, 1); + { + op0 = XEXP (src, 0), op1 = XEXP (src, 1); + if (GET_CODE (op0) == COMPARE && op1 == const0_rtx) + { + inner_compare = op0; + op0 = XEXP (inner_compare, 0), op1 = XEXP (inner_compare, 1); + } + } else op0 = src, op1 = CONST0_RTX (GET_MODE (src)); @@ -6287,6 +6295,12 @@ simplify_set (rtx x) need to use a different CC mode here. */ if (GET_MODE_CLASS (GET_MODE (op0)) == MODE_CC) compare_mode = GET_MODE (op0); + else if (inner_compare + && GET_MODE_CLASS (GET_MODE (inner_compare)) == MODE_CC + && new_code == old_code + && op0 == XEXP (inner_compare, 0) + && op1 == XEXP (inner_compare, 1)) + compare_mode = GET_MODE (inner_compare); else compare_mode = SELECT_CC_MODE (new_code, op0, op1);