http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49226
Summary: problematic _Complex long double argument passing Product: gcc Version: 4.7.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: target AssignedTo: unassig...@gcc.gnu.org ReportedBy: ebotca...@gcc.gnu.org Blocks: 48830 Target: ia64-*-* rtlanal.c:simplify_subreg_regno has these lines at the end: /* See whether (reg:YMODE YREGNO) is valid. ??? We allow invalid registers if (reg:XMODE XREGNO) is also invalid. This is a kludge to work around how float/complex arguments are passed on 32-bit SPARC and should be fixed. */ if (!HARD_REGNO_MODE_OK (yregno, ymode) && HARD_REGNO_MODE_OK (xregno, xmode)) return -1; It turns out that they are outdated, removing the kludge as follows: /* See whether (reg:YMODE YREGNO) is valid. */ if (!HARD_REGNO_MODE_OK (yregno, ymode)) return -1; works fine on the SPARC (both 32-bit and 64-bit). Now there is a problem on IA-64. For the testcase to be attached, the function is invoked on: #0 simplify_subreg_regno (xregno=122, xmode=XCmode, offset=0, ymode=XFmode) at /home/eric/svn/gcc/gcc/rtlanal.c:3461 3461 return (int) yregno; and must return a valid regno, although everything is invalid according to the HARD_REGNO_MODE_OK macro, otherwise wrong code is generated: --- scalar-by-value-3_0.s 2011-05-29 15:26:12.174486000 -0400 +++ scalar-by-value-3.s 2011-05-29 15:26:29.694284000 -0400 @@ -453,10 +453,10 @@ stfe [r14] = f6 mov r14 = r34 ;; - ld8 r40 = [r14] + ld8 r38 = [r14] adds r14 = 8, r34 ;; - ld8 r41 = [r14] + ld8 r39 = [r14] br.call.sptk.many b0 = testvacld# mov r1 = r35 mov r36 = r0 This is on the way of PR target/48830.