On 03/05/11 10:07, Bernd Schmidt wrote: > On 04/15/2011 12:54 PM, Andrew Stubbs wrote: >> Ping. > > Trying to unblock this... > > I think the point is that both examples: > > long long foolong (long long x, short *a, short *b) > { > return x + (long long)*a * (long long)*b; > } > > and > > > long long foolong (long long x, short *a, short *b) > { > return x + *a * *b; > } > > should produce the same code using the maddhidi pattern, and for that to > happen, simplify_rtx must produce a canonical form of the 16->64 bit > widening multiply. The form that already exists in arm.md looks better > so we should pick that. > > I tried to fix it with the patch below, which unfortunately doesn't work > since during combine we don't see the SIGN_EXTEND operations inside the > MULT, but two shift operations instead. Maybe you can complete it from here? This patch fixes my original testcase (the second one above), and so can be a complete replacement for that patch, if preferred? I did originally want to do it without exporting the function from combine.c (since nothing else appears to be exported like that), but it required moving too much code between files. The patch does not fix the first test case above because combine does not recognise the testcase as a HI -> DI multiply-and-add. It can't do it because it has already combined the HI load with a HI->DI sign-extend, and there's neither a multiply that supports mem arguments, nor a multiply with DI mode inputs. I could add define_and_split patterns to catch these cases, but that seems the wrong way to do it ... The real problem is that the widening-multiply tree optimization pass does not support multiplies that widen by more than one mode. As far as I can tell, ARM is the only backend that tries to do this, although cris has a comment to the effect that it would use it if it worked. I am investigating a way to fix this by introducing an optab matrix akin to the existing one for conversions, but that's another patch. Is this patch OK? (Assuming my tests pass.) Andrew