Commit df6f9d18 by Karl Schimpf

Fix handling of relocation names, so that prefix mangling works.

Fixes bug in the representation of relocation names (in either global initializers or as constant expressions in code) so that they understand when the name is externally defined. This allows us to test this property using command line arguments, and fixes relocation tests in cross compilations (where externnally referenced names shouldn't be name mangled). BUG= R=jvoung@chromium.org, stichnot@chromium.org Review URL: https://codereview.chromium.org/667763002
parent f76fd377
...@@ -45,9 +45,9 @@ namespace Subzero_ { ...@@ -45,9 +45,9 @@ namespace Subzero_ {
// functions receive arguments from the caller in the same way. The // functions receive arguments from the caller in the same way. The
// caller is compiled by llc. // caller is compiled by llc.
size_t ArgNum, Subzero_ArgNum; size_t ArgNum;
CalleePtrTy Callee, Subzero_Callee; CalleePtrTy Callee;
char *Buf, *Subzero_Buf; char *Buf;
const static size_t BUF_SIZE = 16; const static size_t BUF_SIZE = 16;
...@@ -83,13 +83,13 @@ void testCaller(size_t &TotalTests, size_t &Passes, size_t &Failures) { ...@@ -83,13 +83,13 @@ void testCaller(size_t &TotalTests, size_t &Passes, size_t &Failures) {
for (size_t f = 0; f < NumFuncs; ++f) { for (size_t f = 0; f < NumFuncs; ++f) {
char BufLlc[BUF_SIZE], BufSz[BUF_SIZE]; char BufLlc[BUF_SIZE], BufSz[BUF_SIZE];
Callee = Subzero_Callee = Funcs[f].Callee; Callee = Funcs[f].Callee;
for (size_t i = 0; i < Funcs[f].Args; ++i) { for (size_t i = 0; i < Funcs[f].Args; ++i) {
memset(BufLlc, 0xff, sizeof(BufLlc)); memset(BufLlc, 0xff, sizeof(BufLlc));
memset(BufSz, 0xff, sizeof(BufSz)); memset(BufSz, 0xff, sizeof(BufSz));
ArgNum = Subzero_ArgNum = i; ArgNum = i;
Buf = BufLlc; Buf = BufLlc;
Funcs[f].Caller(); Funcs[f].Caller();
...@@ -133,18 +133,18 @@ void testCallee(size_t &TotalTests, size_t &Passes, size_t &Failures) { ...@@ -133,18 +133,18 @@ void testCallee(size_t &TotalTests, size_t &Passes, size_t &Failures) {
for (size_t f = 0; f < NumFuncs; ++f) { for (size_t f = 0; f < NumFuncs; ++f) {
char BufLlc[BUF_SIZE], BufSz[BUF_SIZE]; char BufLlc[BUF_SIZE], BufSz[BUF_SIZE];
Buf = BufLlc;
Subzero_Buf = BufSz;
for (size_t i = 0; i < Funcs[f].Args; ++i) { for (size_t i = 0; i < Funcs[f].Args; ++i) {
memset(BufLlc, 0xff, sizeof(BufLlc)); memset(BufLlc, 0xff, sizeof(BufLlc));
memset(BufSz, 0xff, sizeof(BufSz)); memset(BufSz, 0xff, sizeof(BufSz));
ArgNum = Subzero_ArgNum = i; ArgNum = i;
Buf = BufLlc;
Callee = Funcs[f].Callee; Callee = Funcs[f].Callee;
Funcs[f].Caller(); Funcs[f].Caller();
Buf = BufSz;
Callee = Funcs[f].Subzero_Callee; Callee = Funcs[f].Subzero_Callee;
Funcs[f].Caller(); Funcs[f].Caller();
......
...@@ -31,12 +31,6 @@ int ArrayInitFull[] = {10, 20, 30, 40, 50}; ...@@ -31,12 +31,6 @@ int ArrayInitFull[] = {10, 20, 30, 40, 50};
const int ArrayConst[] = {-10, -20, -30}; const int ArrayConst[] = {-10, -20, -30};
static double ArrayDouble[10] = { 0.5, 1.5, 2.5, 3.5 }; static double ArrayDouble[10] = { 0.5, 1.5, 2.5, 3.5 };
#if 0
// TODO(kschimpf) Add this example once we know how to not mangle
// uninitialized, external globals (so that we can compare that
// the same, unmangled relocations are used). See comment in
// TargetGlobalInitX8632::lower in IceTargetLoweringX8632.cpp for
// details.
static struct { static struct {
int Array1[5]; int Array1[5];
uint8_t *Pointer1; uint8_t *Pointer1;
...@@ -56,7 +50,6 @@ static struct { ...@@ -56,7 +50,6 @@ static struct {
{ ExternName3, {1000, 1010, 1020}, ExternName2 }, { ExternName3, {1000, 1010, 1020}, ExternName2 },
ExternName5, ExternName5,
}; };
#endif
#define ARRAY(a) \ #define ARRAY(a) \
{ (uint8_t *)(a), sizeof(a) } { (uint8_t *)(a), sizeof(a) }
...@@ -74,7 +67,7 @@ struct { ...@@ -74,7 +67,7 @@ struct {
ARRAY(ArrayDouble), ARRAY(ArrayDouble),
{(uint8_t *)(ArrayInitPartial + 2), {(uint8_t *)(ArrayInitPartial + 2),
sizeof(ArrayInitPartial) - 2 * sizeof(int)}, sizeof(ArrayInitPartial) - 2 * sizeof(int)},
// { (uint8_t*)(&StructEx), sizeof(StructEx) }, { (uint8_t*)(&StructEx), sizeof(StructEx) },
}; };
size_t NumArraysElements = sizeof(Arrays) / sizeof(*Arrays); size_t NumArraysElements = sizeof(Arrays) / sizeof(*Arrays);
......
...@@ -349,7 +349,7 @@ void Cfg::dump(const IceString &Message) { ...@@ -349,7 +349,7 @@ void Cfg::dump(const IceString &Message) {
Str << "define "; Str << "define ";
if (getInternal()) if (getInternal())
Str << "internal "; Str << "internal ";
Str << ReturnType << " @" << getFunctionName() << "("; Str << ReturnType << " @" << Ctx->mangleName(getFunctionName()) << "(";
for (SizeT i = 0; i < Args.size(); ++i) { for (SizeT i = 0; i < Args.size(); ++i) {
if (i > 0) if (i > 0)
Str << ", "; Str << ", ";
......
...@@ -114,8 +114,11 @@ public: ...@@ -114,8 +114,11 @@ public:
// global initializers. // global initializers.
Ice::Constant *convertConstant(const Constant *Const) { Ice::Constant *convertConstant(const Constant *Const) {
if (const auto GV = dyn_cast<GlobalValue>(Const)) { if (const auto GV = dyn_cast<GlobalValue>(Const)) {
return Ctx->getConstantSym(convertToIceType(GV->getType()), 0, Ice::GlobalDeclaration *Decl = getConverter().getGlobalDeclaration(GV);
GV->getName()); const Ice::RelocOffsetT Offset = 0;
return Ctx->getConstantSym(TypeConverter.getIcePointerType(),
Offset, Decl->getName(),
Decl->getSuppressMangling());
} else if (const auto CI = dyn_cast<ConstantInt>(Const)) { } else if (const auto CI = dyn_cast<ConstantInt>(Const)) {
Ice::Type Ty = convertToIceType(CI->getType()); Ice::Type Ty = convertToIceType(CI->getType());
if (Ty == Ice::IceType_i64) { if (Ty == Ice::IceType_i64) {
...@@ -690,21 +693,30 @@ void LLVM2ICEGlobalsConverter::convertGlobalsToIce( ...@@ -690,21 +693,30 @@ void LLVM2ICEGlobalsConverter::convertGlobalsToIce(
for (Module::const_global_iterator I = Mod->global_begin(), for (Module::const_global_iterator I = Mod->global_begin(),
E = Mod->global_end(); E = Mod->global_end();
I != E; ++I) { I != E; ++I) {
if (!I->hasInitializer() && Ctx->getFlags().AllowUninitializedGlobals)
continue;
const GlobalVariable *GV = I; const GlobalVariable *GV = I;
Ice::IceString Name = GV->getName();
if (!GV->hasInternalLinkage()) { Ice::GlobalDeclaration *Var = getConverter().getGlobalDeclaration(GV);
Ice::VariableDeclaration* VarDecl = cast<Ice::VariableDeclaration>(Var);
VariableDeclarations.push_back(VarDecl);
if (!GV->hasInternalLinkage() && GV->hasInitializer()) {
std::string Buffer; std::string Buffer;
raw_string_ostream StrBuf(Buffer); raw_string_ostream StrBuf(Buffer);
StrBuf << "Can't define external global declaration: " << Name; StrBuf << "Can't define external global declaration: " << GV->getName();
report_fatal_error(StrBuf.str()); report_fatal_error(StrBuf.str());
} }
Ice::GlobalDeclaration *Var = getConverter().getGlobalDeclaration(GV); if (!GV->hasInitializer()) {
Ice::VariableDeclaration* VarDecl = cast<Ice::VariableDeclaration>(Var); if (Ctx->getFlags().AllowUninitializedGlobals)
VariableDeclarations.push_back(VarDecl); continue;
else {
std::string Buffer;
raw_string_ostream StrBuf(Buffer);
StrBuf << "Global declaration missing initializer: " << GV->getName();
report_fatal_error(StrBuf.str());
}
}
const Constant *Initializer = GV->getInitializer(); const Constant *Initializer = GV->getInitializer();
if (const auto CompoundInit = dyn_cast<ConstantStruct>(Initializer)) { if (const auto CompoundInit = dyn_cast<ConstantStruct>(Initializer)) {
...@@ -858,9 +870,7 @@ void Converter::installGlobalDeclarations(Module *Mod) { ...@@ -858,9 +870,7 @@ void Converter::installGlobalDeclarations(Module *Mod) {
Var->setName(GV->getName()); Var->setName(GV->getName());
Var->setAlignment(GV->getAlignment()); Var->setAlignment(GV->getAlignment());
Var->setIsConstant(GV->isConstant()); Var->setIsConstant(GV->isConstant());
// Note: We allow external for cross tests. Var->setLinkage(GV->getLinkage());
// TODO(kschimpf) Put behind flag AllowUninitializedGlobals.
Var->setIsInternal(!GV->isExternallyInitialized());
GlobalDeclarationMap[GV] = Var; GlobalDeclarationMap[GV] = Var;
} }
} }
......
...@@ -68,12 +68,13 @@ void FunctionDeclaration::dumpType(Ostream &Stream) const { ...@@ -68,12 +68,13 @@ void FunctionDeclaration::dumpType(Ostream &Stream) const {
Stream << Signature; Stream << Signature;
} }
void FunctionDeclaration::dump(Ostream &Stream) const { void FunctionDeclaration::dump(GlobalContext *Ctx, Ostream &Stream) const {
if (IsProto) if (IsProto)
Stream << "declare "; Stream << "declare ";
::dumpLinkage(Stream, Linkage); ::dumpLinkage(Stream, Linkage);
::dumpCallingConv(Stream, CallingConv); ::dumpCallingConv(Stream, CallingConv);
Stream << Signature.getReturnType() << " @" << Name << "("; Stream << Signature.getReturnType() << " @"
<< (Ctx ? Ctx->mangleName(Name) : Name) << "(";
bool IsFirst = true; bool IsFirst = true;
for (Type ArgTy : Signature.getArgList()) { for (Type ArgTy : Signature.getArgList()) {
if (IsFirst) if (IsFirst)
...@@ -111,9 +112,11 @@ void VariableDeclaration::dumpType(Ostream &Stream) const { ...@@ -111,9 +112,11 @@ void VariableDeclaration::dumpType(Ostream &Stream) const {
} }
} }
void VariableDeclaration::dump(Ostream &Stream) const { void VariableDeclaration::dump(GlobalContext *Ctx, Ostream &Stream) const {
Stream << "@" << Name << " = internal " Stream << "@" << ((Ctx && !getSuppressMangling())
<< (IsConstant ? "constant" : "global") << " "; ? Ctx->mangleName(Name) : Name) << " = ";
::dumpLinkage(Stream, Linkage);
Stream << " " << (IsConstant ? "constant" : "global") << " ";
// Add initializer. // Add initializer.
if (Initializers.size() == 1) { if (Initializers.size() == 1) {
...@@ -128,7 +131,7 @@ void VariableDeclaration::dump(Ostream &Stream) const { ...@@ -128,7 +131,7 @@ void VariableDeclaration::dump(Ostream &Stream) const {
} else { } else {
Stream << ", "; Stream << ", ";
} }
Init->dump(Stream); Init->dump(Ctx, Stream);
} }
Stream << " }>"; Stream << " }>";
} }
...@@ -143,7 +146,8 @@ void VariableDeclaration::Initializer::dumpType(Ostream &Stream) const { ...@@ -143,7 +146,8 @@ void VariableDeclaration::Initializer::dumpType(Ostream &Stream) const {
Stream << "[" << getNumBytes() << " x " << Ice::IceType_i8 << "]"; Stream << "[" << getNumBytes() << " x " << Ice::IceType_i8 << "]";
} }
void VariableDeclaration::DataInitializer::dump(Ostream &Stream) const { void VariableDeclaration::DataInitializer::dump(
GlobalContext *, Ostream &Stream) const {
dumpType(Stream); dumpType(Stream);
Stream << " c\""; Stream << " c\"";
// Code taken from PrintEscapedString() in AsmWriter.cpp. Keep // Code taken from PrintEscapedString() in AsmWriter.cpp. Keep
...@@ -158,7 +162,8 @@ void VariableDeclaration::DataInitializer::dump(Ostream &Stream) const { ...@@ -158,7 +162,8 @@ void VariableDeclaration::DataInitializer::dump(Ostream &Stream) const {
Stream << "\""; Stream << "\"";
} }
void VariableDeclaration::ZeroInitializer::dump(Ostream &Stream) const { void VariableDeclaration::ZeroInitializer::dump(
GlobalContext *, Ostream &Stream) const {
dumpType(Stream); dumpType(Stream);
Stream << " zeroinitializer"; Stream << " zeroinitializer";
} }
...@@ -167,7 +172,8 @@ void VariableDeclaration::RelocInitializer::dumpType(Ostream &Stream) const { ...@@ -167,7 +172,8 @@ void VariableDeclaration::RelocInitializer::dumpType(Ostream &Stream) const {
Stream << Ice::IceType_i32; Stream << Ice::IceType_i32;
} }
void VariableDeclaration::RelocInitializer::dump(Ostream &Stream) const { void VariableDeclaration::RelocInitializer::dump(
GlobalContext *Ctx, Ostream &Stream) const {
if (Offset != 0) { if (Offset != 0) {
dumpType(Stream); dumpType(Stream);
Stream << " add ("; Stream << " add (";
...@@ -175,7 +181,12 @@ void VariableDeclaration::RelocInitializer::dump(Ostream &Stream) const { ...@@ -175,7 +181,12 @@ void VariableDeclaration::RelocInitializer::dump(Ostream &Stream) const {
dumpType(Stream); dumpType(Stream);
Stream << " ptrtoint ("; Stream << " ptrtoint (";
Declaration->dumpType(Stream); Declaration->dumpType(Stream);
Stream << "* @" << Declaration->getName() << " to "; Stream << "* @";
if (Ctx)
Stream << Ctx->mangleName(Declaration->getName());
else
Stream << Declaration->getName();
Stream << " to ";
dumpType(Stream); dumpType(Stream);
Stream << ")"; Stream << ")";
if (Offset != 0) { if (Offset != 0) {
......
...@@ -43,26 +43,45 @@ public: ...@@ -43,26 +43,45 @@ public:
const IceString &getName() const { return Name; } const IceString &getName() const { return Name; }
void setName(const IceString &NewName) { Name = NewName; } void setName(const IceString &NewName) { Name = NewName; }
bool hasName() const { return !Name.empty(); } bool hasName() const { return !Name.empty(); }
bool isInternal() const {
return Linkage == llvm::GlobalValue::InternalLinkage;
}
llvm::GlobalValue::LinkageTypes getLinkage() const { return Linkage; }
bool isExternal() const {
return Linkage == llvm::GlobalValue::ExternalLinkage;
}
void setLinkage(llvm::GlobalValue::LinkageTypes NewLinkage) {
Linkage = NewLinkage;
}
virtual ~GlobalDeclaration() {} virtual ~GlobalDeclaration() {}
/// Returns true if the declaration is external.
virtual bool getIsExternal() const = 0;
/// Prints out type of the global declaration. /// Prints out type of the global declaration.
virtual void dumpType(Ostream &Stream) const = 0; virtual void dumpType(Ostream &Stream) const = 0;
/// Prints out the global declaration. /// Prints out the global declaration.
virtual void dump(Ostream &Stream) const = 0; virtual void dump(GlobalContext *Ctx, Ostream &Stream) const = 0;
void dump(Ostream &Stream) const {
GlobalContext *const Ctx = nullptr;
dump(Ctx, Stream);
}
/// Returns true if when emitting names, we should suppress mangling.
virtual bool getSuppressMangling() const = 0;
// Mangles name for cross tests, unless external and not defined locally // Mangles name for cross tests, unless external and not defined locally
// (so that relocations accross llvm2ice and pnacl-llc will work). // (so that relocations accross llvm2ice and pnacl-llc will work).
virtual IceString mangleName(GlobalContext *Ctx) const = 0; virtual IceString mangleName(GlobalContext *Ctx) const {
return getSuppressMangling() ? Name : Ctx->mangleName(Name);
}
protected: protected:
GlobalDeclaration(GlobalDeclarationKind Kind) : Kind(Kind) {} GlobalDeclaration(GlobalDeclarationKind Kind,
llvm::GlobalValue::LinkageTypes Linkage)
: Kind(Kind), Linkage(Linkage) {}
const GlobalDeclarationKind Kind; const GlobalDeclarationKind Kind;
IceString Name; IceString Name;
llvm::GlobalValue::LinkageTypes Linkage;
}; };
// Models a function declaration. This includes the type signature of // Models a function declaration. This includes the type signature of
...@@ -81,33 +100,27 @@ public: ...@@ -81,33 +100,27 @@ public:
~FunctionDeclaration() final {} ~FunctionDeclaration() final {}
const FuncSigType &getSignature() const { return Signature; } const FuncSigType &getSignature() const { return Signature; }
llvm::CallingConv::ID getCallingConv() const { return CallingConv; } llvm::CallingConv::ID getCallingConv() const { return CallingConv; }
llvm::GlobalValue::LinkageTypes getLinkage() const { return Linkage; }
// isProto implies that there isn't a (local) definition for the function. // isProto implies that there isn't a (local) definition for the function.
bool isProto() const { return IsProto; } bool isProto() const { return IsProto; }
static bool classof(const GlobalDeclaration *Addr) { static bool classof(const GlobalDeclaration *Addr) {
return Addr->getKind() == FunctionDeclarationKind; return Addr->getKind() == FunctionDeclarationKind;
} }
void dumpType(Ostream &Stream) const final; void dumpType(Ostream &Stream) const final;
void dump(Ostream &Stream) const final; void dump(GlobalContext *Ctx, Ostream &Stream) const final;
bool getIsExternal() const final { bool getSuppressMangling() const final {
return Linkage == llvm::GlobalValue::ExternalLinkage; return isExternal() && IsProto;
}
virtual IceString mangleName(GlobalContext *Ctx) const final {
return (getIsExternal() && IsProto) ? Name : Ctx->mangleName(Name);
} }
private: private:
const Ice::FuncSigType Signature; const Ice::FuncSigType Signature;
llvm::CallingConv::ID CallingConv; llvm::CallingConv::ID CallingConv;
llvm::GlobalValue::LinkageTypes Linkage;
bool IsProto; bool IsProto;
FunctionDeclaration(const FuncSigType &Signature, FunctionDeclaration(const FuncSigType &Signature,
llvm::CallingConv::ID CallingConv, llvm::CallingConv::ID CallingConv,
llvm::GlobalValue::LinkageTypes Linkage, bool IsProto) llvm::GlobalValue::LinkageTypes Linkage, bool IsProto)
: GlobalDeclaration(FunctionDeclarationKind), Signature(Signature), : GlobalDeclaration(FunctionDeclarationKind, Linkage),
CallingConv(CallingConv), Linkage(Linkage), IsProto(IsProto) {} Signature(Signature), CallingConv(CallingConv), IsProto(IsProto) {}
}; };
/// Models a global variable declaration, and its initializers. /// Models a global variable declaration, and its initializers.
...@@ -134,7 +147,10 @@ public: ...@@ -134,7 +147,10 @@ public:
InitializerKind getKind() const { return Kind; } InitializerKind getKind() const { return Kind; }
virtual ~Initializer() {} virtual ~Initializer() {}
virtual SizeT getNumBytes() const = 0; virtual SizeT getNumBytes() const = 0;
virtual void dump(Ostream &Stream) const = 0; virtual void dump(GlobalContext *Ctx, Ostream &Stream) const = 0;
void dump(Ostream &Stream) const {
dump(nullptr, Stream);
}
virtual void dumpType(Ostream &Stream) const; virtual void dumpType(Ostream &Stream) const;
protected: protected:
...@@ -170,7 +186,7 @@ public: ...@@ -170,7 +186,7 @@ public:
~DataInitializer() override {} ~DataInitializer() override {}
const DataVecType &getContents() const { return Contents; } const DataVecType &getContents() const { return Contents; }
SizeT getNumBytes() const final { return Contents.size(); } SizeT getNumBytes() const final { return Contents.size(); }
void dump(Ostream &Stream) const final; void dump(GlobalContext *Ctx, Ostream &Stream) const final;
static bool classof(const Initializer *D) { static bool classof(const Initializer *D) {
return D->getKind() == DataInitializerKind; return D->getKind() == DataInitializerKind;
} }
...@@ -190,7 +206,7 @@ public: ...@@ -190,7 +206,7 @@ public:
: Initializer(ZeroInitializerKind), Size(Size) {} : Initializer(ZeroInitializerKind), Size(Size) {}
~ZeroInitializer() override {} ~ZeroInitializer() override {}
SizeT getNumBytes() const final { return Size; } SizeT getNumBytes() const final { return Size; }
void dump(Ostream &Stream) const final; void dump(GlobalContext *Ctx, Ostream &Stream) const final;
static bool classof(const Initializer *Z) { static bool classof(const Initializer *Z) {
return Z->getKind() == ZeroInitializerKind; return Z->getKind() == ZeroInitializerKind;
} }
...@@ -218,7 +234,7 @@ public: ...@@ -218,7 +234,7 @@ public:
RelocOffsetType getOffset() const { return Offset; } RelocOffsetType getOffset() const { return Offset; }
const GlobalDeclaration *getDeclaration() const { return Declaration; } const GlobalDeclaration *getDeclaration() const { return Declaration; }
SizeT getNumBytes() const final { return RelocAddrSize; } SizeT getNumBytes() const final { return RelocAddrSize; }
void dump(Ostream &Stream) const final; void dump(GlobalContext *Ctx, Ostream &Stream) const final;
void dumpType(Ostream &Stream) const final; void dumpType(Ostream &Stream) const final;
static bool classof(const Initializer *R) { static bool classof(const Initializer *R) {
return R->getKind() == RelocInitializerKind; return R->getKind() == RelocInitializerKind;
...@@ -242,10 +258,8 @@ public: ...@@ -242,10 +258,8 @@ public:
void setIsConstant(bool NewValue) { IsConstant = NewValue; } void setIsConstant(bool NewValue) { IsConstant = NewValue; }
uint32_t getAlignment() const { return Alignment; } uint32_t getAlignment() const { return Alignment; }
void setAlignment(uint32_t NewAlignment) { Alignment = NewAlignment; } void setAlignment(uint32_t NewAlignment) { Alignment = NewAlignment; }
bool getIsInternal() const { return IsInternal; } bool hasInitializer() const { return !Initializers.empty(); }
void setIsInternal(bool NewValue) { IsInternal = NewValue; } bool hasNonzeroInitializer() const {
bool getIsExternal() const final { return !getIsInternal(); }
bool hasInitializer() const {
return !(Initializers.size() == 1 && return !(Initializers.size() == 1 &&
llvm::isa<ZeroInitializer>(Initializers[0])); llvm::isa<ZeroInitializer>(Initializers[0]));
} }
...@@ -272,18 +286,16 @@ public: ...@@ -272,18 +286,16 @@ public:
/// Prints out the definition of the global variable declaration /// Prints out the definition of the global variable declaration
/// (including initialization). /// (including initialization).
void dump(Ostream &Stream) const final; void dump(GlobalContext *Ctx, Ostream &Stream) const final;
static bool classof(const GlobalDeclaration *Addr) { static bool classof(const GlobalDeclaration *Addr) {
return Addr->getKind() == VariableDeclarationKind; return Addr->getKind() == VariableDeclarationKind;
} }
IceString mangleName(GlobalContext *Ctx) const final { bool getSuppressMangling() const final {
return (getIsExternal() && !hasInitializer()) return isExternal() && !hasInitializer();
? Name : Ctx->mangleName(Name);
} }
private: private:
// list of initializers for the declared variable. // list of initializers for the declared variable.
InitializerListType Initializers; InitializerListType Initializers;
...@@ -291,12 +303,11 @@ private: ...@@ -291,12 +303,11 @@ private:
uint32_t Alignment; uint32_t Alignment;
// True if a declared (global) constant. // True if a declared (global) constant.
bool IsConstant; bool IsConstant;
// True if the declaration is internal.
bool IsInternal;
VariableDeclaration() VariableDeclaration()
: GlobalDeclaration(VariableDeclarationKind), Alignment(0), : GlobalDeclaration(VariableDeclarationKind,
IsConstant(false), IsInternal(true) {} llvm::GlobalValue::InternalLinkage),
Alignment(0), IsConstant(false) {}
}; };
template <class StreamType> template <class StreamType>
......
...@@ -460,8 +460,13 @@ void ConstantRelocatable::emit(GlobalContext *Ctx) const { ...@@ -460,8 +460,13 @@ void ConstantRelocatable::emit(GlobalContext *Ctx) const {
} }
} }
void ConstantRelocatable::dump(const Cfg *, Ostream &Str) const { void ConstantRelocatable::dump(const Cfg *Func, Ostream &Str) const {
Str << "@" << Name; Str << "@";
if (Func && !SuppressMangling) {
Str << Func->getContext()->mangleName(Name);
} else {
Str << Name;
}
if (Offset) if (Offset)
Str << "+" << Offset; Str << "+" << Offset;
} }
......
...@@ -4448,10 +4448,14 @@ void TargetGlobalInitX8632::lower(const VariableDeclaration &Var) { ...@@ -4448,10 +4448,14 @@ void TargetGlobalInitX8632::lower(const VariableDeclaration &Var) {
const VariableDeclaration::InitializerListType &Initializers = const VariableDeclaration::InitializerListType &Initializers =
Var.getInitializers(); Var.getInitializers();
assert(Initializers.size());
bool HasInitializer = Var.hasInitializer(); // If external and not initialized, this must be a cross test.
// Don't generate a declaration for such cases.
bool IsExternal = Var.isExternal();
if (IsExternal && !Var.hasInitializer()) return;
bool HasNonzeroInitializer = Var.hasNonzeroInitializer();
bool IsConstant = Var.getIsConstant(); bool IsConstant = Var.getIsConstant();
bool IsExternal = Var.getIsExternal();
uint32_t Align = Var.getAlignment(); uint32_t Align = Var.getAlignment();
SizeT Size = Var.getNumBytes(); SizeT Size = Var.getNumBytes();
IceString MangledName = Var.mangleName(Ctx); IceString MangledName = Var.mangleName(Ctx);
...@@ -4463,7 +4467,7 @@ void TargetGlobalInitX8632::lower(const VariableDeclaration &Var) { ...@@ -4463,7 +4467,7 @@ void TargetGlobalInitX8632::lower(const VariableDeclaration &Var) {
if (IsConstant) if (IsConstant)
Str << "\t.section\t.rodata" << SectionSuffix << ",\"a\",@progbits\n"; Str << "\t.section\t.rodata" << SectionSuffix << ",\"a\",@progbits\n";
else if (HasInitializer) else if (HasNonzeroInitializer)
Str << "\t.section\t.data" << SectionSuffix << ",\"aw\",@progbits\n"; Str << "\t.section\t.data" << SectionSuffix << ",\"aw\",@progbits\n";
else if (IsExternal) else if (IsExternal)
Str << "\t.section\t.bss" << SectionSuffix << ",\"aw\",@nobits\n"; Str << "\t.section\t.bss" << SectionSuffix << ",\"aw\",@nobits\n";
...@@ -4471,20 +4475,20 @@ void TargetGlobalInitX8632::lower(const VariableDeclaration &Var) { ...@@ -4471,20 +4475,20 @@ void TargetGlobalInitX8632::lower(const VariableDeclaration &Var) {
if (IsExternal) if (IsExternal)
Str << "\t.globl\t" << MangledName << "\n"; Str << "\t.globl\t" << MangledName << "\n";
else if (!IsConstant && !HasInitializer) else if (!IsConstant && !HasNonzeroInitializer)
Str << "\t.local\t" << MangledName << "\n"; Str << "\t.local\t" << MangledName << "\n";
// Internal symbols only get .local when using .comm. // Internal symbols only get .local when using .comm.
if ((IsConstant || HasInitializer || IsExternal) && Align > 1) if ((IsConstant || HasNonzeroInitializer || IsExternal) && Align > 1)
Str << "\t.align\t" << Align << "\n"; Str << "\t.align\t" << Align << "\n";
// Alignment is part of .comm. // Alignment is part of .comm.
if (IsConstant || HasInitializer || IsExternal) if (IsConstant || HasNonzeroInitializer || IsExternal)
Str << MangledName << ":\n"; Str << MangledName << ":\n";
else else
Str << "\t.comm\t" << MangledName << "," << Size << "," << Align << "\n"; Str << "\t.comm\t" << MangledName << "," << Size << "," << Align << "\n";
if (HasInitializer) { if (HasNonzeroInitializer) {
for (VariableDeclaration::Initializer *Init : Initializers) { for (VariableDeclaration::Initializer *Init : Initializers) {
switch (Init->getKind()) { switch (Init->getKind()) {
case VariableDeclaration::Initializer::DataInitializerKind: { case VariableDeclaration::Initializer::DataInitializerKind: {
...@@ -4526,7 +4530,7 @@ void TargetGlobalInitX8632::lower(const VariableDeclaration &Var) { ...@@ -4526,7 +4530,7 @@ void TargetGlobalInitX8632::lower(const VariableDeclaration &Var) {
Str << "\t.zero\t" << Size << "\n"; Str << "\t.zero\t" << Size << "\n";
// Size is part of .comm. // Size is part of .comm.
if (IsConstant || HasInitializer || IsExternal) if (IsConstant || HasNonzeroInitializer || IsExternal)
Str << "\t.size\t" << MangledName << ", " << Size << "\n"; Str << "\t.size\t" << MangledName << ", " << Size << "\n";
// Size is part of .comm. // Size is part of .comm.
} }
......
...@@ -88,7 +88,7 @@ void Translator::lowerGlobals( ...@@ -88,7 +88,7 @@ void Translator::lowerGlobals(
Ostream &Stream = Ctx->getStrDump(); Ostream &Stream = Ctx->getStrDump();
for (const Ice::VariableDeclaration *Global : VariableDeclarations) { for (const Ice::VariableDeclaration *Global : VariableDeclarations) {
if (DumpGlobalVariables) if (DumpGlobalVariables)
Global->dump(Stream); Global->dump(getContext(), Stream);
if(!DisableTranslation) if(!DisableTranslation)
GlobalLowering->lower(*Global); GlobalLowering->lower(*Global);
} }
......
...@@ -286,22 +286,30 @@ public: ...@@ -286,22 +286,30 @@ public:
// If reached, no such constant exists, create one. // If reached, no such constant exists, create one.
// TODO(kschimpf) Don't get addresses of intrinsic function declarations. // TODO(kschimpf) Don't get addresses of intrinsic function declarations.
std::string Name; Ice::GlobalDeclaration *Decl = nullptr;
unsigned FcnIDSize = FunctionDeclarationList.size(); unsigned FcnIDSize = FunctionDeclarationList.size();
if (ID < FcnIDSize) { if (ID < FcnIDSize) {
Name = FunctionDeclarationList[ID]->getName(); Decl = FunctionDeclarationList[ID];
} else if ((ID - FcnIDSize) < VariableDeclarations.size()) { } else if ((ID - FcnIDSize) < VariableDeclarations.size()) {
Name = VariableDeclarations[ID - FcnIDSize]->getName(); Decl = VariableDeclarations[ID - FcnIDSize];
}
std::string Name;
bool SuppressMangling;
if (Decl) {
Name = Decl->getName();
SuppressMangling = Decl->getSuppressMangling();
} else { } else {
std::string Buffer; std::string Buffer;
raw_string_ostream StrBuf(Buffer); raw_string_ostream StrBuf(Buffer);
StrBuf << "Reference to global not defined: " << ID; StrBuf << "Reference to global not defined: " << ID;
Error(StrBuf.str()); Error(StrBuf.str());
// TODO(kschimpf) Remove error recovery once implementation complete.
Name = "??"; Name = "??";
SuppressMangling = false;
} }
const Ice::RelocOffsetT Offset = 0; const Ice::RelocOffsetT Offset = 0;
C = getTranslator().getContext()->getConstantSym( C = getTranslator().getContext()->getConstantSym(
getIcePointerType(), Offset, Name); getIcePointerType(), Offset, Name, SuppressMangling);
ValueIDConstants[ID] = C; ValueIDConstants[ID] = C;
return C; return C;
} }
......
; Test whether we don't mangle external, undefined, global names. This
; feature is needed for cross tests on global initializer relocations.
;
; Note: This code was generated by compiling subzero/crosstest/test_global.cpp
; We use lc2i (rather than p2i) because PNaCl bitcode files do not
; allow externally defined global variables. Hence, this test can only
; work if we read LLVM IR source, and convert to to ICE.
; RUN: %lc2i -i %s --insts --args --allow-uninitialized-globals | FileCheck %s
; RUN: %lc2i -i %s --insts --args --allow-uninitialized-globals \
; RUN: -prefix Subzero_ | FileCheck --check-prefix=CROSS %s
target datalayout = "e-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-p:32:32:32-v128:32:32"
target triple = "i686-pc-linux-gnu"
@ArrayInitPartial = internal global [40 x i8] c"<\00\00\00F\00\00\00P\00\00\00Z\00\00\00d\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00", align 4
; CHECK: @ArrayInitPartial = internal global [40 x i8] c"<\00\00\00F\00\00\00P\00\00\00Z\00\00\00d\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00", align 4
; CROSS: @Subzero_ArrayInitPartial = internal global [40 x i8] c"<\00\00\00F\00\00\00P\00\00\00Z\00\00\00d\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00", align 4
@ArrayInitFull = internal global [20 x i8] c"\0A\00\00\00\14\00\00\00\1E\00\00\00(\00\00\002\00\00\00", align 4
; CHECK: @ArrayInitFull = internal global [20 x i8] c"\0A\00\00\00\14\00\00\00\1E\00\00\00(\00\00\002\00\00\00", align 4
; CROSS: @Subzero_ArrayInitFull = internal global [20 x i8] c"\0A\00\00\00\14\00\00\00\1E\00\00\00(\00\00\002\00\00\00", align 4
@NumArraysElements = internal global [4 x i8] c"\06\00\00\00", align 4
; CHECK: @NumArraysElements = internal global [4 x i8] c"\06\00\00\00", align 4
; CROSS: @Subzero_NumArraysElements = internal global [4 x i8] c"\06\00\00\00", align 4
@Arrays = internal constant <{ i32, [4 x i8], i32, [4 x i8], i32, [4 x i8], i32, [4 x i8], i32, [4 x i8], i32, [4 x i8] }> <{ i32 ptrtoint ([40 x i8]* @ArrayInitPartial to i32), [4 x i8] c"(\00\00\00", i32 ptrtoint ([20 x i8]* @ArrayInitFull to i32), [4 x i8] c"\14\00\00\00", i32 ptrtoint ([12 x i8]* @_ZL10ArrayConst to i32), [4 x i8] c"\0C\00\00\00", i32 ptrtoint ([80 x i8]* @_ZL11ArrayDouble to i32), [4 x i8] c"P\00\00\00", i32 add (i32 ptrtoint ([40 x i8]* @ArrayInitPartial to i32), i32 8), [4 x i8] c" \00\00\00", i32 ptrtoint ([80 x i8]* @_ZL8StructEx to i32), [4 x i8] c"P\00\00\00" }>, align 4
; CHECK: @Arrays = internal constant <{ i32, [4 x i8], i32, [4 x i8], i32, [4 x i8], i32, [4 x i8], i32, [4 x i8], i32, [4 x i8] }> <{ i32 ptrtoint ([40 x i8]* @ArrayInitPartial to i32), [4 x i8] c"(\00\00\00", i32 ptrtoint ([20 x i8]* @ArrayInitFull to i32), [4 x i8] c"\14\00\00\00", i32 ptrtoint ([12 x i8]* @_ZL10ArrayConst to i32), [4 x i8] c"\0C\00\00\00", i32 ptrtoint ([80 x i8]* @_ZL11ArrayDouble to i32), [4 x i8] c"P\00\00\00", i32 add (i32 ptrtoint ([40 x i8]* @ArrayInitPartial to i32), i32 8), [4 x i8] c" \00\00\00", i32 ptrtoint ([80 x i8]* @_ZL8StructEx to i32), [4 x i8] c"P\00\00\00" }>, align 4
; CROSS: @Subzero_Arrays = internal constant <{ i32, [4 x i8], i32, [4 x i8], i32, [4 x i8], i32, [4 x i8], i32, [4 x i8], i32, [4 x i8] }> <{ i32 ptrtoint ([40 x i8]* @Subzero_ArrayInitPartial to i32), [4 x i8] c"(\00\00\00", i32 ptrtoint ([20 x i8]* @Subzero_ArrayInitFull to i32), [4 x i8] c"\14\00\00\00", i32 ptrtoint ([12 x i8]* @Subzero__ZL10ArrayConst to i32), [4 x i8] c"\0C\00\00\00", i32 ptrtoint ([80 x i8]* @Subzero__ZL11ArrayDouble to i32), [4 x i8] c"P\00\00\00", i32 add (i32 ptrtoint ([40 x i8]* @Subzero_ArrayInitPartial to i32), i32 8), [4 x i8] c" \00\00\00", i32 ptrtoint ([80 x i8]* @Subzero__ZL8StructEx to i32), [4 x i8] c"P\00\00\00" }>, align 4
@_ZL10ArrayConst = internal constant [12 x i8] c"\F6\FF\FF\FF\EC\FF\FF\FF\E2\FF\FF\FF", align 4
; CHECK: @_ZL10ArrayConst = internal constant [12 x i8] c"\F6\FF\FF\FF\EC\FF\FF\FF\E2\FF\FF\FF", align 4
; CROSS: @Subzero__ZL10ArrayConst = internal constant [12 x i8] c"\F6\FF\FF\FF\EC\FF\FF\FF\E2\FF\FF\FF", align 4
@_ZL11ArrayDouble = internal global [80 x i8] c"\00\00\00\00\00\00\E0?\00\00\00\00\00\00\F8?\00\00\00\00\00\00\04@\00\00\00\00\00\00\0C@\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00", align 8
; CHECK: @_ZL11ArrayDouble = internal global [80 x i8] c"\00\00\00\00\00\00\E0?\00\00\00\00\00\00\F8?\00\00\00\00\00\00\04@\00\00\00\00\00\00\0C@\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00", align 8
; CROSS: @Subzero__ZL11ArrayDouble = internal global [80 x i8] c"\00\00\00\00\00\00\E0?\00\00\00\00\00\00\F8?\00\00\00\00\00\00\04@\00\00\00\00\00\00\0C@\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00", align 8
@_ZL8StructEx = internal global [80 x i8] zeroinitializer, align 8
; CHECK: @_ZL8StructEx = internal global [80 x i8] zeroinitializer, align 8
; CROSS: @Subzero__ZL8StructEx = internal global [80 x i8] zeroinitializer, align 8
@ExternName1 = external global [4 x i8], align 4
; CHECK: @ExternName1 = external global <{ }> <{ }>, align 4
; CROSS: @ExternName1 = external global <{ }> <{ }>, align 4
@ExternName4 = external global [4 x i8], align 4
; CHECK: @ExternName4 = external global <{ }> <{ }>, align 4
; CROSS: @ExternName4 = external global <{ }> <{ }>, align 4
@ExternName3 = external global [4 x i8], align 4
; CHECK: @ExternName3 = external global <{ }> <{ }>, align 4
; CROSS: @ExternName3 = external global <{ }> <{ }>, align 4
@ExternName2 = external global [4 x i8], align 4
; CHECK: @ExternName2 = external global <{ }> <{ }>, align 4
; CROSS: @ExternName2 = external global <{ }> <{ }>, align 4
@ExternName5 = external global [4 x i8], align 4
; CHECK: @ExternName5 = external global <{ }> <{ }>, align 4
; CROSS: @ExternName5 = external global <{ }> <{ }>, align 4
define i32 @_Z12getNumArraysv() {
; CHECK: define i32 @_Z12getNumArraysv() {
; CROSS: define i32 @_ZN8Subzero_12getNumArraysEv() {
entry:
%NumArraysElements.bc = bitcast [4 x i8]* @NumArraysElements to i32*
; CHECK: %NumArraysElements.bc = bitcast i32 @NumArraysElements to i32
; CROSS: %NumArraysElements.bc = bitcast i32 @Subzero_NumArraysElements to i32
%0 = load i32* %NumArraysElements.bc, align 1
ret i32 %0
}
define i32 @_Z8getArrayjRj(i32 %WhichArray, i32 %Len) {
; CHECK: define i32 @_Z8getArrayjRj(i32 %WhichArray, i32 %Len) {
; CROSS: define i32 @_ZN8Subzero_8getArrayEjRj(i32 %WhichArray, i32 %Len) {
entry:
%NumArraysElements.bc = bitcast [4 x i8]* @NumArraysElements to i32*
; CHECK: %NumArraysElements.bc = bitcast i32 @NumArraysElements to i32
; CROSS: %NumArraysElements.bc = bitcast i32 @Subzero_NumArraysElements to i32
%0 = load i32* %NumArraysElements.bc, align 1
%cmp = icmp ugt i32 %0, %WhichArray
; CHECK: %cmp = icmp ugt i32 %__3, %WhichArray
; CROSS: %cmp = icmp ugt i32 %__3, %WhichArray
br i1 %cmp, label %if.end, label %if.then
if.then: ; preds = %entry
%Len.asptr = inttoptr i32 %Len to i32*
; CHECK: %Len.asptr = i32 %Len
; CROSS: %Len.asptr = i32 %Len
store i32 -1, i32* %Len.asptr, align 1
br label %return
if.end: ; preds = %entry
%gep_array = mul i32 %WhichArray, 8
; CHECK: %gep_array = mul i32 %WhichArray, 8
; CROSS: %gep_array = mul i32 %WhichArray, 8
%expanded1 = ptrtoint <{ i32, [4 x i8], i32, [4 x i8], i32, [4 x i8], i32, [4 x i8], i32, [4 x i8], i32, [4 x i8] }>* @Arrays to i32
; CHECK: %expanded1 = i32 @Arrays
; CROSS: %expanded1 = i32 @Subzero_Arrays
%gep = add i32 %expanded1, %gep_array
%gep1 = add i32 %gep, 4
%gep1.asptr = inttoptr i32 %gep1 to i32*
%1 = load i32* %gep1.asptr, align 1
%Len.asptr3 = inttoptr i32 %Len to i32*
; CHECK: %Len.asptr3 = i32 %Len
; CROSS: %Len.asptr3 = i32 %Len
store i32 %1, i32* %Len.asptr3, align 1
%gep_array3 = mul i32 %WhichArray, 8
; CHECK: %gep_array3 = mul i32 %WhichArray, 8
; CROSS: %gep_array3 = mul i32 %WhichArray, 8
%expanded2 = ptrtoint <{ i32, [4 x i8], i32, [4 x i8], i32, [4 x i8], i32, [4 x i8], i32, [4 x i8], i32, [4 x i8] }>* @Arrays to i32
; CHECK: %expanded2 = i32 @Arrays
; CROSS: %expanded2 = i32 @Subzero_Arrays
%gep4 = add i32 %expanded2, %gep_array3
%gep4.asptr = inttoptr i32 %gep4 to i32*
%2 = load i32* %gep4.asptr, align 1
br label %return
return: ; preds = %if.end, %if.then
%retval.0 = phi i32 [ 0, %if.then ], [ %2, %if.end ]
ret i32 %retval.0
}
define void @_GLOBAL__I_a() {
; CHECK: define void @_GLOBAL__I_a() {
; CROSS: define void @Subzero__GLOBAL__I_a() {
entry:
%_ZL8StructEx.bc = bitcast [80 x i8]* @_ZL8StructEx to i32*
; CHECK: %_ZL8StructEx.bc = bitcast i32 @_ZL8StructEx to i32
; CROSS: %_ZL8StructEx.bc = bitcast i32 @Subzero__ZL8StructEx to i32
store i32 10, i32* %_ZL8StructEx.bc, align 1
%expanded1 = ptrtoint [80 x i8]* @_ZL8StructEx to i32
; CHECK: %expanded1 = i32 @_ZL8StructEx
; CROSS: %expanded1 = i32 @Subzero__ZL8StructEx
%gep = add i32 %expanded1, 4
%gep.asptr = inttoptr i32 %gep to i32*
store i32 20, i32* %gep.asptr, align 1
%expanded2 = ptrtoint [80 x i8]* @_ZL8StructEx to i32
; CHECK: %expanded2 = i32 @_ZL8StructEx
; CROSS: %expanded2 = i32 @Subzero__ZL8StructEx
%gep18 = add i32 %expanded2, 8
%gep18.asptr = inttoptr i32 %gep18 to i32*
store i32 30, i32* %gep18.asptr, align 1
%expanded3 = ptrtoint [80 x i8]* @_ZL8StructEx to i32
; CHECK: %expanded3 = i32 @_ZL8StructEx
; CROSS: %expanded3 = i32 @Subzero__ZL8StructEx
%gep20 = add i32 %expanded3, 12
%gep20.asptr = inttoptr i32 %gep20 to i32*
store i32 40, i32* %gep20.asptr, align 1
%expanded4 = ptrtoint [80 x i8]* @_ZL8StructEx to i32
; CHECK: %expanded4 = i32 @_ZL8StructEx
; CROSS: %expanded4 = i32 @Subzero__ZL8StructEx
%gep22 = add i32 %expanded4, 16
%gep22.asptr = inttoptr i32 %gep22 to i32*
store i32 50, i32* %gep22.asptr, align 1
%ExternName1.bc = bitcast [4 x i8]* @ExternName1 to i32*
; CHECK: %ExternName1.bc = bitcast i32 @ExternName1 to i32
; CROSS: %ExternName1.bc = bitcast i32 @ExternName1 to i32
%0 = load i32* %ExternName1.bc, align 1
%expanded6 = ptrtoint [80 x i8]* @_ZL8StructEx to i32
; CHECK: %expanded6 = i32 @_ZL8StructEx
; CROSS: %expanded6 = i32 @Subzero__ZL8StructEx
%gep24 = add i32 %expanded6, 20
%gep24.asptr = inttoptr i32 %gep24 to i32*
store i32 %0, i32* %gep24.asptr, align 1
%expanded7 = ptrtoint [80 x i8]* @_ZL8StructEx to i32
; CHECK: %expanded7 = i32 @_ZL8StructEx
; CROSS: %expanded7 = i32 @Subzero__ZL8StructEx
%gep26 = add i32 %expanded7, 24
%gep26.asptr = inttoptr i32 %gep26 to double*
store double 5.000000e-01, double* %gep26.asptr, align 8
%expanded8 = ptrtoint [80 x i8]* @_ZL8StructEx to i32
; CHECK: %expanded8 = i32 @_ZL8StructEx
; CROSS: %expanded8 = i32 @Subzero__ZL8StructEx
%gep28 = add i32 %expanded8, 32
%gep28.asptr = inttoptr i32 %gep28 to double*
store double 1.500000e+00, double* %gep28.asptr, align 8
%expanded9 = ptrtoint [80 x i8]* @_ZL8StructEx to i32
; CHECK: %expanded9 = i32 @_ZL8StructEx
; CROSS: %expanded9 = i32 @Subzero__ZL8StructEx
%gep30 = add i32 %expanded9, 40
%gep30.asptr = inttoptr i32 %gep30 to double*
store double 2.500000e+00, double* %gep30.asptr, align 8
%ExternName4.bc = bitcast [4 x i8]* @ExternName4 to i32*
; CHECK: %ExternName4.bc = bitcast i32 @ExternName4 to i32
; CROSS: %ExternName4.bc = bitcast i32 @ExternName4 to i32
%1 = load i32* %ExternName4.bc, align 1
%expanded11 = ptrtoint [80 x i8]* @_ZL8StructEx to i32
; CHECK: %expanded11 = i32 @_ZL8StructEx
; CROSS: %expanded11 = i32 @Subzero__ZL8StructEx
%gep32 = add i32 %expanded11, 48
%gep32.asptr = inttoptr i32 %gep32 to i32*
store i32 %1, i32* %gep32.asptr, align 1
%ExternName3.bc = bitcast [4 x i8]* @ExternName3 to i32*
; CHECK: %ExternName3.bc = bitcast i32 @ExternName3 to i32
; CROSS: %ExternName3.bc = bitcast i32 @ExternName3 to i32
%2 = load i32* %ExternName3.bc, align 1
%expanded13 = ptrtoint [80 x i8]* @_ZL8StructEx to i32
; CHECK: %expanded13 = i32 @_ZL8StructEx
; CROSS: %expanded13 = i32 @Subzero__ZL8StructEx
%gep34 = add i32 %expanded13, 52
%gep34.asptr = inttoptr i32 %gep34 to i32*
store i32 %2, i32* %gep34.asptr, align 1
%expanded14 = ptrtoint [80 x i8]* @_ZL8StructEx to i32
; CHECK: %expanded14 = i32 @_ZL8StructEx
; CROSS: %expanded14 = i32 @Subzero__ZL8StructEx
%gep36 = add i32 %expanded14, 56
%gep36.asptr = inttoptr i32 %gep36 to i32*
store i32 1000, i32* %gep36.asptr, align 1
%expanded15 = ptrtoint [80 x i8]* @_ZL8StructEx to i32
; CHECK: %expanded15 = i32 @_ZL8StructEx
; CROSS: %expanded15 = i32 @Subzero__ZL8StructEx
%gep38 = add i32 %expanded15, 60
%gep38.asptr = inttoptr i32 %gep38 to i32*
store i32 1010, i32* %gep38.asptr, align 1
%expanded16 = ptrtoint [80 x i8]* @_ZL8StructEx to i32
; CHECK: %expanded16 = i32 @_ZL8StructEx
; CROSS: %expanded16 = i32 @Subzero__ZL8StructEx
%gep40 = add i32 %expanded16, 64
%gep40.asptr = inttoptr i32 %gep40 to i32*
store i32 1020, i32* %gep40.asptr, align 1
%ExternName2.bc = bitcast [4 x i8]* @ExternName2 to i32*
; CHECK: %ExternName2.bc = bitcast i32 @ExternName2 to i32
; CROSS: %ExternName2.bc = bitcast i32 @ExternName2 to i32
%3 = load i32* %ExternName2.bc, align 1
%expanded18 = ptrtoint [80 x i8]* @_ZL8StructEx to i32
; CHECK: %expanded18 = i32 @_ZL8StructEx
; CROSS: %expanded18 = i32 @Subzero__ZL8StructEx
%gep42 = add i32 %expanded18, 68
%gep42.asptr = inttoptr i32 %gep42 to i32*
store i32 %3, i32* %gep42.asptr, align 1
%ExternName5.bc = bitcast [4 x i8]* @ExternName5 to i32*
; CHECK: %ExternName5.bc = bitcast i32 @ExternName5 to i32
; CROSS: %ExternName5.bc = bitcast i32 @ExternName5 to i32
%4 = load i32* %ExternName5.bc, align 1
%expanded20 = ptrtoint [80 x i8]* @_ZL8StructEx to i32
; CHECK: %expanded20 = i32 @_ZL8StructEx
; CROSS: %expanded20 = i32 @Subzero__ZL8StructEx
%gep44 = add i32 %expanded20, 72
%gep44.asptr = inttoptr i32 %gep44 to i32*
store i32 %4, i32* %gep44.asptr, align 1
ret void
}
define i32 @nacl_tp_tdb_offset(i32) {
entry:
ret i32 0
}
define i32 @nacl_tp_tls_offset(i32 %size) {
entry:
%result = sub i32 0, %size
ret i32 %result
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment