Vendor import of llvm release_40 branch r292951:

https://llvm.org/svn/llvm-project/llvm/branches/release_40@292951
This commit is contained in:
Dimitry Andric 2017-01-24 19:17:53 +00:00
parent 7c71d32ab5
commit 02a3368019
21 changed files with 673 additions and 491 deletions

View File

@ -512,7 +512,7 @@ private:
}
Metadata *getFnMetadataByID(unsigned ID) {
return MDLoader->getMetadataFwdRef(ID);
return MDLoader->getMetadataFwdRefOrLoad(ID);
}
BasicBlock *getBasicBlock(unsigned ID) const {

View File

@ -485,8 +485,21 @@ public:
Error parseMetadata(bool ModuleLevel);
bool hasFwdRefs() const { return MetadataList.hasFwdRefs(); }
Metadata *getMetadataFwdRef(unsigned Idx) {
return MetadataList.getMetadataFwdRef(Idx);
Metadata *getMetadataFwdRefOrLoad(unsigned ID) {
if (ID < MDStringRef.size())
return lazyLoadOneMDString(ID);
if (auto *MD = MetadataList.lookup(ID))
return MD;
// If lazy-loading is enabled, we try recursively to load the operand
// instead of creating a temporary.
if (ID < (MDStringRef.size() + GlobalMetadataBitPosIndex.size())) {
PlaceholderQueue Placeholders;
lazyLoadOneMetadata(ID, Placeholders);
resolveForwardRefsAndPlaceholders(Placeholders);
return MetadataList.lookup(ID);
}
return MetadataList.getMetadataFwdRef(ID);
}
MDNode *getMDNodeFwdRefOrNull(unsigned Idx) {
@ -1727,8 +1740,8 @@ bool MetadataLoader::hasFwdRefs() const { return Pimpl->hasFwdRefs(); }
/// Return the given metadata, creating a replaceable forward reference if
/// necessary.
Metadata *MetadataLoader::getMetadataFwdRef(unsigned Idx) {
return Pimpl->getMetadataFwdRef(Idx);
Metadata *MetadataLoader::getMetadataFwdRefOrLoad(unsigned Idx) {
return Pimpl->getMetadataFwdRefOrLoad(Idx);
}
MDNode *MetadataLoader::getMDNodeFwdRefOrNull(unsigned Idx) {

View File

@ -63,7 +63,7 @@ public:
/// Return the given metadata, creating a replaceable forward reference if
/// necessary.
Metadata *getMetadataFwdRef(unsigned Idx);
Metadata *getMetadataFwdRefOrLoad(unsigned Idx);
MDNode *getMDNodeFwdRefOrNull(unsigned Idx);

View File

@ -687,9 +687,30 @@ AArch64LoadStoreOpt::mergePairedInsns(MachineBasicBlock::iterator I,
MachineInstrBuilder MIB;
DebugLoc DL = I->getDebugLoc();
MachineBasicBlock *MBB = I->getParent();
MachineOperand RegOp0 = getLdStRegOp(*RtMI);
MachineOperand RegOp1 = getLdStRegOp(*Rt2MI);
// Kill flags may become invalid when moving stores for pairing.
if (RegOp0.isUse()) {
if (!MergeForward) {
// Clear kill flags on store if moving upwards. Example:
// STRWui %w0, ...
// USE %w1
// STRWui kill %w1 ; need to clear kill flag when moving STRWui upwards
RegOp0.setIsKill(false);
RegOp1.setIsKill(false);
} else {
// Clear kill flags of the first stores register. Example:
// STRWui %w1, ...
// USE kill %w1 ; need to clear kill flag when moving STRWui downwards
// STRW %w0
unsigned Reg = getLdStRegOp(*I).getReg();
for (MachineInstr &MI : make_range(std::next(I), Paired))
MI.clearRegisterKills(Reg, TRI);
}
}
MIB = BuildMI(*MBB, InsertionPoint, DL, TII->get(getMatchingPairOpcode(Opc)))
.addOperand(getLdStRegOp(*RtMI))
.addOperand(getLdStRegOp(*Rt2MI))
.addOperand(RegOp0)
.addOperand(RegOp1)
.addOperand(BaseRegOp)
.addImm(OffsetImm)
.setMemRefs(I->mergeMemRefsWith(*Paired));

View File

@ -97,171 +97,6 @@ namespace {
};
}
void ARMTargetLowering::InitLibcallCallingConvs() {
// The builtins on ARM always use AAPCS, irrespective of wheter C is AAPCS or
// AAPCS_VFP.
for (const auto LC : {
RTLIB::SHL_I16,
RTLIB::SHL_I32,
RTLIB::SHL_I64,
RTLIB::SHL_I128,
RTLIB::SRL_I16,
RTLIB::SRL_I32,
RTLIB::SRL_I64,
RTLIB::SRL_I128,
RTLIB::SRA_I16,
RTLIB::SRA_I32,
RTLIB::SRA_I64,
RTLIB::SRA_I128,
RTLIB::MUL_I8,
RTLIB::MUL_I16,
RTLIB::MUL_I32,
RTLIB::MUL_I64,
RTLIB::MUL_I128,
RTLIB::MULO_I32,
RTLIB::MULO_I64,
RTLIB::MULO_I128,
RTLIB::SDIV_I8,
RTLIB::SDIV_I16,
RTLIB::SDIV_I32,
RTLIB::SDIV_I64,
RTLIB::SDIV_I128,
RTLIB::UDIV_I8,
RTLIB::UDIV_I16,
RTLIB::UDIV_I32,
RTLIB::UDIV_I64,
RTLIB::UDIV_I128,
RTLIB::SREM_I8,
RTLIB::SREM_I16,
RTLIB::SREM_I32,
RTLIB::SREM_I64,
RTLIB::SREM_I128,
RTLIB::UREM_I8,
RTLIB::UREM_I16,
RTLIB::UREM_I32,
RTLIB::UREM_I64,
RTLIB::UREM_I128,
RTLIB::SDIVREM_I8,
RTLIB::SDIVREM_I16,
RTLIB::SDIVREM_I32,
RTLIB::SDIVREM_I64,
RTLIB::SDIVREM_I128,
RTLIB::UDIVREM_I8,
RTLIB::UDIVREM_I16,
RTLIB::UDIVREM_I32,
RTLIB::UDIVREM_I64,
RTLIB::UDIVREM_I128,
RTLIB::NEG_I32,
RTLIB::NEG_I64,
RTLIB::ADD_F32,
RTLIB::ADD_F64,
RTLIB::ADD_F80,
RTLIB::ADD_F128,
RTLIB::SUB_F32,
RTLIB::SUB_F64,
RTLIB::SUB_F80,
RTLIB::SUB_F128,
RTLIB::MUL_F32,
RTLIB::MUL_F64,
RTLIB::MUL_F80,
RTLIB::MUL_F128,
RTLIB::DIV_F32,
RTLIB::DIV_F64,
RTLIB::DIV_F80,
RTLIB::DIV_F128,
RTLIB::POWI_F32,
RTLIB::POWI_F64,
RTLIB::POWI_F80,
RTLIB::POWI_F128,
RTLIB::FPEXT_F64_F128,
RTLIB::FPEXT_F32_F128,
RTLIB::FPEXT_F32_F64,
RTLIB::FPEXT_F16_F32,
RTLIB::FPROUND_F32_F16,
RTLIB::FPROUND_F64_F16,
RTLIB::FPROUND_F80_F16,
RTLIB::FPROUND_F128_F16,
RTLIB::FPROUND_F64_F32,
RTLIB::FPROUND_F80_F32,
RTLIB::FPROUND_F128_F32,
RTLIB::FPROUND_F80_F64,
RTLIB::FPROUND_F128_F64,
RTLIB::FPTOSINT_F32_I32,
RTLIB::FPTOSINT_F32_I64,
RTLIB::FPTOSINT_F32_I128,
RTLIB::FPTOSINT_F64_I32,
RTLIB::FPTOSINT_F64_I64,
RTLIB::FPTOSINT_F64_I128,
RTLIB::FPTOSINT_F80_I32,
RTLIB::FPTOSINT_F80_I64,
RTLIB::FPTOSINT_F80_I128,
RTLIB::FPTOSINT_F128_I32,
RTLIB::FPTOSINT_F128_I64,
RTLIB::FPTOSINT_F128_I128,
RTLIB::FPTOUINT_F32_I32,
RTLIB::FPTOUINT_F32_I64,
RTLIB::FPTOUINT_F32_I128,
RTLIB::FPTOUINT_F64_I32,
RTLIB::FPTOUINT_F64_I64,
RTLIB::FPTOUINT_F64_I128,
RTLIB::FPTOUINT_F80_I32,
RTLIB::FPTOUINT_F80_I64,
RTLIB::FPTOUINT_F80_I128,
RTLIB::FPTOUINT_F128_I32,
RTLIB::FPTOUINT_F128_I64,
RTLIB::FPTOUINT_F128_I128,
RTLIB::SINTTOFP_I32_F32,
RTLIB::SINTTOFP_I32_F64,
RTLIB::SINTTOFP_I32_F80,
RTLIB::SINTTOFP_I32_F128,
RTLIB::SINTTOFP_I64_F32,
RTLIB::SINTTOFP_I64_F64,
RTLIB::SINTTOFP_I64_F80,
RTLIB::SINTTOFP_I64_F128,
RTLIB::SINTTOFP_I128_F32,
RTLIB::SINTTOFP_I128_F64,
RTLIB::SINTTOFP_I128_F80,
RTLIB::SINTTOFP_I128_F128,
RTLIB::UINTTOFP_I32_F32,
RTLIB::UINTTOFP_I32_F64,
RTLIB::UINTTOFP_I32_F80,
RTLIB::UINTTOFP_I32_F128,
RTLIB::UINTTOFP_I64_F32,
RTLIB::UINTTOFP_I64_F64,
RTLIB::UINTTOFP_I64_F80,
RTLIB::UINTTOFP_I64_F128,
RTLIB::UINTTOFP_I128_F32,
RTLIB::UINTTOFP_I128_F64,
RTLIB::UINTTOFP_I128_F80,
RTLIB::UINTTOFP_I128_F128,
RTLIB::OEQ_F32,
RTLIB::OEQ_F64,
RTLIB::OEQ_F128,
RTLIB::UNE_F32,
RTLIB::UNE_F64,
RTLIB::UNE_F128,
RTLIB::OGE_F32,
RTLIB::OGE_F64,
RTLIB::OGE_F128,
RTLIB::OLT_F32,
RTLIB::OLT_F64,
RTLIB::OLT_F128,
RTLIB::OLE_F32,
RTLIB::OLE_F64,
RTLIB::OLE_F128,
RTLIB::OGT_F32,
RTLIB::OGT_F64,
RTLIB::OGT_F128,
RTLIB::UO_F32,
RTLIB::UO_F64,
RTLIB::UO_F128,
RTLIB::O_F32,
RTLIB::O_F64,
RTLIB::O_F128,
})
setLibcallCallingConv(LC, CallingConv::ARM_AAPCS);
}
// The APCS parameter registers.
static const MCPhysReg GPRArgRegs[] = {
ARM::R0, ARM::R1, ARM::R2, ARM::R3
@ -349,7 +184,22 @@ ARMTargetLowering::ARMTargetLowering(const TargetMachine &TM,
setBooleanVectorContents(ZeroOrNegativeOneBooleanContent);
InitLibcallCallingConvs();
if (!Subtarget->isTargetDarwin() && !Subtarget->isTargetIOS() &&
!Subtarget->isTargetWatchOS()) {
const auto &E = Subtarget->getTargetTriple().getEnvironment();
bool IsHFTarget = E == Triple::EABIHF || E == Triple::GNUEABIHF ||
E == Triple::MuslEABIHF;
// Windows is a special case. Technically, we will replace all of the "GNU"
// calls with calls to MSVCRT if appropriate and adjust the calling
// convention then.
IsHFTarget = IsHFTarget || Subtarget->isTargetWindows();
for (int LCID = 0; LCID < RTLIB::UNKNOWN_LIBCALL; ++LCID)
setLibcallCallingConv(static_cast<RTLIB::Libcall>(LCID),
IsHFTarget ? CallingConv::ARM_AAPCS_VFP
: CallingConv::ARM_AAPCS);
}
if (Subtarget->isTargetMachO()) {
// Uses VFP for Thumb libfuncs if available.

View File

@ -538,8 +538,6 @@ class InstrItineraryData;
bool HasStandaloneRem = true;
void InitLibcallCallingConvs();
void addTypeForNEON(MVT VT, MVT PromotedLdStVT, MVT PromotedBitwiseVT);
void addDRTypeForNEON(MVT VT);
void addQRTypeForNEON(MVT VT);

View File

@ -28788,10 +28788,12 @@ static SDValue combineExtractVectorElt(SDNode *N, SelectionDAG &DAG,
return SDValue();
}
/// If a vector select has an operand that is -1 or 0, simplify the select to a
/// bitwise logic operation.
static SDValue combineVSelectWithAllOnesOrZeros(SDNode *N, SelectionDAG &DAG,
const X86Subtarget &Subtarget) {
/// If a vector select has an operand that is -1 or 0, try to simplify the
/// select to a bitwise logic operation.
static SDValue
combineVSelectWithAllOnesOrZeros(SDNode *N, SelectionDAG &DAG,
TargetLowering::DAGCombinerInfo &DCI,
const X86Subtarget &Subtarget) {
SDValue Cond = N->getOperand(0);
SDValue LHS = N->getOperand(1);
SDValue RHS = N->getOperand(2);
@ -28853,18 +28855,28 @@ static SDValue combineVSelectWithAllOnesOrZeros(SDNode *N, SelectionDAG &DAG,
}
}
if (!TValIsAllOnes && !FValIsAllZeros)
// vselect Cond, 111..., 000... -> Cond
if (TValIsAllOnes && FValIsAllZeros)
return DAG.getBitcast(VT, Cond);
if (!DCI.isBeforeLegalize() && !TLI.isTypeLegal(CondVT))
return SDValue();
SDValue Ret;
if (TValIsAllOnes && FValIsAllZeros)
Ret = Cond;
else if (TValIsAllOnes)
Ret = DAG.getNode(ISD::OR, DL, CondVT, Cond, DAG.getBitcast(CondVT, RHS));
else if (FValIsAllZeros)
Ret = DAG.getNode(ISD::AND, DL, CondVT, Cond, DAG.getBitcast(CondVT, LHS));
// vselect Cond, 111..., X -> or Cond, X
if (TValIsAllOnes) {
SDValue CastRHS = DAG.getBitcast(CondVT, RHS);
SDValue Or = DAG.getNode(ISD::OR, DL, CondVT, Cond, CastRHS);
return DAG.getBitcast(VT, Or);
}
return DAG.getBitcast(VT, Ret);
// vselect Cond, X, 000... -> and Cond, X
if (FValIsAllZeros) {
SDValue CastLHS = DAG.getBitcast(CondVT, LHS);
SDValue And = DAG.getNode(ISD::AND, DL, CondVT, Cond, CastLHS);
return DAG.getBitcast(VT, And);
}
return SDValue();
}
static SDValue combineSelectOfTwoConstants(SDNode *N, SelectionDAG &DAG) {
@ -29353,7 +29365,7 @@ static SDValue combineSelect(SDNode *N, SelectionDAG &DAG,
}
}
if (SDValue V = combineVSelectWithAllOnesOrZeros(N, DAG, Subtarget))
if (SDValue V = combineVSelectWithAllOnesOrZeros(N, DAG, DCI, Subtarget))
return V;
// If this is a *dynamic* select (non-constant condition) and we can match

View File

@ -600,6 +600,22 @@ private:
void initializeCallbacks(Module &M);
bool InstrumentGlobals(IRBuilder<> &IRB, Module &M);
void InstrumentGlobalsCOFF(IRBuilder<> &IRB, Module &M,
ArrayRef<GlobalVariable *> ExtendedGlobals,
ArrayRef<Constant *> MetadataInitializers);
void InstrumentGlobalsMachO(IRBuilder<> &IRB, Module &M,
ArrayRef<GlobalVariable *> ExtendedGlobals,
ArrayRef<Constant *> MetadataInitializers);
void
InstrumentGlobalsWithMetadataArray(IRBuilder<> &IRB, Module &M,
ArrayRef<GlobalVariable *> ExtendedGlobals,
ArrayRef<Constant *> MetadataInitializers);
GlobalVariable *CreateMetadataGlobal(Module &M, Constant *Initializer,
StringRef OriginalName);
void SetComdatForGlobalMetadata(GlobalVariable *G, GlobalVariable *Metadata);
IRBuilder<> CreateAsanModuleDtor(Module &M);
bool ShouldInstrumentGlobal(GlobalVariable *G);
bool ShouldUseMachOGlobalsSection() const;
StringRef getGlobalMetadataSection() const;
@ -1553,17 +1569,173 @@ void AddressSanitizerModule::initializeCallbacks(Module &M) {
// Declare the functions that find globals in a shared object and then invoke
// the (un)register function on them.
AsanRegisterImageGlobals = checkSanitizerInterfaceFunction(
M.getOrInsertFunction(kAsanRegisterImageGlobalsName,
IRB.getVoidTy(), IntptrTy, nullptr));
AsanRegisterImageGlobals =
checkSanitizerInterfaceFunction(M.getOrInsertFunction(
kAsanRegisterImageGlobalsName, IRB.getVoidTy(), IntptrTy, nullptr));
AsanRegisterImageGlobals->setLinkage(Function::ExternalLinkage);
AsanUnregisterImageGlobals = checkSanitizerInterfaceFunction(
M.getOrInsertFunction(kAsanUnregisterImageGlobalsName,
IRB.getVoidTy(), IntptrTy, nullptr));
AsanUnregisterImageGlobals =
checkSanitizerInterfaceFunction(M.getOrInsertFunction(
kAsanUnregisterImageGlobalsName, IRB.getVoidTy(), IntptrTy, nullptr));
AsanUnregisterImageGlobals->setLinkage(Function::ExternalLinkage);
}
// Put the metadata and the instrumented global in the same group. This ensures
// that the metadata is discarded if the instrumented global is discarded.
void AddressSanitizerModule::SetComdatForGlobalMetadata(
GlobalVariable *G, GlobalVariable *Metadata) {
Module &M = *G->getParent();
Comdat *C = G->getComdat();
if (!C) {
if (!G->hasName()) {
// If G is unnamed, it must be internal. Give it an artificial name
// so we can put it in a comdat.
assert(G->hasLocalLinkage());
G->setName(Twine(kAsanGenPrefix) + "_anon_global");
}
C = M.getOrInsertComdat(G->getName());
// Make this IMAGE_COMDAT_SELECT_NODUPLICATES on COFF.
if (TargetTriple.isOSBinFormatCOFF())
C->setSelectionKind(Comdat::NoDuplicates);
G->setComdat(C);
}
assert(G->hasComdat());
Metadata->setComdat(G->getComdat());
}
// Create a separate metadata global and put it in the appropriate ASan
// global registration section.
GlobalVariable *
AddressSanitizerModule::CreateMetadataGlobal(Module &M, Constant *Initializer,
StringRef OriginalName) {
GlobalVariable *Metadata =
new GlobalVariable(M, Initializer->getType(), false,
GlobalVariable::InternalLinkage, Initializer,
Twine("__asan_global_") +
GlobalValue::getRealLinkageName(OriginalName));
Metadata->setSection(getGlobalMetadataSection());
return Metadata;
}
IRBuilder<> AddressSanitizerModule::CreateAsanModuleDtor(Module &M) {
Function *AsanDtorFunction =
Function::Create(FunctionType::get(Type::getVoidTy(*C), false),
GlobalValue::InternalLinkage, kAsanModuleDtorName, &M);
BasicBlock *AsanDtorBB = BasicBlock::Create(*C, "", AsanDtorFunction);
appendToGlobalDtors(M, AsanDtorFunction, kAsanCtorAndDtorPriority);
return IRBuilder<>(ReturnInst::Create(*C, AsanDtorBB));
}
void AddressSanitizerModule::InstrumentGlobalsCOFF(
IRBuilder<> &IRB, Module &M, ArrayRef<GlobalVariable *> ExtendedGlobals,
ArrayRef<Constant *> MetadataInitializers) {
assert(ExtendedGlobals.size() == MetadataInitializers.size());
auto &DL = M.getDataLayout();
for (size_t i = 0; i < ExtendedGlobals.size(); i++) {
Constant *Initializer = MetadataInitializers[i];
GlobalVariable *G = ExtendedGlobals[i];
GlobalVariable *Metadata =
CreateMetadataGlobal(M, Initializer, G->getName());
// The MSVC linker always inserts padding when linking incrementally. We
// cope with that by aligning each struct to its size, which must be a power
// of two.
unsigned SizeOfGlobalStruct = DL.getTypeAllocSize(Initializer->getType());
assert(isPowerOf2_32(SizeOfGlobalStruct) &&
"global metadata will not be padded appropriately");
Metadata->setAlignment(SizeOfGlobalStruct);
SetComdatForGlobalMetadata(G, Metadata);
}
}
void AddressSanitizerModule::InstrumentGlobalsMachO(
IRBuilder<> &IRB, Module &M, ArrayRef<GlobalVariable *> ExtendedGlobals,
ArrayRef<Constant *> MetadataInitializers) {
assert(ExtendedGlobals.size() == MetadataInitializers.size());
// On recent Mach-O platforms, use a structure which binds the liveness of
// the global variable to the metadata struct. Keep the list of "Liveness" GV
// created to be added to llvm.compiler.used
StructType *LivenessTy = StructType::get(IntptrTy, IntptrTy, nullptr);
SmallVector<GlobalValue *, 16> LivenessGlobals(ExtendedGlobals.size());
for (size_t i = 0; i < ExtendedGlobals.size(); i++) {
Constant *Initializer = MetadataInitializers[i];
GlobalVariable *G = ExtendedGlobals[i];
GlobalVariable *Metadata =
CreateMetadataGlobal(M, Initializer, G->getName());
// On recent Mach-O platforms, we emit the global metadata in a way that
// allows the linker to properly strip dead globals.
auto LivenessBinder = ConstantStruct::get(
LivenessTy, Initializer->getAggregateElement(0u),
ConstantExpr::getPointerCast(Metadata, IntptrTy), nullptr);
GlobalVariable *Liveness = new GlobalVariable(
M, LivenessTy, false, GlobalVariable::InternalLinkage, LivenessBinder,
Twine("__asan_binder_") + G->getName());
Liveness->setSection("__DATA,__asan_liveness,regular,live_support");
LivenessGlobals[i] = Liveness;
}
// Update llvm.compiler.used, adding the new liveness globals. This is
// needed so that during LTO these variables stay alive. The alternative
// would be to have the linker handling the LTO symbols, but libLTO
// current API does not expose access to the section for each symbol.
if (!LivenessGlobals.empty())
appendToCompilerUsed(M, LivenessGlobals);
// RegisteredFlag serves two purposes. First, we can pass it to dladdr()
// to look up the loaded image that contains it. Second, we can store in it
// whether registration has already occurred, to prevent duplicate
// registration.
//
// common linkage ensures that there is only one global per shared library.
GlobalVariable *RegisteredFlag = new GlobalVariable(
M, IntptrTy, false, GlobalVariable::CommonLinkage,
ConstantInt::get(IntptrTy, 0), kAsanGlobalsRegisteredFlagName);
RegisteredFlag->setVisibility(GlobalVariable::HiddenVisibility);
IRB.CreateCall(AsanRegisterImageGlobals,
{IRB.CreatePointerCast(RegisteredFlag, IntptrTy)});
// We also need to unregister globals at the end, e.g., when a shared library
// gets closed.
IRBuilder<> IRB_Dtor = CreateAsanModuleDtor(M);
IRB_Dtor.CreateCall(AsanUnregisterImageGlobals,
{IRB.CreatePointerCast(RegisteredFlag, IntptrTy)});
}
void AddressSanitizerModule::InstrumentGlobalsWithMetadataArray(
IRBuilder<> &IRB, Module &M, ArrayRef<GlobalVariable *> ExtendedGlobals,
ArrayRef<Constant *> MetadataInitializers) {
assert(ExtendedGlobals.size() == MetadataInitializers.size());
unsigned N = ExtendedGlobals.size();
assert(N > 0);
// On platforms that don't have a custom metadata section, we emit an array
// of global metadata structures.
ArrayType *ArrayOfGlobalStructTy =
ArrayType::get(MetadataInitializers[0]->getType(), N);
auto AllGlobals = new GlobalVariable(
M, ArrayOfGlobalStructTy, false, GlobalVariable::InternalLinkage,
ConstantArray::get(ArrayOfGlobalStructTy, MetadataInitializers), "");
IRB.CreateCall(AsanRegisterGlobals,
{IRB.CreatePointerCast(AllGlobals, IntptrTy),
ConstantInt::get(IntptrTy, N)});
// We also need to unregister globals at the end, e.g., when a shared library
// gets closed.
IRBuilder<> IRB_Dtor = CreateAsanModuleDtor(M);
IRB_Dtor.CreateCall(AsanUnregisterGlobals,
{IRB.CreatePointerCast(AllGlobals, IntptrTy),
ConstantInt::get(IntptrTy, N)});
}
// This function replaces all global variables with new variables that have
// trailing redzones. It also creates a function that poisons
// redzones and inserts this function into llvm.global_ctors.
@ -1580,9 +1752,6 @@ bool AddressSanitizerModule::InstrumentGlobals(IRBuilder<> &IRB, Module &M) {
if (n == 0) return false;
auto &DL = M.getDataLayout();
bool UseComdatMetadata = TargetTriple.isOSBinFormatCOFF();
bool UseMachOGlobalsSection = ShouldUseMachOGlobalsSection();
bool UseMetadataArray = !(UseComdatMetadata || UseMachOGlobalsSection);
// A global is described by a structure
// size_t beg;
@ -1597,19 +1766,8 @@ bool AddressSanitizerModule::InstrumentGlobals(IRBuilder<> &IRB, Module &M) {
StructType *GlobalStructTy =
StructType::get(IntptrTy, IntptrTy, IntptrTy, IntptrTy, IntptrTy,
IntptrTy, IntptrTy, IntptrTy, nullptr);
unsigned SizeOfGlobalStruct = DL.getTypeAllocSize(GlobalStructTy);
assert(isPowerOf2_32(SizeOfGlobalStruct) &&
"global metadata will not be padded appropriately");
SmallVector<Constant *, 16> Initializers(UseMetadataArray ? n : 0);
// On recent Mach-O platforms, use a structure which binds the liveness of
// the global variable to the metadata struct. Keep the list of "Liveness" GV
// created to be added to llvm.compiler.used
StructType *LivenessTy = nullptr;
if (UseMachOGlobalsSection)
LivenessTy = StructType::get(IntptrTy, IntptrTy, nullptr);
SmallVector<GlobalValue *, 16> LivenessGlobals(
UseMachOGlobalsSection ? n : 0);
SmallVector<GlobalVariable *, 16> NewGlobals(n);
SmallVector<Constant *, 16> Initializers(n);
bool HasDynamicallyInitializedGlobals = false;
@ -1681,25 +1839,7 @@ bool AddressSanitizerModule::InstrumentGlobals(IRBuilder<> &IRB, Module &M) {
ConstantExpr::getGetElementPtr(NewTy, NewGlobal, Indices2, true));
NewGlobal->takeName(G);
G->eraseFromParent();
G = NewGlobal;
if (UseComdatMetadata) {
// Get or create a COMDAT for G so that we can use it with our metadata.
Comdat *C = G->getComdat();
if (!C) {
if (!G->hasName()) {
// If G is unnamed, it must be internal. Give it an artificial name
// so we can put it in a comdat.
assert(G->hasLocalLinkage());
G->setName(Twine(kAsanGenPrefix) + "_anon_global");
}
C = M.getOrInsertComdat(G->getName());
// Make this IMAGE_COMDAT_SELECT_NODUPLICATES on COFF.
if (TargetTriple.isOSBinFormatCOFF())
C->setSelectionKind(Comdat::NoDuplicates);
G->setComdat(C);
}
}
NewGlobals[i] = NewGlobal;
Constant *SourceLoc;
if (!MD.SourceLoc.empty()) {
@ -1750,117 +1890,21 @@ bool AddressSanitizerModule::InstrumentGlobals(IRBuilder<> &IRB, Module &M) {
DEBUG(dbgs() << "NEW GLOBAL: " << *NewGlobal << "\n");
// If we aren't using separate metadata globals, add it to the initializer
// list and continue.
if (UseMetadataArray) {
Initializers[i] = Initializer;
continue;
}
Initializers[i] = Initializer;
}
// Create a separate metadata global and put it in the appropriate ASan
// global registration section.
GlobalVariable *Metadata = new GlobalVariable(
M, GlobalStructTy, false, GlobalVariable::InternalLinkage,
Initializer, Twine("__asan_global_") +
GlobalValue::getRealLinkageName(G->getName()));
Metadata->setSection(getGlobalMetadataSection());
// We don't want any padding, but we also need a reasonable alignment.
// The MSVC linker always inserts padding when linking incrementally. We
// cope with that by aligning each struct to its size, which must be a power
// of two.
Metadata->setAlignment(SizeOfGlobalStruct);
// On platforms that support comdats, put the metadata and the
// instrumented global in the same group. This ensures that the metadata
// is discarded if the instrumented global is discarded.
if (UseComdatMetadata) {
assert(G->hasComdat());
Metadata->setComdat(G->getComdat());
continue;
}
assert(UseMachOGlobalsSection);
// On recent Mach-O platforms, we emit the global metadata in a way that
// allows the linker to properly strip dead globals.
auto LivenessBinder = ConstantStruct::get(
LivenessTy, Initializer->getAggregateElement(0u),
ConstantExpr::getPointerCast(Metadata, IntptrTy), nullptr);
GlobalVariable *Liveness = new GlobalVariable(
M, LivenessTy, false, GlobalVariable::InternalLinkage, LivenessBinder,
Twine("__asan_binder_") + G->getName());
Liveness->setSection("__DATA,__asan_liveness,regular,live_support");
LivenessGlobals[i] = Liveness;
if (TargetTriple.isOSBinFormatCOFF()) {
InstrumentGlobalsCOFF(IRB, M, NewGlobals, Initializers);
} else if (ShouldUseMachOGlobalsSection()) {
InstrumentGlobalsMachO(IRB, M, NewGlobals, Initializers);
} else {
InstrumentGlobalsWithMetadataArray(IRB, M, NewGlobals, Initializers);
}
// Create calls for poisoning before initializers run and unpoisoning after.
if (HasDynamicallyInitializedGlobals)
createInitializerPoisonCalls(M, ModuleName);
// Platforms with a dedicated metadata section don't need to emit any more
// code.
if (UseComdatMetadata)
return true;
GlobalVariable *AllGlobals = nullptr;
GlobalVariable *RegisteredFlag = nullptr;
if (UseMachOGlobalsSection) {
// RegisteredFlag serves two purposes. First, we can pass it to dladdr()
// to look up the loaded image that contains it. Second, we can store in it
// whether registration has already occurred, to prevent duplicate
// registration.
//
// common linkage ensures that there is only one global per shared library.
RegisteredFlag = new GlobalVariable(
M, IntptrTy, false, GlobalVariable::CommonLinkage,
ConstantInt::get(IntptrTy, 0), kAsanGlobalsRegisteredFlagName);
RegisteredFlag->setVisibility(GlobalVariable::HiddenVisibility);
// Update llvm.compiler.used, adding the new liveness globals. This is
// needed so that during LTO these variables stay alive. The alternative
// would be to have the linker handling the LTO symbols, but libLTO
// current API does not expose access to the section for each symbol.
if (!LivenessGlobals.empty())
appendToCompilerUsed(M, LivenessGlobals);
} else if (UseMetadataArray) {
// On platforms that don't have a custom metadata section, we emit an array
// of global metadata structures.
ArrayType *ArrayOfGlobalStructTy = ArrayType::get(GlobalStructTy, n);
AllGlobals = new GlobalVariable(
M, ArrayOfGlobalStructTy, false, GlobalVariable::InternalLinkage,
ConstantArray::get(ArrayOfGlobalStructTy, Initializers), "");
}
// Create a call to register the globals with the runtime.
if (UseMachOGlobalsSection) {
IRB.CreateCall(AsanRegisterImageGlobals,
{IRB.CreatePointerCast(RegisteredFlag, IntptrTy)});
} else {
IRB.CreateCall(AsanRegisterGlobals,
{IRB.CreatePointerCast(AllGlobals, IntptrTy),
ConstantInt::get(IntptrTy, n)});
}
// We also need to unregister globals at the end, e.g., when a shared library
// gets closed.
Function *AsanDtorFunction =
Function::Create(FunctionType::get(Type::getVoidTy(*C), false),
GlobalValue::InternalLinkage, kAsanModuleDtorName, &M);
BasicBlock *AsanDtorBB = BasicBlock::Create(*C, "", AsanDtorFunction);
IRBuilder<> IRB_Dtor(ReturnInst::Create(*C, AsanDtorBB));
if (UseMachOGlobalsSection) {
IRB_Dtor.CreateCall(AsanUnregisterImageGlobals,
{IRB.CreatePointerCast(RegisteredFlag, IntptrTy)});
} else {
IRB_Dtor.CreateCall(AsanUnregisterGlobals,
{IRB.CreatePointerCast(AllGlobals, IntptrTy),
ConstantInt::get(IntptrTy, n)});
}
appendToGlobalDtors(M, AsanDtorFunction, kAsanCtorAndDtorPriority);
DEBUG(dbgs() << M);
return true;
}

View File

@ -85,6 +85,8 @@ STATISTIC(NumGVNLeaderChanges, "Number of leader changes");
STATISTIC(NumGVNSortedLeaderChanges, "Number of sorted leader changes");
STATISTIC(NumGVNAvoidedSortedLeaderChanges,
"Number of avoided sorted leader changes");
STATISTIC(NumGVNNotMostDominatingLeader,
"Number of times a member dominated it's new classes' leader");
//===----------------------------------------------------------------------===//
// GVN Pass
@ -1073,17 +1075,20 @@ void NewGVN::moveValueToNewCongruenceClass(Instruction *I,
if (I == OldClass->NextLeader.first)
OldClass->NextLeader = {nullptr, ~0U};
// The new instruction and new class leader may either be siblings in the
// dominator tree, or the new class leader should dominate the new member
// instruction. We simply check that the member instruction does not properly
// dominate the new class leader.
assert(
!isa<Instruction>(NewClass->RepLeader) || !NewClass->RepLeader ||
I == NewClass->RepLeader ||
!DT->properlyDominates(
// It's possible, though unlikely, for us to discover equivalences such
// that the current leader does not dominate the old one.
// This statistic tracks how often this happens.
// We assert on phi nodes when this happens, currently, for debugging, because
// we want to make sure we name phi node cycles properly.
if (isa<Instruction>(NewClass->RepLeader) && NewClass->RepLeader &&
I != NewClass->RepLeader &&
DT->properlyDominates(
I->getParent(),
cast<Instruction>(NewClass->RepLeader)->getParent()) &&
"New class for instruction should not be dominated by instruction");
cast<Instruction>(NewClass->RepLeader)->getParent())) {
++NumGVNNotMostDominatingLeader;
assert(!isa<PHINode>(I) &&
"New class for instruction should not be dominated by instruction");
}
if (NewClass->RepLeader != I) {
auto DFSNum = InstrDFS.lookup(I);

View File

@ -1,133 +0,0 @@
# RUN: llc -run-pass=aarch64-ldst-opt %s -o - 2>&1 | FileCheck %s
--- |
target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
target triple = "aarch64--linux-gnu"
; Function Attrs: nounwind
define i16 @promote-load-from-store(i32* %dst, i32 %x) #0 {
store i32 %x, i32* %dst
%dst16 = bitcast i32* %dst to i16*
%dst1 = getelementptr inbounds i16, i16* %dst16, i32 1
%x16 = load i16, i16* %dst1
ret i16 %x16
}
; Function Attrs: nounwind
define void @store-pair(i32* %dst, i32 %x, i32 %y) #0 {
%dst01 = bitcast i32* %dst to i32*
%dst1 = getelementptr inbounds i32, i32* %dst, i32 1
store i32 %x, i32* %dst01
store i32 %x, i32* %dst1
ret void
}
attributes #0 = { nounwind }
...
---
name: promote-load-from-store
alignment: 2
exposesReturnsTwice: false
tracksRegLiveness: true
liveins:
- { reg: '%x0' }
- { reg: '%w1' }
frameInfo:
isFrameAddressTaken: false
isReturnAddressTaken: false
hasStackMap: false
hasPatchPoint: false
stackSize: 0
offsetAdjustment: 0
maxAlignment: 0
adjustsStack: false
hasCalls: false
maxCallFrameSize: 0
hasOpaqueSPAdjustment: false
hasVAStart: false
hasMustTailInVarArgFunc: false
body: |
bb.0 (%ir-block.0):
liveins: %w1, %x0, %lr
STRWui killed %w1, %x0, 0 :: (store 4 into %ir.dst)
CFI_INSTRUCTION 0
CFI_INSTRUCTION 0
CFI_INSTRUCTION 0
CFI_INSTRUCTION 0
CFI_INSTRUCTION 0
CFI_INSTRUCTION 0
CFI_INSTRUCTION 0
CFI_INSTRUCTION 0
CFI_INSTRUCTION 0
CFI_INSTRUCTION 0
CFI_INSTRUCTION 0
CFI_INSTRUCTION 0
CFI_INSTRUCTION 0
CFI_INSTRUCTION 0
CFI_INSTRUCTION 0
CFI_INSTRUCTION 0
CFI_INSTRUCTION 0
CFI_INSTRUCTION 0
CFI_INSTRUCTION 0
CFI_INSTRUCTION 0
%w0 = LDRHHui killed %x0, 1 :: (load 2 from %ir.dst1)
RET %lr, implicit %w0
...
# CHECK-LABEL: name: promote-load-from-store
# CHECK: STRWui %w1
# CHECK: UBFMWri %w1
---
name: store-pair
alignment: 2
exposesReturnsTwice: false
tracksRegLiveness: true
liveins:
- { reg: '%x0' }
- { reg: '%w1' }
frameInfo:
isFrameAddressTaken: false
isReturnAddressTaken: false
hasStackMap: false
hasPatchPoint: false
stackSize: 0
offsetAdjustment: 0
maxAlignment: 0
adjustsStack: false
hasCalls: false
maxCallFrameSize: 0
hasOpaqueSPAdjustment: false
hasVAStart: false
hasMustTailInVarArgFunc: false
body: |
bb.0 (%ir-block.0):
liveins: %w1, %x0, %lr
STRWui %w1, %x0, 0 :: (store 4 into %ir.dst01)
CFI_INSTRUCTION 0
CFI_INSTRUCTION 0
CFI_INSTRUCTION 0
CFI_INSTRUCTION 0
CFI_INSTRUCTION 0
CFI_INSTRUCTION 0
CFI_INSTRUCTION 0
CFI_INSTRUCTION 0
CFI_INSTRUCTION 0
CFI_INSTRUCTION 0
CFI_INSTRUCTION 0
CFI_INSTRUCTION 0
CFI_INSTRUCTION 0
CFI_INSTRUCTION 0
CFI_INSTRUCTION 0
CFI_INSTRUCTION 0
CFI_INSTRUCTION 0
CFI_INSTRUCTION 0
CFI_INSTRUCTION 0
CFI_INSTRUCTION 0
STRWui killed %w1, killed %x0, 1 :: (store 4 into %ir.dst1)
RET %lr
...
# CHECK-LABEL: name: store-pair
# CHECK: STPWi

View File

@ -0,0 +1,132 @@
# RUN: llc -mtriple=aarch64--linux-gnu -run-pass=aarch64-ldst-opt %s -verify-machineinstrs -o - 2>&1 | FileCheck %s
--- |
define void @promote-load-from-store() { ret void }
define void @store-pair() { ret void }
define void @store-pair-clearkill0() { ret void }
define void @store-pair-clearkill1() { ret void }
...
---
name: promote-load-from-store
tracksRegLiveness: true
body: |
bb.0:
liveins: %w1, %x0, %lr
STRWui killed %w1, %x0, 0 :: (store 4)
CFI_INSTRUCTION 0
CFI_INSTRUCTION 0
CFI_INSTRUCTION 0
CFI_INSTRUCTION 0
CFI_INSTRUCTION 0
CFI_INSTRUCTION 0
CFI_INSTRUCTION 0
CFI_INSTRUCTION 0
CFI_INSTRUCTION 0
CFI_INSTRUCTION 0
CFI_INSTRUCTION 0
CFI_INSTRUCTION 0
CFI_INSTRUCTION 0
CFI_INSTRUCTION 0
CFI_INSTRUCTION 0
CFI_INSTRUCTION 0
CFI_INSTRUCTION 0
CFI_INSTRUCTION 0
CFI_INSTRUCTION 0
CFI_INSTRUCTION 0
%w0 = LDRHHui killed %x0, 1 :: (load 2)
RET %lr, implicit %w0
...
# Don't count transient instructions towards search limits.
# CHECK-LABEL: name: promote-load-from-store
# CHECK: STRWui %w1
# CHECK: UBFMWri %w1
---
name: store-pair
tracksRegLiveness: true
body: |
bb.0:
liveins: %w1, %x0, %lr
STRWui %w1, %x0, 0 :: (store 4)
CFI_INSTRUCTION 0
CFI_INSTRUCTION 0
CFI_INSTRUCTION 0
CFI_INSTRUCTION 0
CFI_INSTRUCTION 0
CFI_INSTRUCTION 0
CFI_INSTRUCTION 0
CFI_INSTRUCTION 0
CFI_INSTRUCTION 0
CFI_INSTRUCTION 0
CFI_INSTRUCTION 0
CFI_INSTRUCTION 0
CFI_INSTRUCTION 0
CFI_INSTRUCTION 0
CFI_INSTRUCTION 0
CFI_INSTRUCTION 0
CFI_INSTRUCTION 0
CFI_INSTRUCTION 0
CFI_INSTRUCTION 0
CFI_INSTRUCTION 0
STRWui killed %w1, killed %x0, 1 :: (store 4)
RET %lr
...
# CHECK-LABEL: name: store-pair
# CHECK: STPWi
---
name: store-pair-clearkill0
tracksRegLiveness: true
body: |
bb.0:
liveins: %w1, %x0, %lr
STRWui %w1, %x0, 0 :: (store 4)
%w2 = COPY %w1
%x3 = COPY %x0
STRWui killed %w1, killed %x0, 1 :: (store 4)
RET %lr
...
# When merging a lower store with an upper one, we must clear kill flags on
# the lower store.
# CHECK-LABEL: store-pair-clearkill0
# CHECK-NOT: STPWi %w1, killed %w1, %x0, 0 :: (store 4)
# CHECK: STPWi %w1, %w1, %x0, 0 :: (store 4)
# CHECK: %w2 = COPY %w1
# CHECK: RET %lr
---
name: store-pair-clearkill1
tracksRegLiveness: true
body: |
bb.0:
liveins: %x0, %lr
%w1 = MOVi32imm 13
%w2 = MOVi32imm 7
STRWui %w1, %x0, 1 :: (store 4)
%w2 = COPY killed %w1
STRWui killed %w2, %x0, 0 :: (store 4)
%w1 = MOVi32imm 42
%w2 = MOVi32imm 7
STRWui %w1, %x0, 0 :: (store 4)
%w2 = COPY killed %w1
STRWui killed %w2, killed %x0, 1 :: (store 4)
RET %lr
...
# When merging an upper store with a lower one, kill flags along the way need
# to be removed; In this case the kill flag on %w1.
# CHECK-LABEL: store-pair-clearkill1
# CHECK: %w1 = MOVi32imm
# CHECK: %w2 = MOVi32imm
# CHECK-NOT: %w2 = COPY killed %w1
# CHECK: %w2 = COPY %w1
# CHECK: STPWi killed %w2, %w1, %x0, 0
# CHECK: %w1 = MOVi32imm
# CHECK: %w2 = MOVi32imm
# CHECK-NOT: %w2 = COPY killed %w1
# CHECK: %w2 = COPY %w1
# CHECK: STPWi %w1, killed %w2, killed %x0, 0

View File

@ -18,7 +18,7 @@ declare double @llvm.powi.f64(double %Val, i32 %power)
define double @powi_d(double %a, i32 %b) {
; CHECK-LABEL: powi_d:
; SOFT: {{(bl|b)}} __powidf2
; HARD: bl __powidf2
; HARD: b __powidf2
%1 = call double @llvm.powi.f64(double %a, i32 %b)
ret double %1
}

View File

@ -18,7 +18,7 @@ declare float @llvm.powi.f32(float %Val, i32 %power)
define float @powi_f(float %a, i32 %b) {
; CHECK-LABEL: powi_f:
; SOFT: bl __powisf2
; HARD: bl __powisf2
; HARD: b __powisf2
%1 = call float @llvm.powi.f32(float %a, i32 %b)
ret float %1
}

View File

@ -0,0 +1,41 @@
; RUN: llc -mtriple thumbv7-unknown-none-eabi -float-abi soft -filetype asm -o - %s | FileCheck %s -check-prefix CHECK-MATCH
; RUN: llc -mtriple thumbv7-unknown-none-eabi -float-abi hard -filetype asm -o - %s | FileCheck %s -check-prefix CHECK-MISMATCH -check-prefix CHECK-TO-SOFT
; RUN: llc -mtriple thumbv7-unknown-none-eabihf -float-abi soft -filetype asm -o - %s | FileCheck %s -check-prefix CHECK-MISMATCH -check-prefix CHECK-TO-HARD
; RUN: llc -mtriple thumbv7-unknown-none-eabihf -float-abi hard -filetype asm -o - %s | FileCheck %s -check-prefix CHECK-MATCH
; RUN: llc -mtriple thumbv7-unknown-none-gnueabi -float-abi soft -filetype asm -o - %s | FileCheck %s -check-prefix CHECK-MATCH
; RUN: llc -mtriple thumbv7-unknown-none-gnueabi -float-abi hard -filetype asm -o - %s | FileCheck %s -check-prefix CHECK-MISMATCH -check-prefix CHECK-TO-SOFT
; RUN: llc -mtriple thumbv7-unknown-none-gnueabihf -float-abi soft -filetype asm -o - %s | FileCheck %s -check-prefix CHECK-MISMATCH -check-prefix CHECK-TO-HARD
; RUN: llc -mtriple thumbv7-unknown-none-gnueabihf -float-abi hard -filetype asm -o - %s | FileCheck %s -check-prefix CHECK-MATCH
; RUN: llc -mtriple thumbv7-unknown-none-musleabi -float-abi soft -filetype asm -o - %s | FileCheck %s -check-prefix CHECK-MATCH
; RUN: llc -mtriple thumbv7-unknown-none-musleabi -float-abi hard -filetype asm -o - %s | FileCheck %s -check-prefix CHECK-MISMATCH -check-prefix CHECK-TO-SOFT
; RUN: llc -mtriple thumbv7-unknown-none-musleabihf -float-abi soft -filetype asm -o - %s | FileCheck %s -check-prefix CHECK-MISMATCH -check-prefix CHECK-TO-HARD
; RUN: llc -mtriple thumbv7-unknown-none-musleabihf -float-abi hard -filetype asm -o - %s | FileCheck %s -check-prefix CHECK-MATCH
declare float @llvm.powi.f32(float, i32)
define float @f(float %f, i32 %i) {
entry:
%0 = call float @llvm.powi.f32(float %f, i32 %i)
ret float %0
}
; CHECK-MATCH: b __powisf2
; CHECK-MISMATCH: bl __powisf2
; CHECK-TO-SOFT: vmov s0, r0
; CHECK-TO-HARD: vmov r0, s0
declare double @llvm.powi.f64(double, i32)
define double @g(double %d, i32 %i) {
entry:
%0 = call double @llvm.powi.f64(double %d, i32 %i)
ret double %0
}
; CHECK-MATCH: b __powidf2
; CHECK-MISMATCH: bl __powidf2
; CHECK-TO-SOFT: vmov d0, r0, r1
; CHECK-TO-HARD: vmov r0, r1, d0

View File

@ -215,3 +215,136 @@ define <4 x i32> @PR30512(<4 x i32> %x, <4 x i32> %y) nounwind {
ret <4 x i32> %zext
}
; Fragile test warning - we need to induce the generation of a vselect
; post-legalization to cause the crash seen in:
; https://llvm.org/bugs/show_bug.cgi?id=31672
; Is there a way to do that without an unsafe/fast sqrt intrinsic call?
; Also, although the goal for adding this test is to prove that we
; don't crash, I have no idea what this code is doing, so I'm keeping
; the full codegen checks in case there's motivation to improve this.
define <2 x float> @PR31672() #0 {
; X32-LABEL: PR31672:
; X32: # BB#0:
; X32-NEXT: pushl %ebp
; X32-NEXT: movl %esp, %ebp
; X32-NEXT: andl $-16, %esp
; X32-NEXT: subl $80, %esp
; X32-NEXT: xorps %xmm0, %xmm0
; X32-NEXT: movaps {{.*#+}} xmm1 = <42,3,u,u>
; X32-NEXT: movaps %xmm1, %xmm2
; X32-NEXT: cmpeqps %xmm0, %xmm2
; X32-NEXT: movaps %xmm2, {{[0-9]+}}(%esp)
; X32-NEXT: movaps %xmm0, {{[0-9]+}}(%esp)
; X32-NEXT: rsqrtps %xmm1, %xmm0
; X32-NEXT: mulps %xmm0, %xmm1
; X32-NEXT: mulps %xmm0, %xmm1
; X32-NEXT: addps {{\.LCPI.*}}, %xmm1
; X32-NEXT: mulps {{\.LCPI.*}}, %xmm0
; X32-NEXT: mulps %xmm1, %xmm0
; X32-NEXT: movaps %xmm0, {{[0-9]+}}(%esp)
; X32-NEXT: movl {{[0-9]+}}(%esp), %eax
; X32-NEXT: movl {{[0-9]+}}(%esp), %ecx
; X32-NEXT: andl %eax, %ecx
; X32-NEXT: notl %eax
; X32-NEXT: andl {{[0-9]+}}(%esp), %eax
; X32-NEXT: orl %ecx, %eax
; X32-NEXT: movl %eax, (%esp)
; X32-NEXT: movl {{[0-9]+}}(%esp), %eax
; X32-NEXT: movl {{[0-9]+}}(%esp), %ecx
; X32-NEXT: movl {{[0-9]+}}(%esp), %edx
; X32-NEXT: andl %ecx, %edx
; X32-NEXT: notl %ecx
; X32-NEXT: andl {{[0-9]+}}(%esp), %ecx
; X32-NEXT: orl %edx, %ecx
; X32-NEXT: movl %ecx, {{[0-9]+}}(%esp)
; X32-NEXT: movl {{[0-9]+}}(%esp), %ecx
; X32-NEXT: movl {{[0-9]+}}(%esp), %edx
; X32-NEXT: andl %ecx, %edx
; X32-NEXT: notl %ecx
; X32-NEXT: andl {{[0-9]+}}(%esp), %ecx
; X32-NEXT: orl %edx, %ecx
; X32-NEXT: movl %ecx, {{[0-9]+}}(%esp)
; X32-NEXT: movl {{[0-9]+}}(%esp), %ecx
; X32-NEXT: andl %eax, %ecx
; X32-NEXT: notl %eax
; X32-NEXT: andl {{[0-9]+}}(%esp), %eax
; X32-NEXT: orl %ecx, %eax
; X32-NEXT: movl %eax, {{[0-9]+}}(%esp)
; X32-NEXT: movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
; X32-NEXT: movss {{.*#+}} xmm1 = mem[0],zero,zero,zero
; X32-NEXT: unpcklps {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1]
; X32-NEXT: movss {{.*#+}} xmm2 = mem[0],zero,zero,zero
; X32-NEXT: movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
; X32-NEXT: unpcklps {{.*#+}} xmm0 = xmm0[0],xmm2[0],xmm0[1],xmm2[1]
; X32-NEXT: unpcklps {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]
; X32-NEXT: movl %ebp, %esp
; X32-NEXT: popl %ebp
; X32-NEXT: retl
;
; X64-LABEL: PR31672:
; X64: # BB#0:
; X64-NEXT: xorps %xmm0, %xmm0
; X64-NEXT: movaps %xmm0, -{{[0-9]+}}(%rsp)
; X64-NEXT: movaps {{.*#+}} xmm1 = <42,3,u,u>
; X64-NEXT: cmpeqps %xmm1, %xmm0
; X64-NEXT: movaps %xmm0, -{{[0-9]+}}(%rsp)
; X64-NEXT: rsqrtps %xmm1, %xmm0
; X64-NEXT: mulps %xmm0, %xmm1
; X64-NEXT: mulps %xmm0, %xmm1
; X64-NEXT: addps {{.*}}(%rip), %xmm1
; X64-NEXT: mulps {{.*}}(%rip), %xmm0
; X64-NEXT: mulps %xmm1, %xmm0
; X64-NEXT: movaps %xmm0, -{{[0-9]+}}(%rsp)
; X64-NEXT: movq -{{[0-9]+}}(%rsp), %r8
; X64-NEXT: movq -{{[0-9]+}}(%rsp), %r9
; X64-NEXT: movq -{{[0-9]+}}(%rsp), %r10
; X64-NEXT: movq -{{[0-9]+}}(%rsp), %rdi
; X64-NEXT: movl %r9d, %esi
; X64-NEXT: andl %edi, %esi
; X64-NEXT: movl %edi, %ecx
; X64-NEXT: notl %ecx
; X64-NEXT: movq -{{[0-9]+}}(%rsp), %rdx
; X64-NEXT: movq -{{[0-9]+}}(%rsp), %rax
; X64-NEXT: andl %eax, %ecx
; X64-NEXT: orl %esi, %ecx
; X64-NEXT: movl %ecx, -{{[0-9]+}}(%rsp)
; X64-NEXT: movl %r8d, %ecx
; X64-NEXT: andl %r10d, %ecx
; X64-NEXT: movl %r10d, %esi
; X64-NEXT: notl %esi
; X64-NEXT: andl %edx, %esi
; X64-NEXT: orl %ecx, %esi
; X64-NEXT: movl %esi, -{{[0-9]+}}(%rsp)
; X64-NEXT: shrq $32, %r9
; X64-NEXT: shrq $32, %rdi
; X64-NEXT: andl %edi, %r9d
; X64-NEXT: notl %edi
; X64-NEXT: shrq $32, %rax
; X64-NEXT: andl %edi, %eax
; X64-NEXT: orl %r9d, %eax
; X64-NEXT: movl %eax, -{{[0-9]+}}(%rsp)
; X64-NEXT: shrq $32, %r8
; X64-NEXT: shrq $32, %r10
; X64-NEXT: andl %r10d, %r8d
; X64-NEXT: notl %r10d
; X64-NEXT: shrq $32, %rdx
; X64-NEXT: andl %r10d, %edx
; X64-NEXT: orl %r8d, %edx
; X64-NEXT: movl %edx, -{{[0-9]+}}(%rsp)
; X64-NEXT: movss {{.*#+}} xmm1 = mem[0],zero,zero,zero
; X64-NEXT: movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
; X64-NEXT: unpcklps {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]
; X64-NEXT: movss {{.*#+}} xmm1 = mem[0],zero,zero,zero
; X64-NEXT: movss {{.*#+}} xmm2 = mem[0],zero,zero,zero
; X64-NEXT: unpcklps {{.*#+}} xmm2 = xmm2[0],xmm1[0],xmm2[1],xmm1[1]
; X64-NEXT: unpcklps {{.*#+}} xmm0 = xmm0[0],xmm2[0],xmm0[1],xmm2[1]
; X64-NEXT: retq
%t0 = call fast <2 x float> @llvm.sqrt.v2f32(<2 x float> <float 42.0, float 3.0>)
ret <2 x float> %t0
}
declare <2 x float> @llvm.sqrt.v2f32(<2 x float>) #1
attributes #0 = { nounwind "unsafe-fp-math"="true" }

View File

@ -16,18 +16,17 @@ target triple = "x86_64-apple-macosx10.11.0"
; Find the metadata for @global:
; CHECK: [[METADATA:@.+]] = internal global {{.*}} @global {{.*}} section "__DATA,__asan_globals,regular", align 64
; CHECK: [[METADATA:@.+]] = internal global {{.*}} @global {{.*}} section "__DATA,__asan_globals,regular"
; Find the liveness binder for @global and its metadata:
; CHECK: @__asan_binder_global = internal global {{.*}} @global {{.*}} [[METADATA]] {{.*}} section "__DATA,__asan_liveness,regular,live_support"
; Test that there is the flag global variable:
; CHECK: @__asan_globals_registered = common hidden global i64 0
; The binder has to be inserted to llvm.compiler.used to avoid being stripped
; during LTO.
; CHECK: @llvm.compiler.used {{.*}} @__asan_binder_global {{.*}} section "llvm.metadata"
; Test that there is the flag global variable:
; CHECK: @__asan_globals_registered = common hidden global i64 0
; Test that __asan_register_image_globals is invoked from the constructor:
; CHECK-LABEL: define internal void @asan.module_ctor

View File

@ -11,19 +11,20 @@
; RUN: -o /dev/null -stats \
; RUN: 2>&1 | FileCheck %s -check-prefix=LAZY
; LAZY: 49 bitcode-reader - Number of Metadata records loaded
; LAZY: 1 bitcode-reader - Number of MDStrings loaded
; LAZY: 2 bitcode-reader - Number of MDStrings loaded
; RUN: llvm-lto -thinlto-action=import %t2.bc -thinlto-index=%t3.bc \
; RUN: -o /dev/null -disable-ondemand-mds-loading -stats \
; RUN: 2>&1 | FileCheck %s -check-prefix=NOTLAZY
; NOTLAZY: 58 bitcode-reader - Number of Metadata records loaded
; NOTLAZY: 6 bitcode-reader - Number of MDStrings loaded
; NOTLAZY: 7 bitcode-reader - Number of MDStrings loaded
target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-apple-macosx10.11.0"
define void @globalfunc1(i32 %arg) {
%x = call i1 @llvm.type.test(i8* undef, metadata !"typeid1")
%tmp = add i32 %arg, 0, !metadata !2
ret void
}
@ -34,6 +35,7 @@ define void @globalfunc1(i32 %arg) {
; These function are not imported and so we don't want to load their metadata.
define void @globalfunc2(i32 %arg) {
%x = call i1 @llvm.type.test(i8* undef, metadata !"typeid1")
%tmp = add i32 %arg, 0, !metadata !1
ret void
}
@ -43,6 +45,8 @@ define void @globalfunc3(i32 %arg) {
ret void
}
declare i1 @llvm.type.test(i8* %ptr, metadata %bitset) nounwind readnone
!1 = !{!2, !3, !4, !5, !6, !7, !8, !9}
!2 = !{!"Hello World"}
!3 = !{!"3"}
@ -51,4 +55,4 @@ define void @globalfunc3(i32 %arg) {
!6 = !{!9}
!7 = !{!"7"}
!8 = !{!"8"}
!9 = !{!6}
!9 = !{!6}

View File

@ -0,0 +1,42 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt < %s -basicaa -newgvn -S | FileCheck %s
target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
%struct.foo = type { i32, i32, [2 x [4 x [6 x [6 x i16]]]] }
@global = external global %struct.foo*
define void @bar() {
; CHECK-LABEL: @bar(
; CHECK-NEXT: bb:
; CHECK-NEXT: [[TMP:%.*]] = load %struct.foo*, %struct.foo** @global
; CHECK-NEXT: br label [[BB2:%.*]]
; CHECK: bb2:
; CHECK-NEXT: [[TMP4:%.*]] = getelementptr [[STRUCT_FOO:%.*]], %struct.foo* [[TMP]], i64 0, i32 1
; CHECK-NEXT: br i1 undef, label [[BB2]], label [[BB7:%.*]]
; CHECK: bb7:
; CHECK-NEXT: br label [[BB10:%.*]]
; CHECK: bb10:
; CHECK-NEXT: br label [[BB10]]
;
bb:
%tmp = load %struct.foo*, %struct.foo** @global
%tmp1 = getelementptr %struct.foo, %struct.foo* %tmp
br label %bb2
bb2: ; preds = %bb2, %bb
%tmp3 = phi %struct.foo* [ undef, %bb ], [ %tmp6, %bb2 ]
%tmp4 = getelementptr %struct.foo, %struct.foo* %tmp3, i64 0, i32 1
%tmp5 = load i32, i32* %tmp4
%tmp6 = load %struct.foo*, %struct.foo** @global
br i1 undef, label %bb2, label %bb7
bb7: ; preds = %bb2
%tmp8 = phi %struct.foo* [ %tmp6, %bb2 ]
%tmp9 = getelementptr %struct.foo, %struct.foo* %tmp8, i64 0, i32 1
br label %bb10
bb10: ; preds = %bb10, %bb7
%tmp11 = load i32, i32* %tmp9
br label %bb10
}

View File

@ -0,0 +1,6 @@
RUN: llvm-cxxfilt _Z1fi __Z1fi f ___ZSt1ff_block_invoke | FileCheck %s
CHECK: f(int)
CHECK-NEXT: __Z1fi
CHECK-NEXT: f
CHECK-NEXT: invocation function for block in std::f(float)

View File

@ -14,9 +14,12 @@
using namespace llvm;
static void demangle(llvm::raw_ostream &OS, const char *Mangled) {
static void demangle(llvm::raw_ostream &OS, const std::string &Mangled) {
int Status;
char *Demangled = itaniumDemangle(Mangled, nullptr, nullptr, &Status);
char *Demangled = nullptr;
if ((Mangled.size() >= 2 && Mangled.compare(0, 2, "_Z")) ||
(Mangled.size() >= 4 && Mangled.compare(0, 4, "___Z")))
Demangled = itaniumDemangle(Mangled.c_str(), nullptr, nullptr, &Status);
OS << (Demangled ? Demangled : Mangled) << '\n';
free(Demangled);
}
@ -24,7 +27,7 @@ static void demangle(llvm::raw_ostream &OS, const char *Mangled) {
int main(int argc, char **argv) {
if (argc == 1)
for (std::string Mangled; std::getline(std::cin, Mangled);)
demangle(llvm::outs(), Mangled.c_str());
demangle(llvm::outs(), Mangled);
else
for (int I = 1; I < argc; ++I)
demangle(llvm::outs(), argv[I]);

View File

@ -37,6 +37,7 @@ do_libunwind="yes"
do_test_suite="yes"
do_openmp="yes"
do_lldb="no"
do_polly="no"
BuildDir="`pwd`"
ExtraConfigureFlags=""
ExportBranch=""
@ -65,6 +66,8 @@ function usage() {
echo " -no-openmp Disable check-out & build libomp"
echo " -lldb Enable check-out & build lldb"
echo " -no-lldb Disable check-out & build lldb (default)"
echo " -polly Enable check-out & build Polly"
echo " -no-polly Disable check-out & build Polly (default)"
}
while [ $# -gt 0 ]; do
@ -146,6 +149,12 @@ while [ $# -gt 0 ]; do
-no-lldb )
do_lldb="no"
;;
-polly )
do_polly="yes"
;;
-no-polly )
do_polly="no"
;;
-help | --help | -h | --h | -\? )
usage
exit 0
@ -219,6 +228,9 @@ fi
if [ $do_lldb = "yes" ]; then
projects="$projects lldb"
fi
if [ $do_polly = "yes" ]; then
projects="$projects polly"
fi
# Go to the build directory (may be different from CWD)
BuildDir=$BuildDir/$RC
@ -285,7 +297,7 @@ function export_sources() {
cfe)
projsrc=llvm.src/tools/clang
;;
lldb)
lldb|polly)
projsrc=llvm.src/tools/$proj
;;
clang-tools-extra)