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