The below C code is a stripped down version of some code generated by the GHC Haskell compiler. When it is compiled with -O, incorrect code is generated. The Hp variable should live in %r7 but the compiled routine does not set %r7. It does set it when -O is omitted.
I checked a few versions of gcc and the problem is present in at least the following versions: 3.0.2 3.1.1 3.2.3 3.3.6 3.4.6 4.0.1 4.0.4 4.1.2 compile line: gcc -O -o temp.s -x c temp.i -fno-strict-aliasing -S input file: typedef signed char StgInt8; typedef unsigned char StgWord8; typedef signed short StgInt16; typedef unsigned short StgWord16; typedef signed int StgInt32; typedef unsigned int StgWord32; typedef signed long long int StgInt64; typedef unsigned long long int StgWord64; typedef StgInt32 StgInt; typedef StgWord32 StgWord; typedef StgInt16 StgHalfInt; typedef StgWord16 StgHalfWord; typedef void* StgAddr; typedef StgWord32 StgChar; typedef int StgBool; typedef float StgFloat; typedef double StgDouble; typedef void StgVoid; typedef struct StgClosure_ StgClosure; typedef StgClosure* StgClosurePtr; typedef StgWord* StgPtr; typedef StgWord StgOffset; typedef struct StgTSO_* StgTSOPtr; typedef void* StgForeignPtr; typedef StgInt StgStackOffset; typedef StgWord* StgStackPtr; typedef StgWord8 StgCode; typedef StgPtr* StgArray; typedef char* StgByteArray; typedef void* StgStablePtr; typedef void *(*(*StgFunPtr)(void))(void); typedef StgFunPtr StgFun(void); typedef StgChar C_; typedef StgWord W_; typedef StgWord* P_; typedef P_* PP_; typedef StgInt I_; typedef StgAddr A_; typedef const StgWord* D_; typedef StgFunPtr F_; typedef StgByteArray B_; typedef StgClosurePtr L_; typedef StgInt64 LI_; typedef StgWord64 LW_; typedef struct { StgFunPtr stgGCEnter1; StgFunPtr stgGCFun; } StgFunTable; typedef union { StgWord w; StgAddr a; StgChar c; StgInt8 i8; StgInt i; StgPtr p; StgClosurePtr cl; StgStackOffset offset; StgByteArray b; StgTSOPtr t; } StgUnion; typedef struct StgRegTable_ { StgUnion rR1; StgUnion rR2; StgUnion rR3; StgUnion rR4; StgUnion rR5; StgUnion rR6; StgUnion rR7; StgUnion rR8; StgUnion rR9; StgUnion rR10; StgFloat rF1; StgFloat rF2; StgFloat rF3; StgFloat rF4; StgDouble rD1; StgDouble rD2; StgWord64 rL1; StgPtr rSp; StgPtr rSpLim; StgPtr rHp; StgPtr rHpLim; struct StgTSO_ *rCurrentTSO; struct bdescr_ *rNursery; struct bdescr_ *rCurrentNursery; StgWord rHpAlloc; } StgRegTable; typedef struct Capability_ { StgFunTable f; StgRegTable r; } Capability; extern W_ MainCapability[]; register P_ Sp __asm__("%" "r4"); register P_ SpLim __asm__("%" "r6"); register P_ Hp __asm__("%" "r7"); register P_ HpLim __asm__("%" "r8"); F_ stg_returnToStackTop(void) { W_ _c2; _c2 = (W_)((&((Capability *)MainCapability)[0].r)->rCurrentTSO); Sp = (P_)(*((P_)(_c2+52))); SpLim = (P_)(_c2+140); Hp = (P_)((*((P_)((W_)((&((Capability *)MainCapability)[0].r)->rCurrentNursery)+4))) + (-0x4U)); HpLim = (P_)((*((P_)((W_)((&((Capability *)MainCapability)[0].r)->rCurrentNursery)))) + (((((I_)(*((P_)((W_)((&((Capability *)MainCapability)[0].r)->rCurrentNursery)+24))))) * 0x1000U) + (-0x1U))); do { void *_procedure = (void *)(*((P_)((W_)Sp + (0x0 * 0x4U)))); if (((int) _procedure) & 2) _procedure = (void *)(*((int *) (_procedure - 2))); goto *_procedure; } while(0); } -- Summary: optimizer malfunction when mixed with asm statements Product: gcc Version: 4.1.2 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: jbuehler at spirentcom dot com GCC build triplet: hppa1.0-hp-hpux11.00 GCC host triplet: hppa1.0-hp-hpux11.00 GCC target triplet: hppa1.0-hp-hpux11.00 http://gcc.gnu.org/bugzilla/show_bug.cgi?id=32820