gollvm: update to LLVM mainline
Patch switches to mainline LLVM which implies following changes in
gollvm:
- Use of new pass manager
- Use of opaque pointers and implementing type tracking based on Btype
instead of llvm::Type
- Use of debug records instead of intrinsics
- Fix gollvm unit tests
Change-Id: I3b8e3fe4820158a06fd1754ba2e1e0515d65ecca
Reviewed-on: https://go-review.googlesource.com/c/gollvm/+/642655
Reviewed-by: Carlos Amedee <carlos@golang.org>
Reviewed-by: Than McIntosh <thanm@golang.org>
Reviewed-by: Anton Korobeynikov <anton@korobeynikov.info>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 2561f8b..f5b8baa 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -114,6 +114,16 @@
set(gocdep llvm-goc-token)
endif()
+if(CXX_SUPPORTS_SUGGEST_OVERRIDE_FLAG)
+ add_definitions("-Wno-suggest-override")
+ set_target_properties(gollvm PROPERTIES INTERFACE_COMPILE_OPTIONS "-Wno-suggest-override")
+endif()
+
+if(CXX_SUPPORTS_COVERED_SWITCH_DEFAULT_FLAG)
+ add_definitions("-Wno-covered-switch-default")
+ set_target_properties(gollvm PROPERTIES INTERFACE_COMPILE_OPTIONS "-Wno-covered-switch-default")
+endif()
+
# Root of gollvm source code.
set(GOLLVM_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR})
diff --git a/bridge/go-llvm-bexpression.cpp b/bridge/go-llvm-bexpression.cpp
index 1b97168..1b0ff3a 100644
--- a/bridge/go-llvm-bexpression.cpp
+++ b/bridge/go-llvm-bexpression.cpp
@@ -118,12 +118,6 @@
if (!llvm::isa<llvm::Constant>(value_))
return false;
- // Not a constant if there is a pending load
- if (value_->getType()->isPointerTy() &&
- value_->getType()->getPointerElementType() ==
- btype()->type())
- return false;
-
// In some cases, even the underlying value is an
// llvm::Constant, the expression may be not. For
// example, a var expression for a global variable,
diff --git a/bridge/go-llvm-bexpression.h b/bridge/go-llvm-bexpression.h
index 767ac47..9f4be88 100644
--- a/bridge/go-llvm-bexpression.h
+++ b/bridge/go-llvm-bexpression.h
@@ -83,10 +83,6 @@
VarContext() : addrLevel_(0), lvalue_(false), pending_(false) { }
VarContext(bool lvalue, unsigned addrLevel)
: addrLevel_(addrLevel), lvalue_(lvalue), pending_(true) { }
- explicit VarContext(const VarContext &src)
- : addrLevel_(src.addrLevel_), lvalue_(src.lvalue_),
- pending_(src.pending_)
- { }
bool pending() const { return pending_; }
unsigned addrLevel() const { return addrLevel_; }
diff --git a/bridge/go-llvm-bfunction.cpp b/bridge/go-llvm-bfunction.cpp
index 20aed84..e4b741f 100644
--- a/bridge/go-llvm-bfunction.cpp
+++ b/bridge/go-llvm-bfunction.cpp
@@ -74,10 +74,9 @@
return abiOracle_->tm()->tnamegen(tag);
}
-llvm::Instruction *Bfunction::addAlloca(llvm::Type *typ,
- const std::string &name)
-{
+llvm::Instruction *Bfunction::addAlloca(Btype *bty, const std::string &name) {
llvm::Instruction *insBefore = nullptr;
+ llvm::Type *typ = bty->type();
TypeManager *tm = abiOracle_->tm();
llvm::Align aaAlign = tm->datalayout()->getABITypeAlign(typ);
llvm::Value *aaSize = nullptr;
@@ -131,8 +130,7 @@
// Seems weird to create a zero-sized alloca(), but it should
// simplify things in that we can avoid having a Bvariable with a
// null value.
- llvm::Type *llpt = paramTypes[idx]->type();
- llvm::Instruction *inst = addAlloca(llpt, "");
+ llvm::Instruction *inst = addAlloca(paramTypes[idx], "");
paramValues_.push_back(inst);
break;
}
@@ -148,8 +146,7 @@
break;
}
case ParmDirect: {
- llvm::Type *llpt = paramTypes[idx]->type();
- llvm::Instruction *inst = addAlloca(llpt, "");
+ llvm::Instruction *inst = addAlloca(paramTypes[idx], "");
paramValues_.push_back(inst);
if (paramInfo.attr() == AttrSext)
arguments_[argIdx]->addAttr(llvm::Attribute::SExt);
@@ -229,7 +226,7 @@
// Create the spill slot for the param.
std::string spname(name);
spname += ".addr";
- llvm::Instruction *inst = addAlloca(btype->type(), spname);
+ llvm::Instruction *inst = addAlloca(btype, spname);
assert(chainVal_);
assert(llvm::isa<llvm::Argument>(chainVal_));
chainVal_ = inst;
@@ -260,7 +257,7 @@
// to share the same alloca instruction.
inst = llvm::cast<llvm::Instruction>(declVar->value());
} else {
- inst = addAlloca(btype->type(), name);
+ inst = addAlloca(btype, name);
}
if (is_address_taken) {
llvm::Instruction *alloca = inst;
@@ -285,12 +282,7 @@
llvm::Value *Bfunction::createTemporary(Btype *btype, const std::string &tag)
{
- return createTemporary(btype->type(), tag);
-}
-
-llvm::Value *Bfunction::createTemporary(llvm::Type *typ, const std::string &tag)
-{
- return addAlloca(typ, tag);
+ return addAlloca(btype, tag);
}
// This implementation uses an alloca instruction as a placeholder
@@ -378,13 +370,6 @@
llvm::Argument *arg = arguments_[paramInfo.sigOffset()];
assert(sploc->getType()->isPointerTy());
llvm::PointerType *llpt = llvm::cast<llvm::PointerType>(sploc->getType());
- if (paramInfo.abiType()->isVectorTy() ||
- arg->getType() != llpt->getElementType()) {
- std::string tag(namegen("cast"));
- llvm::Type *ptv = llvm::PointerType::get(paramInfo.abiType(), 0);
- llvm::Value *bitcast = builder.CreateBitCast(sploc, ptv, tag);
- sploc = bitcast;
- }
llvm::Instruction *si = builder.CreateStore(arg, sploc);
paramVar->setInitializer(si);
spillInstructions->appendInstructions(builder.instructions());
@@ -398,16 +383,13 @@
llvm::Type *llst = paramInfo.computeABIStructType(tm);
llvm::Type *ptst = llvm::PointerType::get(llst, 0);
- // Cast the spill location to a pointer to the struct created above.
- std::string tag(namegen("cast"));
- llvm::Value *bitcast = builder.CreateBitCast(sploc, ptst, tag);
llvm::Instruction *stinst = nullptr;
// Generate a store to each field.
for (unsigned i = 0; i < paramInfo.abiTypes().size(); ++i) {
std::string tag(namegen("field" + std::to_string(i)));
llvm::Value *fieldgep =
- builder.CreateConstInBoundsGEP2_32(llst, bitcast, 0, i, tag);
+ builder.CreateConstInBoundsGEP2_32(llst, sploc, 0, i, tag);
llvm::Value *argChunk = arguments_[paramInfo.sigOffset() + i];
stinst = builder.CreateStore(argChunk, fieldgep);
}
@@ -457,11 +439,11 @@
// Append allocas for local variables
// FIXME: create lifetime annotations
for (auto aa : allocas_)
- entry->getInstList().push_back(aa);
+ aa->insertBefore(*entry, entry->end());
// Param spills
for (auto sp : spills.instructions())
- entry->getInstList().push_back(sp);
+ sp->insertBefore(*entry, entry->end());
// Debug meta-data generation needs to know the position at which a
// parameter variable is available for inspection -- this is
@@ -496,11 +478,11 @@
// we insert any new temps into the start of the block.
if (! temps.empty())
for (auto ai : temps) {
- entry->getInstList().push_front(ai);
+ ai->insertInto(entry, entry->begin());
if (auto *ascast = llvm::dyn_cast<llvm::AddrSpaceCastInst>(ai)) {
llvm::Value *op = ascast->getPointerOperand();
assert(llvm::isa<llvm::AllocaInst>(op));
- entry->getInstList().push_front(llvm::cast<llvm::Instruction>(op));
+ llvm::cast<llvm::Instruction>(op)->insertInto(entry, entry->begin());
}
}
}
@@ -547,10 +529,8 @@
returnInfo.abiType());
llvm::Type *ptst = llvm::PointerType::get(llrt, 0);
BlockLIRBuilder builder(function(), inamegen);
- std::string castname(namegen("cast"));
- llvm::Value *bitcast = builder.CreateBitCast(toRet->value(), ptst, castname);
std::string loadname(namegen("ld"));
- llvm::Instruction *ldinst = builder.CreateLoad(llrt, bitcast, loadname);
+ llvm::Instruction *ldinst = builder.CreateLoad(llrt, toRet->value(), loadname);
retInstrs->appendInstructions(builder.instructions());
return ldinst;
}
diff --git a/bridge/go-llvm-bfunction.h b/bridge/go-llvm-bfunction.h
index f83aafa..e51cb91 100644
--- a/bridge/go-llvm-bfunction.h
+++ b/bridge/go-llvm-bfunction.h
@@ -124,7 +124,6 @@
// Return an alloca temporary of the specified type.
llvm::Value *createTemporary(Btype *btype, const std::string &tag);
- llvm::Value *createTemporary(llvm::Type *type, const std::string &tag);
// If the function return value is passing via memory instead of
// directly, this function returns the location into which the
@@ -155,7 +154,7 @@
// Create an alloca with the specified type. The alloca is recorded
// in a list so that it can be picked up during prolog generation.
- llvm::Instruction *addAlloca(llvm::Type *vtyp, const std::string &name);
+ llvm::Instruction *addAlloca(Btype *typ, const std::string &name);
// Given an LLVM value, return the Bvariable we created to wrap it (either
// local var or parameter var).
diff --git a/bridge/go-llvm-builtins.cpp b/bridge/go-llvm-builtins.cpp
index 8e7224a..606d02d 100644
--- a/bridge/go-llvm-builtins.cpp
+++ b/bridge/go-llvm-builtins.cpp
@@ -535,14 +535,13 @@
return builder->CreateOr(old, args[1]);
}
-static llvm::Value *atomicCasMaker(llvm::SmallVectorImpl<llvm::Value*> &args,
- BlockLIRBuilder *builder,
- Llvm_backend *be)
-{
+static llvm::Value *atomicCasMaker(llvm::SmallVectorImpl<llvm::Value *> &args,
+ BlockLIRBuilder *builder, Llvm_backend *be,
+ llvm::Type *elemTy) {
assert(args.size() == 6);
// GCC __atomic_compare_exchange_n takes a pointer to the old value.
// We need to load it.
- llvm::Value *old = builder->CreateLoad(args[1]->getType()->getPointerElementType(), args[1]);
+ llvm::Value *old = builder->CreateLoad(elemTy, args[1]);
// FIXME: see atomicLoadMaker, but default to SequentiallyConsistent
// for success order, Monotonic (i.e. relaxed) for failed order,
// and false for weak.
@@ -566,6 +565,18 @@
return builder->CreateZExt(ret, be->llvmInt8Type());
}
+static llvm::Value *atomicCasMaker4(llvm::SmallVectorImpl<llvm::Value *> &args,
+ BlockLIRBuilder *builder,
+ Llvm_backend *be) {
+ return atomicCasMaker(args, builder, be, be->llvmInt32Type());
+}
+
+static llvm::Value *atomicCasMaker8(llvm::SmallVectorImpl<llvm::Value *> &args,
+ BlockLIRBuilder *builder,
+ Llvm_backend *be) {
+ return atomicCasMaker(args, builder, be, be->llvmInt64Type());
+}
+
void BuiltinTable::defineExprBuiltins()
{
Btype *boolType = tman_->boolType();
@@ -655,13 +666,13 @@
{
BuiltinEntryTypeVec typeVec = {boolType, uint32PtrType, uint32PtrType, uint32Type,
boolType, int32Type, int32Type};
- registerExprBuiltin("__atomic_compare_exchange_4", nullptr,
- typeVec, atomicCasMaker);
+ registerExprBuiltin("__atomic_compare_exchange_4", nullptr, typeVec,
+ atomicCasMaker4);
}
{
BuiltinEntryTypeVec typeVec = {boolType, uint64PtrType, uint64PtrType, uint64Type,
boolType, int32Type, int32Type};
- registerExprBuiltin("__atomic_compare_exchange_8", nullptr,
- typeVec, atomicCasMaker);
+ registerExprBuiltin("__atomic_compare_exchange_8", nullptr, typeVec,
+ atomicCasMaker8);
}
}
diff --git a/bridge/go-llvm-dibuildhelper.cpp b/bridge/go-llvm-dibuildhelper.cpp
index 777b8d9..de94946 100644
--- a/bridge/go-llvm-dibuildhelper.cpp
+++ b/bridge/go-llvm-dibuildhelper.cpp
@@ -156,13 +156,7 @@
if(var->initializer() && !var->initializerInstruction()->getParent())
return;
- // Create the declare instruction, giving it an initial position at
- // the end of the entry block (the insertDeclare call below doesn't
- // allow a NULL insert location, so we pick end-of-block arbitrarily).
assert(entryBlock_);
- llvm::Instruction *decl =
- dibuilder().insertDeclare(var->value(), dilv, expr, vloc, entryBlock_);
- decl->removeFromParent();
// Extract the decl from the end of the entry block and reposition
// it according to the var properties.
@@ -173,7 +167,11 @@
} else if (var->flavor() == ParamVar) {
// parameters passing by reference may have no initializers.
// declare them at function entry.
- entryBlock_->getInstList().push_front(decl);
+ if (!entryBlock_->empty())
+ dibuilder().insertDeclare(var->value(), dilv, expr, vloc,
+ &entryBlock_->front());
+ else
+ dibuilder().insertDeclare(var->value(), dilv, expr, vloc, entryBlock_);
return;
} else {
// locals with no initializer should only be zero-sized vars.
@@ -185,7 +183,12 @@
assert(! llvm::isa<llvm::BranchInst>(insertionPoint));
assert(insertionPoint != insertionPoint->getParent()->getTerminator());
- decl->insertAfter(insertionPoint);
+ if (insertionPoint->getNextNode())
+ dibuilder().insertDeclare(var->value(), dilv, expr, vloc,
+ insertionPoint->getNextNode());
+ else
+ dibuilder().insertDeclare(var->value(), dilv, expr, vloc,
+ insertionPoint->getParent());
}
void DIBuildHelper::endFunction(Bfunction *function)
@@ -310,7 +313,7 @@
std::string DIBuildHelper::applyDebugPrefix(llvm::StringRef path) {
for (const auto &remap : debugPrefixMap_)
- if (path.startswith(remap.first))
+ if (path.starts_with(remap.first))
return (llvm::Twine(remap.second) +
path.substr(remap.first.size())).str();
return path.str();
diff --git a/bridge/go-llvm-irbuilders.cpp b/bridge/go-llvm-irbuilders.cpp
index de007b1..d883cec 100644
--- a/bridge/go-llvm-irbuilders.cpp
+++ b/bridge/go-llvm-irbuilders.cpp
@@ -25,14 +25,14 @@
BlockLIRBuilder::~BlockLIRBuilder()
{
- assert(dummyBlock_->getInstList().empty());
+ assert(dummyBlock_->empty());
dummyBlock_->removeFromParent();
}
std::vector<llvm::Instruction*> BlockLIRBuilder::instructions()
{
std::vector<llvm::Instruction*> rv;
- for (auto &i : dummyBlock_->getInstList())
+ for (auto &i : *dummyBlock_)
rv.push_back(&i);
for (auto &i : rv) {
i->removeFromParent();
diff --git a/bridge/go-llvm-irbuilders.h b/bridge/go-llvm-irbuilders.h
index 537eb1d..d54f1b6 100644
--- a/bridge/go-llvm-irbuilders.h
+++ b/bridge/go-llvm-irbuilders.h
@@ -31,8 +31,7 @@
void setDest(Bexpression *expr) { assert(!expr_); expr_ = expr; }
void InsertHelper(llvm::Instruction *I, const llvm::Twine &Name,
- llvm::BasicBlock *BB,
- llvm::BasicBlock::iterator InsertPt) const {
+ llvm::BasicBlock::iterator InsertPt) const override {
assert(expr_);
expr_->appendInstruction(I);
I->setName(Name);
diff --git a/bridge/go-llvm-materialize.cpp b/bridge/go-llvm-materialize.cpp
index 8e89288..3d2bc1a 100644
--- a/bridge/go-llvm-materialize.cpp
+++ b/bridge/go-llvm-materialize.cpp
@@ -121,8 +121,7 @@
assert(valtyp->isPointerTy());
if (valtyp->getPointerAddressSpace() != addressSpace_) {
llvm::Type *typ =
- llvm::PointerType::get(valtyp->getPointerElementType(),
- addressSpace_);
+ llvm::PointerType::get(valtyp->getContext(), addressSpace_);
val = new llvm::AddrSpaceCastInst(val, typ, "ascast");
}
@@ -176,9 +175,8 @@
}
if (lvalue || useCopyForLoadStore(type->type())) {
llvm::Type *et = expr->btype()->type();
- if (valType->isPointerTy() &&
- valType->getPointerElementType() == et)
- toType = llvm::PointerType::get(toType, addressSpace_);
+ if (valType->isPointerTy())
+ toType = llvm::PointerType::get(toType->getContext(), addressSpace_);
}
}
@@ -230,8 +228,7 @@
if (val->getType()->getPointerAddressSpace() != 0) {
// We are using non-integral pointer. Cast to address space 0
// before casting to int.
- llvm::Type *et = val->getType()->getPointerElementType();
- llvm::Type *pt = llvm::PointerType::get(et, 0);
+ llvm::Type *pt = llvm::PointerType::get(val->getContext(), 0);
std::string tname(namegen("ascast"));
val = builder.CreateAddrSpaceCast(val, pt, tname);
expr = nbuilder_.mkConversion(type, val, expr, location);
@@ -248,8 +245,7 @@
if (toType->getPointerAddressSpace() != 0) {
// We are using non-integral pointer. Cast to address space 0
// first.
- llvm::Type *et = toType->getPointerElementType();
- pt = llvm::PointerType::get(et, 0);
+ pt = llvm::PointerType::get(toType->getContext(), 0);
}
std::string tname(namegen("itpcast"));
llvm::Value *itpcast = builder.CreateIntToPtr(val, pt, tname);
@@ -342,14 +338,13 @@
return rval;
}
-llvm::Value *Llvm_backend::makePointerOffsetGEP(llvm::PointerType *llpt,
- llvm::Value *idxval,
- llvm::Value *sptr)
-{
+llvm::Value *Llvm_backend::makePointerOffsetGEP(Btype *pt, llvm::Value *idxval,
+ llvm::Value *sptr) {
LIRBuilder builder(context_, llvm::ConstantFolder());
llvm::SmallVector<llvm::Value *, 1> elems(1);
elems[0] = idxval;
- llvm::Value *val = builder.CreateGEP(llpt->getElementType(), sptr, elems, namegen("ptroff"));
+ llvm::Type *eltTy = pt->castToBPointerType()->toType()->type();
+ llvm::Value *val = builder.CreateGEP(eltTy, sptr, elems, namegen("ptroff"));
return val;
}
@@ -365,12 +360,10 @@
return val;
}
-llvm::Value *Llvm_backend::makeFieldGEP(unsigned fieldIndex,
- llvm::Value *sptr)
-{
+llvm::Value *Llvm_backend::makeFieldGEP(unsigned fieldIndex, llvm::Type *sty,
+ llvm::Value *sptr) {
assert(sptr->getType()->isPointerTy());
- llvm::PointerType *srcTyp = llvm::cast<llvm::PointerType>(sptr->getType());
- llvm::StructType *llst = llvm::cast<llvm::StructType>(srcTyp->getElementType());
+ llvm::StructType *llst = llvm::cast<llvm::StructType>(sty);
LIRBuilder builder(context_, llvm::ConstantFolder());
assert(fieldIndex < llst->getNumElements());
std::string tag(namegen("field"));
@@ -401,7 +394,7 @@
if (bstruct->isConstant())
fval = llvm::cast<llvm::Constant>(sval)->getAggregateElement(index);
else
- fval = makeFieldGEP(index, sval);
+ fval = makeFieldGEP(index, llt, sval);
Btype *bft = elementTypeByIndex(bstruct->btype(), index);
// Wrap result in a Bexpression
@@ -632,29 +625,9 @@
if (leftType == rightType)
return rval;
- // Case 1: nil op X
- if (llvm::isa<llvm::ConstantPointerNull>(leftVal) &&
- rightType->isPointerTy()) {
- BexprLIRBuilder builder(context_, left);
- std::string tag(namegen("cast"));
- llvm::Value *bitcast = builder.CreateBitCast(leftVal, rightType, tag);
- rval.first = bitcast;
- return rval;
- }
-
- // Case 2: X op nil
- if (llvm::isa<llvm::ConstantPointerNull>(rightVal) &&
- leftType->isPointerTy()) {
- BexprLIRBuilder builder(context_, right);
- std::string tag(namegen("cast"));
- llvm::Value *bitcast = builder.CreateBitCast(rightVal, leftType, tag);
- rval.second = bitcast;
- return rval;
- }
-
// Case 3: shift with different sized operands (ex: int64(v) << uint8(3)).
// Promote or demote shift amount operand to match width of left operand.
- if ((op == OPERATOR_LSHIFT || op == OPERATOR_RSHIFT) &&
+ if ((op == OPERATOR_LSHIFT || op == OPERATOR_RSHIFT || op == OPERATOR_EQEQ) &&
leftType != rightType) {
BexprLIRBuilder builder(context_, right);
llvm::IntegerType *leftITyp = llvm::cast<llvm::IntegerType>(leftType);
@@ -668,24 +641,6 @@
return rval;
}
- // Case 4: pointer type comparison
- // We check that if both are pointer types and pointing to the same type,
- // insert a cast (it doesn't matter we cast which one). This mostly needed
- // for circular pointer types (ex: type T *T; var p, q T; p == &q), where
- // the two sides have semantically identical types but with different
- // representations (in this case, T vs. *T).
- if (leftType->isPointerTy() && rightType->isPointerTy()) {
- BPointerType *lbpt = left->btype()->castToBPointerType();
- BPointerType *rbpt = right->btype()->castToBPointerType();
- if (lbpt->toType()->type() == rbpt->toType()->type()) {
- BexprLIRBuilder builder(context_, right);
- std::string tag(namegen("cast"));
- llvm::Value *bitcast = builder.CreateBitCast(rightVal, leftType, tag);
- rval.second = bitcast;
- return rval;
- }
- }
-
return rval;
}
@@ -1024,10 +979,8 @@
base = resolveVarContext(base);
// Construct an appropriate GEP
- llvm::PointerType *llpt =
- llvm::cast<llvm::PointerType>(base->btype()->type());
llvm::Value *gep =
- makePointerOffsetGEP(llpt, index->value(), base->value());
+ makePointerOffsetGEP(base->btype(), index->value(), base->value());
// Wrap in a Bexpression
Bexpression *rval = nbuilder_.mkPointerOffset(base->btype(), gep, base,
@@ -1192,7 +1145,7 @@
if (paramInfo.attr() == AttrByVal && vt->getPointerAddressSpace() != 0) {
// We pass a stack address, which is always in address space 0.
std::string castname(namegen("ascast"));
- llvm::Type *pt = llvm::PointerType::get(vt->getPointerElementType(), 0);
+ llvm::Type *pt = llvm::PointerType::get(vt->getContext(), 0);
val = builder.CreateAddrSpaceCast(val, pt, castname);
}
@@ -1240,29 +1193,13 @@
Bvariable *cv = genVarForConstant(cval, resarg->btype());
val = cv->value();
}
- std::string castname(namegen("cast"));
- // We are going to do a load, so the address space does not matter.
- // It seems we may get here with either address space, so we just
- // do an address-space-preserving cast.
- llvm::Type *ptv =
- llvm::PointerType::get(paramInfo.abiType(),
- val->getType()->getPointerAddressSpace());
- llvm::Value *bitcast = builder.CreateBitCast(val, ptv, castname);
std::string ltag(namegen("ld"));
- llvm::Value *ld = builder.CreateLoad(paramInfo.abiType(), bitcast, ltag);
+ llvm::Value *ld = builder.CreateLoad(paramInfo.abiType(), val, ltag);
state.llargs.push_back(ld);
continue;
}
// Passing a single 8-byte-or-less argument.
- // Apply any necessary pointer type conversions.
- if (val->getType()->isPointerTy() && ctx == VE_rvalue) {
- llvm::FunctionType *llft =
- llvm::cast<llvm::FunctionType>(state.calleeFcnType->type());
- llvm::Type *paramTyp = llft->getParamType(paramInfo.sigOffset());
- val = convertForAssignment(resarg, paramTyp);
- }
-
// Apply any necessary sign-extensions or zero-extensions.
if (paramInfo.abiType()->isIntegerTy()) {
if (paramInfo.attr() == AttrZext)
@@ -1283,7 +1220,6 @@
// Create a struct type of the appropriate shape
llvm::Type *llst = paramInfo.computeABIStructType(typeManager());
- llvm::Type *ptst = makeLLVMPointerType(llst);
// If the value we're passing is a composite constant, we have to
// spill it to memory here in order for the casts below to work.
@@ -1299,16 +1235,11 @@
val = cv->value();
}
- // Cast the value to the struct type
- std::string tag(namegen("cast"));
- llvm::Value *bitcast =
- builder.CreatePointerBitCastOrAddrSpaceCast(val, ptst, tag);
-
// Load up each field
for ( unsigned i = 0; i < paramInfo.abiTypes().size(); ++i) {
std::string ftag(namegen("field"+std::to_string(i)));
llvm::Value *fieldgep =
- builder.CreateConstInBoundsGEP2_32(llst, bitcast, 0, i, ftag);
+ builder.CreateConstInBoundsGEP2_32(llst, val, 0, i, ftag);
std::string ltag(namegen("ld"));
llvm::Value *ld = builder.CreateLoad(paramInfo.abiTypes()[i], fieldgep, ltag);
state.llargs.push_back(ld);
@@ -1389,13 +1320,8 @@
llvm::Type *rt = (returnInfo.abiTypes().size() == 1 ?
returnInfo.abiType() :
returnInfo.computeABIStructType(typeManager()));
- llvm::Type *ptrt = llvm::PointerType::get(rt, 0);
- std::string castname(namegen("cast"));
- llvm::Value *bitcast =
- state.builder.CreateBitCast(state.sretTemp,
- ptrt, castname);
std::string stname(namegen("st"));
- state.builder.CreateStore(callInst, bitcast);
+ state.builder.CreateStore(callInst, state.sretTemp);
callExpr->appendInstructions(state.builder.instructions());
}
}
@@ -1605,152 +1531,6 @@
return rval;
}
-llvm::Value *
-Llvm_backend::convertForAssignment(Bexpression *src,
- llvm::Type *dstToType)
-{
- if (src->value()->getType() == dstToType)
- return src->value();
-
- llvm::Function *dummyFcn = errorFunction_->function();
- BlockLIRBuilder builder(dummyFcn, this);
- llvm::Value *val = convertForAssignment(src->btype(), src->value(),
- dstToType, &builder);
- src->appendInstructions(builder.instructions());
- return val;
-}
-
-llvm::Value *
-Llvm_backend::convertForAssignment(Btype *srcBType,
- llvm::Value *srcVal,
- llvm::Type *dstToType,
- BlockLIRBuilder *builder)
-{
- llvm::Type *srcType = srcVal->getType();
-
- if (dstToType == srcType)
- return srcVal;
-
- // Case 1: handle discrepancies between representations of function
- // descriptors. All front end function descriptor types are structs
- // with a single field, however this field can sometimes be a pointer
- // to function, and sometimes it can be of uintptr type.
- bool srcPtrToFD = isPtrToFuncDescriptorType(srcType);
- bool dstPtrToFD = isPtrToFuncDescriptorType(dstToType);
- if (srcPtrToFD && dstPtrToFD) {
- std::string tag(namegen("cast"));
- llvm::Value *bitcast = builder->CreateBitCast(srcVal, dstToType, tag);
- return bitcast;
- }
-
- // Case 2: handle circular function types.
- bool dstCircFunc = isCircularFunctionType(dstToType);
- bool srcCircFunc = isCircularFunctionType(srcType);
- bool srcFuncPtr = isPtrToFuncType(srcType);
- if (((srcPtrToFD || srcFuncPtr || srcCircFunc) && dstCircFunc) ||
- (srcCircFunc && dstPtrToFD)) {
- std::string tag(namegen("cast"));
- llvm::Value *bitcast = builder->CreateBitCast(srcVal, dstToType, tag);
- return bitcast;
- }
-
- // Case 3: handle raw function pointer assignment (frontend will
- // sometimes take a function pointer and assign it to "void *" without
- // an explicit conversion).
- bool dstPtrToVoid = isPtrToVoidType(dstToType);
- if (dstPtrToVoid && srcFuncPtr) {
- std::string tag(namegen("cast"));
- llvm::Value *bitcast = builder->CreateBitCast(srcVal, dstToType, tag);
- return bitcast;
- }
-
- // Case 4: in some cases when calling a function (for example, __gogo)
- // the front end will pass a raw function vale in place of a function
- // descriptor. Allow this case.
- if (dstPtrToFD && srcFuncPtr) {
- std::string tag(namegen("cast"));
- llvm::Value *bitcast =
- builder->CreatePointerBitCastOrAddrSpaceCast(srcVal, dstToType, tag);
- return bitcast;
- }
-
- // Case 5: handle polymorphic nil pointer expressions-- these are
- // generated without a type initially, so we need to convert them
- // to the appropriate type if they appear in an assignment context.
- if (srcVal == nil_pointer_expression()->value()) {
- std::string tag(namegen("cast"));
- llvm::Value *bitcast = builder->CreateBitCast(srcVal, dstToType, tag);
- return bitcast;
- }
-
- // Case 6: the code that creates interface values stores pointers of
- // various flavors into i8*. Ideally it would be better to insert
- // forced type conversions in the FE, but for now we allow this case.
- bool srcPtrToIface = isPtrToIfaceStructType(srcType);
- if (dstPtrToVoid && srcPtrToIface) {
- std::string tag(namegen("cast"));
- llvm::Value *bitcast = builder->CreateBitCast(srcVal, dstToType, tag);
- return bitcast;
- }
-
- // Case 7: when creating slice values it's common for the frontend
- // to mix pointers and arrays, e.g. assign "[3 x i64]*" to "i64**".
- // Allow this sort of conversion.
- llvm::Type *elt =
- (dstToType->isPointerTy() ?
- llvm::cast<llvm::PointerType>(dstToType)->getElementType() : nullptr);
- if (elt && isPtrToArrayOf(srcType, elt)) {
- std::string tag(namegen("cast"));
- llvm::Value *bitcast = builder->CreateBitCast(srcVal, dstToType, tag);
- return bitcast;
- }
-
- // Case 8: also when creating slice values it's common for the
- // frontend to assign pointer-to-X to unsafe.Pointer (and vice versa)
- // without an explicit cast. Allow this for now.
- if ((dstToType == llvmPtrType() && llvm::isa<llvm::PointerType>(srcType)) ||
- (srcType == llvmPtrType() && llvm::isa<llvm::PointerType>(dstToType))) {
- std::string tag(namegen("cast"));
- llvm::Value *bitcast = builder->CreatePointerBitCastOrAddrSpaceCast(srcVal, dstToType, tag);
- return bitcast;
- }
-
- // Case 9: related to case 1 above, interface value expressions can
- // contain C function pointers stored as "void *" instead of
- // concrete pointer-to-function values. For example, consider a
- // value V1 of the form
- //
- // { { T1*, void* }, O* }
- //
- // where T1 is a type descriptor and O is an object; this value can
- // sometimes be assigned to a location of type
- //
- // { { T1*, F* }, O* }
- //
- // where F is a concrete C pointer-to-function (as opposed to "void*").
- // Allow conversions of this sort for now.
- std::set<llvm::Type *> visited;
- if (fcnPointerCompatible(dstToType, srcType, visited)) {
- std::string tag(namegen("cast"));
- llvm::Value *bitcast =
- builder->CreatePointerBitCastOrAddrSpaceCast(srcVal, dstToType, tag);
- return bitcast;
- }
-
- // Case 10: circular pointer type (ex: type T *T; var p T; p = &p)
- BPointerType *srcbpt = srcBType->castToBPointerType();
- if (srcbpt) {
- Btype *ctypconv = circularTypeAddrConversion(srcbpt->toType());
- if (ctypconv != nullptr && ctypconv->type() == dstToType) {
- std::string tag(namegen("cast"));
- llvm::Value *bitcast = builder->CreateBitCast(srcVal, dstToType, tag);
- return bitcast;
- }
- }
-
- return srcVal;
-}
-
// Walk the specified expression and invoke setVarExprPending on
// each var expression, with correct lvalue/rvalue tag depending on
// context.
diff --git a/bridge/go-llvm-typemanager.cpp b/bridge/go-llvm-typemanager.cpp
index 4301233..d853e43 100644
--- a/bridge/go-llvm-typemanager.cpp
+++ b/bridge/go-llvm-typemanager.cpp
@@ -1008,8 +1008,8 @@
// Circular function/pointer types have isPlaceholder false, but they do
// need to resolve, so special-case them.
if (!placeholder->isPlaceholder() &&
- circularPointerTypes_.find(placeholder->type()) == circularPointerTypes_.end() &&
- circularFunctionTypes_.find(placeholder->type()) == circularFunctionTypes_.end())
+ circularPointerTypes_.find(placeholder) == circularPointerTypes_.end() &&
+ circularFunctionTypes_.find(placeholder) == circularFunctionTypes_.end())
return true;
assert(anonTypes_.find(placeholder) == anonTypes_.end());
@@ -1038,8 +1038,8 @@
}
// Circular pointer type handling
- circularConversionLoadMap_[cpt->type()] = elt;
- circularConversionAddrMap_[elt->type()] = cpt;
+ circularConversionLoadMap_[cpt] = elt;
+ circularConversionAddrMap_[elt] = cpt;
return setPlaceholderPointerType(placeholder, cpt);
}
@@ -1056,9 +1056,9 @@
std::cerr << "redir: "; to_type->dump();
}
- auto it = circularFunctionTypes_.find(placeholder->type());
+ auto it = circularFunctionTypes_.find(placeholder);
if (it != circularFunctionTypes_.end())
- circularFunctionTypes_.insert(to_type->type());
+ circularFunctionTypes_.insert(to_type);
// Update the target type for the pointer
BPointerType *bpt = placeholder->castToBPointerType();
@@ -1251,11 +1251,11 @@
// Push marker and placeholder onto a stack so that we can
// update them when the appropriate function type is created.
circularFunctionPlaceholderTypes_.insert(placeholder);
- circularFunctionTypes_.insert(rval->type());
+ circularFunctionTypes_.insert(rval);
} else {
// Set up to start tracking the types that will make up the
// loop involved in the cycle.
- circularPointerTypes_.insert(circ_typ);
+ circularPointerTypes_.insert(rval);
}
if (traceLevel() > 1) {
@@ -1278,35 +1278,25 @@
auto it = circularFunctionPlaceholderTypes_.find(btype);
if (it != circularFunctionPlaceholderTypes_.end())
return true;
- return isCircularFunctionType(btype->type());
-}
-
-bool TypeManager::isCircularFunctionType(llvm::Type *typ) {
- assert(typ);
- auto it = circularFunctionTypes_.find(typ);
- return it != circularFunctionTypes_.end();
+ auto it2 = circularFunctionTypes_.find(btype);
+ return it2 != circularFunctionTypes_.end();
}
// Return whether we might be looking at a circular pointer type.
-bool TypeManager::isCircularPointerType(Btype *btype) {
- assert(btype);
- return isCircularPointerType(btype->type());
-}
-
-bool TypeManager::isCircularPointerType(llvm::Type *typ) {
+bool TypeManager::isCircularPointerType(Btype *typ) {
assert(typ);
auto it = circularPointerTypes_.find(typ);
return it != circularPointerTypes_.end();
}
Btype *TypeManager::circularTypeLoadConversion(Btype *typ) {
- auto it = circularConversionLoadMap_.find(typ->type());
+ auto it = circularConversionLoadMap_.find(typ);
return it != circularConversionLoadMap_.end() ? it->second : nullptr;
}
Btype *TypeManager::circularTypeAddrConversion(Btype *typ) {
- auto it = circularConversionAddrMap_.find(typ->type());
+ auto it = circularConversionAddrMap_.find(typ);
if (it != circularConversionAddrMap_.end())
return it->second;
return nullptr;
@@ -1506,7 +1496,7 @@
if (btype == errorType_)
return 1;
llvm::Type *toget = getPlaceholderProxyIfNeeded(btype);
- unsigned uval = datalayout_->getABITypeAlignment(toget);
+ unsigned uval = datalayout_->getABITypeAlign(toget).value();
return static_cast<int64_t>(uval);
}
@@ -1538,7 +1528,7 @@
llvm::StructType *dummyst = llvm::StructType::get(context_, elems);
const llvm::StructLayout *sl = datalayout_->getStructLayout(dummyst);
uint64_t uoff = sl->getElementOffset(1);
- unsigned talign = datalayout_->getABITypeAlignment(toget);
+ unsigned talign = datalayout_->getABITypeAlign(toget).value();
int64_t rval = (uoff < talign ? uoff : talign);
return rval;
}
@@ -1564,134 +1554,6 @@
return static_cast<int64_t>(uoff);
}
-bool TypeManager::isPtrToIfaceStructType(llvm::Type *typ)
-{
- if (! typ->isPointerTy())
- return false;
- llvm::PointerType *pt = llvm::cast<llvm::PointerType>(typ);
- llvm::Type *elt = pt->getElementType();
- if (! elt->isStructTy())
- return false;
- llvm::StructType *st = llvm::cast<llvm::StructType>(elt);
- if (st->getNumElements() != 2)
- return false;
- llvm::SmallPtrSet<llvm::Type *, 32> vis;
- // expect { ptr, ptr } or { ptr, uintptr }
- return (st->getElementType(0)->isPointerTy() &&
- (st->getElementType(1)->isPointerTy() ||
- st->getElementType(1) == llvmIntegerType()));
-}
-
-bool TypeManager::isFuncDescriptorType(llvm::Type *typ)
-{
- if (! typ->isStructTy())
- return false;
- llvm::StructType *st = llvm::cast<llvm::StructType>(typ);
- if (st->getNumElements() != 1)
- return false;
- llvm::Type *f0t = st->getElementType(0);
- llvm::PointerType *f0tpt = nullptr;
- if (f0t->isPointerTy())
- f0tpt = llvm::cast<llvm::PointerType>(f0t);
- if (f0t != llvmIntegerType_ &&
- !f0t->isFunctionTy() &&
- !(f0tpt && f0tpt->getElementType()->isFunctionTy()))
- return false;
- return true;
-}
-
-bool TypeManager::isPtrToFuncDescriptorType(llvm::Type *typ)
-{
- if (! typ->isPointerTy())
- return false;
- llvm::PointerType *pt = llvm::cast<llvm::PointerType>(typ);
- return isFuncDescriptorType(pt->getElementType());
-}
-
-bool TypeManager::isPtrToFuncType(llvm::Type *typ)
-{
- if (! typ->isPointerTy())
- return false;
- llvm::PointerType *pt = llvm::cast<llvm::PointerType>(typ);
- return pt->getElementType()->isFunctionTy();
-}
-
-bool TypeManager::isPtrToVoidType(llvm::Type *typ)
-{
- if (! typ->isPointerTy())
- return false;
- llvm::PointerType *pt = llvm::cast<llvm::PointerType>(typ);
- return pt->getElementType() == llvmInt8Type_;
-}
-
-bool TypeManager::isPtrToArrayOf(llvm::Type *typ, llvm::Type *arElmTyp)
-{
- if (! typ->isPointerTy())
- return false;
- llvm::PointerType *pt = llvm::cast<llvm::PointerType>(typ);
- llvm::Type *elt = pt->getElementType();
- if (! elt->isArrayTy())
- return false;
- llvm::ArrayType *llat = llvm::cast<llvm::ArrayType>(elt);
- llvm::Type *aelt = llat->getElementType();
- if (aelt == arElmTyp)
- return true;
- if (isCircularFunctionType(aelt) && isCircularFunctionType(arElmTyp))
- return true; // TODO: check they are same circular function type?
- return false;
-}
-
-bool TypeManager::fcnPointerCompatible(llvm::Type *left,
- llvm::Type *right,
- std::set<llvm::Type *> &visited)
-{
- // Allow for pointer-to-fp and func-desc matching
- bool leftFPD = isPtrToFuncType(left) || isPtrToVoidType(left);
- bool rightFPD = isPtrToFuncType(right) || isPtrToVoidType(right);
- if (leftFPD && rightFPD)
- return true;
-
- bool visleft = (visited.find(left) != visited.end());
- bool visright = (visited.find(right) != visited.end());
- if (visleft != visright)
- return false;
- if (visleft)
- return true;
- visited.insert(left);
- visited.insert(right);
-
- // Compare type ID, children, etc.
- if (left->getTypeID() != right->getTypeID())
- return false;
-
- // For pointer types, visit pointed-to elements
- if (left->isPointerTy()) {
- llvm::PointerType *ptl = llvm::cast<llvm::PointerType>(left);
- llvm::PointerType *ptr = llvm::cast<llvm::PointerType>(right);
- llvm::Type *eltl = ptl->getElementType();
- llvm::Type *eltr = ptr->getElementType();
- return fcnPointerCompatible(eltl, eltr, visited);
- }
-
- // For aggregate types, compare children.
- if (left->isAggregateType()) {
- unsigned leftnct = left->getNumContainedTypes();
- unsigned rightnct = right->getNumContainedTypes();
- if (leftnct != rightnct)
- return false;
- for (unsigned cti = 0; cti < leftnct; cti++) {
- llvm::Type *leftchild = left->getContainedType(cti);
- llvm::Type *rightchild = right->getContainedType(cti);
- if (!fcnPointerCompatible(leftchild, rightchild, visited))
- return false;
- }
- return true;
- } else {
- // For non-aggregate types, we expect underlying llvm types to match
- return (left == right);
- }
-}
-
std::string TypeManager::typToString(Btype *typ)
{
std::map<Btype *, std::string> smap;
@@ -1750,7 +1612,7 @@
assert(!bpt->isPlaceholder());
// handle circular pointer types
- auto cpit = circularPointerTypes_.find(typ->type());
+ auto cpit = circularPointerTypes_.find(typ);
if (cpit != circularPointerTypes_.end()) {
std::string s;
llvm::raw_string_ostream os(s);
@@ -1848,7 +1710,7 @@
// Now create struct type itself. Q: should this be
// getTypeAllocSize here instead of getTypeSizeInBits?
uint64_t sizeInBits = datalayout_->getTypeSizeInBits(bst->type());
- uint32_t alignInBits = datalayout_->getABITypeAlignment(bst->type());
+ uint32_t alignInBits = datalayout_->getABITypeAlign(bst->type()).value();
llvm::DIType *derivedFrom = nullptr;
llvm::DICompositeType *dist =
dibuilder.createStructType(scope, typToString(bst),
@@ -1976,7 +1838,7 @@
uint64_t arElems = bat->nelSize();
uint64_t arSize = datalayout_->getTypeSizeInBits(bat->type());
uint64_t arAlign =
- datalayout_->getABITypeAlignment(bat->elemType()->type());
+ datalayout_->getABITypeAlign(bat->elemType()->type()).value();
llvm::SmallVector<llvm::Metadata *, 1> subscripts;
subscripts.push_back(dibuilder.getOrCreateSubrange(0, arElems));
llvm::DINodeArray subsAr = dibuilder.getOrCreateArray(subscripts);
diff --git a/bridge/go-llvm-typemanager.h b/bridge/go-llvm-typemanager.h
index d77a3ab..4db9ccc 100644
--- a/bridge/go-llvm-typemanager.h
+++ b/bridge/go-llvm-typemanager.h
@@ -74,9 +74,7 @@
Btype *namedType(const std::string &, Btype *, Location);
Btype *circularPointerType(Btype *, bool);
bool isCircularPointerType(Btype *);
- bool isCircularPointerType(llvm::Type *);
bool isCircularFunctionType(Btype *);
- bool isCircularFunctionType(llvm::Type *);
int64_t typeSize(Btype *);
int64_t typeAlignment(Btype *);
int64_t typeFieldAlignment(Btype *);
@@ -205,24 +203,6 @@
// found.
bool addPlaceholderRefs(Btype *type);
- // Helpers
- bool isFuncDescriptorType(llvm::Type *typ);
- bool isPtrToFuncDescriptorType(llvm::Type *typ);
- bool isPtrToIfaceStructType(llvm::Type *typ);
- bool isPtrToFuncType(llvm::Type *typ);
- bool isPtrToVoidType(llvm::Type *typ);
- bool isPtrToArrayOf(llvm::Type *ptyp, llvm::Type *arrayElmTyp);
-
- // This helper looks at two LLVM types and does a structural
- // comparison to determine if 'left' is equivalent to 'right' modulo
- // discrepancies between raw function pointers and "void *" (or
- // equivalent). This is to allow for cases where the front end will
- // store a function pointer in a table or struct somewhere as "void
- // *" instead of the precise function type.
- bool fcnPointerCompatible(llvm::Type *left,
- llvm::Type *right,
- std::set<llvm::Type *> &visited);
-
// If specified type is a pointer flagged as being a circular
// type, return conversion needed on load from that type, or NULL
// if the type is not circular.
@@ -337,15 +317,15 @@
// Set of circular pointer types. These are pointers to opaque types that
// are returned by the ::circular_pointer_type() method.
- std::unordered_set<llvm::Type *> circularPointerTypes_;
+ std::unordered_set<Btype *> circularPointerTypes_;
// Map from placeholder type to circular pointer type. Key is placeholder
// pointer type, value is circular pointer type marker.
std::unordered_map<Btype *, Btype *> circularPointerTypeMap_;
// Maps for inserting conversions involving circular pointers.
- std::unordered_map<llvm::Type *, Btype *> circularConversionLoadMap_;
- std::unordered_map<llvm::Type *, Btype *> circularConversionAddrMap_;
+ std::unordered_map<Btype *, Btype *> circularConversionLoadMap_;
+ std::unordered_map<Btype *, Btype *> circularConversionAddrMap_;
// Set of top-level circular function types.
std::unordered_set<Btype *> circularFunctionPlaceholderTypes_;
@@ -353,7 +333,7 @@
// This set holds the marker types returned for the self-referential
// elements within a circular function type, also any resolved LLVM
// function types created from placeholders.
- std::unordered_set<llvm::Type *> circularFunctionTypes_;
+ std::unordered_set<Btype *> circularFunctionTypes_;
// Name generation helper
NameGen *nametags_;
diff --git a/bridge/go-llvm.cpp b/bridge/go-llvm.cpp
index 8ee5a24..be0f0bc 100644
--- a/bridge/go-llvm.cpp
+++ b/bridge/go-llvm.cpp
@@ -412,10 +412,7 @@
Bfunction *Llvm_backend::createIntrinsicFcn(const std::string &name,
llvm::Function *fcn)
{
- llvm::PointerType *llpft =
- llvm::cast<llvm::PointerType>(fcn->getType());
- llvm::FunctionType *llft =
- llvm::cast<llvm::FunctionType>(llpft->getElementType());
+ llvm::FunctionType *llft = fcn->getFunctionType();
BFunctionType *fcnType = makeAuxFcnType(llft);
Location pdcl = linemap()->get_predeclared_location();
Bfunction *bfunc = new Bfunction(fcn, fcnType, name, name, pdcl,
@@ -567,18 +564,10 @@
llvm::Type *vt = val->getType();
assert(vt->isPointerTy());
llvm::Type *llToType = toType->type();
- if (expr->varExprPending()) {
- llvm::Type *et = expr->btype()->type();
- if (vt->getPointerElementType() == et)
- llToType = llvm::PointerType::get(llToType, vt->getPointerAddressSpace());
- }
if (vt == llToType)
return expr;
- std::string tag(namegen("cast"));
- LIRBuilder builder(context_, llvm::ConstantFolder());
- llvm::Value *bitcast = builder.CreatePointerBitCastOrAddrSpaceCast(val, llToType, tag);
- return nbuilder_.mkConversion(toType, bitcast, expr, loc);
+ return nbuilder_.mkConversion(toType, val, expr, loc);
}
Bexpression *Llvm_backend::genLoad(Bexpression *expr,
@@ -593,6 +582,7 @@
// pointer types.
Bexpression *space = expr;
Btype *loadResultType;
+ bool needs_extra_deref = false;
if (btype) {
loadResultType = btype;
Btype *tctyp = circularTypeLoadConversion(expr->btype());
@@ -600,6 +590,21 @@
space = genCircularConversion(pointer_type(tctyp), expr, loc);
loadResultType = tctyp;
}
+ int flavor = expr->flavor();
+ // In most cases loadResultType is the same as value llvm type,
+ // or they're both pointers. Still in some cases we need additional
+ // level of indirection. This happens when:
+ // 1. expr is used to access variable, structure field or is a compound
+ // expression. Those expression's llvm value is alloca or GEP, which
+ // is actually a pointer to a value, not value itself.
+ // 2. expr is dereference (N_Deref), which has not yet been fully handled
+ // by the bridge. In such case the load instruction has not yet been
+ // generated.
+ if (!loadResultType->type()->isPointerTy())
+ needs_extra_deref =
+ ((flavor == N_Deref && expr->varExprPending()) || flavor == N_Var ||
+ flavor == N_StructField || flavor == N_Compound);
+
} else {
// Here we are resolving a pending var expression. The LLVM
// value should already be pointer to the expression type.
@@ -608,18 +613,10 @@
}
llvm::Value *spaceVal = space->value();
- if (spaceVal == nil_pointer_expression()->value()) {
- llvm::Function *dummyFcn = errorFunction_->function();
- BlockLIRBuilder builder(dummyFcn, this);
- llvm::Type *spaceTyp = llvm::PointerType::get(loadResultType->type(), addressSpace_);
- std::string tag(namegen("cast"));
- spaceVal = builder.CreateBitCast(spaceVal, spaceTyp, tag);
- space->appendInstructions(builder.instructions());
- }
-
- llvm::PointerType *llpt =
- llvm::cast<llvm::PointerType>(spaceVal->getType());
- llvm::Type *llrt = llpt->getElementType();
+ llvm::Type *llrt = loadResultType->type();
+ if (needs_extra_deref)
+ llrt = llvm::PointerType::get(
+ llrt, expr->btype()->type()->getPointerAddressSpace());
// If this type meets our criteria (composite/aggregate whose
// size is above a certain threshhold) then assume that the
@@ -631,13 +628,11 @@
std::string ldname(tag);
ldname += ".ld";
ldname = namegen(ldname);
- llvm::Type *vt = spaceVal->getType()->getPointerElementType();
llvm::Instruction *insBefore = nullptr;
- llvm::Align ldAlign = datalayout_->getABITypeAlign(vt);
+ llvm::Align ldAlign = datalayout_->getABITypeAlign(llrt);
bool isVolatile = false;
- llvm::Instruction *loadInst = new llvm::LoadInst(vt, spaceVal, ldname,
- isVolatile, ldAlign,
- insBefore);
+ llvm::Instruction *loadInst = new llvm::LoadInst(
+ llrt, spaceVal, ldname, isVolatile, ldAlign, insBefore);
rval = nbuilder_.mkDeref(loadResultType, loadInst, space, loc);
rval->appendInstruction(loadInst);
} else {
@@ -879,17 +874,6 @@
// Decide whether we want a simple store instruction or a memcpy.
if (! useCopyForLoadStore(srcType)) {
- if (srcVal->getType()->isPointerTy()) {
- llvm::PointerType *dstpt =
- llvm::cast<llvm::PointerType>(dstType);
- srcVal = convertForAssignment(srcType, srcVal,
- dstpt->getElementType(), builder);
- }
-
- // At this point the types should agree
- llvm::PointerType *dpt = llvm::cast<llvm::PointerType>(dstType);
- assert(srcVal->getType() == dpt->getElementType());
-
// Create and return store
return builder->CreateStore(srcVal, dstLoc);
}
@@ -1101,21 +1085,6 @@
// Normal case
llvm::Value *varval = var->value();
-
- // Special case for zero-sized globals. These require a type conversion,
- // since the underlying definition has been coerced to something with
- // non-zero size (as a means of avoiding linker misbehavior).
- Btype *underlyingType = var->underlyingType();
- if (underlyingType != nullptr) {
- LIRBuilder irbuilder(context_, llvm::ConstantFolder());
- std::string tag(namegen("zeroSizeCast"));
- llvm::Type *toType = llvm::PointerType::get(var->btype()->type(),
- addressSpace_);
- llvm::Value *bitcast =
- irbuilder.CreateBitCast(var->value(), toType, tag);
- varval = bitcast;
- }
-
Bexpression *varexp = nbuilder_.mkVar(var, varval, location);
varexp->setTag(var->name().c_str());
return varexp;
@@ -1172,13 +1141,13 @@
BIntegerType *bit = btype->castToBIntegerType();
if (bit->isUnsigned()) {
uint64_t val = checked_convert_mpz_to_int<uint64_t>(mpz_val);
- llvm::APInt apiv(bit->bits(), val);
+ llvm::APInt apiv(bit->bits(), val, false, true);
llvm::Constant *lval = llvm::ConstantInt::get(btype->type(), apiv);
Bexpression *bconst = nbuilder_.mkConst(btype, lval);
return makeGlobalExpression(bconst, lval, btype, Location());
} else {
int64_t val = checked_convert_mpz_to_int<int64_t>(mpz_val);
- llvm::APInt apiv(bit->bits(), val, true);
+ llvm::APInt apiv(bit->bits(), val, true, true);
llvm::Constant *lval = llvm::ConstantInt::get(btype->type(), apiv);
Bexpression *bconst = nbuilder_.mkConst(btype, lval);
return makeGlobalExpression(bconst, lval, btype, Location());
@@ -1310,11 +1279,9 @@
MV_SkipDebug, llvm::GlobalValue::PrivateLinkage,
scon, 1);
llvm::Constant *varval = llvm::cast<llvm::Constant>(svar->value());
- llvm::Constant *bitcast =
- llvm::ConstantExpr::getBitCast(varval, stringType()->type());
- Bexpression *bconst = nbuilder_.mkConst(stringType(), bitcast);
+ Bexpression *bconst = nbuilder_.mkConst(stringType(), varval);
Bexpression *rval =
- makeGlobalExpression(bconst, bitcast, stringType(), Location());
+ makeGlobalExpression(bconst, varval, stringType(), Location());
stringConstantMap_[scon] = rval;
return rval;
}
@@ -2159,7 +2126,7 @@
llvm::Value *old = nullptr;
if (glob && glob->getLinkage() == linkage) {
// A global variable with same name already exists.
- if (glob->getType()->getElementType() == btype->type()) {
+ if (glob->getValueType() == btype->type()) {
if (isExtInit == MV_NotExternallyInitialized) {
// A definition overrides a declaration for external var.
glob->setExternallyInitialized(false);
@@ -2190,16 +2157,12 @@
// Here we are creating an external declaration
// of a different type. We make a bitcast to the
// new type.
- llvm::Constant *decl = module_->getOrInsertGlobal(gname, btype->type());
- bool addressTaken = true; // for now
- Bvariable *bv =
- new Bvariable(btype, location, gname, GlobalVar, addressTaken, decl);
- assert(valueVarMap_.find(bv->value()) == valueVarMap_.end());
- valueVarMap_[bv->value()] = bv;
- if (genDebug == MV_GenDebug && dibuildhelper() && !errorCount_) {
- bool exported = (linkage == llvm::GlobalValue::ExternalLinkage);
- dibuildhelper()->processGlobal(bv, exported);
- }
+
+ // Starting from LLVM-17 we're no longer using bitcasts
+ // for pointer types
+ auto it = valueVarMap_.find(glob);
+ assert(it != valueVarMap_.end());
+ Bvariable *bv = it->second;
return bv;
}
}
@@ -2239,8 +2202,7 @@
// Fix up old declaration if there is one
if (old) {
assert(llvm::isa<llvm::PointerType>(old->getType()));
- llvm::Type *declTyp =
- llvm::cast<llvm::PointerType>(old->getType())->getElementType();
+ llvm::Type *declTyp = llvm::cast<llvm::GlobalValue>(old)->getValueType();
llvm::Constant *newDecl = module_->getOrInsertGlobal(gname, declTyp);
old->replaceAllUsesWith(newDecl);
// NB: previously we had a call to old->deleteValue() here, but this
@@ -2534,7 +2496,7 @@
// A global with the same name already declared?
llvm::GlobalVariable *glob = module_->getGlobalVariable(gname);
if (glob) {
- assert(glob->getType()->getElementType() == btype->type());
+ assert(glob->getValueType() == btype->type());
auto it = valueVarMap_.find(glob);
assert(it != valueVarMap_.end());
Bvariable *bv = it->second;
@@ -2784,17 +2746,17 @@
fns == "runtime.mapaccess2_fast64" ||
fns == "runtime.mapaccess2_faststr" ||
fns == "runtime.mapaccess2_fat"))
- fcn->addFnAttr(llvm::Attribute::ReadOnly);
+ fcn->setOnlyReadsMemory();
// memcmp-like.
if (fns == "runtime.memequal" ||
fns == "runtime.cmpstring") {
- fcn->addFnAttr(llvm::Attribute::ReadOnly);
- fcn->addFnAttr(llvm::Attribute::ArgMemOnly);
+ fcn->setOnlyReadsMemory();
+ fcn->setOnlyAccessesArgMemory();
}
if (fns == "runtime.memclrNoHeapPointers")
- fcn->addFnAttr(llvm::Attribute::ArgMemOnly);
+ fcn->setOnlyAccessesArgMemory();
// These functions are called in unlikely branches. But they
// themselves are not actually cold in the runtime. So only
@@ -3152,10 +3114,7 @@
// possibly-excepting call with landing pad.
llvm::SmallVector<llvm::Value *, 8> args(call->arg_begin(), call->arg_end());
llvm::Value *callop = call->getCalledOperand();
- llvm::PointerType *pft =
- llvm::cast<llvm::PointerType>(callop->getType());
- llvm::FunctionType *fty =
- llvm::cast<llvm::FunctionType>(pft->getElementType());
+ llvm::FunctionType *fty = call->getFunctionType();
llvm::InvokeInst *invcall =
llvm::InvokeInst::Create(fty, callop, contbb, padbb, args,
call->getName());
@@ -3284,7 +3243,7 @@
changed = true;
if (dibuildhelper_)
dibuildhelper_->processExprInst(containingStmt, expr, inst);
- curblock->getInstList().push_back(inst);
+ inst->insertBefore(*curblock, curblock->end());
curblock = pair.second;
newinsts.push_back(inst);
@@ -3294,7 +3253,7 @@
// current block.
LIRBuilder builder(context_, llvm::ConstantFolder());
llvm::Instruction *unreachable = builder.CreateUnreachable();
- curblock->getInstList().push_back(unreachable);
+ unreachable->insertBefore(*curblock, curblock->end());
curblock = nullptr;
changed = true;
@@ -3370,7 +3329,7 @@
else {
LIRBuilder builder(context_, llvm::ConstantFolder());
llvm::Instruction *unreachable = builder.CreateUnreachable();
- tsucc->getInstList().push_back(unreachable);
+ unreachable->insertBefore(*tsucc, tsucc->end());
}
}
@@ -3383,7 +3342,7 @@
else {
LIRBuilder builder(context_, llvm::ConstantFolder());
llvm::Instruction *unreachable = builder.CreateUnreachable();
- fsucc->getInstList().push_back(unreachable);
+ unreachable->insertBefore(*fsucc, fsucc->end());
}
}
}
@@ -3578,12 +3537,12 @@
if (&inst == term)
break; // terminator is handled below
llvm::Instruction *c = cloneInstruction(&inst, argMap);
- curblock->getInstList().push_back(c);
+ c->insertBefore(*curblock, curblock->end());
}
if (llvm::isa<llvm::InvokeInst>(term)) {
// This is the call to DEFERRETURN. Copy this then we're done.
llvm::Instruction *c = cloneInstruction(term, argMap);
- curblock->getInstList().push_back(c);
+ c->insertBefore(*curblock, curblock->end());
break;
}
// By construction it should be linear code.
@@ -3736,7 +3695,8 @@
// Populate resume block
builder.SetInsertPoint(finResBB);
std::string ename(be_->namegen("excv"));
- llvm::LoadInst *exload = builder.CreateLoad(extmp->getType()->getPointerElementType(), extmp, ename);
+ llvm::Type *vty = llvm::cast<llvm::AllocaInst>(extmp)->getAllocatedType();
+ llvm::LoadInst *exload = builder.CreateLoad(vty, extmp, ename);
builder.CreateResume(exload);
return finRetBB;
@@ -4021,7 +3981,7 @@
llvm::Value *zv = llvm::Constant::getNullValue(rtyp);
ri = builder.CreateRet(zv);
}
- epilog->getInstList().push_back(ri);
+ ri->insertBefore(*epilog, epilog->end());
}
}
diff --git a/bridge/go-llvm.h b/bridge/go-llvm.h
index cd4d855..78602e3 100644
--- a/bridge/go-llvm.h
+++ b/bridge/go-llvm.h
@@ -65,7 +65,7 @@
struct GenCallState;
#include "llvm/IR/GlobalValue.h"
-#include "llvm/ADT/Triple.h"
+#include "llvm/TargetParser/Triple.h"
//
// LLVM-specific implementation of the Backend class; the code in
@@ -487,7 +487,7 @@
Location location);
// Field GEP helper
- llvm::Value *makeFieldGEP(unsigned fieldIndex,
+ llvm::Value *makeFieldGEP(unsigned fieldIndex, llvm::Type *sty,
llvm::Value *sptr);
// Array indexing GEP helper
@@ -496,8 +496,7 @@
llvm::Value *sptr);
// Pointer indexing GEP helper
- llvm::Value *makePointerOffsetGEP(llvm::PointerType *pt,
- llvm::Value *idx,
+ llvm::Value *makePointerOffsetGEP(Btype *pt, llvm::Value *idx,
llvm::Value *sptr);
// Assignment helper
@@ -614,39 +613,6 @@
// error statement, returning TRUE if so.
bool stmtVectorHasError(const std::vector<Bstatement *> &stmts);
- // Converts value "src" for assignment to container of type
- // "dstType" in assignment-like contexts. This helper exists to help
- // with cases where the frontend is creating an assignment of form
- // "X = Y" where X and Y's types are considered matching by the
- // front end, but are non-matching in an LLVM context. For example,
- //
- // type Ifi func(int) int
- // ...
- // var fp Ifi = myfunctionfoobar
- //
- // Here the right hand side will come out as pointer-to-descriptor,
- // whereas variable "fp" will have type "pointer to functon", which are
- // not the same. Another example is assignments involving nil, e.g.
- //
- // var ip *float32
- // ...
- // ip = nil
- //
- // The type of the right hand side of the assignment will be a
- // generic "*i64" as opposed to "*float32", since the backend
- // "nil_pointer_expression" does not allow for creation of nil
- // pointers of specific types.
- //
- // Return value will be a new convert Bexpression if a convert is
- // needed, NULL otherwise.
- llvm::Value *convertForAssignment(Bexpression *src,
- llvm::Type *dstToType);
- // lower-level version of the routine above
- llvm::Value *convertForAssignment(Btype *srcType,
- llvm::Value *srcVal,
- llvm::Type *dstToType,
- BlockLIRBuilder *builder);
-
// Apply type conversion for a binary operation. This helper exists
// to resolve situations where expressions are created by the front
diff --git a/bridge/go-sha1.cpp b/bridge/go-sha1.cpp
index 54925d5..e978c8e 100644
--- a/bridge/go-sha1.cpp
+++ b/bridge/go-sha1.cpp
@@ -47,7 +47,8 @@
std::string
Llvm_Sha1_Helper::finish()
{
- std::string result(ctx_->final().str(), 0, checksum_len);
+ auto arr = ctx_->final();
+ std::string result(std::begin(arr), std::begin(arr) + checksum_len);
return result;
}
diff --git a/driver-main/llvm-goc.cpp b/driver-main/llvm-goc.cpp
index 472dc2f..f635e00 100644
--- a/driver-main/llvm-goc.cpp
+++ b/driver-main/llvm-goc.cpp
@@ -26,7 +26,6 @@
#include "Tool.h"
#include "llvm/ADT/STLExtras.h"
-#include "llvm/ADT/Triple.h"
#include "llvm/Analysis/TargetLibraryInfo.h"
#include "llvm/Bitcode/BitcodeWriterPass.h"
#include "llvm/IR/DiagnosticInfo.h"
@@ -35,7 +34,6 @@
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/LegacyPassManager.h"
#include "llvm/IR/Verifier.h"
-#include "llvm/MC/SubtargetFeature.h"
#include "llvm/Option/Arg.h"
#include "llvm/Option/ArgList.h"
#include "llvm/Option/OptTable.h"
@@ -43,8 +41,8 @@
#include "llvm/Passes/PassBuilder.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
-#include "llvm/Support/Format.h"
#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Format.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Path.h"
@@ -56,8 +54,9 @@
#include "llvm/Support/ToolOutputFile.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetMachine.h"
+#include "llvm/TargetParser/SubtargetFeature.h"
+#include "llvm/TargetParser/Triple.h"
#include "llvm/Transforms/IPO.h"
-#include "llvm/Transforms/IPO/PassManagerBuilder.h"
#include <algorithm>
#include <cstring>
@@ -95,7 +94,7 @@
const char *progname = argv[0];
unsigned missingArgIndex, missingArgCount;
- ArrayRef<const char *> argvv = makeArrayRef(argv, argc);
+ ArrayRef<const char *> argvv(argv, argc);
args_ = opts_->ParseArgs(argvv.slice(1), missingArgIndex, missingArgCount);
// Honor --help first
@@ -172,9 +171,8 @@
// that standard input be empty (so as to support the Go tool, but
// not act as a general-purposes C compiler).
opt::Arg *xarg = args_.getLastArg(gollvm::options::OPT_x);
- if (xarg != nullptr &&
- ! llvm::StringRef(xarg->getValue()).equals("c") &&
- ! llvm::StringRef(xarg->getValue()).equals("go")) {
+ if (xarg != nullptr && llvm::StringRef(xarg->getValue()) != "c" &&
+ llvm::StringRef(xarg->getValue()) != "go") {
errs() << progname << ": invalid argument '"
<< xarg->getValue() << "' to '"
<< xarg->getAsString(args_) << "' option\n";
diff --git a/driver/ArchCpuSetup.cpp b/driver/ArchCpuSetup.cpp
index a7eb765..bf91983 100644
--- a/driver/ArchCpuSetup.cpp
+++ b/driver/ArchCpuSetup.cpp
@@ -13,8 +13,8 @@
#include "ArchCpuSetup.h"
#include "llvm/Option/Arg.h"
-#include "llvm/Support/Host.h"
#include "llvm/Support/raw_ostream.h"
+#include "llvm/TargetParser/Host.h"
namespace gollvm { namespace arch {
#include "ArchCpusAttrs.h"
diff --git a/driver/Command.cpp b/driver/Command.cpp
index 2f10e8c..956108a 100644
--- a/driver/Command.cpp
+++ b/driver/Command.cpp
@@ -36,13 +36,11 @@
argv.reserve(n);
for (size_t i = 0; i < n; ++i)
argv.push_back(arguments_[i]);
- return llvm::sys::ExecuteAndWait(executable_,
- argv,
- /*env=*/llvm::None,
- /*Redirects*/{},
+ return llvm::sys::ExecuteAndWait(executable_, argv,
+ /*env=*/{},
+ /*Redirects*/ {},
/*secondsToWait=*/0,
- /*memoryLimit=*/0,
- errMsg);
+ /*memoryLimit=*/0, errMsg);
}
void Command::print(llvm::raw_ostream &os, bool quoteArgs)
diff --git a/driver/Compilation.cpp b/driver/Compilation.cpp
index 4123e40..6abf2f0 100644
--- a/driver/Compilation.cpp
+++ b/driver/Compilation.cpp
@@ -127,8 +127,8 @@
return newFileArtifact(ofn.c_str(), false);
}
-llvm::Optional<Artifact*> Compilation::createTemporaryFileArtifact(Action *act)
-{
+std::optional<Artifact *>
+Compilation::createTemporaryFileArtifact(Action *act) {
llvm::SmallString<128> tempFileName;
std::error_code tfcEC =
llvm::sys::fs::createTemporaryFile(act->getName(),
@@ -137,7 +137,7 @@
if (tfcEC) {
llvm::errs() << driver_.progname() << ": error: "
<< tfcEC.message() << "\n";
- return llvm::None;
+ return {};
}
return newFileArtifact(tempFileName.c_str(), true);
}
diff --git a/driver/Compilation.h b/driver/Compilation.h
index ec96bc8..4861b60 100644
--- a/driver/Compilation.h
+++ b/driver/Compilation.h
@@ -45,9 +45,9 @@
// Generate a new temp file and return an artifact for it. Here
// llvm::Optional is used in case the temp file creation fails for
// some reason.
- llvm::Optional<Artifact*> createTemporaryFileArtifact(Action *act);
+ std::optional<Artifact *> createTemporaryFileArtifact(Action *act);
- // Create new artifact based on file name. If 'isTempfile' is set,
+ // Create new artifact based on file name. If 'isTempfile' is set,
// the file should be scheduled for deletion after compilation finishes.
Artifact *newFileArtifact(const char *path, bool isTempFile);
diff --git a/driver/CompileGo.cpp b/driver/CompileGo.cpp
index 26af4e7..3601a36 100644
--- a/driver/CompileGo.cpp
+++ b/driver/CompileGo.cpp
@@ -41,25 +41,24 @@
#include "llvm/Config/llvm-config.h"
#include "llvm/IR/DiagnosticInfo.h"
#include "llvm/IR/DiagnosticPrinter.h"
-#include "llvm/IR/IRPrintingPasses.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/LLVMRemarkStreamer.h"
#include "llvm/IR/LegacyPassManager.h"
#include "llvm/IR/Verifier.h"
-#include "llvm/MC/SubtargetFeature.h"
+#include "llvm/IRPrinter/IRPrintingPasses.h"
#include "llvm/MC/TargetRegistry.h"
#include "llvm/Option/Arg.h"
#include "llvm/Option/ArgList.h"
#include "llvm/Option/OptTable.h"
#include "llvm/Option/Option.h"
#include "llvm/Passes/PassBuilder.h"
+#include "llvm/Passes/StandardInstrumentations.h"
#include "llvm/Remarks/RemarkStreamer.h"
#include "llvm/Remarks/YAMLRemarkSerializer.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Format.h"
-#include "llvm/Support/Host.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Path.h"
@@ -70,11 +69,14 @@
#include "llvm/Support/Signals.h"
#include "llvm/Support/TargetSelect.h"
#include "llvm/Support/ToolOutputFile.h"
+#include "llvm/Support/VirtualFileSystem.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetMachine.h"
+#include "llvm/TargetParser/Host.h"
+#include "llvm/TargetParser/SubtargetFeature.h"
#include "llvm/Transforms/IPO.h"
-#include "llvm/Transforms/IPO/PassManagerBuilder.h"
#include "llvm/Transforms/Utils.h"
+#include "llvm/Transforms/Utils/AddDiscriminators.h"
#include <sstream>
@@ -111,8 +113,10 @@
const char *progname_;
std::string executablePath_;
opt::InputArgList &args_;
- CodeGenOpt::Level cgolvl_;
- unsigned olvl_;
+ CodeGenOptLevel cgolvl_;
+ OptimizationLevel olvl_;
+ PipelineTuningOptions pto_;
+ std::optional<PGOOptions> pgo_;
bool hasError_;
std::unique_ptr<Llvm_backend> bridge_;
std::unique_ptr<TargetMachine> target_;
@@ -129,8 +133,6 @@
std::string sampleProfileFile_;
bool enable_gc_;
- void createPasses(legacy::PassManager &MPM,
- legacy::FunctionPassManager &FPM);
void setupGoSearchPath();
void setCConv();
@@ -148,22 +150,13 @@
bool enableVectorization(bool slp);
};
-CompileGoImpl::CompileGoImpl(CompileGo &cg,
- ToolChain &tc,
+CompileGoImpl::CompileGoImpl(CompileGo &cg, ToolChain &tc,
const std::string &executablePath)
- : cg_(cg),
- triple_(tc.driver().triple()),
- toolchain_(tc),
- driver_(tc.driver()),
- cconv_(CallingConvId::MaxID),
- progname_(tc.driver().progname()),
- executablePath_(executablePath),
- args_(tc.driver().args()),
- cgolvl_(CodeGenOpt::Default),
- olvl_(2),
- hasError_(false),
- enable_gc_(false)
-{
+ : cg_(cg), triple_(tc.driver().triple()), toolchain_(tc),
+ driver_(tc.driver()), cconv_(CallingConvId::MaxID),
+ progname_(tc.driver().progname()), executablePath_(executablePath),
+ args_(tc.driver().args()), cgolvl_(CodeGenOptLevel::Default),
+ olvl_(OptimizationLevel::O2), hasError_(false), enable_gc_(false) {
InitializeAllTargets();
InitializeAllTargetMCs();
InitializeAllAsmPrinters();
@@ -311,21 +304,28 @@
}
switch (lev[0]) {
case '0':
- olvl_ = 0;
- cgolvl_ = CodeGenOpt::None;
+ olvl_ = OptimizationLevel::O0;
+ cgolvl_ = CodeGenOptLevel::None;
break;
case '1':
- olvl_ = 1;
- cgolvl_ = CodeGenOpt::Less;
+ olvl_ = OptimizationLevel::O1;
+ cgolvl_ = CodeGenOptLevel::Less;
break;
- case 's': // TODO: -Os same as -O for now.
+ case 'z':
+ olvl_ = OptimizationLevel::Oz;
+ cgolvl_ = CodeGenOptLevel::Less;
+ break;
+ case 's':
+ olvl_ = OptimizationLevel::Os;
+ cgolvl_ = CodeGenOptLevel::Less;
+ break;
case '2':
- olvl_ = 2;
- cgolvl_ = CodeGenOpt::Default;
+ olvl_ = OptimizationLevel::O2;
+ cgolvl_ = CodeGenOptLevel::Default;
break;
case '3':
- olvl_ = 3;
- cgolvl_ = CodeGenOpt::Aggressive;
+ olvl_ = OptimizationLevel::O3;
+ cgolvl_ = CodeGenOptLevel::Aggressive;
break;
default:
errs() << progname_ << ": invalid optimization level.\n";
@@ -333,11 +333,18 @@
}
}
- go_no_warn = args_.hasArg(gollvm::options::OPT_w);
- go_loc_show_column =
- driver_.reconcileOptionPair(gollvm::options::OPT_fshow_column,
- gollvm::options::OPT_fno_show_column,
- true);
+ pto_.LoopVectorization = enableVectorization(false);
+ pto_.SLPVectorization = enableVectorization(true);
+ pto_.LoopUnrolling = driver_.reconcileOptionPair(gollvm::options::OPT_funroll_loops,
+ gollvm::options::OPT_fno_unroll_loops, true);
+ pto_.LoopInterleaving = driver_.reconcileOptionPair(gollvm::options::OPT_finterleave_loops,
+ gollvm::options::OPT_fno_interleave_loops, true);
+ // Merge identical functions at the LLVM IR level.
+ pto_.MergeFunctions = driver_.reconcileOptionPair(gollvm::options::OPT_fmerge_functions,
+ gollvm::options::OPT_fno_merge_functions, false);
+ // Provide .cgoprofile section for lld to order functions.
+ pto_.CallGraphProfile = driver_.reconcileOptionPair(gollvm::options::OPT_fcg_profile,
+ gollvm::options::OPT_fno_cg_profile, false);
// AutoFDO.
opt::Arg *sprofarg =
@@ -365,6 +372,29 @@
}
}
+ pto_.LoopVectorization = enableVectorization(false);
+ pto_.SLPVectorization = enableVectorization(true);
+ pto_.LoopUnrolling =
+ driver_.reconcileOptionPair(gollvm::options::OPT_funroll_loops,
+ gollvm::options::OPT_fno_unroll_loops, true);
+ pto_.LoopInterleaving = driver_.reconcileOptionPair(
+ gollvm::options::OPT_finterleave_loops,
+ gollvm::options::OPT_fno_interleave_loops, true);
+ // Merge identical functions at the LLVM IR level.
+ pto_.MergeFunctions = driver_.reconcileOptionPair(
+ gollvm::options::OPT_fmerge_functions,
+ gollvm::options::OPT_fno_merge_functions, false);
+ // Provide .cgoprofile section for lld to order functions.
+ pto_.CallGraphProfile =
+ driver_.reconcileOptionPair(gollvm::options::OPT_fcg_profile,
+ gollvm::options::OPT_fno_cg_profile, false);
+
+ go_no_warn = args_.hasArg(gollvm::options::OPT_w);
+ go_loc_show_column =
+ driver_.reconcileOptionPair(gollvm::options::OPT_fshow_column,
+ gollvm::options::OPT_fno_show_column,
+ true);
+
// Capture optimization record.
opt::Arg *optrecordarg =
args_.getLastArg(gollvm::options::OPT_fsave_optimization_record,
@@ -420,7 +450,7 @@
llvm::DebugCompressionType dct = llvm::DebugCompressionType::None;
if (!driver_.determineDebugCompressionType(&dct))
return false;
- Options.CompressDebugSections = dct;
+ Options.MCOptions.CompressDebugSections = dct;
// FIXME: this hard-wires on the equivalent of -ffunction-sections
// and -fdata-sections, since there doesn't seem to be a high-level
@@ -473,7 +503,7 @@
return false;
// Create target machine
- Optional<llvm::CodeModel::Model> CM = None;
+ std::optional<llvm::CodeModel::Model> CM = {};
target_.reset(
TheTarget->createTargetMachine(triple_.getTriple(),
targetCpuAttr_, targetFeaturesAttr_,
@@ -497,7 +527,7 @@
std::make_unique<BEDiagnosticHandler>(&this->hasError_,
this->remarkCtl_));
- llvm::Optional<unsigned> enable_gc =
+ std::optional<unsigned> enable_gc =
driver_.getLastArgAsInteger(gollvm::options::OPT_enable_gc_EQ, 0u);
enable_gc_ = enable_gc && *enable_gc;
@@ -523,7 +553,7 @@
bridge_.reset(new Llvm_backend(context_, module_.get(), linemap_.get(), addrspace, triple_, cconv_));
// Honor inline, tracelevel cmd line options
- llvm::Optional<unsigned> tl =
+ std::optional<unsigned> tl =
driver_.getLastArgAsInteger(gollvm::options::OPT_tracelevel_EQ, 0u);
if (!tl)
return false;
@@ -601,7 +631,7 @@
true);
args.compiling_runtime =
args_.hasArg(gollvm::options::OPT_fgo_compiling_runtime);
- llvm::Optional<int> del =
+ std::optional<int> del =
driver_.getLastArgAsInteger(gollvm::options::OPT_fgo_debug_escape_EQ, 0);
if (!del)
return false;
@@ -759,7 +789,7 @@
bridge_->dumpModule();
if (!args_.hasArg(gollvm::options::OPT_noverify) && !go_be_saw_errors())
bridge_->verifyModule();
- llvm::Optional<unsigned> tl =
+ std::optional<unsigned> tl =
driver_.getLastArgAsInteger(gollvm::options::OPT_tracelevel_EQ, 0u);
if (*tl)
std::cerr << "linemap stats:" << linemap_->statistics() << "\n";
@@ -780,7 +810,7 @@
bool CompileGoImpl::enableVectorization(bool slp)
{
- bool enable = (olvl_ > 1);
+ bool enable = (olvl_.getSpeedupLevel() > 1);
if (slp)
return driver_.reconcileOptionPair(gollvm::options::OPT_fslp_vectorize,
gollvm::options::OPT_fno_slp_vectorize,
@@ -791,108 +821,116 @@
enable);
}
-static void addAddDiscriminatorsPass(const llvm::PassManagerBuilder &Builder,
- llvm::legacy::PassManagerBase &PM) {
- PM.add(createAddDiscriminatorsPass());
-}
-
-void CompileGoImpl::createPasses(legacy::PassManager &MPM,
- legacy::FunctionPassManager &FPM)
+bool CompileGoImpl::invokeBackEnd(const Action &jobAction)
{
- if (args_.hasArg(gollvm::options::OPT_disable_llvm_passes))
- return;
+ LoopAnalysisManager lam;
+ FunctionAnalysisManager fam;
+ CGSCCAnalysisManager gcam;
+ ModuleAnalysisManager mam;
- // FIXME: support LTO, ThinLTO, PGO
+ bool debugPassStructure = false;
+ bool debugPassManager = args_.hasArg(gollvm::options::OPT_fdebug_pass_manager);
+ bool verifyEach = args_.hasArg(gollvm::options::OPT_fverify_each);
+ PassInstrumentationCallbacks pic;
+ PrintPassOptions printPassOpts;
+ printPassOpts.Indent = debugPassStructure;
+ printPassOpts.SkipAnalyses = debugPassStructure;
+ StandardInstrumentations si(context_, debugPassManager || debugPassStructure,
+ verifyEach, printPassOpts);
- PassManagerBuilder pmb;
+ // TODO: Maybe better to keep some kind of pass table.
+ pic.addClassToPassName("GoStatepoints", "go-statepoints");
+ pic.addClassToPassName("GoSafeGetgPass", "go-safegetg");
+ pic.addClassToPassName("RemoveAddrSpacePass", "remove-addrspacecast");
- // Configure the inliner
- if (args_.hasArg(gollvm::options::OPT_fno_inline) || olvl_ == 0) {
- // Nothing here at the moment. There is go:noinline, but no equivalent
- // of go:alwaysinline.
- } else {
- bool disableInlineHotCallSite = false; // for autofdo, not yet supported
- pmb.Inliner =
- createFunctionInliningPass(olvl_, 2, disableInlineHotCallSite);
+ si.registerCallbacks(pic);
+
+ PassBuilder pb(target_.get(), pto_, pgo_, &pic);
+
+ // Register the target library analysis directly and give it a customized
+ // preset TLI.
+ tlii_.reset(new TargetLibraryInfoImpl(triple_));
+ fam.registerPass([this] { return TargetLibraryAnalysis(*tlii_); });
+
+ // Register all the basic analyses with the managers.
+ pb.registerModuleAnalyses(mam);
+ pb.registerCGSCCAnalyses(gcam);
+ pb.registerFunctionAnalyses(fam);
+ pb.registerLoopAnalyses(lam);
+ pb.crossRegisterProxies(lam, fam, gcam, mam);
+
+ bool disablePasses = args_.hasArg(gollvm::options::OPT_disable_llvm_passes);
+ ThinOrFullLTOPhase lto_phase = ThinOrFullLTOPhase::None;
+
+ ModulePassManager modulePasses;
+ if (!disablePasses) {
+ if (olvl_ == OptimizationLevel::O0) {
+
+ modulePasses = pb.buildO0DefaultPipeline(olvl_, lto_phase);
+ } else if (lto_phase == ThinOrFullLTOPhase::ThinLTOPreLink) {
+ modulePasses = pb.buildThinLTOPreLinkDefaultPipeline(olvl_);
+ } else if (lto_phase == ThinOrFullLTOPhase::FullLTOPreLink) {
+ modulePasses = pb.buildLTOPreLinkDefaultPipeline(olvl_);
+ } else {
+ modulePasses = pb.buildPerModuleDefaultPipeline(olvl_);
+ }
}
- pmb.OptLevel = olvl_;
- pmb.SizeLevel = 0; // TODO: decide on right value here
- pmb.PrepareForThinLTO = false;
- pmb.PrepareForLTO = false;
- pmb.SLPVectorize = enableVectorization(true);
- pmb.LoopVectorize = enableVectorization(false);
+ bool needDwarfDiscr = !sampleProfileFile_.empty();
- bool needDwarfDiscr = false;
- if (! sampleProfileFile_.empty()) {
- pmb.PGOSampleUse = sampleProfileFile_;
- needDwarfDiscr = true;
- }
opt::Arg *dbgprofarg =
args_.getLastArg(gollvm::options::OPT_fdebug_info_for_profiling,
gollvm::options::OPT_fno_debug_info_for_profiling);
if (dbgprofarg) {
- if (dbgprofarg->getOption().matches(gollvm::options::OPT_fdebug_info_for_profiling))
+ if (dbgprofarg->getOption().matches(
+ gollvm::options::OPT_fdebug_info_for_profiling))
needDwarfDiscr = true;
else
needDwarfDiscr = false;
}
- if (needDwarfDiscr)
- pmb.addExtension(llvm::PassManagerBuilder::EP_EarlyAsPossible,
- addAddDiscriminatorsPass);
-
-
- FPM.add(new TargetLibraryInfoWrapperPass(*tlii_));
- if (! args_.hasArg(gollvm::options::OPT_noverify))
- FPM.add(createVerifierPass());
-
- pmb.populateFunctionPassManager(FPM);
- pmb.populateModulePassManager(MPM);
-}
-
-bool CompileGoImpl::invokeBackEnd(const Action &jobAction)
-{
- tlii_.reset(new TargetLibraryInfoImpl(triple_));
-
- // Set up module and function passes
- legacy::PassManager modulePasses;
- modulePasses.add(
- createTargetTransformInfoWrapperPass(target_->getTargetIRAnalysis()));
- legacy::FunctionPassManager functionPasses(module_.get());
- functionPasses.add(
- createTargetTransformInfoWrapperPass(target_->getTargetIRAnalysis()));
- createPasses(modulePasses, functionPasses);
+ if (needDwarfDiscr) {
+ pb.registerPipelineStartEPCallback([](llvm::ModulePassManager &MPM,
+ llvm::OptimizationLevel) {
+ MPM.addPass(createModuleToFunctionPassAdaptor(AddDiscriminatorsPass()));
+ });
+ }
// Disable inlining getg in some cases on x86_64.
if (triple_.getArch() == llvm::Triple::x86_64) {
- modulePasses.add(createGoSafeGetgPass());
+ modulePasses.addPass(GoSafeGetgPass());
}
// Add statepoint insertion pass to the end of optimization pipeline,
// right before lowering to machine IR.
if (enable_gc_) {
- modulePasses.add(createGoStatepointsLegacyPass());
- modulePasses.add(createRemoveAddrSpacePass(target_->createDataLayout()));
+ modulePasses.addPass(GoStatepoints());
+ modulePasses.addPass(RemoveAddrSpacePass(target_->createDataLayout()));
}
+ // We still use the legacy PM to run the codegen pipeline since the new PM
+ // does not work with the codegen pipeline.
legacy::PassManager codeGenPasses;
bool noverify = args_.hasArg(gollvm::options::OPT_noverify);
- CodeGenFileType ft = (jobAction.type() == Action::A_CompileAndAssemble ?
- CGFT_ObjectFile : CGFT_AssemblyFile);
// Add passes to emit bitcode or LLVM IR as appropriate. Here we mimic
// clang behavior, which is to emit bitcode when "-emit-llvm" is specified
// but an LLVM IR dump of "-S -emit-llvm" is used.
raw_pwrite_stream *OS = &asmout_->os();
if (args_.hasArg(gollvm::options::OPT_emit_llvm)) {
+ if (!noverify) {
+ modulePasses.addPass(VerifierPass());
+ }
bool bitcode = !args_.hasArg(gollvm::options::OPT_S);
bool preserveUseLists =
driver_.reconcileOptionPair(gollvm::options::OPT_emit_llvm_uselists,
gollvm::options::OPT_no_emit_llvm_uselists,
false);
- modulePasses.add(bitcode ?
- createBitcodeWriterPass(*OS, preserveUseLists) :
- createPrintModulePass(*OS, "", preserveUseLists));
+ if (bitcode) {
+ modulePasses.addPass(BitcodeWriterPass(*OS, preserveUseLists,
+ /* ThinLTO summary */ false));
+ } else {
+ modulePasses.addPass(PrintModulePass(*OS, "", preserveUseLists));
+ }
goto run;
}
@@ -909,7 +947,11 @@
// LLVMTargetMachine::addPassesToEmitFile (and its callee).
// TODO: error check.
{
- LLVMTargetMachine *lltm = (LLVMTargetMachine*)(target_.get()); // FIXME: TargetMachine doesn't support llvm::cast?
+ CodeGenFileType ft = (jobAction.type() == Action::A_CompileAndAssemble
+ ? CodeGenFileType::ObjectFile
+ : CodeGenFileType::AssemblyFile);
+ llvm::TargetMachine *lltm =
+ target_.get(); // FIXME: TargetMachine doesn't support llvm::cast?
TargetPassConfig *passConfig = lltm->createPassConfig(codeGenPasses);
// Set PassConfig options provided by TargetMachine.
passConfig->setDisableVerify(noverify);
@@ -932,15 +974,8 @@
}
run:
- // Here we go... first function passes
- functionPasses.doInitialization();
- for (Function &F : *module_.get())
- if (!F.isDeclaration())
- functionPasses.run(F);
- functionPasses.doFinalization();
-
// ... then module passes
- modulePasses.run(*module_.get());
+ modulePasses.run(*module_.get(), mam);
// ... and finally code generation
if (!args_.hasArg(gollvm::options::OPT_emit_llvm))
diff --git a/driver/Distro.cpp b/driver/Distro.cpp
index 2eace0d..0b02411 100644
--- a/driver/Distro.cpp
+++ b/driver/Distro.cpp
@@ -12,7 +12,7 @@
#include "Distro.h"
-#include "llvm/Support/Host.h"
+#include "llvm/TargetParser/Host.h"
namespace distro {
diff --git a/driver/Distro.h b/driver/Distro.h
index 4bd0a36..086e0e7 100644
--- a/driver/Distro.h
+++ b/driver/Distro.h
@@ -14,7 +14,7 @@
#define GOLLVM_DRIVER_DISTRO_H
#include "GccUtils.h"
-#include "llvm/ADT/Triple.h"
+#include "llvm/TargetParser/Triple.h"
namespace distro {
diff --git a/driver/Driver.cpp b/driver/Driver.cpp
index 777cc2b..4355475 100644
--- a/driver/Driver.cpp
+++ b/driver/Driver.cpp
@@ -11,9 +11,9 @@
//===----------------------------------------------------------------------===//
#include "llvm/Support/FileSystem.h"
-#include "llvm/Support/Host.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/Program.h"
+#include "llvm/TargetParser/Host.h"
#include <sstream>
@@ -185,9 +185,9 @@
value == "--nocompress-debug-sections") {
continue;
}
- if (value.startswith("-compress-debug-sections") ||
- value.startswith("--compress-debug-sections") ||
- value.startswith("-march")) {
+ if (value.starts_with("-compress-debug-sections") ||
+ value.starts_with("--compress-debug-sections") ||
+ value.starts_with("-march")) {
continue;
}
// Unrecognized -Wa,... option
@@ -203,11 +203,11 @@
llvm::DebugCompressionType *dct,
const char *which)
{
- if (ga == "zlib") {
- *dct = llvm::DebugCompressionType::Z;
+ if (ga == "zlib" || ga == "zlib-gnu") {
+ *dct = llvm::DebugCompressionType::Zlib;
return dct;
- } else if (ga == "zlib-gnu") {
- *dct = llvm::DebugCompressionType::GNU;
+ } else if (ga == "zstd") {
+ *dct = llvm::DebugCompressionType::Zstd;
return dct;
} else if (ga == "none") {
*dct = llvm::DebugCompressionType::None;
@@ -231,7 +231,7 @@
gollvm::options::OPT_Wa_COMMA,
gollvm::options::OPT_Xassembler)) {
if (arg->getOption().matches(gollvm::options::OPT_gz)) {
- *dct = llvm::DebugCompressionType::GNU;
+ *dct = llvm::DebugCompressionType::Zlib;
} else if (arg->getOption().matches(gollvm::options::OPT_gz_EQ)) {
auto value = llvm::StringRef(arg->getValue());
if (gzArgToDCT(value, dct, "-gz=") == nullptr)
@@ -242,15 +242,15 @@
if (value == "-nocompress-debug-sections" ||
value == "--nocompress-debug-sections") {
*dct = llvm::DebugCompressionType::None;
- } else if (value.startswith("-compress-debug-sections") ||
- value.startswith("--compress-debug-sections")) {
+ } else if (value.starts_with("-compress-debug-sections") ||
+ value.starts_with("--compress-debug-sections")) {
const char *wh =
(arg->getOption().matches(gollvm::options::OPT_Xassembler) ?
"-Xassembler" : "-Wa,");
value.consume_front("--compress-debug-sections");
value.consume_front("-compress-debug-sections");
auto arg = value;
- if (value.startswith("="))
+ if (value.starts_with("="))
arg.consume_front("=");
else
arg = "zlib";
@@ -365,20 +365,16 @@
return false;
}
-Optional<Reloc::Model>
-Driver::reconcileRelocModel()
-{
+std::optional<Reloc::Model> Driver::reconcileRelocModel() {
auto picLevel = getPicLevel();
if (picLevel != PICLevel::NotPIC) {
Reloc::Model R = Reloc::PIC_;
return R;
}
- return None;
+ return {};
}
-Optional<FPOpFusion::FPOpFusionMode>
-Driver::getFPOpFusionMode()
-{
+std::optional<FPOpFusion::FPOpFusionMode> Driver::getFPOpFusionMode() {
opt::Arg *arg = args_.getLastArg(gollvm::options::OPT_ffp_contract_EQ);
FPOpFusion::FPOpFusionMode res = FPOpFusion::Standard;
if (arg != nullptr) {
@@ -393,7 +389,7 @@
errs() << progname_ << ": invalid argument '"
<< arg->getValue() << "' to '"
<< arg->getAsString(args_) << "' option\n";
- return None;
+ return {};
}
}
return res;
@@ -504,8 +500,8 @@
opt::Arg *xarg = args_.getLastArg(gollvm::options::OPT_x);
assert(xarg);
const char *suf =
- (llvm::StringRef(xarg->getValue()).equals("c") ? "c" :
- (llvm::StringRef(xarg->getValue()).equals("go") ? "go" : "?"));
+ (xarg->containsValue("c") ? "c"
+ : (xarg->containsValue("go") ? "go" : "?"));
act = new ReadStdinAction(suf);
schedAction = true;
} else {
diff --git a/driver/Driver.h b/driver/Driver.h
index 3b2813d..6c87d5d 100644
--- a/driver/Driver.h
+++ b/driver/Driver.h
@@ -13,16 +13,15 @@
#ifndef GOLLVM_DRIVER_DRIVER_H
#define GOLLVM_DRIVER_DRIVER_H
-#include "llvm/ADT/Optional.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
-#include "llvm/ADT/Triple.h"
#include "llvm/Option/ArgList.h"
#include "llvm/Option/OptTable.h"
#include "llvm/Support/CodeGen.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetOptions.h"
+#include "llvm/TargetParser/Triple.h"
#include "Action.h"
#include "Artifact.h"
@@ -112,14 +111,14 @@
bool supportedAsmOptions();
bool determineDebugCompressionType(llvm::DebugCompressionType *dct);
bool usingSplitStack() const { return usingSplitStack_; }
- template<typename IT>
- llvm::Optional<IT> getLastArgAsInteger(gollvm::options::ID id,
- IT defaultValue);
- llvm::Optional<llvm::Reloc::Model> reconcileRelocModel();
+ template <typename IT>
+ std::optional<IT> getLastArgAsInteger(gollvm::options::ID id,
+ IT defaultValue);
+ std::optional<llvm::Reloc::Model> reconcileRelocModel();
bool reconcileOptionPair(gollvm::options::ID yesOption,
gollvm::options::ID noOption,
bool defaultVal);
- llvm::Optional<llvm::FPOpFusion::FPOpFusionMode> getFPOpFusionMode();
+ std::optional<llvm::FPOpFusion::FPOpFusionMode> getFPOpFusionMode();
typedef llvm::SmallVector<llvm::opt::Arg *, 8> inarglist;
void appendInputActions(const inarglist &infiles,
ActionList &result,
@@ -155,11 +154,9 @@
const char *which);
};
-template<typename IT>
-llvm::Optional<IT>
-Driver::getLastArgAsInteger(gollvm::options::ID id,
- IT defaultValue)
-{
+template <typename IT>
+std::optional<IT> Driver::getLastArgAsInteger(gollvm::options::ID id,
+ IT defaultValue) {
IT result = defaultValue;
llvm::opt::Arg *arg = args_.getLastArg(id);
if (arg != nullptr) {
@@ -167,7 +164,7 @@
llvm::errs() << progname_ << ": invalid argument '"
<< arg->getValue() << "' to '"
<< arg->getAsString(args_) << "' option\n";
- return llvm::None;
+ return {};
}
}
return result;
diff --git a/driver/GollvmOptions.cpp b/driver/GollvmOptions.cpp
index 4455b1a..d8697e9 100644
--- a/driver/GollvmOptions.cpp
+++ b/driver/GollvmOptions.cpp
@@ -20,23 +20,35 @@
#include "GollvmOptions.inc"
#undef PREFIX
+#define OPTTABLE_STR_TABLE_CODE
+#include "GollvmOptions.inc"
+#undef OPTTABLE_STR_TABLE_CODE
+
+#define OPTTABLE_VALUES_CODE
+#include "GollvmOptions.inc"
+#undef OPTTABLE_VALUES_CODE
+
+#define OPTTABLE_PREFIXES_TABLE_CODE
+#include "GollvmOptions.inc"
+#undef OPTTABLE_PREFIXES_TABLE_CODE
+
+#define OPTTABLE_PREFIXES_UNION_CODE
+#include "GollvmOptions.inc"
+#undef OPTTABLE_PREFIXES_UNION_CODE
+
static const OptTable::Info InfoTable[] = {
-#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
- HELPTEXT, METAVAR, VALUES) \
- {PREFIX, NAME, HELPTEXT, METAVAR, OPT_##ID, Option::KIND##Class, \
- PARAM, FLAGS, OPT_##GROUP, OPT_##ALIAS, ALIASARGS, VALUES},
+#define OPTION(...) LLVM_CONSTRUCT_OPT_INFO(__VA_ARGS__),
#include "GollvmOptions.inc"
#undef OPTION
};
namespace {
-
-class DriverOptTable : public OptTable {
+class DriverOptTable : public PrecomputedOptTable {
public:
DriverOptTable()
- : OptTable(InfoTable) {}
+ : PrecomputedOptTable(OptionStrTable, OptionPrefixesTable, InfoTable,
+ OptionPrefixesUnion) {}
};
-
}
std::unique_ptr<OptTable> createGollvmDriverOptTable() {
diff --git a/driver/GollvmOptions.h b/driver/GollvmOptions.h
index 5ab4477..2a98647 100644
--- a/driver/GollvmOptions.h
+++ b/driver/GollvmOptions.h
@@ -9,6 +9,7 @@
#ifndef LLVM_GOLLVM_DRIVER_GOLLVMOPTIONS_H
#define LLVM_GOLLVM_DRIVER_GOLLVMOPTIONS_H
+#include "llvm/Option/OptTable.h"
#include <memory>
namespace llvm {
@@ -31,9 +32,7 @@
enum ID {
OPT_INVALID = 0, // This is not an option ID.
-#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
- HELPTEXT, METAVAR, VALUES) \
- OPT_##ID,
+#define OPTION(...) LLVM_MAKE_OPT_ID(__VA_ARGS__),
#include "GollvmOptions.inc"
LastOption
#undef OPTION
diff --git a/driver/GollvmOptions.td b/driver/GollvmOptions.td
index 404a1ad..18e0e99 100644
--- a/driver/GollvmOptions.td
+++ b/driver/GollvmOptions.td
@@ -275,6 +275,26 @@
def fno_slp_vectorize : Flag<["-"], "fno-slp-vectorize">, Group<f_Group>,
HelpText<"Disable the superword-level parallelism vectorization passes">;
+def fmerge_functions : Flag<["-"], "fmerge-functions">, Group<f_Group>,
+ HelpText<"Enable merging identical functions">;
+def fno_merge_functions : Flag<["-"], "fno-merge-functions">, Group<f_Group>,
+ HelpText<"Disable merging identical functions">;
+
+def funroll_loops : Flag<["-"], "funroll-loops">, Group<f_Group>,
+ HelpText<"Enable loop unrolling">;
+def fno_unroll_loops : Flag<["-"], "fno-unroll-loops">, Group<f_Group>,
+ HelpText<"Disable loop unrolling">;
+
+def finterleave_loops : Flag<["-"], "finterleave-loops">, Group<f_Group>,
+ HelpText<"Enable loop interleaving">;
+def fno_interleave_loops : Flag<["-"], "fno-interleave-loops">, Group<f_Group>,
+ HelpText<"Disable loop interleaving">;
+
+def fcg_profile : Flag<["-"], "fcg-profile">, Group<f_Group>,
+ HelpText<"Enable linker re-ordering functions by CG profile (supported by LLD)">;
+def fno_cg_profile : Flag<["-"], "fno-cg-profile">, Group<f_Group>,
+ HelpText<"Disable linker re-ordering functions by CG profile">;
+
def ffp_contract_EQ : Joined<["-"], "ffp-contract=">, Group<f_Group>,
HelpText<"Form fused FP ops (e.g. FMAs): fast (everywhere)"
" | on (according to FP_CONTRACT pragma, default) | off (never fuse)">,
@@ -443,9 +463,6 @@
def finline_functions : Flag<["-"], "finline-functions">,
Flags<[Ignored]>, HelpText<"This option is ignored">;
-def funroll_loops : Flag<["-"], "funroll-loops">,
- Flags<[Ignored]>, HelpText<"This option is ignored">;
-
def pedantic_errors : Flag<["-"], "pedantic-errors">,
Flags<[Ignored]>, HelpText<"This option is ignored">;
@@ -519,3 +536,9 @@
def enable_gc_EQ : Joined<["-"], "enable-gc=">,
HelpText<"Enable stack map generation">;
+
+def fdebug_pass_manager : Flag<["-"], "fdebug-pass-manager">,
+ HelpText<"Print passes run and other information for debugging the pass manager">;
+
+def fverify_each : Flag<["-"], "fverify-each">,
+ HelpText<"Run verification after each pass in new pass manager">;
diff --git a/driver/IntegAssembler.cpp b/driver/IntegAssembler.cpp
index a40be9f..0cdea73 100644
--- a/driver/IntegAssembler.cpp
+++ b/driver/IntegAssembler.cpp
@@ -27,7 +27,6 @@
#include "Driver.h"
#include "ToolChain.h"
-#include "llvm/ADT/Triple.h"
#include "llvm/Config/llvm-config.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/MC/MCAsmBackend.h"
@@ -52,7 +51,6 @@
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/FileSystem.h"
-#include "llvm/Support/Host.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/Process.h"
@@ -63,6 +61,8 @@
#include "llvm/Support/TargetSelect.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetMachine.h"
+#include "llvm/TargetParser/Host.h"
+#include "llvm/TargetParser/Triple.h"
#include <sstream>
@@ -194,7 +194,7 @@
// Ensure MCAsmInfo initialization occurs before any use, otherwise sections
// may be created with a combination of default and explicit settings.
- MAI->setCompressDebugSections(CompressDebugSections);
+ MCOptions.CompressDebugSections = CompressDebugSections;
// Build up the feature string from the target feature list.
std::string FS;
@@ -242,8 +242,7 @@
Out = BOS.get();
}
- std::unique_ptr<MCCodeEmitter> CE(
- TheTarget->createMCCodeEmitter(*MCII, *MRI, Ctx));
+ std::unique_ptr<MCCodeEmitter> CE(TheTarget->createMCCodeEmitter(*MCII, Ctx));
std::unique_ptr<MCAsmBackend> MAB(
TheTarget->createMCAsmBackend(*STI, *MRI, MCOptions));
std::unique_ptr<MCObjectWriter> OW = MAB->createObjectWriter(*Out);
diff --git a/driver/LinuxToolChain.cpp b/driver/LinuxToolChain.cpp
index a12b794..f8ebea7 100644
--- a/driver/LinuxToolChain.cpp
+++ b/driver/LinuxToolChain.cpp
@@ -101,7 +101,7 @@
Tool *Linux::buildCompiler()
{
llvm::opt::Arg *xarg = driver().args().getLastArg(gollvm::options::OPT_x);
- if (xarg != nullptr && llvm::StringRef(xarg->getValue()).equals("c")) {
+ if (xarg != nullptr && xarg->containsValue("c")) {
// This is a dummy C compile.
return new DummyCompileC(*this, driver().executablePath());
}
diff --git a/driver/Tool.h b/driver/Tool.h
index abde3ca..17d3b19 100644
--- a/driver/Tool.h
+++ b/driver/Tool.h
@@ -13,9 +13,9 @@
#ifndef GOLLVM_DRIVER_TOOL_H
#define GOLLVM_DRIVER_TOOL_H
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/Triple.h"
#include "Artifact.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/TargetParser/Triple.h"
namespace gollvm {
namespace driver {
diff --git a/driver/ToolChain.h b/driver/ToolChain.h
index c20e14b..89a28df 100644
--- a/driver/ToolChain.h
+++ b/driver/ToolChain.h
@@ -13,9 +13,9 @@
#ifndef GOLLVM_DRIVER_TOOLCHAIN_H
#define GOLLVM_DRIVER_TOOLCHAIN_H
-#include <string>
-#include "llvm/ADT/Triple.h"
#include "llvm/Option/ArgList.h"
+#include "llvm/TargetParser/Triple.h"
+#include <string>
#include "Action.h"
#include "Tool.h"
diff --git a/libgo/godumpspec/godumpspec.cpp b/libgo/godumpspec/godumpspec.cpp
index 37a854d..15a66d2 100644
--- a/libgo/godumpspec/godumpspec.cpp
+++ b/libgo/godumpspec/godumpspec.cpp
@@ -26,6 +26,7 @@
//===----------------------------------------------------------------------===//
#include "llvm/DebugInfo/DIContext.h"
+#include "llvm/DebugInfo/DWARF/DWARFCompileUnit.h"
#include "llvm/DebugInfo/DWARF/DWARFContext.h"
#include "llvm/Object/Binary.h"
#include "llvm/Object/ObjectFile.h"
diff --git a/passes/GC.cpp b/passes/GC.cpp
index 3932bab..e5dd0bc 100644
--- a/passes/GC.cpp
+++ b/passes/GC.cpp
@@ -44,7 +44,7 @@
// TODO: write barrier?
}
- Optional<bool> isGCManagedPointer(const Type *Ty) const override {
+ std::optional<bool> isGCManagedPointer(const Type *Ty) const override {
return isa<PointerType>(Ty);
}
};
@@ -171,7 +171,7 @@
for (uint8_t Byte : V)
OS.emitIntValue(Byte, 1);
}
- OS.emitValueToAlignment(8);
+ OS.emitValueToAlignment(llvm::Align(8));
}
}
@@ -183,7 +183,7 @@
// Create the section.
MCSection *StackMapSection =
OutContext.getObjectFileInfo()->getStackMapSection();
- OS.SwitchSection(StackMapSection);
+ OS.switchSection(StackMapSection);
emitCallsiteEntries(SM, OS);
diff --git a/passes/GoAnnotation.cpp b/passes/GoAnnotation.cpp
index 95f5fe3..d180248 100644
--- a/passes/GoAnnotation.cpp
+++ b/passes/GoAnnotation.cpp
@@ -19,6 +19,7 @@
#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/CodeGen/Passes.h"
#include "llvm/CodeGen/TargetInstrInfo.h"
+#include "llvm/IR/Module.h"
#include "llvm/PassRegistry.h"
#include "llvm/Target/TargetMachine.h"
diff --git a/passes/GoNilChecks.cpp b/passes/GoNilChecks.cpp
index 7561d65..e091699 100644
--- a/passes/GoNilChecks.cpp
+++ b/passes/GoNilChecks.cpp
@@ -25,8 +25,6 @@
#include "GollvmPasses.h"
#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/None.h"
-#include "llvm/ADT/Optional.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Statistic.h"
@@ -102,11 +100,11 @@
/// If non-None, then an instruction in \p Insts that also must be
/// hoisted.
- Optional<ArrayRef<MachineInstr *>::iterator> PotentialDependence;
+ std::optional<ArrayRef<MachineInstr *>::iterator> PotentialDependence;
/*implicit*/ DependenceResult(
bool CanReorder,
- Optional<ArrayRef<MachineInstr *>::iterator> PotentialDependence)
+ std::optional<ArrayRef<MachineInstr *>::iterator> PotentialDependence)
: CanReorder(CanReorder), PotentialDependence(PotentialDependence) {
assert((!PotentialDependence || CanReorder) &&
"!CanReorder && PotentialDependence.hasValue() not allowed!");
@@ -252,18 +250,18 @@
assert(llvm::all_of(Block, canHandle) && "Check this first!");
assert(!is_contained(Block, MI) && "Block must be exclusive of MI!");
- Optional<ArrayRef<MachineInstr *>::iterator> Dep;
+ std::optional<ArrayRef<MachineInstr *>::iterator> Dep;
for (auto I = Block.begin(), E = Block.end(); I != E; ++I) {
if (canReorder(*I, MI))
continue;
- if (Dep == None) {
+ if (!Dep.has_value()) {
// Found one possible dependency, keep track of it.
Dep = I;
} else {
// We found two dependencies, so bail out.
- return {false, None};
+ return {false, {}};
}
}
@@ -654,7 +652,7 @@
// Insert an *unconditional* branch to not-null successor.
if (!CheckBB->isLayoutSuccessor(NC.getNotNullSucc()))
TII->insertBranch(*CheckBB, NC.getNotNullSucc(), nullptr,
- /*Cond=*/None, DL);
+ /*Cond=*/{}, DL);
NumImplicitNullChecks++;
@@ -724,7 +722,7 @@
MI.eraseFromParent();
break;
}
- TII->insertBranch(*FaultBB, PadBB, nullptr, None, DL);
+ TII->insertBranch(*FaultBB, PadBB, nullptr, {}, DL);
}
// Add EH labels before and after the faulting op.
diff --git a/passes/GoSafeGetg.cpp b/passes/GoSafeGetg.cpp
index 52b54c2..66dbedd 100644
--- a/passes/GoSafeGetg.cpp
+++ b/passes/GoSafeGetg.cpp
@@ -12,6 +12,7 @@
//
//===----------------------------------------------------------------------===//
+#include "GoSafeGetg.h"
#include "GollvmPasses.h"
#include "llvm/IR/BasicBlock.h"
@@ -76,8 +77,7 @@
// found, replace it with a call of runtime.getg (i.e. undoing the
// inlining).
//
-bool
-GoSafeGetg::runOnModule(Module &M) {
+static bool updateModule(Module &M) {
GlobalVariable *GV = M.getGlobalVariable("runtime.g");
if (!GV)
return false; // no access of g, nothing to do
@@ -132,3 +132,12 @@
return Changed;
}
+
+bool GoSafeGetg::runOnModule(Module &M) { return updateModule(M); }
+
+PreservedAnalyses GoSafeGetgPass::run(Module &M, ModuleAnalysisManager &AM) {
+ bool Changed = updateModule(M);
+ if (!Changed)
+ return PreservedAnalyses::all();
+ return PreservedAnalyses::none();
+}
diff --git a/passes/GoSafeGetg.h b/passes/GoSafeGetg.h
new file mode 100644
index 0000000..89e9d23
--- /dev/null
+++ b/passes/GoSafeGetg.h
@@ -0,0 +1,26 @@
+//===--- GoSafeGetg.h -----------------------------------------------------===//
+//
+// Copyright 2024 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+//
+//===----------------------------------------------------------------------===//
+//
+// Make sure the TLS address is not cached across a thread switch.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_GOLLVM_PASSES_GOSAFEGETG_H
+#define LLVM_GOLLVM_PASSES_GOSAFEGETG_H
+
+#include "llvm/IR/PassManager.h"
+
+namespace llvm {
+
+struct GoSafeGetgPass : public PassInfoMixin<GoSafeGetgPass> {
+ PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
+};
+
+} // namespace llvm
+
+#endif // LLVM_GOLLVM_PASSES_GOSAFEGETG_H
diff --git a/passes/GoStatepoints.cpp b/passes/GoStatepoints.cpp
index 6453db4..02062f6 100644
--- a/passes/GoStatepoints.cpp
+++ b/passes/GoStatepoints.cpp
@@ -22,8 +22,6 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/MapVector.h"
-#include "llvm/ADT/None.h"
-#include "llvm/ADT/Optional.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallSet.h"
@@ -34,6 +32,7 @@
#include "llvm/Analysis/TargetLibraryInfo.h"
#include "llvm/Analysis/TargetTransformInfo.h"
#include "llvm/IR/Argument.h"
+#include "llvm/IR/AttributeMask.h"
#include "llvm/IR/Attributes.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/Constant.h"
@@ -58,8 +57,8 @@
#include "llvm/IR/User.h"
#include "llvm/IR/Value.h"
#include "llvm/IR/ValueHandle.h"
-#include "llvm/Pass.h"
#include "llvm/InitializePasses.h"
+#include "llvm/Pass.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Compiler.h"
@@ -120,6 +119,32 @@
static bool shouldRewriteStatepointsIn(Function &F);
+static Type *getPointerElementType(Value *V) {
+ assert(V->getType()->isPointerTy());
+ if (Argument *A = dyn_cast<Argument>(V)) {
+ if (A->hasByValAttr())
+ return A->getParamByValType();
+ // FIXME: Do we need to handle other types of arguments?
+ // fallback to ptr
+ return V->getType();
+
+ } else if (AllocaInst *AI = dyn_cast<AllocaInst>(V)) {
+ return AI->getAllocatedType();
+ } else if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(V)) {
+ return GEP->getResultElementType();
+ } else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V)) {
+ auto *Inst = CE->getAsInstruction();
+ Type *ITy = getPointerElementType(CE->getAsInstruction());
+ Inst->deleteValue();
+ return ITy;
+ } else if (GlobalValue *GV = dyn_cast<GlobalValue>(V)) {
+ return GV->getValueType();
+ } else {
+ // fallback to ptr
+ return V->getType();
+ }
+}
+
PreservedAnalyses GoStatepoints::run(Module &M,
ModuleAnalysisManager &AM) {
// Create a sentinel global variable for stack maps.
@@ -993,8 +1018,9 @@
// TODO: In many cases, the new instruction is just EE itself. We should
// exploit this, but can't do it here since it would break the invariant
// about the BDV not being known to be a base.
- auto *BaseInst = ExtractElementInst::Create(
- State.getBaseValue(), EE->getIndexOperand(), "base_ee", EE);
+ auto *BaseInst = ExtractElementInst::Create(State.getBaseValue(),
+ EE->getIndexOperand(),
+ "base_ee", EE->getIterator());
BaseInst->setMetadata("is_base_value", MDNode::get(I->getContext(), {}));
States[I] = BDVState(BDVState::Base, BaseInst);
}
@@ -1015,29 +1041,30 @@
int NumPreds = pred_size(BB);
assert(NumPreds > 0 && "how did we reach here");
std::string Name = suffixed_name_or(I, ".base", "base_phi");
- return PHINode::Create(I->getType(), NumPreds, Name, I);
+ return PHINode::Create(I->getType(), NumPreds, Name, I->getIterator());
} else if (SelectInst *SI = dyn_cast<SelectInst>(I)) {
// The undef will be replaced later
UndefValue *Undef = UndefValue::get(SI->getType());
std::string Name = suffixed_name_or(I, ".base", "base_select");
- return SelectInst::Create(SI->getCondition(), Undef, Undef, Name, SI);
+ return SelectInst::Create(SI->getCondition(), Undef, Undef, Name,
+ SI->getIterator());
} else if (auto *EE = dyn_cast<ExtractElementInst>(I)) {
UndefValue *Undef = UndefValue::get(EE->getVectorOperand()->getType());
std::string Name = suffixed_name_or(I, ".base", "base_ee");
return ExtractElementInst::Create(Undef, EE->getIndexOperand(), Name,
- EE);
+ EE->getIterator());
} else if (auto *IE = dyn_cast<InsertElementInst>(I)) {
UndefValue *VecUndef = UndefValue::get(IE->getOperand(0)->getType());
UndefValue *ScalarUndef = UndefValue::get(IE->getOperand(1)->getType());
std::string Name = suffixed_name_or(I, ".base", "base_ie");
- return InsertElementInst::Create(VecUndef, ScalarUndef,
- IE->getOperand(2), Name, IE);
+ return InsertElementInst::Create(
+ VecUndef, ScalarUndef, IE->getOperand(2), Name, IE->getIterator());
} else {
auto *SV = cast<ShuffleVectorInst>(I);
UndefValue *VecUndef = UndefValue::get(SV->getOperand(0)->getType());
std::string Name = suffixed_name_or(I, ".base", "base_sv");
return new ShuffleVectorInst(VecUndef, VecUndef, SV->getOperand(2),
- Name, SV);
+ Name, SV->getIterator());
}
};
Instruction *BaseInst = MakeBaseInstPlaceholder(I);
@@ -1067,7 +1094,8 @@
assert(Base && "Can't be null");
// The cast is needed since base traversal may strip away bitcasts
if (Base->getType() != Input->getType() && InsertPt)
- Base = CastInst::CreatePointerBitCastOrAddrSpaceCast(Base, Input->getType(), "cast", InsertPt);
+ Base = CastInst::CreatePointerBitCastOrAddrSpaceCast(
+ Base, Input->getType(), "cast", InsertPt->getIterator());
return Base;
};
@@ -1262,8 +1290,6 @@
// both function declarations and call sites.
static constexpr Attribute::AttrKind FnAttrsToStrip[] =
{Attribute::ReadNone, Attribute::ReadOnly, Attribute::WriteOnly,
- Attribute::ArgMemOnly, Attribute::InaccessibleMemOnly,
- Attribute::InaccessibleMemOrArgMemOnly,
Attribute::NoSync, Attribute::NoFree};
// List of all parameter and return attributes which must be stripped when
@@ -1356,7 +1382,7 @@
// Note: we've inserted instructions, so the call to llvm.deoptimize may
// not necessarily be followed by the matching return.
auto *RI = cast<ReturnInst>(OldI->getParent()->getTerminator());
- new UnreachableInst(RI->getContext(), RI);
+ new UnreachableInst(RI->getContext(), RI->getIterator());
RI->eraseFromParent();
}
@@ -1430,7 +1456,7 @@
if (isa<AllocaInst>(V) ||
(isa<Argument>(V) && cast<Argument>(V)->hasByValAttr())) {
// Byval argument is at a fixed frame offset. Treat it the same as alloca.
- Type *T = cast<PointerType>(V->getType())->getElementType();
+ Type *T = getPointerElementType(V);
if (hasPointer(T)) {
PtrFields.push_back(V);
getPtrBitmapForType(T, DL, PtrFields);
@@ -1627,8 +1653,9 @@
SetVector<Value *> AllAllocas;
if (ClobberNonLive)
for (Instruction &I : F.getEntryBlock())
- if (isa<AllocaInst>(I) && hasPointer(I.getType()->getPointerElementType()))
- AllAllocas.insert(&I);
+ if (AllocaInst *AI = dyn_cast<AllocaInst>(&I))
+ if (hasPointer(AI->getAllocatedType()))
+ AllAllocas.insert(&I);
computeLiveInValues(DT, F, OriginalLivenessData, AddrTakenAllocas,
ToZero, BadLoads, DVCache);
@@ -1702,7 +1729,7 @@
} else if (ToZero.count(V) != 0) {
// Non-addrtaken alloca. Just insert zeroing, keep the lifetime marker.
IRBuilder<> Builder(I.getNextNode());
- Value *Zero = Constant::getNullValue(V->getType()->getPointerElementType());
+ Value *Zero = Constant::getNullValue(getPointerElementType(V));
Builder.CreateStore(Zero, V);
// Don't remove V from ToZero for now, as there may be multiple
// lifetime start markers, where we need to insert zeroing.
@@ -1737,14 +1764,14 @@
for (Instruction &I : F.getEntryBlock())
if (ToZero.count(&I) != 0) {
IRBuilder<> Builder(I.getNextNode());
- Type *ElemTyp = I.getType()->getPointerElementType();
if (AddrTakenAllocas.count(&I) != 0) {
+ Type *ElemTyp = cast<AllocaInst>(I).getAllocatedType();
// For addrtaken alloca, we removed the lifetime marker above.
// Insert a new one at the entry block.
unsigned Size = DL.getTypeStoreSize(ElemTyp);
Builder.CreateLifetimeStart(&I, ConstantInt::get(Int64Ty, Size));
}
- Value *Zero = Constant::getNullValue(ElemTyp);
+ Value *Zero = Constant::getNullValue(getPointerElementType(&I));
Builder.CreateStore(Zero, &I);
ToZero.remove(&I);
}
@@ -1942,8 +1969,8 @@
// That Value* no longer exists and we need to use the new gc_result.
// Thankfully, the live set is embedded in the statepoint (and updated), so
// we just grab that.
- Live.insert(Live.end(), Info.StatepointToken->gc_args_begin(),
- Info.StatepointToken->gc_args_end());
+ Live.insert(Live.end(), Info.StatepointToken->gc_live_begin(),
+ Info.StatepointToken->gc_live_end());
#ifndef NDEBUG
// Do some basic sanity checks on our liveness results before performing
// relocation. Relocation can and will turn mistakes in liveness results
@@ -1951,7 +1978,7 @@
// TODO: It would be nice to test consistency as well
assert(DT.isReachableFromEntry(Info.StatepointToken->getParent()) &&
"statepoint must be reachable or liveness is meaningless");
- for (Value *V : Info.StatepointToken->gc_args()) {
+ for (Value *V : Info.StatepointToken->gc_live()) {
if (!isa<Instruction>(V))
// Non-instruction values trivial dominate all possible uses
continue;
@@ -2024,7 +2051,7 @@
if (isa<PointerType>(F.getReturnType()))
RemoveNonValidAttrAtIndex(Ctx, F, AttributeList::ReturnIndex);
- for (auto Attr : FnAttrsToStrip)
+ for (auto Attr : FnAttrsToStrip)
F.removeFnAttr(Attr);
}
@@ -2161,11 +2188,12 @@
// Create a dummy landing pad block.
LLVMContext &C = F.getContext();
BasicBlock *PadBB = BasicBlock::Create(C, "dummy", &F);
- Type *ExnTy = StructType::get(Type::getInt8PtrTy(C), Type::getInt32Ty(C));
+ Type *ExnTy =
+ StructType::get(PointerType::getUnqual(C), Type::getInt32Ty(C));
LandingPadInst *LPad =
LandingPadInst::Create(ExnTy, 1, "dummy.ex", PadBB);
- LPad->addClause(Constant::getNullValue(Type::getInt8PtrTy(C)));
+ LPad->addClause(Constant::getNullValue(PointerType::getUnqual(C)));
new UnreachableInst(PadBB->getContext(), PadBB);
BasicBlock *Old = CI->getParent();
@@ -2179,7 +2207,7 @@
for (DomTreeNode *I : Children)
DT.changeImmediateDominator(I, NewNode);
- DTU.insertEdge(Old, PadBB);
+ DTU.applyUpdates({{DominatorTree::Insert, Old, PadBB}});
}
}
@@ -2269,10 +2297,11 @@
static Value*
isTrackedAlloca(Value *V, DefiningValueMapTy &DVCache) {
- Value *Base = isAlloca(V, DVCache);
- if (Base &&
- hasPointer(Base->getType()->getPointerElementType()))
- return Base;
+ if (Value *Base = isAlloca(V, DVCache)) {
+ Type *AllocedTy = cast<AllocaInst>(Base)->getAllocatedType();
+ if (Base && hasPointer(AllocedTy))
+ return Base;
+ }
return nullptr;
}
@@ -2450,7 +2479,7 @@
// Use the metadata inserted by the FE.
for (Instruction &I : F.getEntryBlock())
if (isa<AllocaInst>(I) && I.getMetadata("go_addrtaken") &&
- hasPointer(I.getType()->getPointerElementType()))
+ hasPointer(cast<AllocaInst>(I).getAllocatedType()))
AddrTakenAllocas.insert(&I);
// The FE's addrtaken mark may be imprecise. Look for certain
@@ -2581,7 +2610,7 @@
SetVector<Value *> &ToZero,
DefiningValueMapTy &DVCache) {
unsigned PtrSize = DL.getPointerSize();
- unsigned Size = DL.getTypeStoreSize(V->getType()->getPointerElementType());
+ unsigned Size = DL.getTypeStoreSize(cast<AllocaInst>(V)->getAllocatedType());
if (Size <= PtrSize)
return;
@@ -2597,7 +2626,8 @@
if (hasStructRetAttr(CI)) {
Value *Ptr = CI->getOperand(0);
if (isTrackedAlloca(Ptr, DVCache) == V)
- StoreSize += DL.getTypeStoreSize(Ptr->getType()->getPointerElementType());
+ StoreSize +=
+ DL.getTypeStoreSize(cast<AllocaInst>(Ptr)->getAllocatedType());
}
if (Function *Fn = CI->getCalledFunction())
switch (Fn->getIntrinsicID()) {
@@ -2621,7 +2651,9 @@
if (hasStructRetAttr(II)) {
Value *Ptr = II->getOperand(0);
if (isTrackedAlloca(Ptr, DVCache) == V)
- if (DL.getTypeStoreSize(Ptr->getType()->getPointerElementType()) + PtrSize - 1 >= Size)
+ if (DL.getTypeStoreSize(cast<AllocaInst>(Ptr)->getAllocatedType()) +
+ PtrSize - 1 >=
+ Size)
// We are storing the whole type
return;
@@ -2919,8 +2951,8 @@
Value *V = Ptr->stripPointerCasts();
const DataLayout &DL = Inst->getModule()->getDataLayout();
if (!Data.LiveIn[BB].count(V) &&
- (DL.getTypeStoreSize(Ptr->getType()->getPointerElementType()) >=
- DL.getTypeStoreSize(V->getType()->getPointerElementType())))
+ (DL.getTypeStoreSize(getPointerElementType(Ptr)) >=
+ DL.getTypeStoreSize(getPointerElementType(V))))
LiveOut.remove(V);
}
@@ -2935,7 +2967,7 @@
Value *Bad = ConstantInt::get(Int8Ty, 0xff);
for (Value *Alloca : ToClobber) {
unsigned Siz =
- DL.getTypeStoreSize(Alloca->getType()->getPointerElementType());
+ DL.getTypeStoreSize(cast<AllocaInst>(Alloca)->getAllocatedType());
Builder.CreateMemSet(Alloca, Bad, Siz, MaybeAlign(0));
//dbgs() << "clobber " << *Alloca << " at " << *Inst << "\n";
}
@@ -2962,7 +2994,7 @@
for (Instruction &I : instructions(F)) {
if (auto *CI = dyn_cast<CallInst>(&I))
if (Function *Callee = CI->getCalledFunction()) {
- if (Callee->getName().equals("runtime.gcWriteBarrier")) {
+ if (Callee->getName() == "runtime.gcWriteBarrier") {
// gcWriteBarrier(dst, val)
// there is an extra "nest" argument.
Value *Dst = CI->getArgOperand(1), *Val = CI->getArgOperand(2);
@@ -2974,7 +3006,7 @@
PointerType::get(Val->getType(), AS));
Builder.CreateStore(Val, Dst);
ToDel.insert(CI);
- } else if (Callee->getName().equals("runtime.typedmemmove")) {
+ } else if (Callee->getName() == "runtime.typedmemmove") {
// typedmemmove(typ, dst, src)
// there is an extra "nest" argument.
Value *Dst = CI->getArgOperand(2), *Src = CI->getArgOperand(3);
@@ -2986,7 +3018,7 @@
// for now. The size is the first field. The optimizer should be
// able to constant-fold it.
Value *TD = CI->getArgOperand(1);
- Type *etyp = TD->getType()->getPointerElementType();
+ Type *etyp = cast<GlobalValue>(TD)->getValueType();
Value *GEP = Builder.CreateConstInBoundsGEP2_32(
etyp, TD, 0, 0);
Value *Siz = Builder.CreateLoad(etyp, GEP);
diff --git a/passes/GollvmPasses.h b/passes/GollvmPasses.h
index 398df82..d1900a4 100644
--- a/passes/GollvmPasses.h
+++ b/passes/GollvmPasses.h
@@ -11,6 +11,10 @@
#include "llvm/ADT/SmallVector.h"
+#include "GoSafeGetg.h"
+#include "GoStatepoints.h"
+#include "RemoveAddrSpace.h"
+
namespace llvm {
class DataLayout;
@@ -25,14 +29,14 @@
void initializeGoSafeGetgPass(PassRegistry&);
void initializeGoStatepointsLegacyPassPass(PassRegistry&);
void initializeGoWrappersPass(PassRegistry&);
-void initializeRemoveAddrSpacePassPass(PassRegistry&);
+void initializeRemoveAddrSpaceWrapperPass(PassRegistry&);
FunctionPass *createGoAnnotationPass();
FunctionPass *createGoNilChecksPass();
ModulePass *createGoSafeGetgPass();
ModulePass *createGoStatepointsLegacyPass();
FunctionPass *createGoWrappersPass();
-ModulePass *createRemoveAddrSpacePass(const DataLayout&);
+ModulePass *createRemoveAddrSpaceWrapper(const DataLayout&);
void linkGoGC();
void linkGoGCPrinter();
diff --git a/passes/RemoveAddrSpace.cpp b/passes/RemoveAddrSpace.cpp
index e31e9ac..085db3d 100644
--- a/passes/RemoveAddrSpace.cpp
+++ b/passes/RemoveAddrSpace.cpp
@@ -1,4 +1,4 @@
-//===--- GoStackMap.cpp ---------------------------------------------------===//
+//===--- RemoveAddrSpace.cpp ----------------------------------------------===//
//
// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
@@ -12,6 +12,7 @@
//
//===----------------------------------------------------------------------===//
+#include "RemoveAddrSpace.h"
#include "GollvmPasses.h"
#include "llvm/ADT/DenseSet.h"
@@ -27,21 +28,8 @@
namespace {
-class RemoveAddrSpacePass : public ModulePass {
- public:
- static char ID;
-
- RemoveAddrSpacePass() : ModulePass(ID), DL("") {}
-
- RemoveAddrSpacePass(const DataLayout &DL) : ModulePass(ID), DL(DL) {
- initializeRemoveAddrSpacePassPass(
- *PassRegistry::getPassRegistry());
- }
-
- bool runOnModule(Module &M) override;
-
- private:
- Type *IntTy; // type of uintptr_t, used to cast pointer to/from integer
+class RemoveAddrSpace {
+ Type *IntTy {nullptr}; // type of uintptr_t, used to cast pointer to/from integer
DataLayout DL; // data layout without non-integral pointer, passed in from the driver
DenseSet<Constant*> Visited; // handle circular references
@@ -49,20 +37,44 @@
// of ptr-to-int and int-to-ptr casts, as codegen cannot handle
// addrspacecast in static initializer.
void removeAddrSpaceCast(Constant *C);
+
+public:
+ RemoveAddrSpace(const DataLayout &DL) : DL(DL) {}
+ bool runOnModule(Module &M);
+};
+
+
+class RemoveAddrSpaceWrapper : public ModulePass {
+ DataLayout DL;
+
+ public:
+ static char ID;
+
+ RemoveAddrSpaceWrapper() : ModulePass(ID), DL("") {}
+
+ RemoveAddrSpaceWrapper(const DataLayout &DL) : ModulePass(ID), DL(DL) {
+ initializeRemoveAddrSpaceWrapperPass(
+ *PassRegistry::getPassRegistry());
+ }
+
+ bool runOnModule(Module &M) override {
+ RemoveAddrSpace R(DL);
+ return R.runOnModule(M);
+ }
};
} // namespace
-char RemoveAddrSpacePass::ID = 0;
-INITIALIZE_PASS(RemoveAddrSpacePass, "remove-addrspacecast",
+char RemoveAddrSpaceWrapper::ID = 0;
+INITIALIZE_PASS(RemoveAddrSpaceWrapper, "remove-addrspacecast",
"Remove addrspacecast instructions", false,
false)
-ModulePass *llvm::createRemoveAddrSpacePass(const DataLayout &DL) {
- return new RemoveAddrSpacePass(DL);
+ModulePass *llvm::createRemoveAddrSpaceWrapper(const DataLayout &DL) {
+ return new RemoveAddrSpaceWrapper(DL);
}
void
-RemoveAddrSpacePass::removeAddrSpaceCast(Constant *C) {
+RemoveAddrSpace::removeAddrSpaceCast(Constant *C) {
if (Visited.count(C))
return;
Visited.insert(C);
@@ -86,7 +98,7 @@
}
bool
-RemoveAddrSpacePass::runOnModule(Module &M) {
+RemoveAddrSpace::runOnModule(Module &M) {
// At this point we no longer need non-integral pointers.
// Set data layout back to default.
M.setDataLayout(DL);
@@ -97,3 +109,10 @@
removeAddrSpaceCast(GV.getInitializer());
return true;
}
+
+PreservedAnalyses llvm::RemoveAddrSpacePass::run(Module &M,
+ ModuleAnalysisManager &AM) {
+ RemoveAddrSpace R(DL);
+ R.runOnModule(M);
+ return PreservedAnalyses::all();
+}
diff --git a/passes/RemoveAddrSpace.h b/passes/RemoveAddrSpace.h
new file mode 100644
index 0000000..e994139
--- /dev/null
+++ b/passes/RemoveAddrSpace.h
@@ -0,0 +1,36 @@
+//===--- RemoveAddrSpace.h ------------------------------------------------===//
+//
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+//
+//===----------------------------------------------------------------------===//
+//
+// LLVM backend pass to remove addrspacecast instructions
+// in static initializers (because codegen cannot handle
+// them).
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_GOLLVM_PASSES_REMOVEADDRSPACE_H
+#define LLVM_GOLLVM_PASSES_REMOVEADDRSPACE_H
+
+#include "llvm/IR/DataLayout.h"
+#include "llvm/IR/PassManager.h"
+
+namespace llvm {
+
+class RemoveAddrSpacePass : public PassInfoMixin<RemoveAddrSpacePass> {
+ DataLayout DL; // data layout without non-integral pointer
+
+public:
+ /// Construct a pass with update data layout optional optmizations.
+ RemoveAddrSpacePass(const DataLayout &DL) : DL(DL) {}
+
+ /// Run the pass over the module.
+ PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
+};
+
+} // namespace llvm
+
+#endif // LLVM_GOLLVM_PASSES_REMOVEADDRSPACE_H
diff --git a/passes/Util.cpp b/passes/Util.cpp
index 08b3ddb..00bc3bd 100644
--- a/passes/Util.cpp
+++ b/passes/Util.cpp
@@ -61,7 +61,7 @@
for (unsigned i = 0, n = T->getArrayNumElements(); i < n; ++i) {
Value *ivals[2] = { ConstantInt::get(Int32Ty, 0),
ConstantInt::get(Int32Ty, i) };
- ArrayRef<Value*> Idx = makeArrayRef(ivals, 2);
+ ArrayRef<Value *> Idx(ivals, 2);
uint64_t Offset = DL.getIndexedOffsetInType(T, Idx);
getPtrBitmapForTypeHelper(ET, DL, BaseOffset+Offset, BV);
}
@@ -73,7 +73,7 @@
for (unsigned i = 0, n = VT->getNumElements(); i < n; ++i) {
Value *ivals[2] = { ConstantInt::get(Int32Ty, 0),
ConstantInt::get(Int32Ty, i) };
- ArrayRef<Value*> Idx = makeArrayRef(ivals, 2);
+ ArrayRef<Value *> Idx(ivals, 2);
uint64_t Offset = DL.getIndexedOffsetInType(T, Idx);
getPtrBitmapForTypeHelper(ET, DL, BaseOffset+Offset, BV);
}
@@ -86,7 +86,7 @@
continue;
Value *ivals[2] = { ConstantInt::get(Int32Ty, 0),
ConstantInt::get(Int32Ty, i) };
- ArrayRef<Value*> Idx = makeArrayRef(ivals, 2);
+ ArrayRef<Value *> Idx(ivals, 2);
uint64_t Offset = DL.getIndexedOffsetInType(T, Idx);
getPtrBitmapForTypeHelper(ET, DL, BaseOffset+Offset, BV);
}
diff --git a/unittests/BackendCore/BackendArrayStruct.cpp b/unittests/BackendCore/BackendArrayStruct.cpp
index a488338..4fd7244 100644
--- a/unittests/BackendCore/BackendArrayStruct.cpp
+++ b/unittests/BackendCore/BackendArrayStruct.cpp
@@ -79,19 +79,18 @@
h.mkAssign(bfex2, bc2);
DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
- %cast.0 = bitcast { i8*, i32 }* %loc1 to i8*
- call addrspace(0) void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.0, i8* align 8 bitcast ({ i8*, i32 }* @const.0 to i8*), i64 16, i1 false)
- store { i8*, i32 }* %loc1, { i8*, i32 }** %loc2, align 8
- store i32 0, i32* %x, align 4
- %field.0 = getelementptr inbounds { i8*, i32 }, { i8*, i32 }* %loc1, i32 0, i32 1
- %loc1.field.ld.0 = load i32, i32* %field.0, align 4
- store i32 %loc1.field.ld.0, i32* %x, align 4
- store i8 0, i8* %b2, align 1
- %field.1 = getelementptr inbounds { i8*, i32 }, { i8*, i32 }* %loc1, i32 0, i32 0
- store i8* %b2, i8** %field.1, align 8
- %loc2.ld.0 = load { i8*, i32 }*, { i8*, i32 }** %loc2, align 8
- %field.2 = getelementptr inbounds { i8*, i32 }, { i8*, i32 }* %loc2.ld.0, i32 0, i32 1
- store i32 2, i32* %field.2, align 4
+ call addrspace(0) void @llvm.memcpy.p0.p0.i64(ptr align 8 %loc1, ptr align 8 @const.0, i64 16, i1 false)
+ store ptr %loc1, ptr %loc2, align 8
+ store i32 0, ptr %x, align 4
+ %field.0 = getelementptr inbounds { ptr, i32 }, ptr %loc1, i32 0, i32 1
+ %loc1.field.ld.0 = load i32, ptr %field.0, align 4
+ store i32 %loc1.field.ld.0, ptr %x, align 4
+ store i8 0, ptr %b2, align 1
+ %field.1 = getelementptr inbounds { ptr, i32 }, ptr %loc1, i32 0, i32 0
+ store ptr %b2, ptr %field.1, align 8
+ %loc2.ld.0 = load ptr, ptr %loc2, align 8
+ %field.2 = getelementptr inbounds { ptr, i32 }, ptr %loc2.ld.0, i32 0, i32 1
+ store i32 2, ptr %field.2, align 4
)RAW_RESULT");
bool isOK = h.expectBlock(exp);
@@ -145,24 +144,24 @@
h.mkAssign(vex2, fex2);
DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
- define void @foo(i8* nest %nest.0) #0 {
+ define void @foo(ptr nest %nest.0) #0 {
entry:
- %tmp.0 = alloca { i8*, i32 }, align 8
+ %tmp.0 = alloca { ptr, i32 }, align 8
%x = alloca i32, align 4
%y = alloca i32, align 4
%z = alloca i32, align 4
- store i32 0, i32* %x, align 4
- store i32 0, i32* %y, align 4
- %y.ld.0 = load i32, i32* %y, align 4
- %field.0 = getelementptr inbounds { i8*, i32 }, { i8*, i32 }* %tmp.0, i32 0, i32 0
- store i8* null, i8** %field.0, align 8
- %field.1 = getelementptr inbounds { i8*, i32 }, { i8*, i32 }* %tmp.0, i32 0, i32 1
- store i32 %y.ld.0, i32* %field.1, align 4
- %field.2 = getelementptr inbounds { i8*, i32 }, { i8*, i32 }* %tmp.0, i32 0, i32 1
- %.field.ld.0 = load i32, i32* %field.2, align 4
- store i32 %.field.ld.0, i32* %x, align 4
- store i32 0, i32* %z, align 4
- store i32 42, i32* %z, align 4
+ store i32 0, ptr %x, align 4
+ store i32 0, ptr %y, align 4
+ %y.ld.0 = load i32, ptr %y, align 4
+ %field.0 = getelementptr inbounds { ptr, i32 }, ptr %tmp.0, i32 0, i32 0
+ store ptr null, ptr %field.0, align 8
+ %field.1 = getelementptr inbounds { ptr, i32 }, ptr %tmp.0, i32 0, i32 1
+ store i32 %y.ld.0, ptr %field.1, align 4
+ %field.2 = getelementptr inbounds { ptr, i32 }, ptr %tmp.0, i32 0, i32 1
+ %.field.ld.0 = load i32, ptr %field.2, align 4
+ store i32 %.field.ld.0, ptr %x, align 4
+ store i32 0, ptr %z, align 4
+ store i32 42, ptr %z, align 4
ret void
}
)RAW_RESULT");
@@ -231,34 +230,34 @@
h.mkAssign(vex3, eex3);
DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
- define void @foo(i8* nest %nest.0) #0 {
+ define void @foo(ptr nest %nest.0) #0 {
entry:
%tmp.0 = alloca [4 x i64], align 8
%x = alloca i64, align 8
%y = alloca i64, align 8
%z = alloca i64, align 8
%w = alloca i64, align 8
- store i64 0, i64* %x, align 8
- store i64 0, i64* %y, align 8
- %y.ld.0 = load i64, i64* %y, align 8
- %index.0 = getelementptr [4 x i64], [4 x i64]* %tmp.0, i32 0, i32 0
- store i64 %y.ld.0, i64* %index.0, align 8
- %index.1 = getelementptr [4 x i64], [4 x i64]* %tmp.0, i32 0, i32 1
- store i64 3, i64* %index.1, align 8
- %index.2 = getelementptr [4 x i64], [4 x i64]* %tmp.0, i32 0, i32 2
- store i64 2, i64* %index.2, align 8
- %index.3 = getelementptr [4 x i64], [4 x i64]* %tmp.0, i32 0, i32 3
- store i64 1, i64* %index.3, align 8
- %index.4 = getelementptr [4 x i64], [4 x i64]* %tmp.0, i32 0, i32 1
- %.index.ld.0 = load i64, i64* %index.4, align 8
- store i64 %.index.ld.0, i64* %x, align 8
- store i64 0, i64* %z, align 8
- store i64 3, i64* %z, align 8
- store i64 0, i64* %w, align 8
- %x.ld.0 = load i64, i64* %x, align 8
- %index.5 = getelementptr [4 x i64], [4 x i64]* @const.0, i32 0, i64 %x.ld.0
- %.index.ld.1 = load i64, i64* %index.5, align 8
- store i64 %.index.ld.1, i64* %w, align 8
+ store i64 0, ptr %x, align 8
+ store i64 0, ptr %y, align 8
+ %y.ld.0 = load i64, ptr %y, align 8
+ %index.0 = getelementptr [4 x i64], ptr %tmp.0, i32 0, i32 0
+ store i64 %y.ld.0, ptr %index.0, align 8
+ %index.1 = getelementptr [4 x i64], ptr %tmp.0, i32 0, i32 1
+ store i64 3, ptr %index.1, align 8
+ %index.2 = getelementptr [4 x i64], ptr %tmp.0, i32 0, i32 2
+ store i64 2, ptr %index.2, align 8
+ %index.3 = getelementptr [4 x i64], ptr %tmp.0, i32 0, i32 3
+ store i64 1, ptr %index.3, align 8
+ %index.4 = getelementptr [4 x i64], ptr %tmp.0, i32 0, i32 1
+ %.index.ld.0 = load i64, ptr %index.4, align 8
+ store i64 %.index.ld.0, ptr %x, align 8
+ store i64 0, ptr %z, align 8
+ store i64 3, ptr %z, align 8
+ store i64 0, ptr %w, align 8
+ %x.ld.0 = load i64, ptr %x, align 8
+ %index.5 = getelementptr [4 x i64], ptr @const.0, i32 0, i64 %x.ld.0
+ %.index.ld.1 = load i64, ptr %index.5, align 8
+ store i64 %.index.ld.1, ptr %w, align 8
ret void
}
)RAW_RESULT");
@@ -306,20 +305,18 @@
h.mkLocal("ac", at4, arcon3);
DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
- %cast.0 = bitcast [4 x i64]* %aa to i8*
- call addrspace(0) void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.0, i8* align 8 bitcast ([4 x i64]* @const.0 to i8*), i64 32, i1 false)
- %cast.1 = bitcast [4 x i64]* %ab to i8*
- call addrspace(0) void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.1, i8* align 8 bitcast ([4 x i64]* @const.1 to i8*), i64 32, i1 false)
- store i64 0, i64* %z, align 8
- %z.ld.0 = load i64, i64* %z, align 8
- %index.0 = getelementptr [4 x i64], [4 x i64]* %ac, i32 0, i32 0
- store i64 0, i64* %index.0, align 8
- %index.1 = getelementptr [4 x i64], [4 x i64]* %ac, i32 0, i32 1
- store i64 %z.ld.0, i64* %index.1, align 8
- %index.2 = getelementptr [4 x i64], [4 x i64]* %ac, i32 0, i32 2
- store i64 0, i64* %index.2, align 8
- %index.3 = getelementptr [4 x i64], [4 x i64]* %ac, i32 0, i32 3
- store i64 0, i64* %index.3, align 8
+ call addrspace(0) void @llvm.memcpy.p0.p0.i64(ptr align 8 %aa, ptr align 8 @const.0, i64 32, i1 false)
+ call addrspace(0) void @llvm.memcpy.p0.p0.i64(ptr align 8 %ab, ptr align 8 @const.1, i64 32, i1 false)
+ store i64 0, ptr %z, align 8
+ %z.ld.0 = load i64, ptr %z, align 8
+ %index.0 = getelementptr [4 x i64], ptr %ac, i32 0, i32 0
+ store i64 0, ptr %index.0, align 8
+ %index.1 = getelementptr [4 x i64], ptr %ac, i32 0, i32 1
+ store i64 %z.ld.0, ptr %index.1, align 8
+ %index.2 = getelementptr [4 x i64], ptr %ac, i32 0, i32 2
+ store i64 0, ptr %index.2, align 8
+ %index.3 = getelementptr [4 x i64], ptr %ac, i32 0, i32 3
+ store i64 0, ptr %index.3, align 8
)RAW_RESULT");
bool isOK = h.expectBlock(exp);
@@ -367,14 +364,13 @@
h.mkLocal("loc2", s2t, scon2);
DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
- %cast.0 = bitcast { i32*, i32 }* %loc1 to i8*
- call addrspace(0) void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.0, i8* align 8 bitcast ({ i32*, i32 }* @const.0 to i8*), i64 16, i1 false)
- %field.0 = getelementptr inbounds { i32*, i32 }, { i32*, i32 }* %loc1, i32 0, i32 1
- %loc1.field.ld.0 = load i32, i32* %field.0, align 4
- %field.1 = getelementptr inbounds { i32*, i32 }, { i32*, i32 }* %loc2, i32 0, i32 0
- store i32* %param1.addr, i32** %field.1, align 8
- %field.2 = getelementptr inbounds { i32*, i32 }, { i32*, i32 }* %loc2, i32 0, i32 1
- store i32 %loc1.field.ld.0, i32* %field.2, align 4
+ call addrspace(0) void @llvm.memcpy.p0.p0.i64(ptr align 8 %loc1, ptr align 8 @const.0, i64 16, i1 false)
+ %field.0 = getelementptr inbounds { ptr, i32 }, ptr %loc1, i32 0, i32 1
+ %loc1.field.ld.0 = load i32, ptr %field.0, align 4
+ %field.1 = getelementptr inbounds { ptr, i32 }, ptr %loc2, i32 0, i32 0
+ store ptr %param1.addr, ptr %field.1, align 8
+ %field.2 = getelementptr inbounds { ptr, i32 }, ptr %loc2, i32 0, i32 1
+ store i32 %loc1.field.ld.0, ptr %field.2, align 4
)RAW_RESULT");
bool isOK = h.expectBlock(exp);
@@ -423,18 +419,15 @@
h.mkAssign(vex, scon2);
DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
- %cast.0 = bitcast { { i32*, i32 }, float }* %loc1 to i8*
- call addrspace(0) void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.0, i8* align 8 bitcast ({ { i32*, i32 }, float }* @const.0 to i8*), i64 24, i1 false)
- %field.0 = getelementptr inbounds { i32*, i32 }, { i32*, i32 }* %tmp.0, i32 0, i32 0
- store i32* %param1.addr, i32** %field.0, align 8
- %field.1 = getelementptr inbounds { i32*, i32 }, { i32*, i32 }* %tmp.0, i32 0, i32 1
- store i32 3, i32* %field.1, align 4
- %field.2 = getelementptr inbounds { { i32*, i32 }, float }, { { i32*, i32 }, float }* %loc1, i32 0, i32 0
- %cast.1 = bitcast { i32*, i32 }* %field.2 to i8*
- %cast.2 = bitcast { i32*, i32 }* %tmp.0 to i8*
- call addrspace(0) void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.1, i8* align 8 %cast.2, i64 16, i1 false)
- %field.3 = getelementptr inbounds { { i32*, i32 }, float }, { { i32*, i32 }, float }* %loc1, i32 0, i32 1
- store float 3.000000e+00, float* %field.3, align 4
+ call addrspace(0) void @llvm.memcpy.p0.p0.i64(ptr align 8 %loc1, ptr align 8 @const.0, i64 24, i1 false)
+ %field.0 = getelementptr inbounds { ptr, i32 }, ptr %tmp.0, i32 0, i32 0
+ store ptr %param1.addr, ptr %field.0, align 8
+ %field.1 = getelementptr inbounds { ptr, i32 }, ptr %tmp.0, i32 0, i32 1
+ store i32 3, ptr %field.1, align 4
+ %field.2 = getelementptr inbounds { { ptr, i32 }, float }, ptr %loc1, i32 0, i32 0
+ call addrspace(0) void @llvm.memcpy.p0.p0.i64(ptr align 8 %field.2, ptr align 8 %tmp.0, i64 16, i1 false)
+ %field.3 = getelementptr inbounds { { ptr, i32 }, float }, ptr %loc1, i32 0, i32 1
+ store float 3.000000e+00, ptr %field.3, align 4
)RAW_RESULT");
bool isOK = h.expectBlock(exp);
@@ -472,12 +465,12 @@
h.mkAssign(dex, scon);
DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
- %p0.ld.0 = load { i32*, i32 }*, { i32*, i32 }** %p0.addr, align 8
- %p1.ld.0 = load i32*, i32** %p1.addr, align 8
- %field.0 = getelementptr inbounds { i32*, i32 }, { i32*, i32 }* %p0.ld.0, i32 0, i32 0
- store i32* %p1.ld.0, i32** %field.0, align 8
- %field.1 = getelementptr inbounds { i32*, i32 }, { i32*, i32 }* %p0.ld.0, i32 0, i32 1
- store i32 101, i32* %field.1, align 4
+ %p0.ld.0 = load ptr, ptr %p0.addr, align 8
+ %p1.ld.0 = load ptr, ptr %p1.addr, align 8
+ %field.0 = getelementptr inbounds { ptr, i32 }, ptr %p0.ld.0, i32 0, i32 0
+ store ptr %p1.ld.0, ptr %field.0, align 8
+ %field.1 = getelementptr inbounds { ptr, i32 }, ptr %p0.ld.0, i32 0, i32 1
+ store i32 101, ptr %field.1, align 4
)RAW_RESULT");
bool isOK = h.expectBlock(exp);
@@ -521,11 +514,11 @@
h.mkLocal("t2", s1t, scon2);
DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
- %x.ld.0 = load i32, i32* @x, align 4
- store i32 %x.ld.0, i32* getelementptr inbounds ({ i32 }, { i32 }* @t, i32 0, i32 0), align 4
- %t.field.ld.0 = load i32, i32* getelementptr inbounds ({ i32 }, { i32 }* @t, i32 0, i32 0), align 4
- %field.2 = getelementptr inbounds { i32 }, { i32 }* %t2, i32 0, i32 0
- store i32 %t.field.ld.0, i32* %field.2, align 4
+ %x.ld.0 = load i32, ptr @x, align 4
+ store i32 %x.ld.0, ptr @t, align 4
+ %t.field.ld.0 = load i32, ptr @t, align 4
+ %field.2 = getelementptr inbounds { i32 }, ptr %t2, i32 0, i32 0
+ store i32 %t.field.ld.0, ptr %field.2, align 4
)RAW_RESULT");
bool isOK = h.expectBlock(exp);
@@ -575,16 +568,15 @@
h.mkAssign(aa4, aa3);
DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
- %cast.0 = bitcast [4 x i64]* %aa to i8*
- call addrspace(0) void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.0, i8* align 8 bitcast ([4 x i64]* @const.0 to i8*), i64 32, i1 false)
- %index.0 = getelementptr [4 x i64], [4 x i64]* %aa, i32 0, i32 1
- %aa.index.ld.0 = load i64, i64* %index.0, align 8
- %index.1 = getelementptr [4 x i64], [4 x i64]* %aa, i32 0, i64 %aa.index.ld.0
- %index.2 = getelementptr [4 x i64], [4 x i64]* %aa, i32 0, i64 3
- %aa.index.ld.1 = load i64, i64* %index.2, align 8
- %index.3 = getelementptr [4 x i64], [4 x i64]* %aa, i32 0, i64 %aa.index.ld.1
- %aa.index.ld.2 = load i64, i64* %index.3, align 8
- store i64 %aa.index.ld.2, i64* %index.1, align 8
+ call addrspace(0) void @llvm.memcpy.p0.p0.i64(ptr align 8 %aa, ptr align 8 @const.0, i64 32, i1 false)
+ %index.0 = getelementptr [4 x i64], ptr %aa, i32 0, i32 1
+ %aa.index.ld.0 = load i64, ptr %index.0, align 8
+ %index.1 = getelementptr [4 x i64], ptr %aa, i32 0, i64 %aa.index.ld.0
+ %index.2 = getelementptr [4 x i64], ptr %aa, i32 0, i64 3
+ %aa.index.ld.1 = load i64, ptr %index.2, align 8
+ %index.3 = getelementptr [4 x i64], ptr %aa, i32 0, i64 %aa.index.ld.1
+ %aa.index.ld.2 = load i64, ptr %index.3, align 8
+ store i64 %aa.index.ld.2, ptr %index.1, align 8
)RAW_RESULT");
bool isOK = h.expectBlock(exp);
@@ -644,15 +636,12 @@
h.mkAssign(fx, bi64five);
DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
- %cast.0 = bitcast [10 x { i8, [4 x { i64, i64 }*], i8 }*]* %t1 to i8*
- call addrspace(0) void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.0, i8* align 8 bitcast ([10 x { i8, [4 x { i64, i64 }*], i8 }*]* @const.0 to i8*), i64 80, i1 false)
- %index.0 = getelementptr [10 x { i8, [4 x { i64, i64 }*], i8 }*], [10 x { i8, [4 x { i64, i64 }*], i8 }*]* %t1, i32 0, i32 7
- %t1.index.ld.0 = load { i8, [4 x { i64, i64 }*], i8 }*, { i8, [4 x { i64, i64 }*], i8 }** %index.0, align 8
- %field.0 = getelementptr inbounds { i8, [4 x { i64, i64 }*], i8 }, { i8, [4 x { i64, i64 }*], i8 }* %t1.index.ld.0, i32 0, i32 1
- %index.1 = getelementptr [4 x { i64, i64 }*], [4 x { i64, i64 }*]* %field.0, i32 0, i32 3
- %.field.index.ld.0 = load { i64, i64 }*, { i64, i64 }** %index.1, align 8
- %field.1 = getelementptr inbounds { i64, i64 }, { i64, i64 }* %.field.index.ld.0, i32 0, i32 0
- store i64 5, i64* %field.1, align 8
+ call addrspace(0) void @llvm.memcpy.p0.p0.i64(ptr align 8 %t1, ptr align 8 @const.0, i64 80, i1 false)
+ %index.0 = getelementptr [10 x ptr], ptr %t1, i32 0, i32 7
+ %field.0 = getelementptr inbounds { i8, [4 x ptr], i8 }, ptr %index.0, i32 0, i32 1
+ %index.1 = getelementptr [4 x ptr], ptr %field.0, i32 0, i32 3
+ %field.1 = getelementptr inbounds { i64, i64 }, ptr %index.1, i32 0, i32 0
+ store i64 5, ptr %field.1, align 8
)RAW_RESULT");
bool isOK = h.expectBlock(exp);
@@ -675,14 +664,12 @@
h.mkLocal("q", bi64t, fx);
DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
- %index.2 = getelementptr [10 x { i8, [4 x { i64, i64 }*], i8 }*], [10 x { i8, [4 x { i64, i64 }*], i8 }*]* %t1, i32 0, i32 0
- %t1.index.ld.1 = load { i8, [4 x { i64, i64 }*], i8 }*, { i8, [4 x { i64, i64 }*], i8 }** %index.2, align 8
- %field.2 = getelementptr inbounds { i8, [4 x { i64, i64 }*], i8 }, { i8, [4 x { i64, i64 }*], i8 }* %t1.index.ld.1, i32 0, i32 1
- %index.3 = getelementptr [4 x { i64, i64 }*], [4 x { i64, i64 }*]* %field.2, i32 0, i32 0
- %.field.index.ld.1 = load { i64, i64 }*, { i64, i64 }** %index.3, align 8
- %field.3 = getelementptr inbounds { i64, i64 }, { i64, i64 }* %.field.index.ld.1, i32 0, i32 1
- %.field.ld.0 = load i64, i64* %field.3, align 8
- store i64 %.field.ld.0, i64* %q, align 8
+ %index.2 = getelementptr [10 x ptr], ptr %t1, i32 0, i32 0
+ %field.2 = getelementptr inbounds { i8, [4 x ptr], i8 }, ptr %index.2, i32 0, i32 1
+ %index.3 = getelementptr [4 x ptr], ptr %field.2, i32 0, i32 0
+ %field.3 = getelementptr inbounds { i64, i64 }, ptr %index.3, i32 0, i32 1
+ %.field.ld.0 = load i64, ptr %field.3, align 8
+ store i64 %.field.ld.0, ptr %q, align 8
)RAW_RESULT");
bool isOK = h.expectBlock(exp);
@@ -725,20 +712,12 @@
h.mkAssign(ve3, ve4);
DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
- %cast.0 = bitcast { i8* }* %x1 to i8*
- call addrspace(0) void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.0, i8* align 8 bitcast ({ i8* }* @const.0 to i8*), i64 8, i1 false)
- %cast.1 = bitcast { i8* }* %y1 to i8*
- call addrspace(0) void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.1, i8* align 8 bitcast ({ i8* }* @const.0 to i8*), i64 8, i1 false)
- %cast.2 = bitcast { i64, i64, i64, i64, i64, i64 }* %x2 to i8*
- call addrspace(0) void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.2, i8* align 8 bitcast ({ i64, i64, i64, i64, i64, i64 }* @const.1 to i8*), i64 48, i1 false)
- %cast.3 = bitcast { i64, i64, i64, i64, i64, i64 }* %y2 to i8*
- call addrspace(0) void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.3, i8* align 8 bitcast ({ i64, i64, i64, i64, i64, i64 }* @const.1 to i8*), i64 48, i1 false)
- %cast.4 = bitcast { i8* }* %x1 to i8*
- %cast.5 = bitcast { i8* }* %y1 to i8*
- call addrspace(0) void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.4, i8* align 8 %cast.5, i64 8, i1 false)
- %cast.6 = bitcast { i64, i64, i64, i64, i64, i64 }* %x2 to i8*
- %cast.7 = bitcast { i64, i64, i64, i64, i64, i64 }* %y2 to i8*
- call addrspace(0) void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.6, i8* align 8 %cast.7, i64 48, i1 false)
+ call addrspace(0) void @llvm.memcpy.p0.p0.i64(ptr align 8 %x1, ptr align 8 @const.0, i64 8, i1 false)
+ call addrspace(0) void @llvm.memcpy.p0.p0.i64(ptr align 8 %y1, ptr align 8 @const.0, i64 8, i1 false)
+ call addrspace(0) void @llvm.memcpy.p0.p0.i64(ptr align 8 %x2, ptr align 8 @const.1, i64 48, i1 false)
+ call addrspace(0) void @llvm.memcpy.p0.p0.i64(ptr align 8 %y2, ptr align 8 @const.1, i64 48, i1 false)
+ call addrspace(0) void @llvm.memcpy.p0.p0.i64(ptr align 8 %x1, ptr align 8 %y1, i64 8, i1 false)
+ call addrspace(0) void @llvm.memcpy.p0.p0.i64(ptr align 8 %x2, ptr align 8 %y2, i64 48, i1 false)
)RAW_RESULT");
bool isOK = h.expectBlock(exp);
@@ -780,11 +759,10 @@
h.mkLocal("a2", bpi32t, aex2);
DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
- %cast.0 = bitcast { i32 }* %t1 to i8*
- call addrspace(0) void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %cast.0, i8* align 4 bitcast ({ i32 }* @const.0 to i8*), i64 4, i1 false)
- %field.0 = getelementptr inbounds { i32 }, { i32 }* %t1, i32 0, i32 0
- store i32* %field.0, i32** %a1, align 8
- store i32* getelementptr inbounds ({ i32 }, { i32 }* @t2, i32 0, i32 0), i32** %a2, align 8
+ call addrspace(0) void @llvm.memcpy.p0.p0.i64(ptr align 4 %t1, ptr align 4 @const.0, i64 4, i1 false)
+ %field.0 = getelementptr inbounds { i32 }, ptr %t1, i32 0, i32 0
+ store ptr %field.0, ptr %a1, align 8
+ store ptr @t2, ptr %a2, align 8
)RAW_RESULT");
bool isOK = h.expectBlock(exp);
diff --git a/unittests/BackendCore/BackendCABIOracleTests.cpp b/unittests/BackendCore/BackendCABIOracleTests.cpp
index 3f3c902..e675043 100644
--- a/unittests/BackendCore/BackendCABIOracleTests.cpp
+++ b/unittests/BackendCore/BackendCABIOracleTests.cpp
@@ -55,7 +55,7 @@
CABIOracle cab(befty1, be->typeManager());
DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
Return: Direct { { double, double } } sigOffset: -1
- Param 1: Direct AttrNest { i8* } sigOffset: 0
+ Param 1: Direct AttrNest { ptr } sigOffset: 0
Param 2: Direct AttrSext { i8 } sigOffset: 1
Param 3: Direct { float } sigOffset: 2
Param 4: Ignore { void } sigOffset: -1
@@ -65,7 +65,7 @@
bool equal = difftokens(exp.content, cab.toString(), reason);
EXPECT_EQ("pass", equal ? "pass" : reason);
EXPECT_EQ(repr(cab.getFunctionTypeForABI()),
- "{ double, double } (i8*, i8, float, i64)");
+ "{ double, double } (ptr, i8, float, i64)");
}
}
@@ -118,99 +118,98 @@
std::vector<FcnItem> items = {
// 1
- FcnItem( { }, { },
+ FcnItem({}, {},
"Return: Ignore { void } sigOffset: -1 "
- "Param 1: Direct AttrNest { i8* } sigOffset: 0",
- "void (i8*)"),
+ "Param 1: Direct AttrNest { ptr } sigOffset: 0",
+ "void (ptr)"),
// 2
- FcnItem( { bi8t }, { },
+ FcnItem({bi8t}, {},
"Return: Direct AttrSext { i8 } sigOffset: -1 "
- "Param 1: Direct AttrNest { i8* } sigOffset: 0",
- "i8 (i8*)"),
+ "Param 1: Direct AttrNest { ptr } sigOffset: 0",
+ "i8 (ptr)"),
// 3
- FcnItem( { }, { bi8t },
+ FcnItem({}, {bi8t},
"Return: Ignore { void } sigOffset: -1 "
- "Param 1: Direct AttrNest { i8* } sigOffset: 0 "
+ "Param 1: Direct AttrNest { ptr } sigOffset: 0 "
"Param 2: Direct AttrSext { i8 } sigOffset: 1",
- "void (i8*, i8)"),
+ "void (ptr, i8)"),
// 4
- FcnItem( { }, { st5, bpf64t },
+ FcnItem({}, {st5, bpf64t},
"Return: Ignore { void } sigOffset: -1 "
- "Param 1: Direct AttrNest { i8* } sigOffset: 0 "
+ "Param 1: Direct AttrNest { ptr } sigOffset: 0 "
"Param 2: Direct { float } sigOffset: 1 "
- "Param 3: Direct { double* } sigOffset: 2",
- "void (i8*, float, double*)"),
+ "Param 3: Direct { ptr } sigOffset: 2",
+ "void (ptr, float, ptr)"),
// 5
- FcnItem({ bi8t, bf64t }, { bi8t, bu8t, st0 },
+ FcnItem({bi8t, bf64t}, {bi8t, bu8t, st0},
"Return: Direct { { i8, double } } sigOffset: -1 "
- "Param 1: Direct AttrNest { i8* } sigOffset: 0 "
+ "Param 1: Direct AttrNest { ptr } sigOffset: 0 "
"Param 2: Direct AttrSext { i8 } sigOffset: 1 "
"Param 3: Direct AttrZext { i8 } sigOffset: 2 "
"Param 4: Ignore { void } sigOffset: -1",
- "{ i8, double } (i8*, i8, i8)"),
+ "{ i8, double } (ptr, i8, i8)"),
// 6
- FcnItem({ st2 }, { st2, st0, st4, st1 },
+ FcnItem({st2}, {st2, st0, st4, st1},
"Return: Direct { { double, double } } sigOffset: -1 "
- "Param 1: Direct AttrNest { i8* } sigOffset: 0 "
+ "Param 1: Direct AttrNest { ptr } sigOffset: 0 "
"Param 2: Direct { double, double } sigOffset: 1 "
"Param 3: Ignore { void } sigOffset: -1 "
"Param 4: Direct { <2 x float> } sigOffset: 3 "
"Param 5: Direct { i64 } sigOffset: 4 ",
- "{ double, double } (i8*, double, double, <2 x float>, i64)"),
+ "{ double, double } (ptr, double, double, <2 x float>, i64)"),
// 7
- FcnItem({ st3 }, { st3, st0, bu8t },
- "Return: Indirect AttrStructReturn { { { double, double }, i8 }* } sigOffset: 0 "
- "Param 1: Direct AttrNest { i8* } sigOffset: 1 "
- "Param 2: Indirect AttrByVal { { { double, double }, i8 }* } sigOffset: 2 "
+ FcnItem({st3}, {st3, st0, bu8t},
+ "Return: Indirect AttrStructReturn { ptr } sigOffset: 0 "
+ "Param 1: Direct AttrNest { ptr } sigOffset: 1 "
+ "Param 2: Indirect AttrByVal { ptr } sigOffset: 2 "
"Param 3: Ignore { void } sigOffset: -1 "
"Param 4: Direct AttrZext { i8 } sigOffset: 3 ",
- "void ({ { double, double }, i8 }*, i8*, "
- "{ { double, double }, i8 }*, i8)"),
+ "void (ptr, ptr, ptr, i8)"),
// 8
- FcnItem( { st6 }, { st6, st6 },
+ FcnItem({st6}, {st6, st6},
"Return: Direct { { i64, i64 } } sigOffset: -1 "
- "Param 1: Direct AttrNest { i8* } sigOffset: 0 "
+ "Param 1: Direct AttrNest { ptr } sigOffset: 0 "
"Param 2: Direct { i64, i64 } sigOffset: 1 "
"Param 3: Direct { i64, i64 } sigOffset: 3",
- "{ i64, i64 } (i8*, i64, i64, i64, i64)"),
+ "{ i64, i64 } (ptr, i64, i64, i64, i64)"),
// 9
- FcnItem( { st8 }, { st8 },
+ FcnItem({st8}, {st8},
"Return: Direct { { i64, i32 } } sigOffset: -1 "
- "Param 1: Direct AttrNest { i8* } sigOffset: 0 "
+ "Param 1: Direct AttrNest { ptr } sigOffset: 0 "
"Param 2: Direct { i64, i32 } sigOffset: 1",
- "{ i64, i32 } (i8*, i64, i32)"),
+ "{ i64, i32 } (ptr, i64, i32)"),
// 10
- FcnItem( { at0 }, { at1 },
+ FcnItem({at0}, {at1},
"Return: Ignore { void } sigOffset: -1 "
- "Param 1: Direct AttrNest { i8* } sigOffset: 0 "
+ "Param 1: Direct AttrNest { ptr } sigOffset: 0 "
"Param 2: Direct { i32 } sigOffset: 1",
- "void (i8*, i32)"),
+ "void (ptr, i32)"),
// 11
- FcnItem( { at2 }, { at3 },
+ FcnItem({at2}, {at3},
"Return: Direct { { i64, i32 } } sigOffset: -1 "
- "Param 1: Direct AttrNest { i8* } sigOffset: 0 "
+ "Param 1: Direct AttrNest { ptr } sigOffset: 0 "
"Param 2: Direct { i64, i64 } sigOffset: 1",
- "{ i64, i32 } (i8*, i64, i64)"),
+ "{ i64, i32 } (ptr, i64, i64)"),
// 12
// Make sure pointerness is preserved.
- FcnItem( { stip }, { stii, stpp, stpi },
- "Return: Direct { { i64, i8* } } sigOffset: -1 "
- "Param 1: Direct AttrNest { i8* } sigOffset: 0 "
+ FcnItem({stip}, {stii, stpp, stpi},
+ "Return: Direct { { i64, ptr } } sigOffset: -1 "
+ "Param 1: Direct AttrNest { ptr } sigOffset: 0 "
"Param 2: Direct { i64, i64 } sigOffset: 1 "
- "Param 3: Direct { i8*, i8* } sigOffset: 3 "
- "Param 4: Direct { i8*, i64 } sigOffset: 5",
- "{ i64, i8* } (i8*, i64, i64, i8*, i8*, i8*, i64)"),
+ "Param 3: Direct { ptr, ptr } sigOffset: 3 "
+ "Param 4: Direct { ptr, i64 } sigOffset: 5",
+ "{ i64, ptr } (ptr, i64, i64, ptr, ptr, ptr, i64)"),
};
unsigned count = 1;
@@ -303,99 +302,97 @@
// 1
FcnItem({}, {},
"Return: Ignore { void } sigOffset: -1 "
- "Param 1: Direct AttrNest { i8* } sigOffset: 0",
- "void (i8*)"),
+ "Param 1: Direct AttrNest { ptr } sigOffset: 0",
+ "void (ptr)"),
// 2
FcnItem({bi8t}, {},
"Return: Direct AttrSext { i8 } sigOffset: -1 "
- "Param 1: Direct AttrNest { i8* } sigOffset: 0",
- "i8 (i8*)"),
+ "Param 1: Direct AttrNest { ptr } sigOffset: 0",
+ "i8 (ptr)"),
// 3
FcnItem({}, {bi8t},
"Return: Ignore { void } sigOffset: -1 "
- "Param 1: Direct AttrNest { i8* } sigOffset: 0 "
+ "Param 1: Direct AttrNest { ptr } sigOffset: 0 "
"Param 2: Direct AttrSext { i8 } sigOffset: 1",
- "void (i8*, i8)"),
+ "void (ptr, i8)"),
// 4
FcnItem({}, {st5, bpf64t},
"Return: Ignore { void } sigOffset: -1 "
- "Param 1: Direct AttrNest { i8* } sigOffset: 0 "
+ "Param 1: Direct AttrNest { ptr } sigOffset: 0 "
"Param 2: Direct { float } sigOffset: 1 "
- "Param 3: Direct { double* } sigOffset: 2",
- "void (i8*, float, double*)"),
+ "Param 3: Direct { ptr } sigOffset: 2",
+ "void (ptr, float, ptr)"),
// 5
FcnItem({bi8t, bf64t}, {bi8t, bu8t, st0},
"Return: Direct { { i64, i64 } } sigOffset: -1 "
- "Param 1: Direct AttrNest { i8* } sigOffset: 0 "
+ "Param 1: Direct AttrNest { ptr } sigOffset: 0 "
"Param 2: Direct AttrSext { i8 } sigOffset: 1 "
"Param 3: Direct AttrZext { i8 } sigOffset: 2 "
"Param 4: Ignore { void } sigOffset: -1",
- "{ i64, i64 } (i8*, i8, i8)"),
+ "{ i64, i64 } (ptr, i8, i8)"),
// 6
FcnItem({st2}, {st2, st0, st4, st1},
"Return: Direct { { double, double } } sigOffset: -1 "
- "Param 1: Direct AttrNest { i8* } sigOffset: 0 "
+ "Param 1: Direct AttrNest { ptr } sigOffset: 0 "
"Param 2: Direct { [2 x double] } sigOffset: 1 "
"Param 3: Ignore { void } sigOffset: -1 "
"Param 4: Direct { [2 x float] } sigOffset: 2 "
"Param 5: Direct { i64 } sigOffset: 3",
- "{ double, double } (i8*, [2 x double], [2 x float], i64)"),
+ "{ double, double } (ptr, [2 x double], [2 x float], i64)"),
// 7
FcnItem({st3}, {st3, st0, bu8t},
- "Return: Indirect AttrStructReturn { { { double, double }, i8 "
- "}* } sigOffset: 0 "
- "Param 1: Direct AttrNest { i8* } sigOffset: 1 "
- "Param 2: Indirect AttrDoCopy { { { double, double }, i8 }* } "
+ "Return: Indirect AttrStructReturn { ptr } sigOffset: 0 "
+ "Param 1: Direct AttrNest { ptr } sigOffset: 1 "
+ "Param 2: Indirect AttrDoCopy { ptr } "
"sigOffset: 2 "
"Param 3: Ignore { void } sigOffset: -1 "
"Param 4: Direct AttrZext { i8 } sigOffset: 3 ",
- "void ({ { double, double }, i8 }*, i8*, "
- "{ { double, double }, i8 }*, i8)"),
+ "void (ptr, ptr, ptr, i8)"),
// 8
FcnItem({st6}, {st6, st6},
"Return: Direct { { i64, i64 } } sigOffset: -1 "
- "Param 1: Direct AttrNest { i8* } sigOffset: 0 "
+ "Param 1: Direct AttrNest { ptr } sigOffset: 0 "
"Param 2: Direct { i64, i64 } sigOffset: 1 "
"Param 3: Direct { i64, i64 } sigOffset: 3",
- "{ i64, i64 } (i8*, i64, i64, i64, i64)"),
+ "{ i64, i64 } (ptr, i64, i64, i64, i64)"),
// 9
FcnItem({st8}, {st8},
"Return: Direct { { i64, i32 } } sigOffset: -1 "
- "Param 1: Direct AttrNest { i8* } sigOffset: 0 "
+ "Param 1: Direct AttrNest { ptr } sigOffset: 0 "
"Param 2: Direct { i64, i32 } sigOffset: 1",
- "{ i64, i32 } (i8*, i64, i32)"),
+ "{ i64, i32 } (ptr, i64, i32)"),
// 10
FcnItem({at0}, {at1},
"Return: Ignore { void } sigOffset: -1 "
- "Param 1: Direct AttrNest { i8* } sigOffset: 0 "
+ "Param 1: Direct AttrNest { ptr } sigOffset: 0 "
"Param 2: Direct { i32 } sigOffset: 1",
- "void (i8*, i32)"),
+ "void (ptr, i32)"),
// 11
FcnItem({at2}, {at3},
"Return: Direct { { i64, i32 } } sigOffset: -1 "
- "Param 1: Direct AttrNest { i8* } sigOffset: 0 "
+ "Param 1: Direct AttrNest { ptr } sigOffset: 0 "
"Param 2: Direct { i64, i64 } sigOffset: 1",
- "{ i64, i32 } (i8*, i64, i64)"),
+ "{ i64, i32 } (ptr, i64, i64)"),
// 12
// Make sure pointerness is preserved.
FcnItem({stip}, {stii, stpp, stpi},
- "Return: Direct { { i64, i8* } } sigOffset: -1 "
- "Param 1: Direct AttrNest { i8* } sigOffset: 0 "
+ "Return: Direct { { i64, ptr } } sigOffset: -1 "
+ "Param 1: Direct AttrNest { ptr } sigOffset: 0 "
"Param 2: Direct { i64, i64 } sigOffset: 1 "
- "Param 3: Direct { i8*, i8* } sigOffset: 3 "
- "Param 4: Direct { i8*, i64 } sigOffset: 5",
- "{ i64, i8* } (i8*, i64, i64, i8*, i8*, i8*, i64)"),
+ "Param 3: Direct { ptr, ptr } sigOffset: 3 "
+ "Param 4: Direct { ptr, i64 } sigOffset: 5",
+ "{ i64, ptr } (ptr, i64, i64, ptr, ptr, ptr, i64)"),
};
unsigned count = 1;
@@ -532,24 +529,20 @@
Bstatement *rst2 = h.mkReturn(rvals2, FcnTestHarness::NoAppend);
DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
- %p3.ld.0 = load i8, i8* %p3.addr, align 1
+ %p3.ld.0 = load i8, ptr %p3.addr, align 1
%sub.0 = sub i8 %p3.ld.0, 1
- %p4.ld.0 = load i8, i8* %p4.addr, align 1
- %cast.1 = bitcast { float, float, i16, i16, i16 }* %p0.addr to { <2 x float>, i48 }*
- %field0.0 = getelementptr inbounds { <2 x float>, i48 }, { <2 x float>, i48 }* %cast.1, i32 0, i32 0
- %ld.1 = load <2 x float>, <2 x float>* %field0.0, align 8
- %field1.0 = getelementptr inbounds { <2 x float>, i48 }, { <2 x float>, i48 }* %cast.1, i32 0, i32 1
- %ld.2 = load i48, i48* %field1.0, align 8
- %cast.2 = bitcast { double, float, float }* %p1.addr to { double, <2 x float> }*
- %field0.1 = getelementptr inbounds { double, <2 x float> }, { double, <2 x float> }* %cast.2, i32 0, i32 0
- %ld.3 = load double, double* %field0.1, align 8
- %field1.1 = getelementptr inbounds { double, <2 x float> }, { double, <2 x float> }* %cast.2, i32 0, i32 1
- %ld.4 = load <2 x float>, <2 x float>* %field1.1, align 8
- %call.0 = call addrspace(0) { double, <2 x float> } @foo(i8* nest undef, <2 x float> %ld.1, i48 %ld.2, double %ld.3, <2 x float> %ld.4, i8 zeroext %sub.0, i8 signext %p4.ld.0, { { float, float, i16, i16, i16 }, { double, float, float } }* byval({ { float, float, i16, i16, i16 }, { double, float, float } }) %p5)
- %cast.3 = bitcast { double, float, float }* %sret.actual.0 to { double, <2 x float> }*
- store { double, <2 x float> } %call.0, { double, <2 x float> }* %cast.3, align 8
- %cast.4 = bitcast { double, float, float }* %sret.actual.0 to { double, <2 x float> }*
- %ld.5 = load { double, <2 x float> }, { double, <2 x float> }* %cast.4, align 8
+ %p4.ld.0 = load i8, ptr %p4.addr, align 1
+ %field0.0 = getelementptr inbounds { <2 x float>, i48 }, ptr %p0.addr, i32 0, i32 0
+ %ld.1 = load <2 x float>, ptr %field0.0, align 8
+ %field1.0 = getelementptr inbounds { <2 x float>, i48 }, ptr %p0.addr, i32 0, i32 1
+ %ld.2 = load i48, ptr %field1.0, align 8
+ %field0.1 = getelementptr inbounds { double, <2 x float> }, ptr %p1.addr, i32 0, i32 0
+ %ld.3 = load double, ptr %field0.1, align 8
+ %field1.1 = getelementptr inbounds { double, <2 x float> }, ptr %p1.addr, i32 0, i32 1
+ %ld.4 = load <2 x float>, ptr %field1.1, align 8
+ %call.0 = call addrspace(0) { double, <2 x float> } @foo(ptr nest undef, <2 x float> %ld.1, i48 %ld.2, double %ld.3, <2 x float> %ld.4, i8 zeroext %sub.0, i8 signext %p4.ld.0, ptr byval({ { float, float, i16, i16, i16 }, { double, float, float } }) %p5)
+ store { double, <2 x float> } %call.0, ptr %sret.actual.0, align 8
+ %ld.5 = load { double, <2 x float> }, ptr %sret.actual.0, align 8
ret { double, <2 x float> } %ld.5
)RAW_RESULT");
@@ -651,27 +644,21 @@
Bstatement *rst2 = h.mkReturn(rvals2, FcnTestHarness::NoAppend);
DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
- %p3.ld.0 = load i8, i8* %p3.addr, align 1
+ %p3.ld.0 = load i8, ptr %p3.addr, align 1
%sub.0 = sub i8 %p3.ld.0, 1
- %p4.ld.0 = load i8, i8* %p4.addr, align 1
- %cast.1 = bitcast { float, float, i16, i16, i16 }* %p0.addr to { i64, i48 }*
- %field0.0 = getelementptr inbounds { i64, i48 }, { i64, i48 }* %cast.1, i32 0, i32 0
- %ld.1 = load i64, i64* %field0.0, align 8
- %field1.0 = getelementptr inbounds { i64, i48 }, { i64, i48 }* %cast.1, i32 0, i32 1
- %ld.2 = load i48, i48* %field1.0, align 8
- %cast.2 = bitcast { double, float, float }* %p1.addr to { i64, i64 }*
- %field0.1 = getelementptr inbounds { i64, i64 }, { i64, i64 }* %cast.2, i32 0, i32 0
- %ld.3 = load i64, i64* %field0.1, align 8
- %field1.1 = getelementptr inbounds { i64, i64 }, { i64, i64 }* %cast.2, i32 0, i32 1
- %ld.4 = load i64, i64* %field1.1, align 8
- %cast.3 = bitcast { { float, float, i16, i16, i16 }, { double, float, float } }* %doCopy.addr.0 to i8*
- %cast.4 = bitcast { { float, float, i16, i16, i16 }, { double, float, float } }* %p5 to i8*
- call addrspace(0) void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.3, i8* align 8 %cast.4, i64 32, i1 false)
- %call.0 = call addrspace(0) { i64, i64 } @foo(i8* nest undef, i64 %ld.1, i48 %ld.2, i64 %ld.3, i64 %ld.4, i8 zeroext %sub.0, i8 signext %p4.ld.0, { { float, float, i16, i16, i16 }, { double, float, float } }* %doCopy.addr.0)
- %cast.5 = bitcast { double, float, float }* %sret.actual.0 to { i64, i64 }*
- store { i64, i64 } %call.0, { i64, i64 }* %cast.5, align 8
- %cast.6 = bitcast { double, float, float }* %sret.actual.0 to { i64, i64 }*
- %ld.5 = load { i64, i64 }, { i64, i64 }* %cast.6, align 8
+ %p4.ld.0 = load i8, ptr %p4.addr, align 1
+ %field0.0 = getelementptr inbounds { i64, i48 }, ptr %p0.addr, i32 0, i32 0
+ %ld.1 = load i64, ptr %field0.0, align 8
+ %field1.0 = getelementptr inbounds { i64, i48 }, ptr %p0.addr, i32 0, i32 1
+ %ld.2 = load i48, ptr %field1.0, align 8
+ %field0.1 = getelementptr inbounds { i64, i64 }, ptr %p1.addr, i32 0, i32 0
+ %ld.3 = load i64, ptr %field0.1, align 8
+ %field1.1 = getelementptr inbounds { i64, i64 }, ptr %p1.addr, i32 0, i32 1
+ %ld.4 = load i64, ptr %field1.1, align 8
+ call addrspace(0) void @llvm.memcpy.p0.p0.i64(ptr align 8 %doCopy.addr.0, ptr align 8 %p5, i64 32, i1 false)
+ %call.0 = call addrspace(0) { i64, i64 } @foo(ptr nest undef, i64 %ld.1, i48 %ld.2, i64 %ld.3, i64 %ld.4, i8 zeroext %sub.0, i8 signext %p4.ld.0, ptr %doCopy.addr.0)
+ store { i64, i64 } %call.0, ptr %sret.actual.0, align 8
+ %ld.5 = load { i64, i64 }, ptr %sret.actual.0, align 8
ret { i64, i64 } %ld.5
)RAW_RESULT");
@@ -716,12 +703,9 @@
h.mkReturn(rvals);
DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
- %cast.0 = bitcast [2 x float]* %p0.addr to <2 x float>*
- %ld.0 = load <2 x float>, <2 x float>* %cast.0, align 8
- call addrspace(0) void @foo([3 x double]* sret([3 x double]) "go_sret" %sret.actual.0, i8* nest undef, <2 x float> %ld.0)
- %cast.1 = bitcast [3 x double]* %sret.formal.0 to i8*
- %cast.2 = bitcast [3 x double]* %sret.actual.0 to i8*
- call addrspace(0) void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.1, i8* align 8 %cast.2, i64 24, i1 false)
+ %ld.0 = load <2 x float>, ptr %p0.addr, align 8
+ call addrspace(0) void @foo(ptr sret([3 x double]) "go_sret" %sret.actual.0, ptr nest undef, <2 x float> %ld.0)
+ call addrspace(0) void @llvm.memcpy.p0.p0.i64(ptr align 8 %sret.formal.0, ptr align 8 %sret.actual.0, i64 24, i1 false)
ret void
)RAW_RESULT");
@@ -760,12 +744,10 @@
h.mkReturn(rvals);
DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
- %ld.0 = load [2 x float], [2 x float]* %p0.addr, align 4
- %call.0 = call addrspace(0) { double, double, double } @foo(i8* nest undef, [2 x float] %ld.0)
- %cast.1 = bitcast [3 x double]* %sret.actual.0 to { double, double, double }*
- store { double, double, double } %call.0, { double, double, double }* %cast.1, align 8
- %cast.2 = bitcast [3 x double]* %sret.actual.0 to { double, double, double }*
- %ld.1 = load { double, double, double }, { double, double, double }* %cast.2, align 8
+ %ld.0 = load [2 x float], ptr %p0.addr, align 4
+ %call.0 = call addrspace(0) { double, double, double } @foo(ptr nest undef, [2 x float] %ld.0)
+ store { double, double, double } %call.0, ptr %sret.actual.0, align 8
+ %ld.1 = load { double, double, double }, ptr %sret.actual.0, align 8
ret { double, double, double } %ld.1
)RAW_RESULT");
@@ -813,7 +795,7 @@
h.mkReturn(rvals);
DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
- call addrspace(0) void @foo(i8* nest undef, i32 4)
+ call addrspace(0) void @foo(ptr nest undef, i32 4)
ret void
)RAW_RESULT");
@@ -895,26 +877,20 @@
h.mkReturn(rvals);
DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
- %cast.0 = bitcast { float, float }* %p0.addr to <2 x float>*
- %ld.0 = load <2 x float>, <2 x float>* %cast.0, align 8
- %field0.0 = getelementptr inbounds { double, double }, { double, double }* %p1.addr, i32 0, i32 0
- %ld.1 = load double, double* %field0.0, align 8
- %field1.0 = getelementptr inbounds { double, double }, { double, double }* %p1.addr, i32 0, i32 1
- %ld.2 = load double, double* %field1.0, align 8
- %call.0 = call addrspace(0) <2 x float> @foo(i8* nest undef, <2 x float> %ld.0, double %ld.1, double %ld.2)
- %cast.2 = bitcast { float, float }* %sret.actual.0 to <2 x float>*
- store <2 x float> %call.0, <2 x float>* %cast.2, align 8
- %cast.3 = bitcast { float, float }* %z to i8*
- %cast.4 = bitcast { float, float }* %sret.actual.0 to i8*
- call addrspace(0) void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %cast.3, i8* align 4 %cast.4, i64 8, i1 false)
- %ld.3 = load <2 x float>, <2 x float>* bitcast ({ float, float }* @const.0 to <2 x float>*), align 8
- %ld.4 = load double, double* getelementptr inbounds ({ double, double }, { double, double }* @const.1, i32 0, i32 0), align 8
- %ld.5 = load double, double* getelementptr inbounds ({ double, double }, { double, double }* @const.1, i32 0, i32 1), align 8
- %call.1 = call addrspace(0) <2 x float> @foo(i8* nest undef, <2 x float> %ld.3, double %ld.4, double %ld.5)
- %cast.7 = bitcast { float, float }* %sret.actual.1 to <2 x float>*
- store <2 x float> %call.1, <2 x float>* %cast.7, align 8
- %cast.8 = bitcast { float, float }* %sret.actual.1 to <2 x float>*
- %ld.6 = load <2 x float>, <2 x float>* %cast.8, align 8
+ %ld.0 = load <2 x float>, ptr %p0.addr, align 8
+ %field0.0 = getelementptr inbounds { double, double }, ptr %p1.addr, i32 0, i32 0
+ %ld.1 = load double, ptr %field0.0, align 8
+ %field1.0 = getelementptr inbounds { double, double }, ptr %p1.addr, i32 0, i32 1
+ %ld.2 = load double, ptr %field1.0, align 8
+ %call.0 = call addrspace(0) <2 x float> @foo(ptr nest undef, <2 x float> %ld.0, double %ld.1, double %ld.2)
+ store <2 x float> %call.0, ptr %sret.actual.0, align 8
+ call addrspace(0) void @llvm.memcpy.p0.p0.i64(ptr align 4 %z, ptr align 4 %sret.actual.0, i64 8, i1 false)
+ %ld.3 = load <2 x float>, ptr @const.0, align 8
+ %ld.4 = load double, ptr @const.1, align 8
+ %ld.5 = load double, ptr getelementptr inbounds ({ double, double }, ptr @const.1, i32 0, i32 1), align 8
+ %call.1 = call addrspace(0) <2 x float> @foo(ptr nest undef, <2 x float> %ld.3, double %ld.4, double %ld.5)
+ store <2 x float> %call.1, ptr %sret.actual.1, align 8
+ %ld.6 = load <2 x float>, ptr %sret.actual.1, align 8
ret <2 x float> %ld.6
)RAW_RESULT");
@@ -968,20 +944,16 @@
h.mkReturn(rvals);
DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
- %cast.0 = bitcast { float, float }* %p0.addr to [2 x float]*
- %ld.0 = load [2 x float], [2 x float]* %cast.0, align 4
- %cast.1 = bitcast { double, double }* %p1.addr to [2 x double]*
- %ld.1 = load [2 x double], [2 x double]* %cast.1, align 8
- %call.0 = call addrspace(0) { float, float } @foo(i8* nest undef, [2 x float] %ld.0, [2 x double] %ld.1)
- store { float, float } %call.0, { float, float }* %sret.actual.0, align 4
- %cast.3 = bitcast { float, float }* %z to i8*
- %cast.4 = bitcast { float, float }* %sret.actual.0 to i8*
- call addrspace(0) void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %cast.3, i8* align 4 %cast.4, i64 8, i1 false)
- %ld.2 = load [2 x float], [2 x float]* bitcast ({ float, float }* @const.0 to [2 x float]*), align 4
- %ld.3 = load [2 x double], [2 x double]* bitcast ({ double, double }* @const.1 to [2 x double]*), align 8
- %call.1 = call addrspace(0) { float, float } @foo(i8* nest undef, [2 x float] %ld.2, [2 x double] %ld.3)
- store { float, float } %call.1, { float, float }* %sret.actual.1, align 4
- %ld.4 = load { float, float }, { float, float }* %sret.actual.1, align 4
+ %ld.0 = load [2 x float], ptr %p0.addr, align 4
+ %ld.1 = load [2 x double], ptr %p1.addr, align 8
+ %call.0 = call addrspace(0) { float, float } @foo(ptr nest undef, [2 x float] %ld.0, [2 x double] %ld.1)
+ store { float, float } %call.0, ptr %sret.actual.0, align 4
+ call addrspace(0) void @llvm.memcpy.p0.p0.i64(ptr align 4 %z, ptr align 4 %sret.actual.0, i64 8, i1 false)
+ %ld.2 = load [2 x float], ptr @const.0, align 4
+ %ld.3 = load [2 x double], ptr @const.1, align 8
+ %call.1 = call addrspace(0) { float, float } @foo(ptr nest undef, [2 x float] %ld.2, [2 x double] %ld.3)
+ store { float, float } %call.1, ptr %sret.actual.1, align 4
+ %ld.4 = load { float, float }, ptr %sret.actual.1, align 4
ret { float, float } %ld.4
)RAW_RESULT");
diff --git a/unittests/BackendCore/BackendCallTests.cpp b/unittests/BackendCore/BackendCallTests.cpp
index b8d7eaf..bd9da2a 100644
--- a/unittests/BackendCore/BackendCallTests.cpp
+++ b/unittests/BackendCore/BackendCallTests.cpp
@@ -47,9 +47,9 @@
h.mkReturn(be->var_expression(x, loc));
DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
- %call.0 = call addrspace(0) i64 @foo(i8* nest undef, i32 3, i32 6, i64* null)
- store i64 %call.0, i64* %x, align 8
- %x.ld.0 = load i64, i64* %x, align 8
+ %call.0 = call addrspace(0) i64 @foo(ptr nest undef, i32 3, i32 6, ptr null)
+ store i64 %call.0, ptr %x, align 8
+ %x.ld.0 = load i64, ptr %x, align 8
ret i64 %x.ld.0
)RAW_RESULT");
@@ -80,7 +80,7 @@
h.mkExprStmt(call);
DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
- call addrspace(0) void @bar(i8* nest undef)
+ call addrspace(0) void @bar(ptr nest undef)
)RAW_RESULT");
bool isOK = h.expectBlock(exp);
@@ -119,8 +119,7 @@
{
DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
- %cast.0 = bitcast { i8*, i32*, i64*, i64 }* %sret.formal.0 to i8*
- call addrspace(0) void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.0, i8* align 8 bitcast ({ i8*, i32*, i64*, i64 }* @const.0 to i8*), i64 32, i1 false)
+ call addrspace(0) void @llvm.memcpy.p0.p0.i64(ptr align 8 %sret.formal.0, ptr align 8 @const.0, i64 32, i1 false)
ret void
)RAW_RESULT");
@@ -143,19 +142,17 @@
{
DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
- %p0.ld.0 = load i8*, i8** %p0.addr, align 8
- %field.0 = getelementptr inbounds { i8*, i32*, i64*, i64 }, { i8*, i32*, i64*, i64 }* %tmp.0, i32 0, i32 0
- store i8* %p0.ld.0, i8** %field.0, align 8
- %field.1 = getelementptr inbounds { i8*, i32*, i64*, i64 }, { i8*, i32*, i64*, i64 }* %tmp.0, i32 0, i32 1
- store i32* null, i32** %field.1, align 8
- %field.2 = getelementptr inbounds { i8*, i32*, i64*, i64 }, { i8*, i32*, i64*, i64 }* %tmp.0, i32 0, i32 2
- store i64* null, i64** %field.2, align 8
- %field.3 = getelementptr inbounds { i8*, i32*, i64*, i64 }, { i8*, i32*, i64*, i64 }* %tmp.0, i32 0, i32 3
- store i64 101, i64* %field.3, align 8
- %cast.2 = bitcast { i8*, i32*, i64*, i64 }* %sret.formal.0 to i8*
- %cast.3 = bitcast { i8*, i32*, i64*, i64 }* %tmp.0 to i8*
- call addrspace(0) void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.2, i8* align 8 %cast.3, i64 32, i1 false)
- ret void
+ %p0.ld.0 = load ptr, ptr %p0.addr, align 8
+ %field.0 = getelementptr inbounds { ptr, ptr, ptr, i64 }, ptr %tmp.0, i32 0, i32 0
+ store ptr %p0.ld.0, ptr %field.0, align 8
+ %field.1 = getelementptr inbounds { ptr, ptr, ptr, i64 }, ptr %tmp.0, i32 0, i32 1
+ store ptr null, ptr %field.1, align 8
+ %field.2 = getelementptr inbounds { ptr, ptr, ptr, i64 }, ptr %tmp.0, i32 0, i32 2
+ store ptr null, ptr %field.2, align 8
+ %field.3 = getelementptr inbounds { ptr, ptr, ptr, i64 }, ptr %tmp.0, i32 0, i32 3
+ store i64 101, ptr %field.3, align 8
+ call addrspace(0) void @llvm.memcpy.p0.p0.i64(ptr align 8 %sret.formal.0, ptr align 8 %tmp.0, i64 32, i1 false)
+ ret void
)RAW_RESULT");
bool isOK = h.expectStmt(s2, exp);
@@ -206,12 +203,12 @@
FcnTestHarness::YesAppend);
DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
- define void @foo(i8* nest %nest.0) #0 {
+ define void @foo(ptr nest %nest.0) #0 {
entry:
br i1 true, label %then.0, label %else.0
then.0: ; preds = %entry
- call void @noret(i8* nest undef)
+ call void @noret(ptr nest undef)
unreachable
fallthrough.0: ; preds = %else.0
@@ -283,18 +280,18 @@
h.mkReturn(be->var_expression(z, loc));
DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
- %asmcall.0 = call addrspace(0) i64* asm sideeffect "adrp x0, :tlsdesc:runtime.g\0Aldr $0, [x0, :tlsdesc_lo12:runtime.g]\0Aadd x0, x0, :tlsdesc_lo12:runtime.g\0A.tlsdesccall runtime.g\0Ablr $0\0Amrs $0, TPIDR_EL0\0Aldr $0, [$0, x0]\0A", "=r,~{x0}"()
- store i64* %asmcall.0, i64** %x, align 8
- call addrspace(0) void @bar(i8* nest undef)
- %asmcall.1 = call addrspace(0) i64* asm sideeffect "adrp x0, :tlsdesc:runtime.g\0Aldr $0, [x0, :tlsdesc_lo12:runtime.g]\0Aadd x0, x0, :tlsdesc_lo12:runtime.g\0A.tlsdesccall runtime.g\0Ablr $0\0Amrs $0, TPIDR_EL0\0Aldr $0, [$0, x0]\0A", "=r,~{x0}"()
- store i64* %asmcall.1, i64** %y, align 8
- %x.ld.0 = load i64*, i64** %x, align 8
- %.ld.0 = load i64, i64* %x.ld.0, align 8
- %y.ld.0 = load i64*, i64** %y, align 8
- %.ld.1 = load i64, i64* %y.ld.0, align 8
+ %asmcall.0 = call addrspace(0) ptr asm sideeffect "adrp x0, :tlsdesc:runtime.g\0Aldr $0, [x0, :tlsdesc_lo12:runtime.g]\0Aadd x0, x0, :tlsdesc_lo12:runtime.g\0A.tlsdesccall runtime.g\0Ablr $0\0Amrs $0, TPIDR_EL0\0Aldr $0, [$0, x0]\0A", "=r,~{x0}"()
+ store ptr %asmcall.0, ptr %x, align 8
+ call addrspace(0) void @bar(ptr nest undef)
+ %asmcall.1 = call addrspace(0) ptr asm sideeffect "adrp x0, :tlsdesc:runtime.g\0Aldr $0, [x0, :tlsdesc_lo12:runtime.g]\0Aadd x0, x0, :tlsdesc_lo12:runtime.g\0A.tlsdesccall runtime.g\0Ablr $0\0Amrs $0, TPIDR_EL0\0Aldr $0, [$0, x0]\0A", "=r,~{x0}"()
+ store ptr %asmcall.1, ptr %y, align 8
+ %x.ld.0 = load ptr, ptr %x, align 8
+ %.ld.0 = load i64, ptr %x.ld.0, align 8
+ %y.ld.0 = load ptr, ptr %y, align 8
+ %.ld.1 = load i64, ptr %y.ld.0, align 8
%add.0 = add i64 %.ld.0, %.ld.1
- store i64 %add.0, i64* %z, align 8
- %z.ld.0 = load i64, i64* %z, align 8
+ store i64 %add.0, ptr %z, align 8
+ %z.ld.0 = load i64, ptr %z, align 8
ret i64 %z.ld.0
)RAW_RESULT");
diff --git a/unittests/BackendCore/BackendCoreTests.cpp b/unittests/BackendCore/BackendCoreTests.cpp
index 30923a0..9ca75f5 100644
--- a/unittests/BackendCore/BackendCoreTests.cpp
+++ b/unittests/BackendCore/BackendCoreTests.cpp
@@ -86,7 +86,7 @@
ASSERT_TRUE(best != nullptr);
ASSERT_TRUE(llst != nullptr);
EXPECT_EQ(llst, best->type());
- EXPECT_EQ(repr(best->type()), "{ i8, float*, i64 }");
+ EXPECT_EQ(repr(best->type()), "{ i8, ptr, i64 }");
// If a field has error type, entire struct has error type
std::vector<Backend::Btyped_identifier> fields = {
@@ -186,14 +186,14 @@
Btype *phpt2 = be->placeholder_pointer_type("ph", loc, false);
Btype *phpt3 = be->placeholder_pointer_type("ph", loc, false);
ASSERT_TRUE(phpt2 != phpt3);
- EXPECT_TRUE(phpt2->type() != phpt3->type());
+ // ptr == ptr
+ EXPECT_TRUE(phpt2->type() == phpt3->type());
// Replace placeholder pointer type
Btype *pst = be->pointer_type(mkBackendThreeFieldStruct(be.get()));
be->set_placeholder_pointer_type(phpt1, pst);
ASSERT_TRUE(phpt1->type()->isPointerTy());
PointerType *llpt = cast<PointerType>(phpt1->type());
- EXPECT_TRUE(llpt->getElementType()->isStructTy());
// Placeholder struct type
Btype *phst1 = be->placeholder_struct_type("ph", loc);
@@ -398,8 +398,6 @@
// However the underlying LLVM types should be considered
// assignment-compatible.
std::set<llvm::Type *> visited;
- bool equiv = tm->fcnPointerCompatible(pht->type(), pht2->type(), visited);
- EXPECT_TRUE(equiv);
bool broken = h.finish(PreserveDebugInfo);
EXPECT_FALSE(broken && "Module failed to verify.");
@@ -468,9 +466,9 @@
EXPECT_FALSE(broken && "Module failed to verify.");
bool ok = h.expectModuleDumpContains(
- "@gv = global { { i8, i8*, i32 }, %ph.0 } { { i8, i8*, i32 } { i8 0, "
- "i8* "
- "null, i32 101 }, %ph.0 { i8 0, i8* null, i32 101 } }");
+ "@gv = global { { i8, ptr, i32 }, %ph.0 } { { i8, ptr, i32 } { i8 0, "
+ "ptr "
+ "null, i32 101 }, %ph.0 { i8 0, ptr null, i32 101 } }");
EXPECT_TRUE(ok);
}
diff --git a/unittests/BackendCore/BackendDebugEmit.cpp b/unittests/BackendCore/BackendDebugEmit.cpp
index 7859104..f880cb2 100644
--- a/unittests/BackendCore/BackendDebugEmit.cpp
+++ b/unittests/BackendCore/BackendDebugEmit.cpp
@@ -42,13 +42,13 @@
h.mkLocal("x", bu32t);
DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
- define void @foo(i8* nest %nest.0) #0 {
- entry:
- %x = alloca i32, align 4
- store i32 0, i32* %x, align 4
- call void @llvm.dbg.declare(metadata i32* %x, metadata !4, metadata !DIExpression()), !dbg !12
- ret void
- }
+ define void @foo(ptr nest %nest.0) #0 {
+ entry:
+ %x = alloca i32, align 4
+ store i32 0, ptr %x, align 4
+ #dbg_declare(ptr %x, !4, !DIExpression(), !12)
+ ret void
+ }
)RAW_RESULT");
bool broken = h.finish(PreserveDebugInfo);
@@ -76,11 +76,11 @@
EXPECT_FALSE(broken && "Module failed to verify.");
DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
- define void @foo(i8* nest %nest.0, { i64, i64, i64 }* byval({ i64, i64, i64 }) %p0) #0 {
- entry:
- call void @llvm.dbg.declare(metadata { i64, i64, i64 }* %p0, metadata !4, metadata !DIExpression()), !dbg !18
- ret void
- }
+ define void @foo(ptr nest %nest.0, ptr byval({ i64, i64, i64 }) %p0) #0 {
+ entry:
+ #dbg_declare(ptr %p0, !4, !DIExpression(), !18)
+ ret void
+ }
)RAW_RESULT");
bool isOK = h.expectValue(func->function(), exp);
@@ -103,10 +103,9 @@
EXPECT_FALSE(broken && "Module failed to verify.");
DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
- define void @foo(i8* nest %nest.0, { i64, i64, i64 }* %p0) #0 {
+ define void @foo(ptr nest %nest.0, ptr %p0) #0 {
entry:
- call void @llvm.dbg.declare(metadata { i64, i64, i64 }* %p0, metadata !4,
- metadata !DIExpression()), !dbg !18
+ #dbg_declare(ptr %p0, !4, !DIExpression(), !18)
ret void
}
)RAW_RESULT");
@@ -188,7 +187,7 @@
std::vector<std::string> tokens = tokenize(fdump);
unsigned declcount = 0;
for (auto t : tokens)
- if (t == "@llvm.dbg.declare(metadata")
+ if (t == "#dbg_declare(ptr")
declcount += 1;
// seven formals and six locals => 13 var decls
@@ -210,11 +209,11 @@
h.mkLocal("x", bu32t);
DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
- define void @foo(i8* nest %nest.0) #0 !dbg !4 {
- entry:
- %x = alloca i32, align 4
- ret void, !dbg !10
- }
+ define void @foo(ptr nest %nest.0) #0 !dbg !4 {
+ entry:
+ %x = alloca i32, align 4
+ ret void, !dbg !10
+ }
)RAW_RESULT");
bool broken = h.finish(PreserveDebugInfo);
diff --git a/unittests/BackendCore/BackendExprTests.cpp b/unittests/BackendCore/BackendExprTests.cpp
index a476f06..5ead97e 100644
--- a/unittests/BackendCore/BackendExprTests.cpp
+++ b/unittests/BackendCore/BackendExprTests.cpp
@@ -196,7 +196,7 @@
Btype *pbt = be->pointer_type(bt);
Bexpression *bpzero = be->zero_expression(pbt);
ASSERT_TRUE(bpzero != nullptr);
- EXPECT_EQ(repr(bpzero->value()), "i8* null");
+ EXPECT_EQ(repr(bpzero->value()), "ptr null");
Btype *bi32t = be->integer_type(false, 32);
Btype *s2t = mkBackendStruct(be, pbt, "f1", bi32t, "f2", nullptr);
Bexpression *bszero = be->zero_expression(s2t);
@@ -244,10 +244,9 @@
h.mkAssign(fex, mkInt32Const(be, 22));
DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
- store i64 0, i64* %x, align 8
- %cast.0 = bitcast i64* %x to { i32, i32 }*
- %field.0 = getelementptr inbounds { i32, i32 }, { i32, i32 }* %cast.0, i32 0, i32 1
- store i32 22, i32* %field.0, align 4
+ store i64 0, ptr %x, align 8
+ %field.0 = getelementptr inbounds { i32, i32 }, ptr %x, i32 0, i32 1
+ store i32 22, ptr %field.0, align 4
)RAW_RESULT");
bool isOK = h.expectBlock(exp);
@@ -295,14 +294,13 @@
}
DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
- %param3.ld.0 = load i64*, i64** %param3.addr, align 8
- %cast.0 = bitcast i64* %param3.ld.0 to i32*
- store i32 5, i32* %cast.0, align 4
- store double 0.000000e+00, double* %p, align 8
- %p.ld.0 = load double, double* %p, align 8
+ %param3.ld.0 = load ptr, ptr %param3.addr, align 8
+ store i32 5, ptr %param3.ld.0, align 4
+ store double 0.000000e+00, ptr %p, align 8
+ %p.ld.0 = load double, ptr %p, align 8
%ftoui.0 = fptoui double %p.ld.0 to i64
- %itpcast.0 = inttoptr i64 %ftoui.0 to i32*
- store i32 5, i32* %itpcast.0, align 4
+ %itpcast.0 = inttoptr i64 %ftoui.0 to ptr
+ store i32 5, ptr %itpcast.0, align 4
)RAW_RESULT");
bool isOK = h.expectBlock(exp);
@@ -354,92 +352,92 @@
}
DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
- %p1.ld.0 = load double, double* %p1.addr, align 8
+ %p1.ld.0 = load double, ptr %p1.addr, align 8
%fptrunc.0 = fptrunc double %p1.ld.0 to float
- store float %fptrunc.0, float* %p0.addr, align 4
- %p0.ld.0 = load float, float* %p0.addr, align 4
+ store float %fptrunc.0, ptr %p0.addr, align 4
+ %p0.ld.0 = load float, ptr %p0.addr, align 4
%fpext.0 = fpext float %p0.ld.0 to double
- store double %fpext.0, double* %p1.addr, align 8
- %p2.ld.0 = load i32, i32* %p2.addr, align 4
+ store double %fpext.0, ptr %p1.addr, align 8
+ %p2.ld.0 = load i32, ptr %p2.addr, align 4
%sitof.0 = sitofp i32 %p2.ld.0 to float
- store float %sitof.0, float* %p0.addr, align 4
- %p0.ld.1 = load float, float* %p0.addr, align 4
+ store float %sitof.0, ptr %p0.addr, align 4
+ %p0.ld.1 = load float, ptr %p0.addr, align 4
%ftosi.0 = fptosi float %p0.ld.1 to i32
- store i32 %ftosi.0, i32* %p2.addr, align 4
- %p2.ld.1 = load i32, i32* %p2.addr, align 4
+ store i32 %ftosi.0, ptr %p2.addr, align 4
+ %p2.ld.1 = load i32, ptr %p2.addr, align 4
%sitof.1 = sitofp i32 %p2.ld.1 to double
- store double %sitof.1, double* %p1.addr, align 8
- %p1.ld.1 = load double, double* %p1.addr, align 8
+ store double %sitof.1, ptr %p1.addr, align 8
+ %p1.ld.1 = load double, ptr %p1.addr, align 8
%ftosi.1 = fptosi double %p1.ld.1 to i32
- store i32 %ftosi.1, i32* %p2.addr, align 4
- %p3.ld.0 = load i64, i64* %p3.addr, align 8
+ store i32 %ftosi.1, ptr %p2.addr, align 4
+ %p3.ld.0 = load i64, ptr %p3.addr, align 8
%sitof.2 = sitofp i64 %p3.ld.0 to float
- store float %sitof.2, float* %p0.addr, align 4
- %p0.ld.2 = load float, float* %p0.addr, align 4
+ store float %sitof.2, ptr %p0.addr, align 4
+ %p0.ld.2 = load float, ptr %p0.addr, align 4
%ftosi.2 = fptosi float %p0.ld.2 to i64
- store i64 %ftosi.2, i64* %p3.addr, align 8
- %p3.ld.1 = load i64, i64* %p3.addr, align 8
+ store i64 %ftosi.2, ptr %p3.addr, align 8
+ %p3.ld.1 = load i64, ptr %p3.addr, align 8
%sitof.3 = sitofp i64 %p3.ld.1 to double
- store double %sitof.3, double* %p1.addr, align 8
- %p1.ld.2 = load double, double* %p1.addr, align 8
+ store double %sitof.3, ptr %p1.addr, align 8
+ %p1.ld.2 = load double, ptr %p1.addr, align 8
%ftosi.3 = fptosi double %p1.ld.2 to i64
- store i64 %ftosi.3, i64* %p3.addr, align 8
- %p3.ld.2 = load i64, i64* %p3.addr, align 8
+ store i64 %ftosi.3, ptr %p3.addr, align 8
+ %p3.ld.2 = load i64, ptr %p3.addr, align 8
%trunc.0 = trunc i64 %p3.ld.2 to i32
- store i32 %trunc.0, i32* %p2.addr, align 4
- %p2.ld.2 = load i32, i32* %p2.addr, align 4
+ store i32 %trunc.0, ptr %p2.addr, align 4
+ %p2.ld.2 = load i32, ptr %p2.addr, align 4
%sext.0 = sext i32 %p2.ld.2 to i64
- store i64 %sext.0, i64* %p3.addr, align 8
- %p4.ld.0 = load i32, i32* %p4.addr, align 4
+ store i64 %sext.0, ptr %p3.addr, align 8
+ %p4.ld.0 = load i32, ptr %p4.addr, align 4
%uitof.0 = uitofp i32 %p4.ld.0 to float
- store float %uitof.0, float* %p0.addr, align 4
- %p0.ld.3 = load float, float* %p0.addr, align 4
+ store float %uitof.0, ptr %p0.addr, align 4
+ %p0.ld.3 = load float, ptr %p0.addr, align 4
%ftoui.0 = fptoui float %p0.ld.3 to i32
- store i32 %ftoui.0, i32* %p4.addr, align 4
- %p4.ld.1 = load i32, i32* %p4.addr, align 4
+ store i32 %ftoui.0, ptr %p4.addr, align 4
+ %p4.ld.1 = load i32, ptr %p4.addr, align 4
%uitof.1 = uitofp i32 %p4.ld.1 to double
- store double %uitof.1, double* %p1.addr, align 8
- %p1.ld.3 = load double, double* %p1.addr, align 8
+ store double %uitof.1, ptr %p1.addr, align 8
+ %p1.ld.3 = load double, ptr %p1.addr, align 8
%ftoui.1 = fptoui double %p1.ld.3 to i32
- store i32 %ftoui.1, i32* %p4.addr, align 4
- %p4.ld.2 = load i32, i32* %p4.addr, align 4
- store i32 %p4.ld.2, i32* %p2.addr, align 4
- %p2.ld.3 = load i32, i32* %p2.addr, align 4
- store i32 %p2.ld.3, i32* %p4.addr, align 4
- %p4.ld.3 = load i32, i32* %p4.addr, align 4
+ store i32 %ftoui.1, ptr %p4.addr, align 4
+ %p4.ld.2 = load i32, ptr %p4.addr, align 4
+ store i32 %p4.ld.2, ptr %p2.addr, align 4
+ %p2.ld.3 = load i32, ptr %p2.addr, align 4
+ store i32 %p2.ld.3, ptr %p4.addr, align 4
+ %p4.ld.3 = load i32, ptr %p4.addr, align 4
%zext.0 = zext i32 %p4.ld.3 to i64
- store i64 %zext.0, i64* %p3.addr, align 8
- %p3.ld.3 = load i64, i64* %p3.addr, align 8
+ store i64 %zext.0, ptr %p3.addr, align 8
+ %p3.ld.3 = load i64, ptr %p3.addr, align 8
%trunc.1 = trunc i64 %p3.ld.3 to i32
- store i32 %trunc.1, i32* %p4.addr, align 4
- %p5.ld.0 = load i64, i64* %p5.addr, align 8
+ store i32 %trunc.1, ptr %p4.addr, align 4
+ %p5.ld.0 = load i64, ptr %p5.addr, align 8
%uitof.2 = uitofp i64 %p5.ld.0 to float
- store float %uitof.2, float* %p0.addr, align 4
- %p0.ld.4 = load float, float* %p0.addr, align 4
+ store float %uitof.2, ptr %p0.addr, align 4
+ %p0.ld.4 = load float, ptr %p0.addr, align 4
%ftoui.2 = fptoui float %p0.ld.4 to i64
- store i64 %ftoui.2, i64* %p5.addr, align 8
- %p5.ld.1 = load i64, i64* %p5.addr, align 8
+ store i64 %ftoui.2, ptr %p5.addr, align 8
+ %p5.ld.1 = load i64, ptr %p5.addr, align 8
%uitof.3 = uitofp i64 %p5.ld.1 to double
- store double %uitof.3, double* %p1.addr, align 8
- %p1.ld.4 = load double, double* %p1.addr, align 8
+ store double %uitof.3, ptr %p1.addr, align 8
+ %p1.ld.4 = load double, ptr %p1.addr, align 8
%ftoui.3 = fptoui double %p1.ld.4 to i64
- store i64 %ftoui.3, i64* %p5.addr, align 8
- %p5.ld.2 = load i64, i64* %p5.addr, align 8
+ store i64 %ftoui.3, ptr %p5.addr, align 8
+ %p5.ld.2 = load i64, ptr %p5.addr, align 8
%trunc.2 = trunc i64 %p5.ld.2 to i32
- store i32 %trunc.2, i32* %p2.addr, align 4
- %p2.ld.4 = load i32, i32* %p2.addr, align 4
+ store i32 %trunc.2, ptr %p2.addr, align 4
+ %p2.ld.4 = load i32, ptr %p2.addr, align 4
%sext.1 = sext i32 %p2.ld.4 to i64
- store i64 %sext.1, i64* %p5.addr, align 8
- %p5.ld.3 = load i64, i64* %p5.addr, align 8
- store i64 %p5.ld.3, i64* %p3.addr, align 8
- %p3.ld.4 = load i64, i64* %p3.addr, align 8
- store i64 %p3.ld.4, i64* %p5.addr, align 8
- %p5.ld.4 = load i64, i64* %p5.addr, align 8
+ store i64 %sext.1, ptr %p5.addr, align 8
+ %p5.ld.3 = load i64, ptr %p5.addr, align 8
+ store i64 %p5.ld.3, ptr %p3.addr, align 8
+ %p3.ld.4 = load i64, ptr %p3.addr, align 8
+ store i64 %p3.ld.4, ptr %p5.addr, align 8
+ %p5.ld.4 = load i64, ptr %p5.addr, align 8
%trunc.3 = trunc i64 %p5.ld.4 to i32
- store i32 %trunc.3, i32* %p4.addr, align 4
- %p4.ld.4 = load i32, i32* %p4.addr, align 4
+ store i32 %trunc.3, ptr %p4.addr, align 4
+ %p4.ld.4 = load i32, ptr %p4.addr, align 4
%zext.1 = zext i32 %p4.ld.4 to i64
- store i64 %zext.1, i64* %p5.addr, align 8
+ store i64 %zext.1, ptr %p5.addr, align 8
)RAW_RESULT");
bool isOK = h.expectBlock(exp);
@@ -493,7 +491,7 @@
h.mkAssign(xvex4, convex4);
DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
- define void @foo(i8* nest %nest.0) #0 {
+ define void @foo(ptr nest %nest.0) #0 {
entry:
%tmp.3 = alloca { double, double }, align 8
%tmp.2 = alloca { float, float }, align 4
@@ -503,52 +501,36 @@
%b = alloca { float, float }, align 4
%x = alloca { double, double }, align 8
%y = alloca { double, double }, align 8
- %cast.0 = bitcast { float, float }* %a to i8*
- call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %cast.0, i8* align 4 bitcast ({ float, float }* @const.0 to i8*), i64 8, i1 false)
- %cast.1 = bitcast { float, float }* %b to i8*
- call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %cast.1, i8* align 4 bitcast ({ float, float }* @const.0 to i8*), i64 8, i1 false)
- %cast.2 = bitcast { double, double }* %x to i8*
- call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.2, i8* align 8 bitcast ({ double, double }* @const.1 to i8*), i64 16, i1 false)
- %cast.3 = bitcast { double, double }* %y to i8*
- call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.3, i8* align 8 bitcast ({ double, double }* @const.1 to i8*), i64 16, i1 false)
- %cast.4 = bitcast { double, double }* %tmp.0 to i8*
- %cast.5 = bitcast { double, double }* %x to i8*
- call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.4, i8* align 8 %cast.5, i64 16, i1 false)
- %field.0 = getelementptr inbounds { double, double }, { double, double }* %tmp.0, i32 0, i32 0
- %.real.ld.0 = load double, double* %field.0, align 8
+ call void @llvm.memcpy.p0.p0.i64(ptr align 4 %a, ptr align 4 @const.0, i64 8, i1 false)
+ call void @llvm.memcpy.p0.p0.i64(ptr align 4 %b, ptr align 4 @const.0, i64 8, i1 false)
+ call void @llvm.memcpy.p0.p0.i64(ptr align 8 %x, ptr align 8 @const.1, i64 16, i1 false)
+ call void @llvm.memcpy.p0.p0.i64(ptr align 8 %y, ptr align 8 @const.1, i64 16, i1 false)
+ call void @llvm.memcpy.p0.p0.i64(ptr align 8 %tmp.0, ptr align 8 %x, i64 16, i1 false)
+ %field.0 = getelementptr inbounds { double, double }, ptr %tmp.0, i32 0, i32 0
+ %.real.ld.0 = load double, ptr %field.0, align 8
%fptrunc.0 = fptrunc double %.real.ld.0 to float
- %field.1 = getelementptr inbounds { double, double }, { double, double }* %tmp.0, i32 0, i32 1
- %.imag.ld.0 = load double, double* %field.1, align 8
+ %field.1 = getelementptr inbounds { double, double }, ptr %tmp.0, i32 0, i32 1
+ %.imag.ld.0 = load double, ptr %field.1, align 8
%fptrunc.1 = fptrunc double %.imag.ld.0 to float
- %field.2 = getelementptr inbounds { float, float }, { float, float }* %tmp.1, i32 0, i32 0
- store float %fptrunc.0, float* %field.2, align 4
- %field.3 = getelementptr inbounds { float, float }, { float, float }* %tmp.1, i32 0, i32 1
- store float %fptrunc.1, float* %field.3, align 4
- %cast.6 = bitcast { float, float }* %a to i8*
- %cast.7 = bitcast { float, float }* %tmp.1 to i8*
- call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %cast.6, i8* align 4 %cast.7, i64 8, i1 false)
- %cast.8 = bitcast { float, float }* %tmp.2 to i8*
- %cast.9 = bitcast { float, float }* %b to i8*
- call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %cast.8, i8* align 4 %cast.9, i64 8, i1 false)
- %field.4 = getelementptr inbounds { float, float }, { float, float }* %tmp.2, i32 0, i32 0
- %.real.ld.1 = load float, float* %field.4, align 4
+ %field.2 = getelementptr inbounds { float, float }, ptr %tmp.1, i32 0, i32 0
+ store float %fptrunc.0, ptr %field.2, align 4
+ %field.3 = getelementptr inbounds { float, float }, ptr %tmp.1, i32 0, i32 1
+ store float %fptrunc.1, ptr %field.3, align 4
+ call void @llvm.memcpy.p0.p0.i64(ptr align 4 %a, ptr align 4 %tmp.1, i64 8, i1 false)
+ call void @llvm.memcpy.p0.p0.i64(ptr align 4 %tmp.2, ptr align 4 %b, i64 8, i1 false)
+ %field.4 = getelementptr inbounds { float, float }, ptr %tmp.2, i32 0, i32 0
+ %.real.ld.1 = load float, ptr %field.4, align 4
%fpext.0 = fpext float %.real.ld.1 to double
- %field.5 = getelementptr inbounds { float, float }, { float, float }* %tmp.2, i32 0, i32 1
- %.imag.ld.1 = load float, float* %field.5, align 4
+ %field.5 = getelementptr inbounds { float, float }, ptr %tmp.2, i32 0, i32 1
+ %.imag.ld.1 = load float, ptr %field.5, align 4
%fpext.1 = fpext float %.imag.ld.1 to double
- %field.6 = getelementptr inbounds { double, double }, { double, double }* %tmp.3, i32 0, i32 0
- store double %fpext.0, double* %field.6, align 8
- %field.7 = getelementptr inbounds { double, double }, { double, double }* %tmp.3, i32 0, i32 1
- store double %fpext.1, double* %field.7, align 8
- %cast.10 = bitcast { double, double }* %y to i8*
- %cast.11 = bitcast { double, double }* %tmp.3 to i8*
- call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.10, i8* align 8 %cast.11, i64 16, i1 false)
- %cast.12 = bitcast { float, float }* %a to i8*
- %cast.13 = bitcast { float, float }* %b to i8*
- call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %cast.12, i8* align 4 %cast.13, i64 8, i1 false)
- %cast.14 = bitcast { double, double }* %x to i8*
- %cast.15 = bitcast { double, double }* %y to i8*
- call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.14, i8* align 8 %cast.15, i64 16, i1 false)
+ %field.6 = getelementptr inbounds { double, double }, ptr %tmp.3, i32 0, i32 0
+ store double %fpext.0, ptr %field.6, align 8
+ %field.7 = getelementptr inbounds { double, double }, ptr %tmp.3, i32 0, i32 1
+ store double %fpext.1, ptr %field.7, align 8
+ call void @llvm.memcpy.p0.p0.i64(ptr align 8 %y, ptr align 8 %tmp.3, i64 16, i1 false)
+ call void @llvm.memcpy.p0.p0.i64(ptr align 4 %a, ptr align 4 %b, i64 8, i1 false)
+ call void @llvm.memcpy.p0.p0.i64(ptr align 8 %x, ptr align 8 %y, i64 16, i1 false)
ret void
}
)RAW_RESULT");
@@ -630,61 +612,61 @@
}
DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
- store i64 0, i64* %x, align 8
- store i64 0, i64* %y, align 8
- store double 0.000000e+00, double* %z, align 8
- %x.ld.0 = load i64, i64* %x, align 8
+ store i64 0, ptr %x, align 8
+ store i64 0, ptr %y, align 8
+ store double 0.000000e+00, ptr %z, align 8
+ %x.ld.0 = load i64, ptr %x, align 8
%icmp.0 = icmp eq i64 9, %x.ld.0
%zext.0 = zext i1 %icmp.0 to i8
- %x.ld.1 = load i64, i64* %x, align 8
+ %x.ld.1 = load i64, ptr %x, align 8
%icmp.1 = icmp ne i64 9, %x.ld.1
%zext.1 = zext i1 %icmp.1 to i8
- %x.ld.2 = load i64, i64* %x, align 8
+ %x.ld.2 = load i64, ptr %x, align 8
%icmp.2 = icmp slt i64 9, %x.ld.2
%zext.2 = zext i1 %icmp.2 to i8
- %x.ld.3 = load i64, i64* %x, align 8
+ %x.ld.3 = load i64, ptr %x, align 8
%icmp.3 = icmp sle i64 9, %x.ld.3
%zext.3 = zext i1 %icmp.3 to i8
- %x.ld.4 = load i64, i64* %x, align 8
+ %x.ld.4 = load i64, ptr %x, align 8
%icmp.4 = icmp sgt i64 9, %x.ld.4
%zext.4 = zext i1 %icmp.4 to i8
- %x.ld.5 = load i64, i64* %x, align 8
+ %x.ld.5 = load i64, ptr %x, align 8
%icmp.5 = icmp sge i64 9, %x.ld.5
%zext.5 = zext i1 %icmp.5 to i8
- %y.ld.0 = load i64, i64* %y, align 8
+ %y.ld.0 = load i64, ptr %y, align 8
%icmp.6 = icmp eq i64 9, %y.ld.0
%zext.6 = zext i1 %icmp.6 to i8
- %y.ld.1 = load i64, i64* %y, align 8
+ %y.ld.1 = load i64, ptr %y, align 8
%icmp.7 = icmp ne i64 9, %y.ld.1
%zext.7 = zext i1 %icmp.7 to i8
- %y.ld.2 = load i64, i64* %y, align 8
+ %y.ld.2 = load i64, ptr %y, align 8
%icmp.8 = icmp ult i64 9, %y.ld.2
%zext.8 = zext i1 %icmp.8 to i8
- %y.ld.3 = load i64, i64* %y, align 8
+ %y.ld.3 = load i64, ptr %y, align 8
%icmp.9 = icmp ule i64 9, %y.ld.3
%zext.9 = zext i1 %icmp.9 to i8
- %y.ld.4 = load i64, i64* %y, align 8
+ %y.ld.4 = load i64, ptr %y, align 8
%icmp.10 = icmp ugt i64 9, %y.ld.4
%zext.10 = zext i1 %icmp.10 to i8
- %y.ld.5 = load i64, i64* %y, align 8
+ %y.ld.5 = load i64, ptr %y, align 8
%icmp.11 = icmp uge i64 9, %y.ld.5
%zext.11 = zext i1 %icmp.11 to i8
- %z.ld.0 = load double, double* %z, align 8
+ %z.ld.0 = load double, ptr %z, align 8
%fcmp.0 = fcmp oeq double 9.000000e+00, %z.ld.0
%zext.12 = zext i1 %fcmp.0 to i8
- %z.ld.1 = load double, double* %z, align 8
+ %z.ld.1 = load double, ptr %z, align 8
%fcmp.1 = fcmp une double 9.000000e+00, %z.ld.1
%zext.13 = zext i1 %fcmp.1 to i8
- %z.ld.2 = load double, double* %z, align 8
+ %z.ld.2 = load double, ptr %z, align 8
%fcmp.2 = fcmp olt double 9.000000e+00, %z.ld.2
%zext.14 = zext i1 %fcmp.2 to i8
- %z.ld.3 = load double, double* %z, align 8
+ %z.ld.3 = load double, ptr %z, align 8
%fcmp.3 = fcmp ole double 9.000000e+00, %z.ld.3
%zext.15 = zext i1 %fcmp.3 to i8
- %z.ld.4 = load double, double* %z, align 8
+ %z.ld.4 = load double, ptr %z, align 8
%fcmp.4 = fcmp ogt double 9.000000e+00, %z.ld.4
%zext.16 = zext i1 %fcmp.4 to i8
- %z.ld.5 = load double, double* %z, align 8
+ %z.ld.5 = load double, ptr %z, align 8
%fcmp.5 = fcmp oge double 9.000000e+00, %z.ld.5
%zext.17 = zext i1 %fcmp.5 to i8
)RAW_RESULT");
@@ -727,15 +709,15 @@
}
DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
- store i64 0, i64* %x, align 8
- store double 0.000000e+00, double* %y, align 8
- %x.ld.0 = load i64, i64* %x, align 8
+ store i64 0, ptr %x, align 8
+ store double 0.000000e+00, ptr %y, align 8
+ %x.ld.0 = load i64, ptr %x, align 8
%add.0 = add i64 9, %x.ld.0
- %x.ld.1 = load i64, i64* %x, align 8
+ %x.ld.1 = load i64, ptr %x, align 8
%sub.0 = sub i64 9, %x.ld.1
- %y.ld.0 = load double, double* %y, align 8
+ %y.ld.0 = load double, ptr %y, align 8
%fadd.0 = fadd double 9.000000e+00, %y.ld.0
- %y.ld.1 = load double, double* %y, align 8
+ %y.ld.1 = load double, ptr %y, align 8
%fsub.0 = fsub double 9.000000e+00, %y.ld.1
)RAW_RESULT");
@@ -769,16 +751,16 @@
h.mkAssign(vex, ypzpw);
DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
- store i64 0, i64* %x, align 8
- store i64 9, i64* %y, align 8
- store i64 10, i64* %z, align 8
- store i64 11, i64* %w, align 8
- %y.ld.0 = load i64, i64* %y, align 8
- %z.ld.0 = load i64, i64* %z, align 8
+ store i64 0, ptr %x, align 8
+ store i64 9, ptr %y, align 8
+ store i64 10, ptr %z, align 8
+ store i64 11, ptr %w, align 8
+ %y.ld.0 = load i64, ptr %y, align 8
+ %z.ld.0 = load i64, ptr %z, align 8
%add.0 = add i64 %y.ld.0, %z.ld.0
- %w.ld.0 = load i64, i64* %w, align 8
+ %w.ld.0 = load i64, ptr %w, align 8
%add.1 = add i64 %add.0, %w.ld.0
- store i64 %add.1, i64* %x, align 8
+ store i64 %add.1, ptr %x, align 8
)RAW_RESULT");
bool isOK = h.expectBlock(exp);
@@ -825,65 +807,65 @@
}
DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
- store i64 0, i64* %x, align 8
- store i64 0, i64* %y, align 8
- store i8 0, i8* %z, align 1
- store i64 0, i64* %x2, align 8
- store i64 0, i64* %y2, align 8
- store i8 0, i8* %z2, align 1
- %x.ld.0 = load i64, i64* %x, align 8
- %x2.ld.0 = load i64, i64* %x2, align 8
+ store i64 0, ptr %x, align 8
+ store i64 0, ptr %y, align 8
+ store i8 0, ptr %z, align 1
+ store i64 0, ptr %x2, align 8
+ store i64 0, ptr %y2, align 8
+ store i8 0, ptr %z2, align 1
+ %x.ld.0 = load i64, ptr %x, align 8
+ %x2.ld.0 = load i64, ptr %x2, align 8
%iand.0 = and i64 %x.ld.0, %x2.ld.0
- %x.ld.1 = load i64, i64* %x, align 8
- %x2.ld.1 = load i64, i64* %x2, align 8
+ %x.ld.1 = load i64, ptr %x, align 8
+ %x2.ld.1 = load i64, ptr %x2, align 8
%ior.0 = or i64 %x.ld.1, %x2.ld.1
- %x.ld.2 = load i64, i64* %x, align 8
- %x2.ld.2 = load i64, i64* %x2, align 8
+ %x.ld.2 = load i64, ptr %x, align 8
+ %x2.ld.2 = load i64, ptr %x2, align 8
%iand.1 = and i64 %x.ld.2, %x2.ld.2
- %x.ld.3 = load i64, i64* %x, align 8
- %x2.ld.3 = load i64, i64* %x2, align 8
+ %x.ld.3 = load i64, ptr %x, align 8
+ %x2.ld.3 = load i64, ptr %x2, align 8
%ior.1 = or i64 %x.ld.3, %x2.ld.3
- %x.ld.4 = load i64, i64* %x, align 8
- %x2.ld.4 = load i64, i64* %x2, align 8
+ %x.ld.4 = load i64, ptr %x, align 8
+ %x2.ld.4 = load i64, ptr %x2, align 8
%xor.0 = xor i64 %x.ld.4, %x2.ld.4
- %x.ld.5 = load i64, i64* %x, align 8
- %x2.ld.5 = load i64, i64* %x2, align 8
+ %x.ld.5 = load i64, ptr %x, align 8
+ %x2.ld.5 = load i64, ptr %x2, align 8
%iand.2 = and i64 %x.ld.5, %x2.ld.5
- %y.ld.0 = load i64, i64* %y, align 8
- %y2.ld.0 = load i64, i64* %y2, align 8
+ %y.ld.0 = load i64, ptr %y, align 8
+ %y2.ld.0 = load i64, ptr %y2, align 8
%iand.3 = and i64 %y.ld.0, %y2.ld.0
- %y.ld.1 = load i64, i64* %y, align 8
- %y2.ld.1 = load i64, i64* %y2, align 8
+ %y.ld.1 = load i64, ptr %y, align 8
+ %y2.ld.1 = load i64, ptr %y2, align 8
%ior.2 = or i64 %y.ld.1, %y2.ld.1
- %y.ld.2 = load i64, i64* %y, align 8
- %y2.ld.2 = load i64, i64* %y2, align 8
+ %y.ld.2 = load i64, ptr %y, align 8
+ %y2.ld.2 = load i64, ptr %y2, align 8
%iand.4 = and i64 %y.ld.2, %y2.ld.2
- %y.ld.3 = load i64, i64* %y, align 8
- %y2.ld.3 = load i64, i64* %y2, align 8
+ %y.ld.3 = load i64, ptr %y, align 8
+ %y2.ld.3 = load i64, ptr %y2, align 8
%ior.3 = or i64 %y.ld.3, %y2.ld.3
- %y.ld.4 = load i64, i64* %y, align 8
- %y2.ld.4 = load i64, i64* %y2, align 8
+ %y.ld.4 = load i64, ptr %y, align 8
+ %y2.ld.4 = load i64, ptr %y2, align 8
%xor.1 = xor i64 %y.ld.4, %y2.ld.4
- %y.ld.5 = load i64, i64* %y, align 8
- %y2.ld.5 = load i64, i64* %y2, align 8
+ %y.ld.5 = load i64, ptr %y, align 8
+ %y2.ld.5 = load i64, ptr %y2, align 8
%iand.5 = and i64 %y.ld.5, %y2.ld.5
- %z.ld.0 = load i8, i8* %z, align 1
- %z2.ld.0 = load i8, i8* %z2, align 1
+ %z.ld.0 = load i8, ptr %z, align 1
+ %z2.ld.0 = load i8, ptr %z2, align 1
%iand.6 = and i8 %z.ld.0, %z2.ld.0
- %z.ld.1 = load i8, i8* %z, align 1
- %z2.ld.1 = load i8, i8* %z2, align 1
+ %z.ld.1 = load i8, ptr %z, align 1
+ %z2.ld.1 = load i8, ptr %z2, align 1
%ior.4 = or i8 %z.ld.1, %z2.ld.1
- %z.ld.2 = load i8, i8* %z, align 1
- %z2.ld.2 = load i8, i8* %z2, align 1
+ %z.ld.2 = load i8, ptr %z, align 1
+ %z2.ld.2 = load i8, ptr %z2, align 1
%iand.7 = and i8 %z.ld.2, %z2.ld.2
- %z.ld.3 = load i8, i8* %z, align 1
- %z2.ld.3 = load i8, i8* %z2, align 1
+ %z.ld.3 = load i8, ptr %z, align 1
+ %z2.ld.3 = load i8, ptr %z2, align 1
%ior.5 = or i8 %z.ld.3, %z2.ld.3
- %z.ld.4 = load i8, i8* %z, align 1
- %z2.ld.4 = load i8, i8* %z2, align 1
+ %z.ld.4 = load i8, ptr %z, align 1
+ %z2.ld.4 = load i8, ptr %z2, align 1
%xor.2 = xor i8 %z.ld.4, %z2.ld.4
- %z.ld.5 = load i8, i8* %z, align 1
- %z2.ld.5 = load i8, i8* %z2, align 1
+ %z.ld.5 = load i8, ptr %z, align 1
+ %z2.ld.5 = load i8, ptr %z2, align 1
%iand.8 = and i8 %z.ld.5, %z2.ld.5
)RAW_RESULT");
@@ -931,24 +913,24 @@
}
DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
- store i16 0, i16* %x, align 2
- store i16 0, i16* %y, align 2
- store double 0.000000e+00, double* %z, align 8
- %x.ld.0 = load i16, i16* %x, align 2
+ store i16 0, ptr %x, align 2
+ store i16 0, ptr %y, align 2
+ store double 0.000000e+00, ptr %z, align 8
+ %x.ld.0 = load i16, ptr %x, align 2
%mul.0 = mul i16 -17, %x.ld.0
- %x.ld.1 = load i16, i16* %x, align 2
+ %x.ld.1 = load i16, ptr %x, align 2
%div.0 = sdiv i16 -17, %x.ld.1
- %x.ld.2 = load i16, i16* %x, align 2
+ %x.ld.2 = load i16, ptr %x, align 2
%mod.0 = srem i16 -17, %x.ld.2
- %y.ld.0 = load i16, i16* %y, align 2
+ %y.ld.0 = load i16, ptr %y, align 2
%mul.1 = mul i16 13, %y.ld.0
- %y.ld.1 = load i16, i16* %y, align 2
+ %y.ld.1 = load i16, ptr %y, align 2
%div.1 = udiv i16 13, %y.ld.1
- %y.ld.2 = load i16, i16* %y, align 2
+ %y.ld.2 = load i16, ptr %y, align 2
%mod.1 = urem i16 13, %y.ld.2
- %z.ld.0 = load double, double* %z, align 8
+ %z.ld.0 = load double, ptr %z, align 8
%fmul.0 = fmul double 9.000000e+00, %z.ld.0
- %z.ld.1 = load double, double* %z, align 8
+ %z.ld.1 = load double, ptr %z, align 8
%fdiv.0 = fdiv double 9.000000e+00, %z.ld.1
)RAW_RESULT");
@@ -1011,28 +993,28 @@
}
DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
- store i64 0, i64* %x, align 8
- store i64 0, i64* %y, align 8
- store i64 0, i64* %s, align 8
- store i32 0, i32* %z, align 4
- %x.ld.0 = load i64, i64* %x, align 8
- %s.ld.0 = load i64, i64* %s, align 8
+ store i64 0, ptr %x, align 8
+ store i64 0, ptr %y, align 8
+ store i64 0, ptr %s, align 8
+ store i32 0, ptr %z, align 4
+ %x.ld.0 = load i64, ptr %x, align 8
+ %s.ld.0 = load i64, ptr %s, align 8
%shl.0 = shl i64 %x.ld.0, %s.ld.0
- %x.ld.1 = load i64, i64* %x, align 8
- %s.ld.1 = load i64, i64* %s, align 8
+ %x.ld.1 = load i64, ptr %x, align 8
+ %s.ld.1 = load i64, ptr %s, align 8
%shr.0 = ashr i64 %x.ld.1, %s.ld.1
- %y.ld.0 = load i64, i64* %y, align 8
- %s.ld.2 = load i64, i64* %s, align 8
+ %y.ld.0 = load i64, ptr %y, align 8
+ %s.ld.2 = load i64, ptr %s, align 8
%shl.1 = shl i64 %y.ld.0, %s.ld.2
- %y.ld.1 = load i64, i64* %y, align 8
- %s.ld.3 = load i64, i64* %s, align 8
+ %y.ld.1 = load i64, ptr %y, align 8
+ %s.ld.3 = load i64, ptr %s, align 8
%shr.1 = lshr i64 %y.ld.1, %s.ld.3
- %x.ld.2 = load i64, i64* %x, align 8
- %z.ld.0 = load i32, i32* %z, align 4
+ %x.ld.2 = load i64, ptr %x, align 8
+ %z.ld.0 = load i32, ptr %z, align 4
%zext.0 = zext i32 %z.ld.0 to i64
%shl.2 = shl i64 %x.ld.2, %zext.0
- %z.ld.1 = load i32, i32* %z, align 4
- %y.ld.2 = load i64, i64* %y, align 8
+ %z.ld.1 = load i32, ptr %z, align 4
+ %y.ld.2 = load i64, ptr %y, align 8
%trunc.0 = trunc i64 %y.ld.2 to i32
%shr.2 = lshr i32 %z.ld.1, %trunc.0
)RAW_RESULT");
@@ -1074,7 +1056,7 @@
}
DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
- define void @foo(i8* nest %nest.0) #0 {
+ define void @foo(ptr nest %nest.0) #0 {
entry:
%tmp.12 = alloca { double, double }, align 8
%tmp.11 = alloca { double, double }, align 8
@@ -1093,134 +1075,105 @@
%y = alloca { double, double }, align 8
%z = alloca { double, double }, align 8
%b = alloca i8, align 1
- %cast.0 = bitcast { double, double }* %x to i8*
- call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.0, i8* align 8 bitcast ({ double, double }* @const.0 to i8*), i64 16, i1 false)
- %cast.1 = bitcast { double, double }* %y to i8*
- call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.1, i8* align 8 bitcast ({ double, double }* @const.0 to i8*), i64 16, i1 false)
- %cast.2 = bitcast { double, double }* %z to i8*
- call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.2, i8* align 8 bitcast ({ double, double }* @const.0 to i8*), i64 16, i1 false)
- store i8 0, i8* %b, align 1
- %cast.3 = bitcast { double, double }* %tmp.0 to i8*
- %cast.4 = bitcast { double, double }* %x to i8*
- call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.3, i8* align 8 %cast.4, i64 16, i1 false)
- %cast.5 = bitcast { double, double }* %tmp.1 to i8*
- %cast.6 = bitcast { double, double }* %y to i8*
- call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.5, i8* align 8 %cast.6, i64 16, i1 false)
- %field.0 = getelementptr inbounds { double, double }, { double, double }* %tmp.0, i32 0, i32 0
- %.real.ld.0 = load double, double* %field.0, align 8
- %field.1 = getelementptr inbounds { double, double }, { double, double }* %tmp.1, i32 0, i32 0
- %.real.ld.1 = load double, double* %field.1, align 8
+ call void @llvm.memcpy.p0.p0.i64(ptr align 8 %x, ptr align 8 @const.0, i64 16, i1 false)
+ call void @llvm.memcpy.p0.p0.i64(ptr align 8 %y, ptr align 8 @const.0, i64 16, i1 false)
+ call void @llvm.memcpy.p0.p0.i64(ptr align 8 %z, ptr align 8 @const.0, i64 16, i1 false)
+ store i8 0, ptr %b, align 1
+ call void @llvm.memcpy.p0.p0.i64(ptr align 8 %tmp.0, ptr align 8 %x, i64 16, i1 false)
+ call void @llvm.memcpy.p0.p0.i64(ptr align 8 %tmp.1, ptr align 8 %y, i64 16, i1 false)
+ %field.0 = getelementptr inbounds { double, double }, ptr %tmp.0, i32 0, i32 0
+ %.real.ld.0 = load double, ptr %field.0, align 8
+ %field.1 = getelementptr inbounds { double, double }, ptr %tmp.1, i32 0, i32 0
+ %.real.ld.1 = load double, ptr %field.1, align 8
%fadd.0 = fadd double %.real.ld.0, %.real.ld.1
- %field.2 = getelementptr inbounds { double, double }, { double, double }* %tmp.0, i32 0, i32 1
- %.imag.ld.0 = load double, double* %field.2, align 8
- %field.3 = getelementptr inbounds { double, double }, { double, double }* %tmp.1, i32 0, i32 1
- %.imag.ld.1 = load double, double* %field.3, align 8
+ %field.2 = getelementptr inbounds { double, double }, ptr %tmp.0, i32 0, i32 1
+ %.imag.ld.0 = load double, ptr %field.2, align 8
+ %field.3 = getelementptr inbounds { double, double }, ptr %tmp.1, i32 0, i32 1
+ %.imag.ld.1 = load double, ptr %field.3, align 8
%fadd.1 = fadd double %.imag.ld.0, %.imag.ld.1
- %field.4 = getelementptr inbounds { double, double }, { double, double }* %tmp.2, i32 0, i32 0
- store double %fadd.0, double* %field.4, align 8
- %field.5 = getelementptr inbounds { double, double }, { double, double }* %tmp.2, i32 0, i32 1
- store double %fadd.1, double* %field.5, align 8
- %cast.7 = bitcast { double, double }* %z to i8*
- %cast.8 = bitcast { double, double }* %tmp.2 to i8*
- call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.7, i8* align 8 %cast.8, i64 16, i1 false)
- %cast.9 = bitcast { double, double }* %tmp.3 to i8*
- %cast.10 = bitcast { double, double }* %x to i8*
- call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.9, i8* align 8 %cast.10, i64 16, i1 false)
- %cast.11 = bitcast { double, double }* %tmp.4 to i8*
- %cast.12 = bitcast { double, double }* %y to i8*
- call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.11, i8* align 8 %cast.12, i64 16, i1 false)
- %field.6 = getelementptr inbounds { double, double }, { double, double }* %tmp.3, i32 0, i32 0
- %.real.ld.2 = load double, double* %field.6, align 8
- %field.7 = getelementptr inbounds { double, double }, { double, double }* %tmp.4, i32 0, i32 0
- %.real.ld.3 = load double, double* %field.7, align 8
+ %field.4 = getelementptr inbounds { double, double }, ptr %tmp.2, i32 0, i32 0
+ store double %fadd.0, ptr %field.4, align 8
+ %field.5 = getelementptr inbounds { double, double }, ptr %tmp.2, i32 0, i32 1
+ store double %fadd.1, ptr %field.5, align 8
+ call void @llvm.memcpy.p0.p0.i64(ptr align 8 %z, ptr align 8 %tmp.2, i64 16, i1 false)
+ call void @llvm.memcpy.p0.p0.i64(ptr align 8 %tmp.3, ptr align 8 %x, i64 16, i1 false)
+ call void @llvm.memcpy.p0.p0.i64(ptr align 8 %tmp.4, ptr align 8 %y, i64 16, i1 false)
+ %field.6 = getelementptr inbounds { double, double }, ptr %tmp.3, i32 0, i32 0
+ %.real.ld.2 = load double, ptr %field.6, align 8
+ %field.7 = getelementptr inbounds { double, double }, ptr %tmp.4, i32 0, i32 0
+ %.real.ld.3 = load double, ptr %field.7, align 8
%fsub.0 = fsub double %.real.ld.2, %.real.ld.3
- %field.8 = getelementptr inbounds { double, double }, { double, double }* %tmp.3, i32 0, i32 1
- %.imag.ld.2 = load double, double* %field.8, align 8
- %field.9 = getelementptr inbounds { double, double }, { double, double }* %tmp.4, i32 0, i32 1
- %.imag.ld.3 = load double, double* %field.9, align 8
+ %field.8 = getelementptr inbounds { double, double }, ptr %tmp.3, i32 0, i32 1
+ %.imag.ld.2 = load double, ptr %field.8, align 8
+ %field.9 = getelementptr inbounds { double, double }, ptr %tmp.4, i32 0, i32 1
+ %.imag.ld.3 = load double, ptr %field.9, align 8
%fsub.1 = fsub double %.imag.ld.2, %.imag.ld.3
- %field.10 = getelementptr inbounds { double, double }, { double, double }* %tmp.5, i32 0, i32 0
- store double %fsub.0, double* %field.10, align 8
- %field.11 = getelementptr inbounds { double, double }, { double, double }* %tmp.5, i32 0, i32 1
- store double %fsub.1, double* %field.11, align 8
- %cast.13 = bitcast { double, double }* %z to i8*
- %cast.14 = bitcast { double, double }* %tmp.5 to i8*
- call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.13, i8* align 8 %cast.14, i64 16, i1 false)
- %cast.15 = bitcast { double, double }* %tmp.6 to i8*
- %cast.16 = bitcast { double, double }* %x to i8*
- call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.15, i8* align 8 %cast.16, i64 16, i1 false)
- %cast.17 = bitcast { double, double }* %tmp.7 to i8*
- %cast.18 = bitcast { double, double }* %y to i8*
- call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.17, i8* align 8 %cast.18, i64 16, i1 false)
- %field.12 = getelementptr inbounds { double, double }, { double, double }* %tmp.6, i32 0, i32 0
- %.real.ld.4 = load double, double* %field.12, align 8
- %field.13 = getelementptr inbounds { double, double }, { double, double }* %tmp.7, i32 0, i32 0
- %.real.ld.5 = load double, double* %field.13, align 8
+ %field.10 = getelementptr inbounds { double, double }, ptr %tmp.5, i32 0, i32 0
+ store double %fsub.0, ptr %field.10, align 8
+ %field.11 = getelementptr inbounds { double, double }, ptr %tmp.5, i32 0, i32 1
+ store double %fsub.1, ptr %field.11, align 8
+ call void @llvm.memcpy.p0.p0.i64(ptr align 8 %z, ptr align 8 %tmp.5, i64 16, i1 false)
+ call void @llvm.memcpy.p0.p0.i64(ptr align 8 %tmp.6, ptr align 8 %x, i64 16, i1 false)
+ call void @llvm.memcpy.p0.p0.i64(ptr align 8 %tmp.7, ptr align 8 %y, i64 16, i1 false)
+ %field.12 = getelementptr inbounds { double, double }, ptr %tmp.6, i32 0, i32 0
+ %.real.ld.4 = load double, ptr %field.12, align 8
+ %field.13 = getelementptr inbounds { double, double }, ptr %tmp.7, i32 0, i32 0
+ %.real.ld.5 = load double, ptr %field.13, align 8
%fmul.0 = fmul double %.real.ld.4, %.real.ld.5
- %field.14 = getelementptr inbounds { double, double }, { double, double }* %tmp.6, i32 0, i32 1
- %.imag.ld.4 = load double, double* %field.14, align 8
- %field.15 = getelementptr inbounds { double, double }, { double, double }* %tmp.7, i32 0, i32 1
- %.imag.ld.5 = load double, double* %field.15, align 8
+ %field.14 = getelementptr inbounds { double, double }, ptr %tmp.6, i32 0, i32 1
+ %.imag.ld.4 = load double, ptr %field.14, align 8
+ %field.15 = getelementptr inbounds { double, double }, ptr %tmp.7, i32 0, i32 1
+ %.imag.ld.5 = load double, ptr %field.15, align 8
%fmul.1 = fmul double %.imag.ld.4, %.imag.ld.5
%fsub.2 = fsub double %fmul.0, %fmul.1
- %field.16 = getelementptr inbounds { double, double }, { double, double }* %tmp.6, i32 0, i32 0
- %.field.ld.0 = load double, double* %field.16, align 8
- %field.17 = getelementptr inbounds { double, double }, { double, double }* %tmp.7, i32 0, i32 1
- %.field.ld.1 = load double, double* %field.17, align 8
+ %field.16 = getelementptr inbounds { double, double }, ptr %tmp.6, i32 0, i32 0
+ %.field.ld.0 = load double, ptr %field.16, align 8
+ %field.17 = getelementptr inbounds { double, double }, ptr %tmp.7, i32 0, i32 1
+ %.field.ld.1 = load double, ptr %field.17, align 8
%fmul.2 = fmul double %.field.ld.0, %.field.ld.1
- %field.18 = getelementptr inbounds { double, double }, { double, double }* %tmp.6, i32 0, i32 1
- %.field.ld.2 = load double, double* %field.18, align 8
- %field.19 = getelementptr inbounds { double, double }, { double, double }* %tmp.7, i32 0, i32 0
- %.field.ld.3 = load double, double* %field.19, align 8
+ %field.18 = getelementptr inbounds { double, double }, ptr %tmp.6, i32 0, i32 1
+ %.field.ld.2 = load double, ptr %field.18, align 8
+ %field.19 = getelementptr inbounds { double, double }, ptr %tmp.7, i32 0, i32 0
+ %.field.ld.3 = load double, ptr %field.19, align 8
%fmul.3 = fmul double %.field.ld.2, %.field.ld.3
%fadd.2 = fadd double %fmul.2, %fmul.3
- %field.20 = getelementptr inbounds { double, double }, { double, double }* %tmp.8, i32 0, i32 0
- store double %fsub.2, double* %field.20, align 8
- %field.21 = getelementptr inbounds { double, double }, { double, double }* %tmp.8, i32 0, i32 1
- store double %fadd.2, double* %field.21, align 8
- %cast.19 = bitcast { double, double }* %z to i8*
- %cast.20 = bitcast { double, double }* %tmp.8 to i8*
- call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.19, i8* align 8 %cast.20, i64 16, i1 false)
- %cast.21 = bitcast { double, double }* %tmp.9 to i8*
- %cast.22 = bitcast { double, double }* %x to i8*
- call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.21, i8* align 8 %cast.22, i64 16, i1 false)
- %cast.23 = bitcast { double, double }* %tmp.10 to i8*
- %cast.24 = bitcast { double, double }* %y to i8*
- call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.23, i8* align 8 %cast.24, i64 16, i1 false)
- %field.22 = getelementptr inbounds { double, double }, { double, double }* %tmp.9, i32 0, i32 0
- %.real.ld.6 = load double, double* %field.22, align 8
- %field.23 = getelementptr inbounds { double, double }, { double, double }* %tmp.10, i32 0, i32 0
- %.real.ld.7 = load double, double* %field.23, align 8
+ %field.20 = getelementptr inbounds { double, double }, ptr %tmp.8, i32 0, i32 0
+ store double %fsub.2, ptr %field.20, align 8
+ %field.21 = getelementptr inbounds { double, double }, ptr %tmp.8, i32 0, i32 1
+ store double %fadd.2, ptr %field.21, align 8
+ call void @llvm.memcpy.p0.p0.i64(ptr align 8 %z, ptr align 8 %tmp.8, i64 16, i1 false)
+ call void @llvm.memcpy.p0.p0.i64(ptr align 8 %tmp.9, ptr align 8 %x, i64 16, i1 false)
+ call void @llvm.memcpy.p0.p0.i64(ptr align 8 %tmp.10, ptr align 8 %y, i64 16, i1 false)
+ %field.22 = getelementptr inbounds { double, double }, ptr %tmp.9, i32 0, i32 0
+ %.real.ld.6 = load double, ptr %field.22, align 8
+ %field.23 = getelementptr inbounds { double, double }, ptr %tmp.10, i32 0, i32 0
+ %.real.ld.7 = load double, ptr %field.23, align 8
%fcmp.0 = fcmp oeq double %.real.ld.6, %.real.ld.7
%zext.0 = zext i1 %fcmp.0 to i8
- %field.24 = getelementptr inbounds { double, double }, { double, double }* %tmp.9, i32 0, i32 1
- %.imag.ld.6 = load double, double* %field.24, align 8
- %field.25 = getelementptr inbounds { double, double }, { double, double }* %tmp.10, i32 0, i32 1
- %.imag.ld.7 = load double, double* %field.25, align 8
+ %field.24 = getelementptr inbounds { double, double }, ptr %tmp.9, i32 0, i32 1
+ %.imag.ld.6 = load double, ptr %field.24, align 8
+ %field.25 = getelementptr inbounds { double, double }, ptr %tmp.10, i32 0, i32 1
+ %.imag.ld.7 = load double, ptr %field.25, align 8
%fcmp.1 = fcmp oeq double %.imag.ld.6, %.imag.ld.7
%zext.1 = zext i1 %fcmp.1 to i8
%iand.0 = and i8 %zext.0, %zext.1
- store i8 %iand.0, i8* %b, align 1
- %cast.25 = bitcast { double, double }* %tmp.11 to i8*
- %cast.26 = bitcast { double, double }* %x to i8*
- call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.25, i8* align 8 %cast.26, i64 16, i1 false)
- %cast.27 = bitcast { double, double }* %tmp.12 to i8*
- %cast.28 = bitcast { double, double }* %y to i8*
- call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.27, i8* align 8 %cast.28, i64 16, i1 false)
- %field.26 = getelementptr inbounds { double, double }, { double, double }* %tmp.11, i32 0, i32 0
- %.real.ld.8 = load double, double* %field.26, align 8
- %field.27 = getelementptr inbounds { double, double }, { double, double }* %tmp.12, i32 0, i32 0
- %.real.ld.9 = load double, double* %field.27, align 8
+ store i8 %iand.0, ptr %b, align 1
+ call void @llvm.memcpy.p0.p0.i64(ptr align 8 %tmp.11, ptr align 8 %x, i64 16, i1 false)
+ call void @llvm.memcpy.p0.p0.i64(ptr align 8 %tmp.12, ptr align 8 %y, i64 16, i1 false)
+ %field.26 = getelementptr inbounds { double, double }, ptr %tmp.11, i32 0, i32 0
+ %.real.ld.8 = load double, ptr %field.26, align 8
+ %field.27 = getelementptr inbounds { double, double }, ptr %tmp.12, i32 0, i32 0
+ %.real.ld.9 = load double, ptr %field.27, align 8
%fcmp.2 = fcmp une double %.real.ld.8, %.real.ld.9
%zext.2 = zext i1 %fcmp.2 to i8
- %field.28 = getelementptr inbounds { double, double }, { double, double }* %tmp.11, i32 0, i32 1
- %.imag.ld.8 = load double, double* %field.28, align 8
- %field.29 = getelementptr inbounds { double, double }, { double, double }* %tmp.12, i32 0, i32 1
- %.imag.ld.9 = load double, double* %field.29, align 8
+ %field.28 = getelementptr inbounds { double, double }, ptr %tmp.11, i32 0, i32 1
+ %.imag.ld.8 = load double, ptr %field.28, align 8
+ %field.29 = getelementptr inbounds { double, double }, ptr %tmp.12, i32 0, i32 1
+ %.imag.ld.9 = load double, ptr %field.29, align 8
%fcmp.3 = fcmp une double %.imag.ld.8, %.imag.ld.9
%zext.3 = zext i1 %fcmp.3 to i8
%ior.0 = or i8 %zext.2, %zext.3
- store i8 %ior.0, i8* %b, align 1
+ store i8 %ior.0, ptr %b, align 1
ret void
}
)RAW_RESULT");
@@ -1266,22 +1219,21 @@
h.mkAssign(xvex3, compex);
DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
- store double 0.000000e+00, double* %a, align 8
- store double 0.000000e+00, double* %b, align 8
- %cast.0 = bitcast { double, double }* %x to i8*
- call addrspace(0) void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.0, i8* align 8 bitcast ({ double, double }* @const.0 to i8*), i64 16, i1 false)
- %field.0 = getelementptr inbounds { double, double }, { double, double }* %x, i32 0, i32 0
- %x.real.ld.0 = load double, double* %field.0, align 8
- store double %x.real.ld.0, double* %a, align 8
- %field.1 = getelementptr inbounds { double, double }, { double, double }* %x, i32 0, i32 1
- %x.imag.ld.0 = load double, double* %field.1, align 8
- store double %x.imag.ld.0, double* %b, align 8
- %b.ld.0 = load double, double* %b, align 8
- %a.ld.0 = load double, double* %a, align 8
- %field.2 = getelementptr inbounds { double, double }, { double, double }* %x, i32 0, i32 0
- store double %b.ld.0, double* %field.2, align 8
- %field.3 = getelementptr inbounds { double, double }, { double, double }* %x, i32 0, i32 1
- store double %a.ld.0, double* %field.3, align 8
+ store double 0.000000e+00, ptr %a, align 8
+ store double 0.000000e+00, ptr %b, align 8
+ call addrspace(0) void @llvm.memcpy.p0.p0.i64(ptr align 8 %x, ptr align 8 @const.0, i64 16, i1 false)
+ %field.0 = getelementptr inbounds { double, double }, ptr %x, i32 0, i32 0
+ %x.real.ld.0 = load double, ptr %field.0, align 8
+ store double %x.real.ld.0, ptr %a, align 8
+ %field.1 = getelementptr inbounds { double, double }, ptr %x, i32 0, i32 1
+ %x.imag.ld.0 = load double, ptr %field.1, align 8
+ store double %x.imag.ld.0, ptr %b, align 8
+ %b.ld.0 = load double, ptr %b, align 8
+ %a.ld.0 = load double, ptr %a, align 8
+ %field.2 = getelementptr inbounds { double, double }, ptr %x, i32 0, i32 0
+ store double %b.ld.0, ptr %field.2, align 8
+ %field.3 = getelementptr inbounds { double, double }, ptr %x, i32 0, i32 1
+ store double %a.ld.0, ptr %field.3, align 8
)RAW_RESULT");
bool isOK = h.expectBlock(exp);
@@ -1299,7 +1251,7 @@
{
Bexpression *snil = be->string_constant_expression("");
DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
- i8* null
+ ptr null
)RAW_RESULT");
bool isOK = h.expectValue(snil->value(), exp);
EXPECT_TRUE(isOK && "Value does not have expected contents");
@@ -1308,7 +1260,7 @@
{
Bexpression *sblah = be->string_constant_expression("blah");
DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
- i8* getelementptr inbounds ([5 x i8], [5 x i8]* @const.0, i32 0, i32 0)
+ @const.0 = private constant [5 x i8] c"blah\00", align 1
)RAW_RESULT");
bool isOK = h.expectValue(sblah->value(), exp);
EXPECT_TRUE(isOK && "Value does not have expected contents");
@@ -1342,28 +1294,28 @@
h.mkExprStmt(condex);
DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
- define void @foo(i8* nest %nest.0) #0 {
+ define void @foo(ptr nest %nest.0) #0 {
entry:
%a = alloca i64, align 8
%b = alloca i64, align 8
- store i64 0, i64* %a, align 8
- store i64 0, i64* %b, align 8
- %a.ld.0 = load i64, i64* %a, align 8
- %b.ld.0 = load i64, i64* %b, align 8
+ store i64 0, ptr %a, align 8
+ store i64 0, ptr %b, align 8
+ %a.ld.0 = load i64, ptr %a, align 8
+ %b.ld.0 = load i64, ptr %b, align 8
%icmp.0 = icmp slt i64 %a.ld.0, %b.ld.0
%zext.0 = zext i1 %icmp.0 to i8
%trunc.0 = trunc i8 %zext.0 to i1
br i1 %trunc.0, label %then.0, label %else.0
-
+
then.0: ; preds = %entry
- call void @foo(i8* nest undef)
+ call void @foo(ptr nest undef)
br label %fallthrough.0
-
+
fallthrough.0: ; preds = %else.0, %then.0
ret void
-
+
else.0: ; preds = %entry
- call void @foo(i8* nest undef)
+ call void @foo(ptr nest undef)
br label %fallthrough.0
}
)RAW_RESULT");
@@ -1399,24 +1351,24 @@
h.mkExprStmt(condex);
DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
- define void @foo(i8* nest %nest.0) #0 {
+ define void @foo(ptr nest %nest.0) #0 {
entry:
%a = alloca i64, align 8
%tmpv.0 = alloca i64, align 8
- store i64 0, i64* %a, align 8
+ store i64 0, ptr %a, align 8
br i1 true, label %then.0, label %else.0
-
+
then.0: ; preds = %entry
- call void @foo(i8* nest undef)
+ call void @foo(ptr nest undef)
br label %fallthrough.0
-
+
fallthrough.0: ; preds = %else.0, %then.0
- %tmpv.0.ld.0 = load i64, i64* %tmpv.0, align 8
+ %tmpv.0.ld.0 = load i64, ptr %tmpv.0, align 8
ret void
-
+
else.0: ; preds = %entry
- %a.ld.0 = load i64, i64* %a, align 8
- store i64 %a.ld.0, i64* %tmpv.0, align 8
+ %a.ld.0 = load i64, ptr %a, align 8
+ store i64 %a.ld.0, ptr %tmpv.0, align 8
br label %fallthrough.0
}
)RAW_RESULT");
@@ -1455,35 +1407,30 @@
h.mkLocal("a", s2t, cond);
DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
- define void @foo({ [16 x i32], i32 }* sret({ [16 x i32], i32 }) %sret.formal.0, i8* nest %nest.0, { [16 x i32], i32 }* byval({ [16 x i32], i32 }) %p0, i32 %p1) #0 {
- entry:
- %p1.addr = alloca i32, align 4
- %a = alloca { [16 x i32], i32 }, align 4
- %tmpv.0 = alloca { [16 x i32], i32 }, align 4
- store i32 %p1, i32* %p1.addr, align 4
- %p1.ld.0 = load i32, i32* %p1.addr, align 4
- %icmp.0 = icmp slt i32 %p1.ld.0, 7
- %zext.0 = zext i1 %icmp.0 to i8
- %trunc.0 = trunc i8 %zext.0 to i1
- br i1 %trunc.0, label %then.0, label %else.0
-
- then.0: ; preds = %entry
- %cast.0 = bitcast { [16 x i32], i32 }* %tmpv.0 to i8*
- %cast.1 = bitcast { [16 x i32], i32 }* %p0 to i8*
- call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %cast.0, i8* align 4 %cast.1, i64 68, i1 false)
- br label %fallthrough.0
-
- fallthrough.0: ; preds = %else.0, %then.0
- %cast.3 = bitcast { [16 x i32], i32 }* %a to i8*
- %cast.4 = bitcast { [16 x i32], i32 }* %tmpv.0 to i8*
- call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %cast.3, i8* align 4 %cast.4, i64 68, i1 false)
- ret void
-
- else.0: ; preds = %entry
- %cast.2 = bitcast { [16 x i32], i32 }* %tmpv.0 to i8*
- call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %cast.2, i8* align 4 bitcast ({ [16 x i32], i32 }* @const.0 to i8*), i64 68, i1 false)
- br label %fallthrough.0
- }
+ define void @foo(ptr sret({ [16 x i32], i32 }) %sret.formal.0, ptr nest %nest.0, ptr byval({ [16 x i32], i32 }) %p0, i32 %p1) #0 {
+ entry:
+ %p1.addr = alloca i32, align 4
+ %a = alloca { [16 x i32], i32 }, align 4
+ %tmpv.0 = alloca { [16 x i32], i32 }, align 4
+ store i32 %p1, ptr %p1.addr, align 4
+ %p1.ld.0 = load i32, ptr %p1.addr, align 4
+ %icmp.0 = icmp slt i32 %p1.ld.0, 7
+ %zext.0 = zext i1 %icmp.0 to i8
+ %trunc.0 = trunc i8 %zext.0 to i1
+ br i1 %trunc.0, label %then.0, label %else.0
+
+ then.0: ; preds = %entry
+ call void @llvm.memcpy.p0.p0.i64(ptr align 4 %tmpv.0, ptr align 4 %p0, i64 68, i1 false)
+ br label %fallthrough.0
+
+ fallthrough.0: ; preds = %else.0, %then.0
+ call void @llvm.memcpy.p0.p0.i64(ptr align 4 %a, ptr align 4 %tmpv.0, i64 68, i1 false)
+ ret void
+
+ else.0: ; preds = %entry
+ call void @llvm.memcpy.p0.p0.i64(ptr align 4 %tmpv.0, ptr align 4 @const.0, i64 68, i1 false)
+ br label %fallthrough.0
+ }
)RAW_RESULT");
bool broken = h.finish(StripDebugInfo);
@@ -1530,35 +1477,30 @@
h.mkLocal("a", s2t, cond);
DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
- define void @foo({ [16 x i32], i32 }* sret({ [16 x i32], i32 }) %sret.formal.0, i8* nest %nest.0, { [16 x i32], i32 }* %p0, i32 %p1) #0 {
- entry:
- %p1.addr = alloca i32, align 4
- %a = alloca { [16 x i32], i32 }, align 4
- %tmpv.0 = alloca { [16 x i32], i32 }, align 4
- store i32 %p1, i32* %p1.addr, align 4
- %p1.ld.0 = load i32, i32* %p1.addr, align 4
- %icmp.0 = icmp slt i32 %p1.ld.0, 7
- %zext.0 = zext i1 %icmp.0 to i8
- %trunc.0 = trunc i8 %zext.0 to i1
- br i1 %trunc.0, label %then.0, label %else.0
-
- then.0: ; preds = %entry
- %cast.0 = bitcast { [16 x i32], i32 }* %tmpv.0 to i8*
- %cast.1 = bitcast { [16 x i32], i32 }* %p0 to i8*
- call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %cast.0, i8* align 4 %cast.1, i64 68, i1 false)
- br label %fallthrough.0
-
- fallthrough.0: ; preds = %else.0, %then.0
- %cast.3 = bitcast { [16 x i32], i32 }* %a to i8*
- %cast.4 = bitcast { [16 x i32], i32 }* %tmpv.0 to i8*
- call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %cast.3, i8* align 4 %cast.4, i64 68, i1 false)
- ret void
-
- else.0: ; preds = %entry
- %cast.2 = bitcast { [16 x i32], i32 }* %tmpv.0 to i8*
- call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %cast.2, i8* align 4 bitcast ({ [16 x i32], i32 }* @const.0 to i8*), i64 68, i1 false)
- br label %fallthrough.0
- }
+ define void @foo(ptr sret({ [16 x i32], i32 }) %sret.formal.0, ptr nest %nest.0, ptr %p0, i32 %p1) #0 {
+ entry:
+ %p1.addr = alloca i32, align 4
+ %a = alloca { [16 x i32], i32 }, align 4
+ %tmpv.0 = alloca { [16 x i32], i32 }, align 4
+ store i32 %p1, ptr %p1.addr, align 4
+ %p1.ld.0 = load i32, ptr %p1.addr, align 4
+ %icmp.0 = icmp slt i32 %p1.ld.0, 7
+ %zext.0 = zext i1 %icmp.0 to i8
+ %trunc.0 = trunc i8 %zext.0 to i1
+ br i1 %trunc.0, label %then.0, label %else.0
+
+ then.0: ; preds = %entry
+ call void @llvm.memcpy.p0.p0.i64(ptr align 4 %tmpv.0, ptr align 4 %p0, i64 68, i1 false)
+ br label %fallthrough.0
+
+ fallthrough.0: ; preds = %else.0, %then.0
+ call void @llvm.memcpy.p0.p0.i64(ptr align 4 %a, ptr align 4 %tmpv.0, i64 68, i1 false)
+ ret void
+
+ else.0: ; preds = %entry
+ call void @llvm.memcpy.p0.p0.i64(ptr align 4 %tmpv.0, ptr align 4 @const.0, i64 68, i1 false)
+ br label %fallthrough.0
+ }
)RAW_RESULT");
bool broken = h.finish(StripDebugInfo);
@@ -1589,18 +1531,18 @@
h.addStmt(es);
DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
- define i64 @foo(i8* nest %nest.0, i32 %param1, i32 %param2, i64* %param3) #0 {
+ define i64 @foo(ptr nest %nest.0, i32 %param1, i32 %param2, ptr %param3) #0 {
entry:
%param1.addr = alloca i32, align 4
%param2.addr = alloca i32, align 4
- %param3.addr = alloca i64*, align 8
+ %param3.addr = alloca ptr, align 8
%x = alloca i64, align 8
- store i32 %param1, i32* %param1.addr, align 4
- store i32 %param2, i32* %param2.addr, align 4
- store i64* %param3, i64** %param3.addr, align 8
- store i64 0, i64* %x, align 8
- store i64 5, i64* %x, align 8
- %x.ld.0 = load i64, i64* %x, align 8
+ store i32 %param1, ptr %param1.addr, align 4
+ store i32 %param2, ptr %param2.addr, align 4
+ store ptr %param3, ptr %param3.addr, align 8
+ store i64 0, ptr %x, align 8
+ store i64 5, ptr %x, align 8
+ %x.ld.0 = load i64, ptr %x, align 8
ret i64 0
}
)RAW_RESULT");
@@ -1639,30 +1581,27 @@
h.addStmt(st2);
DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
- define i64 @foo(i8* nest %nest.0, i32 %param1, i32 %param2, i64* %param3) #0 {
+ define i64 @foo(ptr nest %nest.0, i32 %param1, i32 %param2, ptr %param3) #0 {
entry:
%tmp.0 = alloca { i64, i64 }, align 8
%param1.addr = alloca i32, align 4
%param2.addr = alloca i32, align 4
- %param3.addr = alloca i64*, align 8
+ %param3.addr = alloca ptr, align 8
%x = alloca i64, align 8
%y = alloca { i64, i64 }, align 8
- store i32 %param1, i32* %param1.addr, align 4
- store i32 %param2, i32* %param2.addr, align 4
- store i64* %param3, i64** %param3.addr, align 8
- store i64 0, i64* %x, align 8
- %cast.0 = bitcast { i64, i64 }* %y to i8*
- call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.0, i8* align 8 bitcast ({ i64, i64 }* @const.0 to i8*), i64 16, i1 false)
- store i64 5, i64* %x, align 8
- %x.ld.0 = load i64, i64* %x, align 8
- %x.ld.1 = load i64, i64* %x, align 8
- %field.0 = getelementptr inbounds { i64, i64 }, { i64, i64 }* %tmp.0, i32 0, i32 0
- store i64 %x.ld.0, i64* %field.0, align 8
- %field.1 = getelementptr inbounds { i64, i64 }, { i64, i64 }* %tmp.0, i32 0, i32 1
- store i64 %x.ld.1, i64* %field.1, align 8
- %cast.1 = bitcast { i64, i64 }* %y to i8*
- %cast.2 = bitcast { i64, i64 }* %tmp.0 to i8*
- call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.1, i8* align 8 %cast.2, i64 16, i1 false)
+ store i32 %param1, ptr %param1.addr, align 4
+ store i32 %param2, ptr %param2.addr, align 4
+ store ptr %param3, ptr %param3.addr, align 8
+ store i64 0, ptr %x, align 8
+ call void @llvm.memcpy.p0.p0.i64(ptr align 8 %y, ptr align 8 @const.0, i64 16, i1 false)
+ store i64 5, ptr %x, align 8
+ %x.ld.0 = load i64, ptr %x, align 8
+ %x.ld.1 = load i64, ptr %x, align 8
+ %field.0 = getelementptr inbounds { i64, i64 }, ptr %tmp.0, i32 0, i32 0
+ store i64 %x.ld.0, ptr %field.0, align 8
+ %field.1 = getelementptr inbounds { i64, i64 }, ptr %tmp.0, i32 0, i32 1
+ store i64 %x.ld.1, ptr %field.1, align 8
+ call void @llvm.memcpy.p0.p0.i64(ptr align 8 %y, ptr align 8 %tmp.0, i64 16, i1 false)
ret i64 0
}
)RAW_RESULT");
@@ -1701,32 +1640,32 @@
h.mkAssign(dex, mkInt32Const(be, 7));
DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
- define void @foo(i8* nest %nest.0, i32* %p0, i32* %p1) #0 {
+ define void @foo(ptr nest %nest.0, ptr %p0, ptr %p1) #0 {
entry:
- %p0.addr = alloca i32*, align 8
- %p1.addr = alloca i32*, align 8
- %tmpv.0 = alloca i32*, align 8
- store i32* %p0, i32** %p0.addr, align 8
- store i32* %p1, i32** %p1.addr, align 8
- %p0.ld.0 = load i32*, i32** %p0.addr, align 8
- %icmp.0 = icmp eq i32* %p0.ld.0, null
+ %p0.addr = alloca ptr, align 8
+ %p1.addr = alloca ptr, align 8
+ %tmpv.0 = alloca ptr, align 8
+ store ptr %p0, ptr %p0.addr, align 8
+ store ptr %p1, ptr %p1.addr, align 8
+ %p0.ld.0 = load ptr, ptr %p0.addr, align 8
+ %icmp.0 = icmp eq ptr %p0.ld.0, null
%zext.0 = zext i1 %icmp.0 to i8
%trunc.0 = trunc i8 %zext.0 to i1
br i1 %trunc.0, label %then.0, label %else.0
-
+
then.0: ; preds = %entry
- %p1.ld.0 = load i32*, i32** %p1.addr, align 8
- store i32* %p1.ld.0, i32** %tmpv.0, align 8
+ %p1.ld.0 = load ptr, ptr %p1.addr, align 8
+ store ptr %p1.ld.0, ptr %tmpv.0, align 8
br label %fallthrough.0
-
+
fallthrough.0: ; preds = %else.0, %then.0
- %tmpv.0.ld.0 = load i32*, i32** %tmpv.0, align 8
- store i32 7, i32* %tmpv.0.ld.0, align 4
+ %tmpv.0.ld.0 = load ptr, ptr %tmpv.0, align 8
+ store i32 7, ptr %tmpv.0.ld.0, align 4
ret void
-
+
else.0: ; preds = %entry
- %p0.ld.1 = load i32*, i32** %p0.addr, align 8
- store i32* %p0.ld.1, i32** %tmpv.0, align 8
+ %p0.ld.1 = load ptr, ptr %p0.addr, align 8
+ store ptr %p0.ld.1, ptr %tmpv.0, align 8
br label %fallthrough.0
}
)RAW_RESULT");
@@ -1774,24 +1713,24 @@
h.mkLocal("r", bf64t, be->unary_expression(OPERATOR_MINUS, veq, loc));
DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
- store i8 0, i8* %x, align 1
- %x.ld.0 = load i8, i8* %x, align 1
+ store i8 0, ptr %x, align 1
+ %x.ld.0 = load i8, ptr %x, align 1
%icmp.0 = icmp ne i8 %x.ld.0, 0
%xor.0 = xor i1 %icmp.0, true
%zext.0 = zext i1 %xor.0 to i8
- store i8 %zext.0, i8* %y, align 1
- store i32 0, i32* %a, align 4
- %a.ld.0 = load i32, i32* %a, align 4
+ store i8 %zext.0, ptr %y, align 1
+ store i32 0, ptr %a, align 4
+ %a.ld.0 = load i32, ptr %a, align 4
%sub.0 = sub i32 0, %a.ld.0
- store i32 %sub.0, i32* %b, align 4
- store i64 0, i64* %z, align 8
- %z.ld.0 = load i64, i64* %z, align 8
+ store i32 %sub.0, ptr %b, align 4
+ store i64 0, ptr %z, align 8
+ %z.ld.0 = load i64, ptr %z, align 8
%xor.1 = xor i64 %z.ld.0, -1
- store i64 %xor.1, i64* %w, align 8
- store double 0.000000e+00, double* %q, align 8
- %q.ld.0 = load double, double* %q, align 8
+ store i64 %xor.1, ptr %w, align 8
+ store double 0.000000e+00, ptr %q, align 8
+ %q.ld.0 = load double, ptr %q, align 8
%fsub.0 = fsub double -0.000000e+00, %q.ld.0
- store double %fsub.0, double* %r, align 8
+ store double %fsub.0, ptr %r, align 8
)RAW_RESULT");
bool isOK = h.expectBlock(exp);
@@ -1821,7 +1760,7 @@
h.mkExprStmt(call1);
DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
- call addrspace(0) void @foo(i8* nest undef, i8* null, i32* null, i64* null)
+ call addrspace(0) void @foo(ptr nest undef, ptr null, ptr null, ptr null)
)RAW_RESULT");
// Note that this
diff --git a/unittests/BackendCore/BackendFcnTests.cpp b/unittests/BackendCore/BackendFcnTests.cpp
index 2af5163..82a0d6f 100644
--- a/unittests/BackendCore/BackendFcnTests.cpp
+++ b/unittests/BackendCore/BackendFcnTests.cpp
@@ -298,8 +298,8 @@
h.mkExprStmt(call);
DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
- store i64 0, i64* %x, align 8
- %x.ld.0 = load i64, i64* %x, align 8
+ store i64 0, ptr %x, align 8
+ %x.ld.0 = load i64, ptr %x, align 8
%call.0 = call addrspace(0) i64 @llvm.cttz.i64(i64 %x.ld.0, i1 true)
)RAW_RESULT");
@@ -364,17 +364,11 @@
}
DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
- store i64 0, i64* %x, align 8
- store i64 10101, i64* %y, align 8
- %cast.0 = bitcast i64* %x to i8*
- %cast.1 = bitcast i64* %y to i8*
- %call.0 = call addrspace(0) i32 @memcmp(i8* %cast.0, i8* %cast.1, i64 8)
- %cast.2 = bitcast i64* %x to i8*
- %cast.3 = bitcast i64* %y to i8*
- call addrspace(0) void @llvm.memmove.p0i8.p0i8.i64(i8* %cast.2, i8* %cast.3, i64 8, i1 false)
- %cast.4 = bitcast i64* %y to i8*
- %cast.5 = bitcast i64* %x to i8*
- call addrspace(0) void @llvm.memcpy.p0i8.p0i8.i64(i8* %cast.4, i8* %cast.5, i64 8, i1 false)
+ store i64 0, ptr %x, align 8
+ store i64 10101, ptr %y, align 8
+ %call.0 = call addrspace(0) i32 @memcmp(ptr %x, ptr %y, i64 8)
+ call addrspace(0) void @llvm.memmove.p0.p0.i64(ptr %x, ptr %y, i64 8, i1 false)
+ call addrspace(0) void @llvm.memcpy.p0.p0.i64(ptr %y, ptr %x, i64 8, i1 false)
)RAW_RESULT");
bool isOK = h.expectBlock(exp);
@@ -425,10 +419,10 @@
h.mkLocal("y", bi32t, call32);
DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
- %call.0 = call addrspace(0) i64 @syscall(i8* nest undef, i64 64)
- store i64 %call.0, i64* %x, align 8
- %call.1 = call addrspace(0) i32 bitcast (i64 (i8*, i64)* @syscall to i32 (i8*, i32)*)(i8* nest undef, i32 32)
- store i32 %call.1, i32* %y, align 4
+ %call.0 = call addrspace(0) i64 @syscall(ptr nest undef, i64 64)
+ store i64 %call.0, ptr %x, align 8
+ %call.1 = call addrspace(0) i32 @syscall(ptr nest undef, i32 32)
+ store i32 %call.1, ptr %y, align 4
)RAW_RESULT");
bool isOK = h.expectBlock(exp);
@@ -498,14 +492,14 @@
h.mkLocal("y", bps1t, call4);
DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
- %call.0 = call addrspace(0) i32 @bar(i8* nest undef)
- store i32 %call.0, i32* %a, align 4
- %call.1 = call addrspace(0) i32 @bar(i8* nest undef)
- store i32 %call.1, i32* %b, align 4
- %call.2 = call addrspace(0) {}* bitcast ({ i32 }* (i8*)* @baz to {}* (i8*)*)(i8* nest undef)
- store {}* %call.2, {}** %x, align 8
- %call.3 = call addrspace(0) { i32 }* @baz(i8* nest undef)
- store { i32 }* %call.3, { i32 }** %y, align 8
+ %call.0 = call addrspace(0) i32 @bar(ptr nest undef)
+ store i32 %call.0, ptr %a, align 4
+ %call.1 = call addrspace(0) i32 @bar(ptr nest undef)
+ store i32 %call.1, ptr %b, align 4
+ %call.2 = call addrspace(0) ptr @baz(ptr nest undef)
+ store ptr %call.2, ptr %x, align 8
+ %call.3 = call addrspace(0) ptr @baz(ptr nest undef)
+ store ptr %call.3, ptr %y, align 8
)RAW_RESULT");
bool isOK = h.expectBlock(exp);
diff --git a/unittests/BackendCore/BackendNodeTests.cpp b/unittests/BackendCore/BackendNodeTests.cpp
index 13a3a5a..9a9396c 100644
--- a/unittests/BackendCore/BackendNodeTests.cpp
+++ b/unittests/BackendCore/BackendNodeTests.cpp
@@ -92,36 +92,36 @@
EXPECT_EQ(res1, matsub);
DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
- node - pre 18
- pre child + 18 15
- node + pre 15
- pre child const 15 1
+ node - pre 17
+ pre child + 17 14
+ node + pre 14
+ pre child const 14 1
node const pre 1
node const post 1
- post child const 15 1
- pre child deref 15 14
- node deref pre 14
- pre child var 14 8
+ post child const 14 1
+ pre child deref 14 13
+ node deref pre 13
+ pre child var 13 8
node var pre 8
node var post 8
- post child var 14 8
- node deref post 14
- post child deref 15 14
- node + post 15
- post child + 18 15
- pre child deref 18 17
- node deref pre 17
+ post child var 13 8
+ node deref post 13
+ post child deref 14 13
+ node + post 14
+ post child + 17 14
pre child deref 17 16
node deref pre 16
- pre child var 16 10
+ pre child deref 16 15
+ node deref pre 15
+ pre child var 15 10
node var pre 10
node var post 10
- post child var 16 10
+ post child var 15 10
+ node deref post 15
+ post child deref 16 15
node deref post 16
post child deref 17 16
- node deref post 17
- post child deref 18 17
- node - post 18
+ node - post 17
)RAW_RESULT");
std::string reason;
@@ -163,12 +163,12 @@
EXPECT_NE(add, matclone);
DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
- %x.ld.0 = load i32, i32* %x, align 4
- %z.ld.0 = load i16, i16* %z, align 2
+ %x.ld.0 = load i32, ptr %x, align 4
+ %z.ld.0 = load i16, ptr %z, align 2
%sext.0 = sext i16 %z.ld.0 to i32
%add.0 = add i32 %x.ld.0, %sext.0
- %y.ld.0 = load i32*, i32** %y, align 8
- %.ld.0 = load i32, i32* %y.ld.0, align 4
+ %y.ld.0 = load ptr, ptr %y, align 8
+ %.ld.0 = load i32, ptr %y.ld.0, align 4
%add.1 = add i32 %add.0, %.ld.0
)RAW_RESULT");
@@ -205,14 +205,14 @@
Bexpression *matadd = be->materialize(add);
DECLARE_EXPECTED_OUTPUT(exp2, R"RAW_RESULT(
- %field.0 = getelementptr inbounds { { i32*, i32 }, { i32*, i32 } }, { { i32*, i32 }, { i32*, i32 } }* %x, i32 0, i32 0
- %field.1 = getelementptr inbounds { i32*, i32 }, { i32*, i32 }* %field.0, i32 0, i32 0
- %x.field.field.ld.0 = load i32*, i32** %field.1, align 8
- %.ld.0 = load i32, i32* %x.field.field.ld.0, align 4
- %field.2 = getelementptr inbounds { { i32*, i32 }, { i32*, i32 } }, { { i32*, i32 }, { i32*, i32 } }* %x, i32 0, i32 0
- %field.3 = getelementptr inbounds { i32*, i32 }, { i32*, i32 }* %field.2, i32 0, i32 0
- %.field.field.ld.0 = load i32*, i32** %field.3, align 8
- %.ld.1 = load i32, i32* %.field.field.ld.0, align 4
+ %field.0 = getelementptr inbounds { { ptr, i32 }, { ptr, i32 } }, ptr %x, i32 0, i32 0
+ %field.1 = getelementptr inbounds { ptr, i32 }, ptr %field.0, i32 0, i32 0
+ %x.field.field.ld.0 = load ptr, ptr %field.1, align 8
+ %.ld.0 = load i32, ptr %x.field.field.ld.0, align 4
+ %field.2 = getelementptr inbounds { { ptr, i32 }, { ptr, i32 } }, ptr %x, i32 0, i32 0
+ %field.3 = getelementptr inbounds { ptr, i32 }, ptr %field.2, i32 0, i32 0
+ %.field.field.ld.0 = load ptr, ptr %field.3, align 8
+ %.ld.1 = load i32, ptr %.field.field.ld.0, align 4
%add.0 = add i32 %.ld.0, %.ld.1
)RAW_RESULT");
diff --git a/unittests/BackendCore/BackendPointerExprTests.cpp b/unittests/BackendCore/BackendPointerExprTests.cpp
index f5882ca..0de8d66 100644
--- a/unittests/BackendCore/BackendPointerExprTests.cpp
+++ b/unittests/BackendCore/BackendPointerExprTests.cpp
@@ -72,14 +72,14 @@
}
DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
- store i64 10, i64* %y, align 8
- store i64* null, i64** %x, align 8
- store i64* %y, i64** %x, align 8
- %x.ld.0 = load i64*, i64** %x, align 8
- %.ld.0 = load i64, i64* %x.ld.0, align 8
- store i64 %.ld.0, i64* %y, align 8
- %x.ld.1 = load i64*, i64** %x, align 8
- store i64 3, i64* %x.ld.1, align 8
+ store i64 10, ptr %y, align 8
+ store ptr null, ptr %x, align 8
+ store ptr %y, ptr %x, align 8
+ %x.ld.0 = load ptr, ptr %x, align 8
+ %.ld.0 = load i64, ptr %x.ld.0, align 8
+ store i64 %.ld.0, ptr %y, align 8
+ %x.ld.1 = load ptr, ptr %x, align 8
+ store i64 3, ptr %x.ld.1, align 8
)RAW_RESULT");
bool isOK = h.expectBlock(exp);
@@ -130,16 +130,13 @@
h.mkAssign(vex3, rvex3);
DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
- %cast.0 = bitcast { i64 }* %fdloc1 to i8*
- call addrspace(0) void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %cast.0, i8* align 8 bitcast ({ i64 }* @const.0 to i8*), i64 8, i1 false)
- store { i64 }* %fdloc1, { i64 }** %fploc1, align 8
- store { i64 (i8*, i32, i32, i64*)* }* null, { i64 (i8*, i32, i32, i64*)* }** %fploc2, align 8
- %fploc1.ld.0 = load { i64 }*, { i64 }** %fploc1, align 8
- %cast.1 = bitcast { i64 }* %fploc1.ld.0 to { i64 (i8*, i32, i32, i64*)* }*
- store { i64 (i8*, i32, i32, i64*)* }* %cast.1, { i64 (i8*, i32, i32, i64*)* }** %fploc2, align 8
- %fploc2.ld.0 = load { i64 (i8*, i32, i32, i64*)* }*, { i64 (i8*, i32, i32, i64*)* }** %fploc2, align 8
- %cast.2 = bitcast { i64 (i8*, i32, i32, i64*)* }* %fploc2.ld.0 to { i64 }*
- store { i64 }* %cast.2, { i64 }** %fploc1, align 8
+ call addrspace(0) void @llvm.memcpy.p0.p0.i64(ptr align 8 %fdloc1, ptr align 8 @const.0, i64 8, i1 false)
+ store ptr %fdloc1, ptr %fploc1, align 8
+ store ptr null, ptr %fploc2, align 8
+ %fploc1.ld.0 = load ptr, ptr %fploc1, align 8
+ store ptr %fploc1.ld.0, ptr %fploc2, align 8
+ %fploc2.ld.0 = load ptr, ptr %fploc2, align 8
+ store ptr %fploc2.ld.0, ptr %fploc1, align 8
)RAW_RESULT");
bool isOK = h.expectBlock(exp);
@@ -157,7 +154,7 @@
// Manufacture a nil pointer expression
Bexpression *npe = be->nil_pointer_expression();
DECLARE_EXPECTED_OUTPUT(exp1, R"RAW_RESULT(
- i64* null
+ ptr null
)RAW_RESULT");
bool isOK = h.expectValue(npe->value(), exp1);
EXPECT_TRUE(isOK && "Value does not have expected contents");
@@ -188,16 +185,16 @@
}
DECLARE_EXPECTED_OUTPUT(exp2, R"RAW_RESULT(
- store i8 0, i8* %b1, align 1
- store i8* null, i8** %pb1, align 8
- %pb1.ld.0 = load i8*, i8** %pb1, align 8
- %icmp.0 = icmp eq i8* %pb1.ld.0, null
+ store i8 0, ptr %b1, align 1
+ store ptr null, ptr %pb1, align 8
+ %pb1.ld.0 = load ptr, ptr %pb1, align 8
+ %icmp.0 = icmp eq ptr %pb1.ld.0, null
%zext.0 = zext i1 %icmp.0 to i8
- store i8 %zext.0, i8* %b1, align 1
- %pb1.ld.1 = load i8*, i8** %pb1, align 8
- %icmp.1 = icmp eq i8* null, %pb1.ld.1
+ store i8 %zext.0, ptr %b1, align 1
+ %pb1.ld.1 = load ptr, ptr %pb1, align 8
+ %icmp.1 = icmp eq ptr null, %pb1.ld.1
%zext.1 = zext i1 %icmp.1 to i8
- store i8 %zext.1, i8* %b1, align 1
+ store i8 %zext.1, ptr %b1, align 1
)RAW_RESULT");
bool isOK2 = h.expectBlock(exp2);
@@ -225,10 +222,9 @@
h.mkLocal("y", bst, deref2);
DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
- %deref.ld.0 = load i32, i32* null, align 4
- store i32 %deref.ld.0, i32* %x, align 4
- %cast.2 = bitcast { i32, i32 }* %y to i8*
- call addrspace(0) void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %cast.2, i8* align 4 null, i64 8, i1 false)
+ %deref.ld.0 = load i32, ptr null, align 4
+ store i32 %deref.ld.0, ptr %x, align 4
+ call addrspace(0) void @llvm.memcpy.p0.p0.i64(ptr align 4 %y, ptr align 4 null, i64 8, i1 false)
)RAW_RESULT");
bool isOK = h.expectBlock(exp);
@@ -321,38 +317,31 @@
}
DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
- store %CPT.0* null, %CPT.0** %cpv1, align 8
- store %CPT.0* null, %CPT.0** %cpv2, align 8
- %cast.0 = bitcast %CPT.0** %cpv2 to %CPT.0*
- store %CPT.0* %cast.0, %CPT.0** %cpv1, align 8
- %cast.1 = bitcast %CPT.0** %cpv1 to %CPT.0*
- store %CPT.0* %cast.1, %CPT.0** %cpv2, align 8
- store i8 0, i8* %b1, align 1
- store i8 0, i8* %b2, align 1
- store i8 0, i8* %b3, align 1
- %cpv1.ld.0 = load %CPT.0*, %CPT.0** %cpv1, align 8
- %cast.2 = bitcast %CPT.0** %cpv2 to %CPT.0***
- %cpv2.ld.0 = load %CPT.0**, %CPT.0*** %cast.2, align 8
- %.ld.0 = load %CPT.0*, %CPT.0** %cpv2.ld.0, align 8
- %icmp.0 = icmp eq %CPT.0* %cpv1.ld.0, %.ld.0
+ store ptr null, ptr %cpv1, align 8
+ store ptr null, ptr %cpv2, align 8
+ store ptr %cpv2, ptr %cpv1, align 8
+ store ptr %cpv1, ptr %cpv2, align 8
+ store i8 0, ptr %b1, align 1
+ store i8 0, ptr %b2, align 1
+ store i8 0, ptr %b3, align 1
+ %cpv1.ld.0 = load ptr, ptr %cpv1, align 8
+ %cpv2.ld.0 = load ptr, ptr %cpv2, align 8
+ %.ld.0 = load ptr, ptr %cpv2.ld.0, align 8
+ %icmp.0 = icmp eq ptr %cpv1.ld.0, %.ld.0
%zext.0 = zext i1 %icmp.0 to i8
- store i8 %zext.0, i8* %b1, align 1
- %cpv2.ld.1 = load %CPT.0*, %CPT.0** %cpv2, align 8
- %cast.3 = bitcast %CPT.0* %cpv2.ld.1 to %CPT.0**
- %icmp.1 = icmp eq %CPT.0** %cpv1, %cast.3
+ store i8 %zext.0, ptr %b1, align 1
+ %cpv2.ld.1 = load ptr, ptr %cpv2, align 8
+ %icmp.1 = icmp eq ptr %cpv1, %cpv2.ld.1
%zext.1 = zext i1 %icmp.1 to i8
- store i8 %zext.1, i8* %b2, align 1
- %cpv1.ld.1 = load %CPT.0*, %CPT.0** %cpv1, align 8
- %cast.4 = bitcast %CPT.0** %cpv2 to %CPT.0***
- %cpv2.ld.2 = load %CPT.0**, %CPT.0*** %cast.4, align 8
- %cast.5 = bitcast %CPT.0** %cpv2.ld.2 to %CPT.0***
- %deref.ld.0 = load %CPT.0**, %CPT.0*** %cast.5, align 8
- %cast.6 = bitcast %CPT.0** %deref.ld.0 to %CPT.0***
- %deref.ld.1 = load %CPT.0**, %CPT.0*** %cast.6, align 8
- %.ld.1 = load %CPT.0*, %CPT.0** %deref.ld.1, align 8
- %icmp.2 = icmp eq %CPT.0* %cpv1.ld.1, %.ld.1
+ store i8 %zext.1, ptr %b2, align 1
+ %cpv1.ld.1 = load ptr, ptr %cpv1, align 8
+ %cpv2.ld.2 = load ptr, ptr %cpv2, align 8
+ %deref.ld.0 = load ptr, ptr %cpv2.ld.2, align 8
+ %deref.ld.1 = load ptr, ptr %deref.ld.0, align 8
+ %.ld.1 = load ptr, ptr %deref.ld.1, align 8
+ %icmp.2 = icmp eq ptr %cpv1.ld.1, %.ld.1
%zext.2 = zext i1 %icmp.2 to i8
- store i8 %zext.2, i8* %b3, align 1
+ store i8 %zext.2, ptr %b3, align 1
)RAW_RESULT");
bool isOK = h.expectBlock(exp);
@@ -422,18 +411,17 @@
}
DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
- store %CPT.0* null, %CPT.0** %x, align 8
- store %CPT.0** null, %CPT.0*** %y, align 8
- %cast.0 = bitcast %CPT.0*** %y to %CPT.0*
- store %CPT.0* %cast.0, %CPT.0** %x, align 8
- store %CPT.0** %x, %CPT.0*** %y, align 8
- store i8 0, i8* %b1, align 1
- %x.ld.0 = load %CPT.0*, %CPT.0** %x, align 8
- %y.ld.0 = load %CPT.0**, %CPT.0*** %y, align 8
- %.ld.0 = load %CPT.0*, %CPT.0** %y.ld.0, align 8
- %icmp.0 = icmp eq %CPT.0* %x.ld.0, %.ld.0
+ store ptr null, ptr %x, align 8
+ store ptr null, ptr %y, align 8
+ store ptr %y, ptr %x, align 8
+ store ptr %x, ptr %y, align 8
+ store i8 0, ptr %b1, align 1
+ %x.ld.0 = load ptr, ptr %x, align 8
+ %y.ld.0 = load ptr, ptr %y, align 8
+ %.ld.0 = load ptr, ptr %y.ld.0, align 8
+ %icmp.0 = icmp eq ptr %x.ld.0, %.ld.0
%zext.0 = zext i1 %icmp.0 to i8
- store i8 %zext.0, i8* %b1, align 1
+ store i8 %zext.0, ptr %b1, align 1
)RAW_RESULT");
bool isOK = h.expectBlock(exp);
@@ -477,14 +465,14 @@
}
DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
- %param3.ld.0 = load i64*, i64** %param3.addr, align 8
- %ptroff.0 = getelementptr i64, i64* %param3.ld.0, i32 5
- store i64 9, i64* %ptroff.0, align 8
- %param3.ld.1 = load i64*, i64** %param3.addr, align 8
- %ptroff.1 = getelementptr i64, i64* %param3.ld.1, i32 7
- %.ptroff.ld.0 = load i64, i64* %ptroff.1, align 8
+ %param3.ld.0 = load ptr, ptr %param3.addr, align 8
+ %ptroff.0 = getelementptr i64, ptr %param3.ld.0, i32 5
+ store i64 9, ptr %ptroff.0, align 8
+ %param3.ld.1 = load ptr, ptr %param3.addr, align 8
+ %ptroff.1 = getelementptr i64, ptr %param3.ld.1, i32 7
+ %.ptroff.ld.0 = load i64, ptr %ptroff.1, align 8
%trunc.0 = trunc i64 %.ptroff.ld.0 to i32
- store i32 %trunc.0, i32* %param1.addr, align 4
+ store i32 %trunc.0, ptr %param1.addr, align 4
)RAW_RESULT");
bool isOK = h.expectBlock(exp);
@@ -516,8 +504,8 @@
h.mkAssign(vexl, ad3);
DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
- store i64 0, i64* %x, align 8
- store i64* %x, i64** %param3.addr, align 8
+ store i64 0, ptr %x, align 8
+ store ptr %x, ptr %param3.addr, align 8
)RAW_RESULT");
bool isOK = h.expectBlock(exp);
@@ -569,8 +557,8 @@
}
DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
- store i32 0, i32* inttoptr (i64 65793 to i32*), align 4
- store i64 2, i64* getelementptr inbounds ({ i64, i64 }, { i64, i64 }* inttoptr (i64 34661 to { i64, i64 }*), i32 0, i32 1), align 8
+ store i32 0, ptr inttoptr (i64 65793 to ptr), align 4
+ store i64 2, ptr getelementptr inbounds ({ i64, i64 }, ptr inttoptr (i64 34661 to ptr), i32 0, i32 1), align 8
)RAW_RESULT");
bool isOK = h.expectBlock(exp);
@@ -622,9 +610,8 @@
h.mkLocal("y", pbefty2);
DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
- store i64 (i8*, i64, i64, %CFT.0*, %CFT.1*)* null, i64 (i8*, i64, i64, %CFT.0*, %CFT.1*)** %x, align 8
- store i64 (i8*, i64, i64, %CFT.1*, %CFT.0*)* null, i64 (i8*, i64, i64, %CFT.1*, %CFT.0*)** %y, align 8
-
+ store ptr null, ptr %x, align 8
+ store ptr null, ptr %y, align 8
)RAW_RESULT");
bool isOK = h.expectBlock(exp);
diff --git a/unittests/BackendCore/BackendStmtTests.cpp b/unittests/BackendCore/BackendStmtTests.cpp
index 7e47928..c2661a9 100644
--- a/unittests/BackendCore/BackendStmtTests.cpp
+++ b/unittests/BackendCore/BackendStmtTests.cpp
@@ -40,7 +40,7 @@
Bstatement *is = be->init_statement(func, loc1, mkInt64Const(be, 10));
ASSERT_TRUE(is != nullptr);
h.addStmt(is);
- EXPECT_EQ(repr(is), "store i64 10, i64* %loc1, align 8");
+ EXPECT_EQ(repr(is), "store i64 10, ptr %loc1, align 8");
// error handling
Bvariable *loc2 = be->local_variable(func, "loc2", bi64t, nullptr, true, loc);
@@ -80,11 +80,11 @@
h.addStmt(as2);
DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
- store i64 0, i64* %loc1, align 8
- store i64 123, i64* %loc1, align 8
- store i64 0, i64* %loc2, align 8
- %loc1.ld.0 = load i64, i64* %loc1, align 8
- store i64 %loc1.ld.0, i64* %loc2, align 8
+ store i64 0, ptr %loc1, align 8
+ store i64 123, ptr %loc1, align 8
+ store i64 0, ptr %loc2, align 8
+ %loc1.ld.0 = load i64, ptr %loc1, align 8
+ store i64 %loc1.ld.0, ptr %loc2, align 8
)RAW_RESULT");
bool isOK = h.expectBlock(exp);
EXPECT_TRUE(isOK && "Block does not have expected contents");
@@ -116,7 +116,7 @@
Bstatement *ret = h.mkReturn(ve1);
DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
- %loc1.ld.0 = load i64, i64* %loc1, align 8
+ %loc1.ld.0 = load i64, ptr %loc1, align 8
ret i64 %loc1.ld.0
)RAW_RESULT");
std::string reason;
@@ -157,19 +157,19 @@
h.mkReturn(addexpr);
DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
- define i64 @foo(i8* nest %nest.0, i32 %param1, i32 %param2, i64* %param3) #0 {
- entry:
- %param1.addr = alloca i32, align 4
- %param2.addr = alloca i32, align 4
- %param3.addr = alloca i64*, align 8
- %x = alloca i64, align 8
- store i32 %param1, i32* %param1.addr, align 4
- store i32 %param2, i32* %param2.addr, align 4
- store i64* %param3, i64** %param3.addr, align 8
- store i64 10, i64* %x, align 8
- %x.ld.0 = load i64, i64* %x, align 8
- ret i64 %x.ld.0
- }
+ define i64 @foo(ptr nest %nest.0, i32 %param1, i32 %param2, ptr %param3) #0 {
+ entry:
+ %param1.addr = alloca i32, align 4
+ %param2.addr = alloca i32, align 4
+ %param3.addr = alloca ptr, align 8
+ %x = alloca i64, align 8
+ store i32 %param1, ptr %param1.addr, align 4
+ store i32 %param2, ptr %param2.addr, align 4
+ store ptr %param3, ptr %param3.addr, align 8
+ store i64 10, ptr %x, align 8
+ %x.ld.0 = load i64, ptr %x, align 8
+ ret i64 %x.ld.0
+ }
)RAW_RESULT");
bool broken = h.finish(StripDebugInfo);
@@ -240,17 +240,17 @@
EXPECT_FALSE(broken && "Module failed to verify.");
DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
- define void @foo(i8* nest %nest.0) #0 {
- entry:
- %loc1 = alloca i8, align 1
- store i8 0, i8* %loc1, align 1
- call void @bar(i8* nest undef, i8* blockaddress(@foo, %label.0))
- br label %label.0
-
- label.0: ; preds = %entry
- store i8 0, i8* %loc1, align 1
- ret void
- }
+ define void @foo(ptr nest %nest.0) #0 {
+ entry:
+ %loc1 = alloca i8, align 1
+ store i8 0, ptr %loc1, align 1
+ call void @bar(ptr nest undef, ptr blockaddress(@foo, %label.0))
+ br label %label.0
+
+ label.0: ; preds = %entry
+ store i8 0, ptr %loc1, align 1
+ ret void
+ }
)RAW_RESULT");
bool isOK = h.expectValue(func->function(), exp);
@@ -311,41 +311,41 @@
// verify
DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
- define i64 @foo(i8* nest %nest.0, i32 %param1, i32 %param2, i64* %param3) #0 {
- entry:
- %param1.addr = alloca i32, align 4
- %param2.addr = alloca i32, align 4
- %param3.addr = alloca i64*, align 8
- %loc1 = alloca i64, align 8
- %loc2 = alloca i64, align 8
- store i32 %param1, i32* %param1.addr, align 4
- store i32 %param2, i32* %param2.addr, align 4
- store i64* %param3, i64** %param3.addr, align 8
- store i64 0, i64* %loc1, align 8
- store i64 0, i64* %loc2, align 8
- br i1 true, label %then.0, label %else.0
-
- then.0: ; preds = %entry
- br i1 true, label %then.1, label %else.1
-
- fallthrough.0: ; preds = %else.0, %fallthrough.1
- ret i64 10101
-
- else.0: ; preds = %entry
- store i64 456, i64* %loc2, align 8
- br label %fallthrough.0
-
- then.1: ; preds = %then.0
- store i64 123, i64* %loc1, align 8
- br label %fallthrough.1
-
- fallthrough.1: ; preds = %else.1, %then.1
- br label %fallthrough.0
-
- else.1: ; preds = %then.0
- store i64 987, i64* %loc1, align 8
- br label %fallthrough.1
- }
+ define i64 @foo(ptr nest %nest.0, i32 %param1, i32 %param2, ptr %param3) #0 {
+ entry:
+ %param1.addr = alloca i32, align 4
+ %param2.addr = alloca i32, align 4
+ %param3.addr = alloca ptr, align 8
+ %loc1 = alloca i64, align 8
+ %loc2 = alloca i64, align 8
+ store i32 %param1, ptr %param1.addr, align 4
+ store i32 %param2, ptr %param2.addr, align 4
+ store ptr %param3, ptr %param3.addr, align 8
+ store i64 0, ptr %loc1, align 8
+ store i64 0, ptr %loc2, align 8
+ br i1 true, label %then.0, label %else.0
+
+ then.0: ; preds = %entry
+ br i1 true, label %then.1, label %else.1
+
+ fallthrough.0: ; preds = %else.0, %fallthrough.1
+ ret i64 10101
+
+ else.0: ; preds = %entry
+ store i64 456, ptr %loc2, align 8
+ br label %fallthrough.0
+
+ then.1: ; preds = %then.0
+ store i64 123, ptr %loc1, align 8
+ br label %fallthrough.1
+
+ fallthrough.1: ; preds = %else.1, %then.1
+ br label %fallthrough.0
+
+ else.1: ; preds = %then.0
+ store i64 987, ptr %loc1, align 8
+ br label %fallthrough.1
+ }
)RAW_RESULT");
bool isOK = h.expectValue(func->function(), exp);
@@ -435,65 +435,65 @@
// verify
DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
- define i64 @foo(i8* nest %nest.0, i32 %param1, i32 %param2, i64* %param3) #0 {
- entry:
- %param1.addr = alloca i32, align 4
- %param2.addr = alloca i32, align 4
- %param3.addr = alloca i64*, align 8
- %loc1 = alloca i64, align 8
- %tmpv.0 = alloca i64, align 8
- store i32 %param1, i32* %param1.addr, align 4
- store i32 %param2, i32* %param2.addr, align 4
- store i64* %param3, i64** %param3.addr, align 8
- store i64 0, i64* %loc1, align 8
- %loc1.ld.4 = load i64, i64* %loc1, align 8
- switch i64 %loc1.ld.4, label %default.0 [
- i64 1, label %case.0
- i64 2, label %case.0
- i64 3, label %case.1
- i64 4, label %case.1
- i64 5, label %case.2
- ]
-
- case.0: ; preds = %entry, %entry
- %loc1.ld.0 = load i64, i64* %loc1, align 8
- %div.0 = sdiv i64 %loc1.ld.0, 123
- store i64 %div.0, i64* %loc1, align 8
- br label %label.0
-
- case.1: ; preds = %entry, %entry
- %loc1.ld.1 = load i64, i64* %loc1, align 8
- %icmp.0 = icmp sle i64 %loc1.ld.1, 987
- %zext.0 = zext i1 %icmp.0 to i8
- %trunc.0 = trunc i8 %zext.0 to i1
- br i1 %trunc.0, label %then.0, label %else.0
-
- case.2: ; preds = %entry, %fallthrough.0
- br label %default.0
-
- default.0: ; preds = %entry, %case.2
- store i64 456, i64* %loc1, align 8
- br label %label.0
-
- label.0: ; preds = %default.0, %case.0
- ret i64 10101
-
- then.0: ; preds = %case.1
- %loc1.ld.3 = load i64, i64* %loc1, align 8
- store i64 %loc1.ld.3, i64* %tmpv.0, align 8
- br label %fallthrough.0
-
- fallthrough.0: ; preds = %else.0, %then.0
- %tmpv.0.ld.0 = load i64, i64* %tmpv.0, align 8
- store i64 %tmpv.0.ld.0, i64* %loc1, align 8
- br label %case.2
-
- else.0: ; preds = %case.1
- %loc1.ld.2 = load i64, i64* %loc1, align 8
- %mul.0 = mul i64 987, %loc1.ld.2
- store i64 %mul.0, i64* %tmpv.0, align 8
- br label %fallthrough.0
- }
+ define i64 @foo(ptr nest %nest.0, i32 %param1, i32 %param2, ptr %param3) #0 {
+ entry:
+ %param1.addr = alloca i32, align 4
+ %param2.addr = alloca i32, align 4
+ %param3.addr = alloca ptr, align 8
+ %loc1 = alloca i64, align 8
+ %tmpv.0 = alloca i64, align 8
+ store i32 %param1, ptr %param1.addr, align 4
+ store i32 %param2, ptr %param2.addr, align 4
+ store ptr %param3, ptr %param3.addr, align 8
+ store i64 0, ptr %loc1, align 8
+ %loc1.ld.4 = load i64, ptr %loc1, align 8
+ switch i64 %loc1.ld.4, label %default.0 [
+ i64 1, label %case.0
+ i64 2, label %case.0
+ i64 3, label %case.1
+ i64 4, label %case.1
+ i64 5, label %case.2
+ ]
+
+ case.0: ; preds = %entry, %entry
+ %loc1.ld.0 = load i64, ptr %loc1, align 8
+ %div.0 = sdiv i64 %loc1.ld.0, 123
+ store i64 %div.0, ptr %loc1, align 8
+ br label %label.0
+
+ case.1: ; preds = %entry, %entry
+ %loc1.ld.1 = load i64, ptr %loc1, align 8
+ %icmp.0 = icmp sle i64 %loc1.ld.1, 987
+ %zext.0 = zext i1 %icmp.0 to i8
+ %trunc.0 = trunc i8 %zext.0 to i1
+ br i1 %trunc.0, label %then.0, label %else.0
+
+ case.2: ; preds = %entry, %fallthrough.0
+ br label %default.0
+
+ default.0: ; preds = %entry, %case.2
+ store i64 456, ptr %loc1, align 8
+ br label %label.0
+
+ label.0: ; preds = %default.0, %case.0
+ ret i64 10101
+
+ then.0: ; preds = %case.1
+ %loc1.ld.3 = load i64, ptr %loc1, align 8
+ store i64 %loc1.ld.3, ptr %tmpv.0, align 8
+ br label %fallthrough.0
+
+ fallthrough.0: ; preds = %else.0, %then.0
+ %tmpv.0.ld.0 = load i64, ptr %tmpv.0, align 8
+ store i64 %tmpv.0.ld.0, ptr %loc1, align 8
+ br label %case.2
+
+ else.0: ; preds = %case.1
+ %loc1.ld.2 = load i64, ptr %loc1, align 8
+ %mul.0 = mul i64 987, %loc1.ld.2
+ store i64 %mul.0, ptr %tmpv.0, align 8
+ br label %fallthrough.0
+ }
)RAW_RESULT");
bool isOK = h.expectValue(func->function(), exp);
@@ -584,28 +584,28 @@
EXPECT_FALSE(broken && "Module failed to verify.");
DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
- define void @foo(i8* nest %nest.0) #0 personality i32 (i32, i32, i64, i8*, i8*)* @__gccgo_personality_v0 {
- entry:
- %x = alloca i8, align 1
- store i8 0, i8* %x, align 1
- br label %finish.0
-
- pad.0: ; preds = %finish.0
- %ex.0 = landingpad { i8*, i32 }
- catch i8* null
- br label %catch.0
-
- catch.0: ; preds = %pad.0
- call void @checkdefer(i8* nest undef, i8* %x)
- br label %finish.0
-
- finish.0: ; preds = %catch.0, %entry
- invoke void @deferreturn(i8* nest undef, i8* %x)
- to label %cont.0 unwind label %pad.0
-
- cont.0: ; preds = %finish.0
- ret void
- }
+ define void @foo(ptr nest %nest.0) #0 personality ptr @__gccgo_personality_v0 {
+ entry:
+ %x = alloca i8, align 1
+ store i8 0, ptr %x, align 1
+ br label %finish.0
+
+ pad.0: ; preds = %finish.0
+ %ex.0 = landingpad { ptr, i32 }
+ catch ptr null
+ br label %catch.0
+
+ catch.0: ; preds = %pad.0
+ call void @checkdefer(ptr nest undef, ptr %x)
+ br label %finish.0
+
+ finish.0: ; preds = %catch.0, %entry
+ invoke void @deferreturn(ptr nest undef, ptr %x)
+ to label %cont.0 unwind label %pad.0
+
+ cont.0: ; preds = %finish.0
+ ret void
+ }
)RAW_RESULT");
bool isOK = h.expectValue(func->function(), exp);
@@ -697,94 +697,94 @@
EXPECT_FALSE(broken && "Module failed to verify.");
DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
- define void @baz(i8* nest %nest.0) #0 personality i32 (i32, i32, i64, i8*, i8*)* @__gccgo_personality_v0 {
- entry:
- %ehtmp.0 = alloca { i8*, i32 }, align 8
- %x = alloca i64, align 8
- %y = alloca i8, align 1
- %sret.actual.0 = alloca { i8, i8 }, align 1
- %sret.actual.1 = alloca { i8, i8 }, align 1
- %finvar.0 = alloca i8, align 1
- store i64 0, i64* %x, align 8
- store i8 0, i8* %y, align 1
- %call.0 = invoke i64 @id(i8* nest undef, i64 99)
- to label %cont.1 unwind label %pad.1
-
- finok.0: ; preds = %cont.4
- store i8 1, i8* %finvar.0, align 1
- br label %finally.0
-
- finally.0: ; preds = %catchpad.0, %finok.0
- br label %finish.0
-
- pad.0: ; preds = %fallthrough.0, %finish.0
- %ex.0 = landingpad { i8*, i32 }
- catch i8* null
- br label %catch.0
-
- catch.0: ; preds = %pad.0
- call void @checkdefer(i8* nest undef, i8* %y)
- br label %finish.0
-
- finish.0: ; preds = %catch.0, %finally.0
- invoke void @deferreturn(i8* nest undef, i8* %y)
- to label %cont.0 unwind label %pad.0
-
- cont.0: ; preds = %fallthrough.0, %finish.0
- %fload.0 = load i8, i8* %finvar.0, align 1
- %icmp.0 = icmp eq i8 %fload.0, 1
- br i1 %icmp.0, label %finret.0, label %finres.0
-
- pad.1: ; preds = %then.0, %cont.1, %entry
- %ex.1 = landingpad { i8*, i32 }
- catch i8* null
- br label %catch.1
-
- catch.1: ; preds = %pad.1
- invoke void @plix(i8* nest undef)
- to label %cont.4 unwind label %catchpad.0
-
- catchpad.0: ; preds = %catch.1
- %ex2.0 = landingpad { i8*, i32 }
- cleanup
- store { i8*, i32 } %ex2.0, { i8*, i32 }* %ehtmp.0, align 8
- store i8 0, i8* %finvar.0, align 1
- br label %finally.0
-
- cont.1: ; preds = %entry
- store i64 %call.0, i64* %x, align 8
- invoke void @plark(i8* nest undef)
- to label %cont.2 unwind label %pad.1
-
- cont.2: ; preds = %cont.1
- br i1 false, label %then.0, label %else.0
-
- then.0: ; preds = %cont.2
- %call.1 = invoke i16 @noret(i8* nest undef)
- to label %cont.3 unwind label %pad.1
-
- fallthrough.0: ; preds = %else.0
- store i64 123, i64* %x, align 8
- store i8 1, i8* %finvar.0, align 1
- invoke void @deferreturn(i8* nest undef, i8* %y)
- to label %cont.0 unwind label %pad.0
-
- else.0: ; preds = %cont.2
- br label %fallthrough.0
-
- cont.3: ; preds = %then.0
- unreachable
-
- cont.4: ; preds = %catch.1
- br label %finok.0
-
- finres.0: ; preds = %cont.0
- %excv.0 = load { i8*, i32 }, { i8*, i32 }* %ehtmp.0, align 8
- resume { i8*, i32 } %excv.0
-
- finret.0: ; preds = %cont.0
- ret void
- }
+ define void @baz(ptr nest %nest.0) #0 personality ptr @__gccgo_personality_v0 {
+ entry:
+ %ehtmp.0 = alloca { ptr, i32 }, align 8
+ %x = alloca i64, align 8
+ %y = alloca i8, align 1
+ %sret.actual.0 = alloca { i8, i8 }, align 1
+ %sret.actual.1 = alloca { i8, i8 }, align 1
+ %finvar.0 = alloca i8, align 1
+ store i64 0, ptr %x, align 8
+ store i8 0, ptr %y, align 1
+ %call.0 = invoke i64 @id(ptr nest undef, i64 99)
+ to label %cont.1 unwind label %pad.1
+
+ finok.0: ; preds = %cont.4
+ store i8 1, ptr %finvar.0, align 1
+ br label %finally.0
+
+ finally.0: ; preds = %catchpad.0, %finok.0
+ br label %finish.0
+
+ pad.0: ; preds = %fallthrough.0, %finish.0
+ %ex.0 = landingpad { ptr, i32 }
+ catch ptr null
+ br label %catch.0
+
+ catch.0: ; preds = %pad.0
+ call void @checkdefer(ptr nest undef, ptr %y)
+ br label %finish.0
+
+ finish.0: ; preds = %catch.0, %finally.0
+ invoke void @deferreturn(ptr nest undef, ptr %y)
+ to label %cont.0 unwind label %pad.0
+
+ cont.0: ; preds = %fallthrough.0, %finish.0
+ %fload.0 = load i8, ptr %finvar.0, align 1
+ %icmp.0 = icmp eq i8 %fload.0, 1
+ br i1 %icmp.0, label %finret.0, label %finres.0
+
+ pad.1: ; preds = %then.0, %cont.1, %entry
+ %ex.1 = landingpad { ptr, i32 }
+ catch ptr null
+ br label %catch.1
+
+ catch.1: ; preds = %pad.1
+ invoke void @plix(ptr nest undef)
+ to label %cont.4 unwind label %catchpad.0
+
+ catchpad.0: ; preds = %catch.1
+ %ex2.0 = landingpad { ptr, i32 }
+ cleanup
+ store { ptr, i32 } %ex2.0, ptr %ehtmp.0, align 8
+ store i8 0, ptr %finvar.0, align 1
+ br label %finally.0
+
+ cont.1: ; preds = %entry
+ store i64 %call.0, ptr %x, align 8
+ invoke void @plark(ptr nest undef)
+ to label %cont.2 unwind label %pad.1
+
+ cont.2: ; preds = %cont.1
+ br i1 false, label %then.0, label %else.0
+
+ then.0: ; preds = %cont.2
+ %call.1 = invoke i16 @noret(ptr nest undef)
+ to label %cont.3 unwind label %pad.1
+
+ fallthrough.0: ; preds = %else.0
+ store i64 123, ptr %x, align 8
+ store i8 1, ptr %finvar.0, align 1
+ invoke void @deferreturn(ptr nest undef, ptr %y)
+ to label %cont.0 unwind label %pad.0
+
+ else.0: ; preds = %cont.2
+ br label %fallthrough.0
+
+ cont.3: ; preds = %then.0
+ unreachable
+
+ cont.4: ; preds = %catch.1
+ br label %finok.0
+
+ finres.0: ; preds = %cont.0
+ %excv.0 = load { ptr, i32 }, ptr %ehtmp.0, align 8
+ resume { ptr, i32 } %excv.0
+
+ finret.0: ; preds = %cont.0
+ ret void
+ }
)RAW_RESULT");
bool isOK = h.expectValue(func->function(), exp);
@@ -886,90 +886,91 @@
EXPECT_FALSE(broken && "Module failed to verify.");
DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
- define i64 @baz(i8* nest %nest.0, i64 %p0) #0 personality i32 (i32, i32, i64, i8*, i8*)* @__gccgo_personality_v0 {
- entry:
- %ehtmp.0 = alloca { i8*, i32 }, align 8
- %p0.addr = alloca i64, align 8
- %ret = alloca i64, align 8
- %x = alloca i8, align 1
- %finvar.0 = alloca i8, align 1
- store i64 %p0, i64* %p0.addr, align 8
- store i64 0, i64* %ret, align 8
- store i8 0, i8* %x, align 1
- %call.0 = invoke i64 @splat(i8* nest undef, i64 99)
- to label %cont.1 unwind label %pad.1
-
- finok.0: ; preds = %cont.2
- store i8 1, i8* %finvar.0, align 1
- br label %finally.0
-
- finally.0: ; preds = %catchpad.0, %finok.0
- br label %finish.0
-
- pad.0: ; preds = %else.0, %then.0, %finish.0
- %ex.0 = landingpad { i8*, i32 }
- catch i8* null
- br label %catch.0
-
- catch.0: ; preds = %pad.0
- call void @checkdefer(i8* nest undef, i8* %x)
- br label %finish.0
-
- finish.0: ; preds = %catch.0, %finally.0
- invoke void @deferreturn(i8* nest undef, i8* %x)
- to label %cont.0 unwind label %pad.0
-
- cont.0: ; preds = %else.0, %then.0, %finish.0
- %fload.0 = load i8, i8* %finvar.0, align 1
- %icmp.1 = icmp eq i8 %fload.0, 1
- br i1 %icmp.1, label %finret.0, label %finres.0
-
- pad.1: ; preds = %entry
- %ex.1 = landingpad { i8*, i32 }
- catch i8* null
- br label %catch.1
-
- catch.1: ; preds = %pad.1
- %call.1 = invoke i64 @splat(i8* nest undef, i64 13)
- to label %cont.2 unwind label %catchpad.0
-
- catchpad.0: ; preds = %catch.1
- %ex2.0 = landingpad { i8*, i32 }
- cleanup
- store { i8*, i32 } %ex2.0, { i8*, i32 }* %ehtmp.0, align 8
- store i8 0, i8* %finvar.0, align 1
- br label %finally.0
-
- cont.1: ; preds = %entry
- %icmp.0 = icmp eq i64 %call.0, 88
- %zext.0 = zext i1 %icmp.0 to i8
- %trunc.0 = trunc i8 %zext.0 to i1
- br i1 %trunc.0, label %then.0, label %else.0
-
- then.0: ; preds = %cont.1
- store i64 22, i64* %ret, align 8
- store i8 1, i8* %finvar.0, align 1
- invoke void @deferreturn(i8* nest undef, i8* %x)
- to label %cont.0 unwind label %pad.0
-
- else.0: ; preds = %cont.1
- %p0.ld.0 = load i64, i64* %p0.addr, align 8
- store i64 %p0.ld.0, i64* %ret, align 8
- store i8 1, i8* %finvar.0, align 1
- invoke void @deferreturn(i8* nest undef, i8* %x)
- to label %cont.0 unwind label %pad.0
-
- cont.2: ; preds = %catch.1
- br label %finok.0
-
- finres.0: ; preds = %cont.0
- %excv.0 = load { i8*, i32 }, { i8*, i32 }* %ehtmp.0, align 8
- resume { i8*, i32 } %excv.0
-
- finret.0: ; preds = %cont.0
- %ret.ld.1 = load i64, i64* %ret, align 8
- ret i64 %ret.ld.1
- }
+ define i64 @baz(ptr nest %nest.0, i64 %p0) #0 personality ptr @__gccgo_personality_v0 {
+ entry:
+ %ehtmp.0 = alloca { ptr, i32 }, align 8
+ %p0.addr = alloca i64, align 8
+ %ret = alloca i64, align 8
+ %x = alloca i8, align 1
+ %finvar.0 = alloca i8, align 1
+ store i64 %p0, ptr %p0.addr, align 8
+ store i64 0, ptr %ret, align 8
+ store i8 0, ptr %x, align 1
+ %call.0 = invoke i64 @splat(ptr nest undef, i64 99)
+ to label %cont.1 unwind label %pad.1
+
+ finok.0: ; preds = %cont.2
+ store i8 1, ptr %finvar.0, align 1
+ br label %finally.0
+
+ finally.0: ; preds = %catchpad.0, %finok.0
+ br label %finish.0
+
+ pad.0: ; preds = %else.0, %then.0, %finish.0
+ %ex.0 = landingpad { ptr, i32 }
+ catch ptr null
+ br label %catch.0
+
+ catch.0: ; preds = %pad.0
+ call void @checkdefer(ptr nest undef, ptr %x)
+ br label %finish.0
+
+ finish.0: ; preds = %catch.0, %finally.0
+ invoke void @deferreturn(ptr nest undef, ptr %x)
+ to label %cont.0 unwind label %pad.0
+
+ cont.0: ; preds = %else.0, %then.0, %finish.0
+ %fload.0 = load i8, ptr %finvar.0, align 1
+ %icmp.1 = icmp eq i8 %fload.0, 1
+ br i1 %icmp.1, label %finret.0, label %finres.0
+
+ pad.1: ; preds = %entry
+ %ex.1 = landingpad { ptr, i32 }
+ catch ptr null
+ br label %catch.1
+
+ catch.1: ; preds = %pad.1
+ %call.1 = invoke i64 @splat(ptr nest undef, i64 13)
+ to label %cont.2 unwind label %catchpad.0
+
+ catchpad.0: ; preds = %catch.1
+ %ex2.0 = landingpad { ptr, i32 }
+ cleanup
+ store { ptr, i32 } %ex2.0, ptr %ehtmp.0, align 8
+ store i8 0, ptr %finvar.0, align 1
+ br label %finally.0
+
+ cont.1: ; preds = %entry
+ %icmp.0 = icmp eq i64 %call.0, 88
+
+ %zext.0 = zext i1 %icmp.0 to i8
+ %trunc.0 = trunc i8 %zext.0 to i1
+ br i1 %trunc.0, label %then.0, label %else.0
+
+ then.0: ; preds = %cont.1
+ store i64 22, ptr %ret, align 8
+ store i8 1, ptr %finvar.0, align 1
+ invoke void @deferreturn(ptr nest undef, ptr %x)
+ to label %cont.0 unwind label %pad.0
+
+ else.0: ; preds = %cont.1
+ %p0.ld.0 = load i64, ptr %p0.addr, align 8
+ store i64 %p0.ld.0, ptr %ret, align 8
+ store i8 1, ptr %finvar.0, align 1
+ invoke void @deferreturn(ptr nest undef, ptr %x)
+ to label %cont.0 unwind label %pad.0
+
+ cont.2: ; preds = %catch.1
+ br label %finok.0
+
+ finres.0: ; preds = %cont.0
+ %excv.0 = load { ptr, i32 }, ptr %ehtmp.0, align 8
+ resume { ptr, i32 } %excv.0
+
+ finret.0: ; preds = %cont.0
+ %ret.ld.1 = load i64, ptr %ret, align 8
+ ret i64 %ret.ld.1
+ }
)RAW_RESULT");
bool isOK = h.expectValue(func->function(), exp);
diff --git a/unittests/BackendCore/BackendVarTests.cpp b/unittests/BackendCore/BackendVarTests.cpp
index 526cd9d..48da657 100644
--- a/unittests/BackendCore/BackendVarTests.cpp
+++ b/unittests/BackendCore/BackendVarTests.cpp
@@ -66,7 +66,7 @@
ASSERT_TRUE(ve2 != nullptr);
Bstatement *es = h.mkExprStmt(ve2);
EXPECT_EQ(repr(ve2->value()), "%loc1 = alloca i64, align 8");
- EXPECT_EQ(repr(es), "%loc1.ld.0 = load i64, i64* %loc1, align 8");
+ EXPECT_EQ(repr(es), "%loc1.ld.0 = load i64, ptr %loc1, align 8");
// Make sure error detection is working
Bvariable *loce = be->local_variable(func1, "", be->error_type(), nullptr,
@@ -159,7 +159,7 @@
false, loc, &inits);
ASSERT_TRUE(tvar != nullptr);
ASSERT_TRUE(inits != nullptr);
- EXPECT_EQ(repr(inits), "store i64 64, i64* %tmpv.0, align 8");
+ EXPECT_EQ(repr(inits), "store i64 64, ptr %tmpv.0, align 8");
h.addStmt(inits);
@@ -302,8 +302,7 @@
{
DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
- @desc = internal constant { i64 } { i64 ptrtoint
- (i64 (i8*, i32, i32, i64*)* @foo to i64) }
+ @desc = internal constant { i64 } { i64 ptrtoint (ptr @foo to i64) }
)RAW_RESULT");
bool isOK = h.expectValue(ims->value(), exp);
@@ -460,8 +459,7 @@
ASSERT_TRUE(gv != nullptr);
EXPECT_TRUE(isa<GlobalVariable>(gv->value()));
EXPECT_EQ(repr(gv->value()), "@x = global { i32 } zeroinitializer");
- EXPECT_EQ(repr(gvdecl->value()),
- "i32* getelementptr inbounds ({ i32 }, { i32 }* @x, i32 0, i32 0)");
+ EXPECT_EQ(repr(gvdecl->value()), "@x = global { i32 } zeroinitializer");
// Create them in the other order: definition first,
// then external declaration.
@@ -478,8 +476,7 @@
ASSERT_TRUE(gvdecl2 != nullptr);
EXPECT_TRUE(isa<GlobalVariable>(gv2->value()));
EXPECT_EQ(repr(gv2->value()), "@y = global { i32 } zeroinitializer");
- EXPECT_EQ(repr(gvdecl2->value()),
- "i32* getelementptr inbounds ({ i32 }, { i32 }* @y, i32 0, i32 0)");
+ EXPECT_EQ(repr(gvdecl2->value()), "@y = global { i32 } zeroinitializer");
bool broken = h.finish(PreserveDebugInfo);
EXPECT_FALSE(broken && "Module failed to verify.");
@@ -519,26 +516,21 @@
EXPECT_FALSE(broken && "Module failed to verify.");
DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
- define void @foo(i8* nest %nest.0) #0 {
- entry:
- %x = alloca i32, align 4
- %y = alloca { i32, i32 }, align 4
- %0 = bitcast i32* %x to i8*
- call void @llvm.lifetime.start.p0i8(i64 4, i8* %0)
- %1 = bitcast { i32, i32 }* %y to i8*
- call void @llvm.lifetime.start.p0i8(i64 8, i8* %1)
- store i32 0, i32* %x, align 4
- %cast.0 = bitcast { i32, i32 }* %y to i8*
- call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %cast.0, i8* align 4 bitcast ({ i32, i32 }* @const.0 to i8*), i64 8, i1 false)
- %field.0 = getelementptr inbounds { i32, i32 }, { i32, i32 }* %y, i32 0, i32 1
- %y.field.ld.0 = load i32, i32* %field.0, align 4
- store i32 %y.field.ld.0, i32* %x, align 4
- %2 = bitcast i32* %x to i8*
- call void @llvm.lifetime.end.p0i8(i64 4, i8* %2)
- %3 = bitcast { i32, i32 }* %y to i8*
- call void @llvm.lifetime.end.p0i8(i64 8, i8* %3)
- ret void
- }
+ define void @foo(ptr nest %nest.0) #0 {
+ entry:
+ %x = alloca i32, align 4
+ %y = alloca { i32, i32 }, align 4
+ call void @llvm.lifetime.start.p0(i64 4, ptr %x)
+ call void @llvm.lifetime.start.p0(i64 8, ptr %y)
+ store i32 0, ptr %x, align 4
+ call void @llvm.memcpy.p0.p0.i64(ptr align 4 %y, ptr align 4 @const.0, i64 8, i1 false)
+ %field.0 = getelementptr inbounds { i32, i32 }, ptr %y, i32 0, i32 1
+ %y.field.ld.0 = load i32, ptr %field.0, align 4
+ store i32 %y.field.ld.0, ptr %x, align 4
+ call void @llvm.lifetime.end.p0(i64 4, ptr %x)
+ call void @llvm.lifetime.end.p0(i64 8, ptr %y)
+ ret void
+ }
)RAW_RESULT");
bool isOK = h.expectValue(func->function(), exp);
@@ -659,12 +651,12 @@
EXPECT_FALSE(broken && "Module failed to verify.");
DECLARE_EXPECTED_OUTPUT(exp, R"RAW_RESULT(
- define void @foo(i8* nest %nest.0) #0 {
- entry:
- %localemptys2f = alloca { {}, {} }, align 1
- %localemptyintar = alloca [0 x i32], align 4
- ret void
- }
+ define void @foo(ptr nest %nest.0) #0 {
+ entry:
+ %localemptys2f = alloca { {}, {} }, align 1
+ %localemptyintar = alloca [0 x i32], align 4
+ ret void
+ }
)RAW_RESULT");
bool isOK = h.expectValue(func->function(), exp);
EXPECT_TRUE(isOK && "Value does not have expected contents");
@@ -711,7 +703,7 @@
// Expect to see only one lifetime start, since A) loc1 is at the top
// level, and B) loc2 uses loc1 as declVar.
- const char *expected = "call void @llvm.lifetime.start.p0i8(i64";
+ const char *expected = "call void @llvm.lifetime.start.p0(i64";
EXPECT_EQ(h.countInstancesInModuleDump(expected), 1u);
}
diff --git a/unittests/BackendCore/TestUtils.h b/unittests/BackendCore/TestUtils.h
index fa6774e..14dc355 100644
--- a/unittests/BackendCore/TestUtils.h
+++ b/unittests/BackendCore/TestUtils.h
@@ -10,8 +10,10 @@
#define GOLLVM_UNITTESTS_BACKENDCORE_TESTUTILS_H
#include "llvm/IR/DerivedTypes.h"
+#include "llvm/IR/Function.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/LLVMContext.h"
+#include "llvm/IR/Module.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/Value.h"
#include "llvm/IR/Verifier.h"
diff --git a/unittests/Driver/DriverTests.cpp b/unittests/Driver/DriverTests.cpp
index 80ddcc2..93bd287 100644
--- a/unittests/Driver/DriverTests.cpp
+++ b/unittests/Driver/DriverTests.cpp
@@ -56,7 +56,7 @@
std::unique_ptr<opt::OptTable> opts =
gollvm::options::createGollvmDriverOptTable();
unsigned missingArgIndex, missingArgCount;
- ArrayRef<const char *> argvv = makeArrayRef(args_);
+ ArrayRef<const char *> argvv(args_);
opt::InputArgList args =
opts->ParseArgs(argvv, missingArgIndex, missingArgCount);
diff --git a/unittests/TestUtils/DiffUtils.cpp b/unittests/TestUtils/DiffUtils.cpp
index 98786d7..e4d8a7e 100644
--- a/unittests/TestUtils/DiffUtils.cpp
+++ b/unittests/TestUtils/DiffUtils.cpp
@@ -30,9 +30,9 @@
// ending line (20). Which one will matter for the machinery that does
// test remastering.
static bool macroLineAtStart() {
- if (baseline.line == 16) {
+ if (baseline.line == 17) {
return true;
- } else if (baseline.line == 20) {
+ } else if (baseline.line == 21) {
return false;
} else {
assert(false && "macroLineAtStart broken -- source edited?");