Bug 10396 - Constraint alternatives cause error " `asm' operand requires impossible reload"
Summary: Constraint alternatives cause error " `asm' operand requires impossible reload"
Status: NEW
Alias: None
Product: gcc
Classification: Unclassified
Component: inline-asm (show other bugs)
Version: 3.4.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: documentation, ice-on-valid-code
Depends on:
Blocks:
 
Reported: 2003-04-14 04:06 UTC by Pete Gonzalez
Modified: 2008-12-31 16:36 UTC (History)
3 users (show)

See Also:
Host: i686-pc-cygwin
Target:
Build: i686-pc-cygwin
Known to work:
Known to fail:
Last reconfirmed: 2005-12-26 04:44:00


Attachments
This is an isolated test case for Bug 10396 (5.30 KB, text/plain)
2004-05-20 23:45 UTC, Pete Gonzalez
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Pete Gonzalez 2003-04-14 04:06:01 UTC
When compiling with optimizations (-O2 or -O3), the function below sometimes causes GCC to fail with the error message "`asm' operand requires impossible reload".  The function compiles fine by itself and also in simple contexts; it seems that the error only occurs in complex inlining situations.

The error goes away if I reduce the constraints to a single alternative (instead of 3).  It does not matter which of the three I choose, which suggests that my constraint expressions are valid.

The "impossible reload" message is coming from line 3933 of gcc/reload1.c, but I can't find any documentation on this error.

_____________________________

inline int multiplyFixedPoint(int mantissaA,int mantissaB) {
  int result;
  int temp;

  asm("\n\
	smull	%0, %1, %2, %3 \n\
	mov	%0, %0, lsr #16 \n\
	orr	%0, %0, %1, lsl #16 \n\
  " : "=&r,&r,&r"(result), "=&r,&r,&r"(temp) // outputs
    : "%r,r,r"(mantissaA), "0,1,r"(mantissaB)  // inputs
    : "cc" // clobbered
  );
  return result;
}

Release:
GCC 3.2.1 (cross compiler)

Environment:
This is a custom build of GCC on Win32 Cygwin, with target CPU arm7tdmi.  I am using the C++ front end.

How-To-Repeat:
If someone is interested in pursuing this, I can isolate some source code that reproduces the problem.  However, the situations which expose the bug might depend on the particular build of GCC.
Comment 1 Steven Bosscher 2003-04-14 07:23:24 UTC
State-Changed-From-To: open->feedback
State-Changed-Why: Do you have this problem with 3.3 as well?  Many reload and inline-asm problems have been fixed for 3.3, maybe your problem is fixed there as well.
Comment 2 Pete Gonzalez 2003-04-27 23:56:05 UTC
From: Pete Gonzalez <gonz@ratloop.com>
To: gcc-gnats@gcc.gnu.org,gcc-bugs@gcc.gnu.org,nobody@gcc.gnu.org,
 gcc-prs@gcc.gnu.org
Cc:  
Subject: Re: inline-asm/10396: Constraint alternatives cause error "
  `asm' operand requires impossible reload"
Date: Sun, 27 Apr 2003 23:56:05 -0400

 >Do you have this problem with 3.3 as well?  Many reload and
 >inline-asm problems have been fixed for 3.3, maybe your problem
 >is fixed there as well.
 
 I attempted to recompile using the latest 3.3 snapshot (20030421),
 however the build fails with this error:
 
 >gcc   -g -O2 -DIN_GCC -DCROSS_COMPILE  -W -Wall -Wwrite-strings 
 >-Wstrict-prototypes -Wmissing-prototypes -Wtraditional -pedantic 
 >-Wno-long-long   -DHAVE_CONFIG_H -DGENERATOR_FILE  -o gengtype.exe \
 >  gengtype.o gengtype-lex.o gengtype-yacc.o ../libiberty/libiberty.a
 >./gengtype
 >Signal 11
 >make[2]: *** [s-gtype] Error 139
 >make[2]: Leaving directory 
 >`/home/Administrator/DevKitAdv-Source/build-gcc/gcc'
 >make[1]: *** [all-gcc] Error 2
 >make[1]: Leaving directory `/home/Administrator/DevKitAdv-Source/build-gcc'
 >make: *** [stmp-gcc-make-all] Error 2
 
 I guess I should wait for a more stable version of the source code.
 How far off is the official 3.3 release?
 
 Thanks,
 -Pete
 

Comment 3 Pete Gonzalez 2003-05-05 21:05:56 UTC
From: Pete Gonzalez <gonz@ratloop.com>
To: gcc-gnats@gcc.gnu.org,gcc-bugs@gcc.gnu.org,nobody@gcc.gnu.org,
 gcc-prs@gcc.gnu.org,gonz@ratloop.com
Cc:  
Subject: Re: inline-asm/10396: Constraint alternatives cause error "
  `asm' operand requires impossible reload"
