svn commit: r312704 - in vendor/llvm/dist: lib/Bitcode/Reader lib/Target/AArch64 lib/Target/ARM lib/Target/X86 lib/Transforms/Instrumentation lib/Transforms/Scalar test/CodeGen/AArch64 test/CodeGen...
Dimitry Andric
dim at FreeBSD.org
Tue Jan 24 19:17:56 UTC 2017
Author: dim
Date: Tue Jan 24 19:17:53 2017
New Revision: 312704
URL: https://svnweb.freebsd.org/changeset/base/312704
Log:
Vendor import of llvm release_40 branch r292951:
https://llvm.org/svn/llvm-project/llvm/branches/release_40@292951
Added:
vendor/llvm/dist/test/CodeGen/AArch64/ldst-opt.mir
vendor/llvm/dist/test/CodeGen/Thumb2/intrinsics-cc.ll
vendor/llvm/dist/test/Transforms/NewGVN/pr31682.ll
vendor/llvm/dist/test/tools/llvm-cxxfilt/invalid.test
Deleted:
vendor/llvm/dist/test/CodeGen/AArch64/ldst-opt-dbg-limit.mir
Modified:
vendor/llvm/dist/lib/Bitcode/Reader/BitcodeReader.cpp
vendor/llvm/dist/lib/Bitcode/Reader/MetadataLoader.cpp
vendor/llvm/dist/lib/Bitcode/Reader/MetadataLoader.h
vendor/llvm/dist/lib/Target/AArch64/AArch64LoadStoreOptimizer.cpp
vendor/llvm/dist/lib/Target/ARM/ARMISelLowering.cpp
vendor/llvm/dist/lib/Target/ARM/ARMISelLowering.h
vendor/llvm/dist/lib/Target/X86/X86ISelLowering.cpp
vendor/llvm/dist/lib/Transforms/Instrumentation/AddressSanitizer.cpp
vendor/llvm/dist/lib/Transforms/Scalar/NewGVN.cpp
vendor/llvm/dist/test/CodeGen/Thumb2/float-intrinsics-double.ll
vendor/llvm/dist/test/CodeGen/Thumb2/float-intrinsics-float.ll
vendor/llvm/dist/test/CodeGen/X86/sse1.ll
vendor/llvm/dist/test/Instrumentation/AddressSanitizer/global_metadata_darwin.ll
vendor/llvm/dist/test/ThinLTO/X86/lazyload_metadata.ll
vendor/llvm/dist/tools/llvm-cxxfilt/llvm-cxxfilt.cpp
vendor/llvm/dist/utils/release/test-release.sh
Modified: vendor/llvm/dist/lib/Bitcode/Reader/BitcodeReader.cpp
==============================================================================
--- vendor/llvm/dist/lib/Bitcode/Reader/BitcodeReader.cpp Tue Jan 24 18:56:09 2017 (r312703)
+++ vendor/llvm/dist/lib/Bitcode/Reader/BitcodeReader.cpp Tue Jan 24 19:17:53 2017 (r312704)
@@ -512,7 +512,7 @@ private:
}
Metadata *getFnMetadataByID(unsigned ID) {
- return MDLoader->getMetadataFwdRef(ID);
+ return MDLoader->getMetadataFwdRefOrLoad(ID);
}
BasicBlock *getBasicBlock(unsigned ID) const {
Modified: vendor/llvm/dist/lib/Bitcode/Reader/MetadataLoader.cpp
==============================================================================
--- vendor/llvm/dist/lib/Bitcode/Reader/MetadataLoader.cpp Tue Jan 24 18:56:09 2017 (r312703)
+++ vendor/llvm/dist/lib/Bitcode/Reader/MetadataLoader.cpp Tue Jan 24 19:17:53 2017 (r312704)
@@ -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 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) {
Modified: vendor/llvm/dist/lib/Bitcode/Reader/MetadataLoader.h
==============================================================================
--- vendor/llvm/dist/lib/Bitcode/Reader/MetadataLoader.h Tue Jan 24 18:56:09 2017 (r312703)
+++ vendor/llvm/dist/lib/Bitcode/Reader/MetadataLoader.h Tue Jan 24 19:17:53 2017 (r312704)
@@ -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);
Modified: vendor/llvm/dist/lib/Target/AArch64/AArch64LoadStoreOptimizer.cpp
==============================================================================
--- vendor/llvm/dist/lib/Target/AArch64/AArch64LoadStoreOptimizer.cpp Tue Jan 24 18:56:09 2017 (r312703)
+++ vendor/llvm/dist/lib/Target/AArch64/AArch64LoadStoreOptimizer.cpp Tue Jan 24 19:17:53 2017 (r312704)
@@ -687,9 +687,30 @@ AArch64LoadStoreOpt::mergePairedInsns(Ma
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));
Modified: vendor/llvm/dist/lib/Target/ARM/ARMISelLowering.cpp
==============================================================================
--- vendor/llvm/dist/lib/Target/ARM/ARMISelLowering.cpp Tue Jan 24 18:56:09 2017 (r312703)
+++ vendor/llvm/dist/lib/Target/ARM/ARMISelLowering.cpp Tue Jan 24 19:17:53 2017 (r312704)
@@ -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(con
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.
Modified: vendor/llvm/dist/lib/Target/ARM/ARMISelLowering.h
==============================================================================
--- vendor/llvm/dist/lib/Target/ARM/ARMISelLowering.h Tue Jan 24 18:56:09 2017 (r312703)
+++ vendor/llvm/dist/lib/Target/ARM/ARMISelLowering.h Tue Jan 24 19:17:53 2017 (r312704)
@@ -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);
Modified: vendor/llvm/dist/lib/Target/X86/X86ISelLowering.cpp
==============================================================================
--- vendor/llvm/dist/lib/Target/X86/X86ISelLowering.cpp Tue Jan 24 18:56:09 2017 (r312703)
+++ vendor/llvm/dist/lib/Target/X86/X86ISelLowering.cpp Tue Jan 24 19:17:53 2017 (r312704)
@@ -28788,10 +28788,12 @@ static SDValue combineExtractVectorElt(S
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 combineVSelectWithAllOnes
}
}
- 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,
}
}
- 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
Modified: vendor/llvm/dist/lib/Transforms/Instrumentation/AddressSanitizer.cpp
==============================================================================
--- vendor/llvm/dist/lib/Transforms/Instrumentation/AddressSanitizer.cpp Tue Jan 24 18:56:09 2017 (r312703)
+++ vendor/llvm/dist/lib/Transforms/Instrumentation/AddressSanitizer.cpp Tue Jan 24 19:17:53 2017 (r312704)
@@ -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::initializeC
// 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::InstrumentG
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::InstrumentG
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::InstrumentG
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::InstrumentG
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;
- }
-
- // 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);
+ Initializers[i] = Initializer;
+ }
- // 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;
}
Modified: vendor/llvm/dist/lib/Transforms/Scalar/NewGVN.cpp
==============================================================================
--- vendor/llvm/dist/lib/Transforms/Scalar/NewGVN.cpp Tue Jan 24 18:56:09 2017 (r312703)
+++ vendor/llvm/dist/lib/Transforms/Scalar/NewGVN.cpp Tue Jan 24 19:17:53 2017 (r312704)
@@ -85,6 +85,8 @@ STATISTIC(NumGVNLeaderChanges, "Number o
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::moveValueToNewCongruenceCla
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);
Added: vendor/llvm/dist/test/CodeGen/AArch64/ldst-opt.mir
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ vendor/llvm/dist/test/CodeGen/AArch64/ldst-opt.mir Tue Jan 24 19:17:53 2017 (r312704)
@@ -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
Modified: vendor/llvm/dist/test/CodeGen/Thumb2/float-intrinsics-double.ll
==============================================================================
--- vendor/llvm/dist/test/CodeGen/Thumb2/float-intrinsics-double.ll Tue Jan 24 18:56:09 2017 (r312703)
+++ vendor/llvm/dist/test/CodeGen/Thumb2/float-intrinsics-double.ll Tue Jan 24 19:17:53 2017 (r312704)
@@ -18,7 +18,7 @@ declare double @llvm.powi.f64(double
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
}
Modified: vendor/llvm/dist/test/CodeGen/Thumb2/float-intrinsics-float.ll
==============================================================================
--- vendor/llvm/dist/test/CodeGen/Thumb2/float-intrinsics-float.ll Tue Jan 24 18:56:09 2017 (r312703)
+++ vendor/llvm/dist/test/CodeGen/Thumb2/float-intrinsics-float.ll Tue Jan 24 19:17:53 2017 (r312704)
@@ -18,7 +18,7 @@ declare float @llvm.powi.f32(float %
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
}
Added: vendor/llvm/dist/test/CodeGen/Thumb2/intrinsics-cc.ll
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ vendor/llvm/dist/test/CodeGen/Thumb2/intrinsics-cc.ll Tue Jan 24 19:17:53 2017 (r312704)
@@ -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
*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
More information about the svn-src-all
mailing list