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_ {
// functions receive arguments from the caller in the same way. The
// caller is compiled by llc.
size_t ArgNum, Subzero_ArgNum;
CalleePtrTy Callee, Subzero_Callee;
char *Buf, *Subzero_Buf;
size_t ArgNum;
CalleePtrTy Callee;
char *Buf;
const static size_t BUF_SIZE = 16;
......@@ -83,13 +83,13 @@ void testCaller(size_t &TotalTests, size_t &Passes, size_t &Failures) {
for (size_t f = 0; f < NumFuncs; ++f) {
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) {
memset(BufLlc, 0xff, sizeof(BufLlc));
memset(BufSz, 0xff, sizeof(BufSz));
ArgNum = Subzero_ArgNum = i;
ArgNum = i;
Buf = BufLlc;
Funcs[f].Caller();
......@@ -133,18 +133,18 @@ void testCallee(size_t &TotalTests, size_t &Passes, size_t &Failures) {
for (size_t f = 0; f < NumFuncs; ++f) {
char BufLlc[BUF_SIZE], BufSz[BUF_SIZE];
Buf = BufLlc;
Subzero_Buf = BufSz;
for (size_t i = 0; i < Funcs[f].Args; ++i) {
memset(BufLlc, 0xff, sizeof(BufLlc));
memset(BufSz, 0xff, sizeof(BufSz));
ArgNum = Subzero_ArgNum = i;
ArgNum = i;
Buf = BufLlc;
Callee = Funcs[f].Callee;
Funcs[f].Caller();
Buf = BufSz;
Callee = Funcs[f].Subzero_Callee;
Funcs[f].Caller();
......
......@@ -31,12 +31,6 @@ int ArrayInitFull[] = {10, 20, 30, 40, 50};
const int ArrayConst[] = {-10, -20, -30};
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 {
int Array1[5];
uint8_t *Pointer1;
......@@ -56,7 +50,6 @@ static struct {
{ ExternName3, {1000, 1010, 1020}, ExternName2 },
ExternName5,
};
#endif
#define ARRAY(a) \
{ (uint8_t *)(a), sizeof(a) }
......@@ -74,7 +67,7 @@ struct {
ARRAY(ArrayDouble),
{(uint8_t *)(ArrayInitPartial + 2),
sizeof(ArrayInitPartial) - 2 * sizeof(int)},
// { (uint8_t*)(&StructEx), sizeof(StructEx) },
{ (uint8_t*)(&StructEx), sizeof(StructEx) },
};
size_t NumArraysElements = sizeof(Arrays) / sizeof(*Arrays);
......
......@@ -349,7 +349,7 @@ void Cfg::dump(const IceString &Message) {
Str << "define ";
if (getInternal())
Str << "internal ";
Str << ReturnType << " @" << getFunctionName() << "(";
Str << ReturnType << " @" << Ctx->mangleName(getFunctionName()) << "(";
for (SizeT i = 0; i < Args.size(); ++i) {
if (i > 0)
Str << ", ";
......
......@@ -114,8 +114,11 @@ public:
// global initializers.
Ice::Constant *convertConstant(const Constant *Const) {
if (const auto GV = dyn_cast<GlobalValue>(Const)) {
return Ctx->getConstantSym(convertToIceType(GV->getType()), 0,
GV->getName());
Ice::GlobalDeclaration *Decl = getConverter().getGlobalDeclaration(GV);
const Ice::RelocOffsetT Offset = 0;
return Ctx->getConstantSym(TypeConverter.getIcePointerType(),
Offset, Decl->getName(),
Decl->getSuppressMangling());
} else if (const auto CI = dyn_cast<ConstantInt>(Const)) {
Ice::Type Ty = convertToIceType(CI->getType());
if (Ty == Ice::IceType_i64) {
......@@ -690,21 +693,30 @@ void LLVM2ICEGlobalsConverter::convertGlobalsToIce(
for (Module::const_global_iterator I = Mod->global_begin(),
E = Mod->global_end();
I != E; ++I) {
if (!I->hasInitializer() && Ctx->getFlags().AllowUninitializedGlobals)
continue;
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;
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());
}
Ice::GlobalDeclaration *Var = getConverter().getGlobalDeclaration(GV);
Ice::VariableDeclaration* VarDecl = cast<Ice::VariableDeclaration>(Var);
VariableDeclarations.push_back(VarDecl);
if (!GV->hasInitializer()) {
if (Ctx->getFlags().AllowUninitializedGlobals)
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();
if (const auto CompoundInit = dyn_cast<ConstantStruct>(Initializer)) {
......@@ -858,9 +870,7 @@ void Converter::installGlobalDeclarations(Module *Mod) {
Var->setName(GV->getName());
Var->setAlignment(GV->getAlignment());
Var->setIsConstant(GV->isConstant());
// Note: We allow external for cross tests.
// TODO(kschimpf) Put behind flag AllowUninitializedGlobals.
Var->setIsInternal(!GV->isExternallyInitialized());
Var->setLinkage(GV->getLinkage());
GlobalDeclarationMap[GV] = Var;
}
}
......
......@@ -68,12 +68,13 @@ void FunctionDeclaration::dumpType(Ostream &Stream) const {
Stream << Signature;
}
void FunctionDeclaration::dump(Ostream &Stream) const {
void FunctionDeclaration::dump(GlobalContext *Ctx, Ostream &Stream) const {
if (IsProto)
Stream << "declare ";
::dumpLinkage(Stream, Linkage);
::dumpCallingConv(Stream, CallingConv);
Stream << Signature.getReturnType() << " @" << Name << "(";
Stream << Signature.getReturnType() << " @"
<< (Ctx ? Ctx->mangleName(Name) : Name) << "(";
bool IsFirst = true;
for (Type ArgTy : Signature.getArgList()) {
if (IsFirst)
......@@ -111,9 +112,11 @@ void VariableDeclaration::dumpType(Ostream &Stream) const {
}
}
void VariableDeclaration::dump(Ostream &Stream) const {
Stream << "@" << Name << " = internal "
<< (IsConstant ? "constant" : "global") << " ";
void VariableDeclaration::dump(GlobalContext *Ctx, Ostream &Stream) const {
Stream << "@" << ((Ctx && !getSuppressMangling())
? Ctx->mangleName(Name) : Name) << " = ";
::dumpLinkage(Stream, Linkage);
Stream << " " << (IsConstant ? "constant" : "global") << " ";
// Add initializer.
if (Initializers.size() == 1) {
......@@ -128,7 +131,7 @@ void VariableDeclaration::dump(Ostream &Stream) const {
} else {
Stream << ", ";
}
Init->dump(Stream);
Init->dump(Ctx, Stream);
}
Stream << " }>";
}
......@@ -143,7 +146,8 @@ void VariableDeclaration::Initializer::dumpType(Ostream &Stream) const {
Stream << "[" << getNumBytes() << " x " << Ice::IceType_i8 << "]";
}
void VariableDeclaration::DataInitializer::dump(Ostream &Stream) const {
void VariableDeclaration::DataInitializer::dump(
GlobalContext *, Ostream &Stream) const {
dumpType(Stream);
Stream << " c\"";
// Code taken from PrintEscapedString() in AsmWriter.cpp. Keep
......@@ -158,7 +162,8 @@ void VariableDeclaration::DataInitializer::dump(Ostream &Stream) const {
Stream << "\"";
}
void VariableDeclaration::ZeroInitializer::dump(Ostream &Stream) const {
void VariableDeclaration::ZeroInitializer::dump(
GlobalContext *, Ostream &Stream) const {
dumpType(Stream);
Stream << " zeroinitializer";
}
......@@ -167,7 +172,8 @@ void VariableDeclaration::RelocInitializer::dumpType(Ostream &Stream) const {
Stream << Ice::IceType_i32;
}
void VariableDeclaration::RelocInitializer::dump(Ostream &Stream) const {
void VariableDeclaration::RelocInitializer::dump(
GlobalContext *Ctx, Ostream &Stream) const {
if (Offset != 0) {
dumpType(Stream);
Stream << " add (";
......@@ -175,7 +181,12 @@ void VariableDeclaration::RelocInitializer::dump(Ostream &Stream) const {
dumpType(Stream);
Stream << " ptrtoint (";
Declaration->dumpType(Stream);
Stream << "* @" << Declaration->getName() << " to ";
Stream << "* @";
if (Ctx)
Stream << Ctx->mangleName(Declaration->getName());
else
Stream << Declaration->getName();
Stream << " to ";
dumpType(Stream);
Stream << ")";
if (Offset != 0) {
......
......@@ -43,26 +43,45 @@ public:
const IceString &getName() const { return Name; }
void setName(const IceString &NewName) { Name = NewName; }
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() {}
/// Returns true if the declaration is external.
virtual bool getIsExternal() const = 0;
/// Prints out type of the global declaration.
virtual void dumpType(Ostream &Stream) const = 0;
/// 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
// (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:
GlobalDeclaration(GlobalDeclarationKind Kind) : Kind(Kind) {}
GlobalDeclaration(GlobalDeclarationKind Kind,
llvm::GlobalValue::LinkageTypes Linkage)
: Kind(Kind), Linkage(Linkage) {}
const GlobalDeclarationKind Kind;
IceString Name;
llvm::GlobalValue::LinkageTypes Linkage;
};
// Models a function declaration. This includes the type signature of
......@@ -81,33 +100,27 @@ public:
~FunctionDeclaration() final {}
const FuncSigType &getSignature() const { return Signature; }
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.
bool isProto() const { return IsProto; }
static bool classof(const GlobalDeclaration *Addr) {
return Addr->getKind() == FunctionDeclarationKind;
}
void dumpType(Ostream &Stream) const final;
void dump(Ostream &Stream) const final;
bool getIsExternal() const final {
return Linkage == llvm::GlobalValue::ExternalLinkage;
}
virtual IceString mangleName(GlobalContext *Ctx) const final {
return (getIsExternal() && IsProto) ? Name : Ctx->mangleName(Name);
void dump(GlobalContext *Ctx, Ostream &Stream) const final;
bool getSuppressMangling() const final {
return isExternal() && IsProto;
}
private:
const Ice::FuncSigType Signature;
llvm::CallingConv::ID CallingConv;
llvm::GlobalValue::LinkageTypes Linkage;
bool IsProto;
FunctionDeclaration(const FuncSigType &Signature,
llvm::CallingConv::ID CallingConv,
llvm::GlobalValue::LinkageTypes Linkage, bool IsProto)
: GlobalDeclaration(FunctionDeclarationKind), Signature(Signature),
CallingConv(CallingConv), Linkage(Linkage), IsProto(IsProto) {}
: GlobalDeclaration(FunctionDeclarationKind, Linkage),
Signature(Signature), CallingConv(CallingConv), IsProto(IsProto) {}
};
/// Models a global variable declaration, and its initializers.
......@@ -134,7 +147,10 @@ public:
InitializerKind getKind() const { return Kind; }
virtual ~Initializer() {}
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;
protected:
......@@ -170,7 +186,7 @@ public:
~DataInitializer() override {}
const DataVecType &getContents() const { return Contents; }
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) {
return D->getKind() == DataInitializerKind;
}
......@@ -190,7 +206,7 @@ public:
: Initializer(ZeroInitializerKind), Size(Size) {}
~ZeroInitializer() override {}
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) {
return Z->getKind() == ZeroInitializerKind;
}
......@@ -218,7 +234,7 @@ public:
RelocOffsetType getOffset() const { return Offset; }
const GlobalDeclaration *getDeclaration() const { return Declaration; }
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;
static bool classof(const Initializer *R) {
return R->getKind() == RelocInitializerKind;
......@@ -242,10 +258,8 @@ public:
void setIsConstant(bool NewValue) { IsConstant = NewValue; }
uint32_t getAlignment() const { return Alignment; }
void setAlignment(uint32_t NewAlignment) { Alignment = NewAlignment; }
bool getIsInternal() const { return IsInternal; }
void setIsInternal(bool NewValue) { IsInternal = NewValue; }
bool getIsExternal() const final { return !getIsInternal(); }
bool hasInitializer() const {
bool hasInitializer() const { return !Initializers.empty(); }
bool hasNonzeroInitializer() const {
return !(Initializers.size() == 1 &&
llvm::isa<ZeroInitializer>(Initializers[0]));
}
......@@ -272,18 +286,16 @@ public:
/// Prints out the definition of the global variable declaration
/// (including initialization).
void dump(Ostream &Stream) const final;
void dump(GlobalContext *Ctx, Ostream &Stream) const final;
static bool classof(const GlobalDeclaration *Addr) {
return Addr->getKind() == VariableDeclarationKind;
}
IceString mangleName(GlobalContext *Ctx) const final {
return (getIsExternal() && !hasInitializer())
? Name : Ctx->mangleName(Name);
bool getSuppressMangling() const final {
return isExternal() && !hasInitializer();
}
private:
// list of initializers for the declared variable.
InitializerListType Initializers;
......@@ -291,12 +303,11 @@ private:
uint32_t Alignment;
// True if a declared (global) constant.
bool IsConstant;
// True if the declaration is internal.
bool IsInternal;
VariableDeclaration()
: GlobalDeclaration(VariableDeclarationKind), Alignment(0),
IsConstant(false), IsInternal(true) {}
: GlobalDeclaration(VariableDeclarationKind,
llvm::GlobalValue::InternalLinkage),
Alignment(0), IsConstant(false) {}
};
template <class StreamType>
......
......@@ -460,8 +460,13 @@ void ConstantRelocatable::emit(GlobalContext *Ctx) const {
}
}
void ConstantRelocatable::dump(const Cfg *, Ostream &Str) const {
Str << "@" << Name;
void ConstantRelocatable::dump(const Cfg *Func, Ostream &Str) const {
Str << "@";
if (Func && !SuppressMangling) {
Str << Func->getContext()->mangleName(Name);
} else {
Str << Name;
}
if (Offset)
Str << "+" << Offset;
}
......
......@@ -4448,10 +4448,14 @@ void TargetGlobalInitX8632::lower(const VariableDeclaration &Var) {
const VariableDeclaration::InitializerListType &Initializers =
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 IsExternal = Var.getIsExternal();
uint32_t Align = Var.getAlignment();
SizeT Size = Var.getNumBytes();
IceString MangledName = Var.mangleName(Ctx);
......@@ -4463,7 +4467,7 @@ void TargetGlobalInitX8632::lower(const VariableDeclaration &Var) {
if (IsConstant)
Str << "\t.section\t.rodata" << SectionSuffix << ",\"a\",@progbits\n";
else if (HasInitializer)
else if (HasNonzeroInitializer)
Str << "\t.section\t.data" << SectionSuffix << ",\"aw\",@progbits\n";
else if (IsExternal)
Str << "\t.section\t.bss" << SectionSuffix << ",\"aw\",@nobits\n";
......@@ -4471,20 +4475,20 @@ void TargetGlobalInitX8632::lower(const VariableDeclaration &Var) {
if (IsExternal)
Str << "\t.globl\t" << MangledName << "\n";
else if (!IsConstant && !HasInitializer)
else if (!IsConstant && !HasNonzeroInitializer)
Str << "\t.local\t" << MangledName << "\n";
// 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";
// Alignment is part of .comm.
if (IsConstant || HasInitializer || IsExternal)
if (IsConstant || HasNonzeroInitializer || IsExternal)
Str << MangledName << ":\n";
else
Str << "\t.comm\t" << MangledName << "," << Size << "," << Align << "\n";
if (HasInitializer) {
if (HasNonzeroInitializer) {
for (VariableDeclaration::Initializer *Init : Initializers) {
switch (Init->getKind()) {
case VariableDeclaration::Initializer::DataInitializerKind: {
......@@ -4526,7 +4530,7 @@ void TargetGlobalInitX8632::lower(const VariableDeclaration &Var) {
Str << "\t.zero\t" << Size << "\n";
// Size is part of .comm.
if (IsConstant || HasInitializer || IsExternal)
if (IsConstant || HasNonzeroInitializer || IsExternal)
Str << "\t.size\t" << MangledName << ", " << Size << "\n";
// Size is part of .comm.
}
......
......@@ -88,7 +88,7 @@ void Translator::lowerGlobals(
Ostream &Stream = Ctx->getStrDump();
for (const Ice::VariableDeclaration *Global : VariableDeclarations) {
if (DumpGlobalVariables)
Global->dump(Stream);
Global->dump(getContext(), Stream);
if(!DisableTranslation)
GlobalLowering->lower(*Global);
}
......
......@@ -286,22 +286,30 @@ public:
// If reached, no such constant exists, create one.
// TODO(kschimpf) Don't get addresses of intrinsic function declarations.
std::string Name;
Ice::GlobalDeclaration *Decl = nullptr;
unsigned FcnIDSize = FunctionDeclarationList.size();
if (ID < FcnIDSize) {
Name = FunctionDeclarationList[ID]->getName();
Decl = FunctionDeclarationList[ID];
} 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 {
std::string Buffer;
raw_string_ostream StrBuf(Buffer);
StrBuf << "Reference to global not defined: " << ID;
Error(StrBuf.str());
// TODO(kschimpf) Remove error recovery once implementation complete.
Name = "??";
SuppressMangling = false;
}
const Ice::RelocOffsetT Offset = 0;
C = getTranslator().getContext()->getConstantSym(
getIcePointerType(), Offset, Name);
getIcePointerType(), Offset, Name, SuppressMangling);
ValueIDConstants[ID] = 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