Date: Mon, 05 May 2003 21:05:56 -0400

 I tried the example again with the GCC 3.3 prerelease (20030428),
 but the "impossible reload" error is still being generated.
 
 For reference, here is the section from gcc/reload1.c which produces
 the error message:
 
 	      /* Substitute the chosen reload regs from reload_reg_rtx
 		 into the insn's body (or perhaps into the bodies of other
 		 load and store insn that we just made for reloading
 		 and that we moved the structure into).  */
 	      subst_reloads (insn);
 
 	      /* If this was an ASM, make sure that all the reload insns
 		 we have generated are valid.  If not, give an error
 		 and delete them.  */
 
 	      if (asm_noperands (PATTERN (insn)) >= 0)
 		for (p = NEXT_INSN (prev); p != next; p = NEXT_INSN (p))
 		  if (p != insn && INSN_P (p)
 		      && GET_CODE (PATTERN (p)) != USE
 		      && (recog_memoized (p) < 0
 			  || (extract_insn (p), ! constrain_operands (1))))
 		    {
 		      error_for_asm (insn,
 				     "`asm' operand requires impossible reload");
 		      delete_insn (p);
 		    }
 
 Once again, each of the constraint alternatives works fine by itself;
 it is only the combination of three alternatives that introduces the
 error.
 
Comment 4 Steven Bosscher 2003-05-13 06:29:34 UTC
State-Changed-From-To: feedback->analyzed
State-Changed-Why: Confirmed vs. 3.3
Comment 5 Pete Gonzalez 2003-07-31 22:00:20 UTC
Today I rebuilt using the "gcc-3.4-20030730" snapshot and confirmed that this 
bug is still present.
Comment 6 Andrew Pinski 2004-01-01 08:04:21 UTC
Can you attach one of those complex situtations?
Comment 7 Pete Gonzalez 2004-01-01 19:21:38 UTC
(In reply to comment #6)
> Can you attach one of those complex situtations?

I'll see what I can do.  The source code that was repeatably 
exposing the bug is proprietary, and my attempts to isolate
the problem were causing the error to go away.  If you know
of a utility that can obfuscate C++ identifiers, I could just
attach a big preprocessed file.  Or, if a specific person 
is debugging this, a simple NDA would be sufficient.

Thanks!
Comment 8 Andrew Pinski 2004-01-01 19:57:22 UTC
Yes I am person who is trying to debug this but I think there is no reason why I should sign a NDA 
as this is opensourced software and I do not get paid doing this.
Comment 9 Andrew Pinski 2004-01-07 19:28:09 UTC
It is okay to supply a testcase which does no one needs a NDA, note if I was a little too 
harsh last time, I am sorry.
Comment 10 Pete Gonzalez 2004-01-08 03:47:13 UTC
(In reply to comment #9)
> It is okay to supply a testcase which does no one needs a NDA, note if I was 
a little too 
> harsh last time, I am sorry.

No problem.  However, since the NDA is not an option, I will need to modify the 
error-reproducing-testcase to satisfy the commercial licensing.  As mentioned, 
I did not have much success isolating the bug, so instead I'll try to obfuscate 
the identifiers somehow.  Based on my current schedule, it will take me about 2 
months to complete this.

Thanks again for your help.  We will solve this!
Comment 11 Richard Earnshaw 2004-01-14 18:32:52 UTC
Note that the compiler gets nearly optimal code if you simply write:

inline int mfp(int a, int b)
{
  return (((long long) a) * b) >> 16;
}

Which is only out by a couple of cycles (A couple of redundant mov insns). 
However, by not using an ASM you allow the compiler to schedule the instructions
independently, and may also expose additional optimization opportunities. 

None of the above fixes the bug, but may be sufficient to solve your immediate
problems.
Comment 12 Pete Gonzalez 2004-01-14 23:44:45 UTC
(In reply to comment #11)
> Which is only out by a couple of cycles (A couple of redundant mov insns). 
> However, by not using an ASM you allow the compiler to schedule the 
instructions
> independently, and may also expose additional optimization opportunities. 

True, although the purpose of the inline assembly is to recover exactly those 
missing cycles.  :-)  I should note also that the simple example above is 
representative of similar problems with more complex cases (e.g. fixed-point 
vector multiplication).  The workaround we're using right now is a manually-
enabled preprocessor flag that reduces the constraint count in files that 
failed to compile without it.
Comment 13 Andrew Pinski 2004-04-12 12:50:52 UTC
No feedback in 3 months.  If we recieve a test case we will reopen this bug.
Comment 14 Pete Gonzalez 2004-05-20 23:45:43 UTC
Created attachment 6351 [details]
This is an isolated test case for Bug 10396
Comment 15 Pete Gonzalez 2004-05-20 23:47:52 UTC
(In reply to comment #13)

I have attached a preprocessed test case for this bug.  If you run 
"arm-arm-gcc -c -O2 ConstraintBug.cpp" you will see the following errors:

ConstraintBug.cpp: In function `void ratloop::computeNormal(const 
ratloop::TVector&, const ratloop::TVector&, const ratloop::TVector&, 
ratloop::TVector&)':
ConstraintBug.cpp:303: error: `asm' operand requires impossible reload
ConstraintBug.cpp:303: error: `asm' operand requires impossible reload
ConstraintBug.cpp:303: error: `asm' operand requires impossible reload
ConstraintBug.cpp:303: error: `asm' operand requires impossible reload
ConstraintBug.cpp:303: error: `asm' operand requires impossible reload
ConstraintBug.cpp:303: error: `asm' operand requires impossible reload

My "gcc -v" shows:

Configured with: ../gcc-3.4.0/configure --prefix=/devkitadv --target=arm-agb-elf
 --with-cpu=arm7tdmi --without-local-prefix --disable-shared --with-newlib --wit
h-headers=../newlib-1.12.0/newlib/libc/include/ --enable-multilib --enable-inter
work --enable-languages=c++ --enable-targets=arm-elf,arm-coff,arm-aout --disable
-threads --disable-win32-registry -v
Thread model: single
gcc version 3.4.0

Comment 16 Andrew Pinski 2004-05-21 00:23:43 UTC
Confirmed, here is a shorter example:
int multiplyFixedPoint(int *mantissaA,int *mantissaB) {
  int result;
  int temp;

  asm("# %0 %1 %2 %3"
  : "=&r"(result), "=&r"(temp) // outputs
    : "%r"(*mantissaA), "01r"(*mantissaB - *mantissaA)  // inputs
  );
  *mantissaB = result;
  asm("# %0 %1 %2 %3"
   : "=&r"(result), "=&r"(temp) // outputs
    : "%r"(*mantissaA - *mantissaB), "01r"(*mantissaB)  // inputs
  );
  return result;
}
Comment 17 Richard Earnshaw 2004-08-25 17:02:19 UTC
>  asm("# %0 %1 %2 %3"
>  : "=&r"(result), "=&r"(temp) // outputs
>    : "%r"(*mantissaA), "01r"(*mantissaB - *mantissaA)  // inputs
>  );

This shorter example is bogus.  You can't tie a single output operand to
multiple input operands.

I think the underlying problem here is that we don't really support alternatives
in asm constraints (see, for example asm_operand_ok, which basically ignores ','
-- hence the reason the bogus example produces the same behaviour).

Maybe we should just document this as a limitation of inline assembly and change
the compiler to reject asm patterns that have multiple alternatives.
Comment 18 Christopher Chua 2008-12-31 16:05:31 UTC
I was going to submit a new bug report but this bug sounds very similar. Here is my test case:

Code (actual assembly code removed for brevity):
int thing(unsigned int a,unsigned int b)
{
  asm("":"=mr,r"(b):"%0,0"(a / 3),"ri,g"(b));
  return b;
}

Result:
$ gcc aorir.c -S -O1
aorir.c: In function 'thing':
aorir.c:3: error: 'asm' operand requires impossible reload

This was tested with GCC 4.3.2 and only occurs if -O, -O1, -O2, -O3 or -Os is used. Like the opening poster, this only occurs if multiple alternatives are specified. Removing one of the alternatives makes the issue disappear (it does not matter which one is removed). Replacing "a / 3" with "a + 3" also makes the issue disappear, regardless of the number of alternatives specified. Removing "%" from the first input constraint results in:

$ gcc aorir.c -S -O1
aorir.c: In function 'thing':
aorir.c:5: internal compiler error: in reg_overlap_mentioned_p, at rtlanal.c:1398
Please submit a full bug report,
with preprocessed source if appropriate.
See <http://gcc.gnu.org/bugs.html> for instructions.

Changing "%0,0" to "%r,r" also makes the issue go away, however that is not an option for the assembly code I'm using.
Comment 19 Andrew Pinski 2008-12-31 16:09:57 UTC
Note commas in inline-asm are ignored.
Comment 20 Christopher Chua 2008-12-31 16:29:25 UTC
(In reply to comment #19)
> Note commas in inline-asm are ignored.
> 

Perhaps this bug could then be "fixed" by simply removing or appropriately modifying section 5.38.2 ("Multiple Alternative Constraints") of the GCC manual.
Comment 21 Andrew Pinski 2008-12-31 16:36:28 UTC
(In reply to comment #20) 
> Perhaps this bug could then be "fixed" by simply removing or appropriately
> modifying section 5.38.2 ("Multiple Alternative Constraints") of the GCC
> manual.

Part of the problem is that section is part of the internals manual also and alternative constraints works correctly for RTL, just not inline-asm.  For some reason I thought it was already patched to say the correct thing.