diff options
author | Paul Kirth <paulkirth@google.com> | 2024-04-30 21:13:30 +0000 |
---|---|---|
committer | Paul Kirth <paulkirth@google.com> | 2024-04-30 21:13:30 +0000 |
commit | 9bb6643e85601d7c185601bfd382cf0016a9c599 (patch) | |
tree | 63e017279c23fbad13d6547e386a34aadde960da | |
parent | 7538df90aee11603bce5146a3f34c06e9ef3f793 (diff) | |
parent | 699243343439285ec2fe61b4ae568c7a958c7ce2 (diff) |
[𝘀𝗽𝗿] changes introduced through rebaseupstream/users/ilovepi/spr/main.llvmnfc-document-clopt-variable-and-fix-typo-2
Created using spr 1.3.4
[skip ci]
35 files changed, 413 insertions, 99 deletions
diff --git a/clang/test/CodeGenCXX/attr-likelihood-if-vs-builtin-expect.cpp b/clang/test/CodeGenCXX/attr-likelihood-if-vs-builtin-expect.cpp index fb236aeb982e..81d933435652 100644 --- a/clang/test/CodeGenCXX/attr-likelihood-if-vs-builtin-expect.cpp +++ b/clang/test/CodeGenCXX/attr-likelihood-if-vs-builtin-expect.cpp @@ -221,5 +221,5 @@ void tu2(int &i) { } } -// CHECK: [[BW_LIKELY]] = !{!"branch_weights", i32 2000, i32 1} -// CHECK: [[BW_UNLIKELY]] = !{!"branch_weights", i32 1, i32 2000} +// CHECK: [[BW_LIKELY]] = !{!"branch_weights", !"expected", i32 2000, i32 1} +// CHECK: [[BW_UNLIKELY]] = !{!"branch_weights", !"expected", i32 1, i32 2000} diff --git a/clang/www/cxx_status.html b/clang/www/cxx_status.html index 6db6ae57d126..260f74ded93c 100755 --- a/clang/www/cxx_status.html +++ b/clang/www/cxx_status.html @@ -177,7 +177,7 @@ C++23, informally referred to as C++26.</p> <tr> <td>Attributes for Structured Bindings</td> <td><a href="https://wg21.link/P0609R3">P0609R3</a></td> - <td class="none" align="center">Clang 19</td> + <td class="unreleased" align="center">Clang 19</td> </tr> <tr> <td>Module Declarations Shouldn’t be Macros</td> @@ -187,7 +187,7 @@ C++23, informally referred to as C++26.</p> <tr> <td>Trivial infinite loops are not Undefined Behavior</td> <td><a href="https://wg21.link/P2809R3">P2809R3</a> (<a href="#dr">DR</a>)</td> - <td class="unreleased" align="center">No</td> + <td class="none" align="center">No</td> </tr> <tr> <td>Erroneous behaviour for uninitialized reads</td> diff --git a/compiler-rt/lib/dfsan/CMakeLists.txt b/compiler-rt/lib/dfsan/CMakeLists.txt index f6479e9da87b..37c386d2de1f 100644 --- a/compiler-rt/lib/dfsan/CMakeLists.txt +++ b/compiler-rt/lib/dfsan/CMakeLists.txt @@ -63,7 +63,8 @@ add_custom_command(OUTPUT ${dfsan_abilist_filename} COMMAND ${CMAKE_COMMAND} -E make_directory ${dfsan_abilist_dir} COMMAND - cat ${CMAKE_CURRENT_SOURCE_DIR}/done_abilist.txt + ${CMAKE_COMMAND} -E cat + ${CMAKE_CURRENT_SOURCE_DIR}/done_abilist.txt ${CMAKE_CURRENT_SOURCE_DIR}/libc_ubuntu1404_abilist.txt > ${dfsan_abilist_filename} DEPENDS done_abilist.txt libc_ubuntu1404_abilist.txt) diff --git a/llvm/docs/BranchWeightMetadata.rst b/llvm/docs/BranchWeightMetadata.rst index 522f37cdad4f..62204753e29b 100644 --- a/llvm/docs/BranchWeightMetadata.rst +++ b/llvm/docs/BranchWeightMetadata.rst @@ -28,11 +28,14 @@ Supported Instructions Metadata is only assigned to the conditional branches. There are two extra operands for the true and the false branch. +We optionally track if the metadata was added by ``__builtin_expect`` or +``__builtin_expect_with_probability`` with an optional field ``!"expected"``. .. code-block:: none !0 = !{ !"branch_weights", + [ !"expected", ] i32 <TRUE_BRANCH_WEIGHT>, i32 <FALSE_BRANCH_WEIGHT> } @@ -47,6 +50,7 @@ is always case #0). !0 = !{ !"branch_weights", + [ !"expected", ] i32 <DEFAULT_BRANCH_WEIGHT> [ , i32 <CASE_BRANCH_WEIGHT> ... ] } @@ -60,6 +64,7 @@ Branch weights are assigned to every destination. !0 = !{ !"branch_weights", + [ !"expected", ] i32 <LABEL_BRANCH_WEIGHT> [ , i32 <LABEL_BRANCH_WEIGHT> ... ] } @@ -75,6 +80,7 @@ block and entry counts which may not be accurate with sampling. !0 = !{ !"branch_weights", + [ !"expected", ] i32 <CALL_BRANCH_WEIGHT> } @@ -95,6 +101,7 @@ is used. !0 = !{ !"branch_weights", + [ !"expected", ] i32 <INVOKE_NORMAL_WEIGHT> [ , i32 <INVOKE_UNWIND_WEIGHT> ] } diff --git a/llvm/include/llvm/IR/MDBuilder.h b/llvm/include/llvm/IR/MDBuilder.h index 3265589b7c8d..e02ec8f5a3d8 100644 --- a/llvm/include/llvm/IR/MDBuilder.h +++ b/llvm/include/llvm/IR/MDBuilder.h @@ -59,7 +59,11 @@ public: //===------------------------------------------------------------------===// /// Return metadata containing two branch weights. - MDNode *createBranchWeights(uint32_t TrueWeight, uint32_t FalseWeight); + /// @param TrueWeight the weight of the true branch + /// @param FalseWeight the weight of the false branch + /// @param Do these weights come from __builtin_expect* + MDNode *createBranchWeights(uint32_t TrueWeight, uint32_t FalseWeight, + bool IsExpected = false); /// Return metadata containing two branch weights, with significant bias /// towards `true` destination. @@ -70,7 +74,10 @@ public: MDNode *createUnlikelyBranchWeights(); /// Return metadata containing a number of branch weights. - MDNode *createBranchWeights(ArrayRef<uint32_t> Weights); + /// @param Weights the weights of all the branches + /// @param Do these weights come from __builtin_expect* + MDNode *createBranchWeights(ArrayRef<uint32_t> Weights, + bool IsExpected = false); /// Return metadata specifying that a branch or switch is unpredictable. MDNode *createUnpredictable(); diff --git a/llvm/include/llvm/IR/ProfDataUtils.h b/llvm/include/llvm/IR/ProfDataUtils.h index 88fbad4d6b9d..7008d3240fed 100644 --- a/llvm/include/llvm/IR/ProfDataUtils.h +++ b/llvm/include/llvm/IR/ProfDataUtils.h @@ -55,6 +55,19 @@ MDNode *getBranchWeightMDNode(const Instruction &I); /// Nullptr otherwise. MDNode *getValidBranchWeightMDNode(const Instruction &I); +/// Check if Branch Weight Metadata has an "expected" field from an llvm.expect* +/// intrinsic +bool hasBranchWeightProvenance(const Instruction &I); + +/// Check if Branch Weight Metadata has an "expected" field from an llvm.expect* +/// intrinsic +bool hasBranchWeightProvenance(const MDNode *ProfileData); + +/// Return the offset to the first branch weight data +unsigned getBranchWeightOffset(const MDNode *ProfileData); + +unsigned getNumBranchWeights(const MDNode &ProfileData); + /// Extract branch weights from MD_prof metadata /// /// \param ProfileData A pointer to an MDNode. @@ -111,7 +124,11 @@ bool extractProfTotalWeight(const Instruction &I, uint64_t &TotalWeights); /// Create a new `branch_weights` metadata node and add or overwrite /// a `prof` metadata reference to instruction `I`. -void setBranchWeights(Instruction &I, ArrayRef<uint32_t> Weights); +/// \param I the Instruction to set branch weights on. +/// \param Weights an array of weights to set on instruction I. +/// \param IsExpected were these weights added from an llvm.expect* intrinsic. +void setBranchWeights(Instruction &I, ArrayRef<uint32_t> Weights, + bool IsExpected); /// Scaling the profile data attached to 'I' using the ratio of S/T. void scaleProfData(Instruction &I, uint64_t S, uint64_t T); diff --git a/llvm/lib/CodeGen/CodeGenPrepare.cpp b/llvm/lib/CodeGen/CodeGenPrepare.cpp index 339a1f1f2f00..210611cc59b9 100644 --- a/llvm/lib/CodeGen/CodeGenPrepare.cpp +++ b/llvm/lib/CodeGen/CodeGenPrepare.cpp @@ -8866,7 +8866,8 @@ bool CodeGenPrepare::splitBranchCondition(Function &F, ModifyDT &ModifiedDT) { scaleWeights(NewTrueWeight, NewFalseWeight); Br1->setMetadata(LLVMContext::MD_prof, MDBuilder(Br1->getContext()) - .createBranchWeights(TrueWeight, FalseWeight)); + .createBranchWeights(TrueWeight, FalseWeight, + hasBranchWeightProvenance(*Br1))); NewTrueWeight = TrueWeight; NewFalseWeight = 2 * FalseWeight; diff --git a/llvm/lib/IR/Instruction.cpp b/llvm/lib/IR/Instruction.cpp index 678edc58ad84..c71a1926258a 100644 --- a/llvm/lib/IR/Instruction.cpp +++ b/llvm/lib/IR/Instruction.cpp @@ -1266,12 +1266,21 @@ Instruction *Instruction::cloneImpl() const { void Instruction::swapProfMetadata() { MDNode *ProfileData = getBranchWeightMDNode(*this); - if (!ProfileData || ProfileData->getNumOperands() != 3) + if (!isBranchWeightMD(ProfileData)) return; - // The first operand is the name. Fetch them backwards and build a new one. - Metadata *Ops[] = {ProfileData->getOperand(0), ProfileData->getOperand(2), - ProfileData->getOperand(1)}; + SmallVector<Metadata *, 4> Ops; + unsigned FirstIdx = getBranchWeightOffset(ProfileData); + unsigned SecondIdx = FirstIdx + 1; + // If there are more weights past the second, we can't swap them + if (ProfileData->getNumOperands() > SecondIdx + 1) + return; + for (unsigned Idx = 0; Idx < FirstIdx; ++Idx) { + Ops.push_back(ProfileData->getOperand(Idx)); + } + // Switch the order of the weights + Ops.push_back(ProfileData->getOperand(SecondIdx)); + Ops.push_back(ProfileData->getOperand(FirstIdx)); setMetadata(LLVMContext::MD_prof, MDNode::get(ProfileData->getContext(), Ops)); } diff --git a/llvm/lib/IR/Instructions.cpp b/llvm/lib/IR/Instructions.cpp index 7ad1ad4cddb7..e199892ebb5d 100644 --- a/llvm/lib/IR/Instructions.cpp +++ b/llvm/lib/IR/Instructions.cpp @@ -5165,7 +5165,7 @@ void SwitchInstProfUpdateWrapper::init() { if (!ProfileData) return; - if (ProfileData->getNumOperands() != SI.getNumSuccessors() + 1) { + if (getNumBranchWeights(*ProfileData) != SI.getNumSuccessors()) { llvm_unreachable("number of prof branch_weights metadata operands does " "not correspond to number of succesors"); } diff --git a/llvm/lib/IR/MDBuilder.cpp b/llvm/lib/IR/MDBuilder.cpp index 0bf41d7cc7c2..2a03337724bf 100644 --- a/llvm/lib/IR/MDBuilder.cpp +++ b/llvm/lib/IR/MDBuilder.cpp @@ -35,8 +35,8 @@ MDNode *MDBuilder::createFPMath(float Accuracy) { } MDNode *MDBuilder::createBranchWeights(uint32_t TrueWeight, - uint32_t FalseWeight) { - return createBranchWeights({TrueWeight, FalseWeight}); + uint32_t FalseWeight, bool IsExpected) { + return createBranchWeights({TrueWeight, FalseWeight}, IsExpected); } MDNode *MDBuilder::createLikelyBranchWeights() { @@ -49,15 +49,19 @@ MDNode *MDBuilder::createUnlikelyBranchWeights() { return createBranchWeights(1, (1U << 20) - 1); } -MDNode *MDBuilder::createBranchWeights(ArrayRef<uint32_t> Weights) { +MDNode *MDBuilder::createBranchWeights(ArrayRef<uint32_t> Weights, + bool IsExpected) { assert(Weights.size() >= 1 && "Need at least one branch weights!"); - SmallVector<Metadata *, 4> Vals(Weights.size() + 1); + unsigned int Offset = IsExpected ? 2 : 1; + SmallVector<Metadata *, 4> Vals(Weights.size() + Offset); Vals[0] = createString("branch_weights"); + if (IsExpected) + Vals[1] = createString("expected"); Type *Int32Ty = Type::getInt32Ty(Context); for (unsigned i = 0, e = Weights.size(); i != e; ++i) - Vals[i + 1] = createConstant(ConstantInt::get(Int32Ty, Weights[i])); + Vals[i + Offset] = createConstant(ConstantInt::get(Int32Ty, Weights[i])); return MDNode::get(Context, Vals); } diff --git a/llvm/lib/IR/ProfDataUtils.cpp b/llvm/lib/IR/ProfDataUtils.cpp index 3d72418593a7..4859e420191f 100644 --- a/llvm/lib/IR/ProfDataUtils.cpp +++ b/llvm/lib/IR/ProfDataUtils.cpp @@ -40,9 +40,6 @@ namespace { // We maintain some constants here to ensure that we access the branch weights // correctly, and can change the behavior in the future if the layout changes -// The index at which the weights vector starts -constexpr unsigned WeightsIdx = 1; - // the minimum number of operands for MD_prof nodes with branch weights constexpr unsigned MinBWOps = 3; @@ -85,6 +82,27 @@ static void extractFromBranchWeightMD(const MDNode *ProfileData, } } +template <typename T, + typename = typename std::enable_if<std::is_arithmetic_v<T>>> +static void extractFromBranchWeightMD(const MDNode *ProfileData, + SmallVectorImpl<T> &Weights) { + assert(isBranchWeightMD(ProfileData) && "wrong metadata"); + + unsigned NOps = ProfileData->getNumOperands(); + unsigned WeightsIdx = getBranchWeightOffset(ProfileData); + assert(WeightsIdx < NOps && "Weights Index must be less than NOps."); + Weights.resize(NOps - WeightsIdx); + + for (unsigned Idx = WeightsIdx, E = NOps; Idx != E; ++Idx) { + ConstantInt *Weight = + mdconst::dyn_extract<ConstantInt>(ProfileData->getOperand(Idx)); + assert(Weight && "Malformed branch_weight in MD_prof node"); + assert(Weight->getValue().getActiveBits() <= (sizeof(T) * 8) && + "Too many bits for MD_prof branch_weight"); + Weights[Idx - WeightsIdx] = Weight->getZExtValue(); + } +} + } // namespace namespace llvm { @@ -106,6 +124,29 @@ bool hasValidBranchWeightMD(const Instruction &I) { return getValidBranchWeightMDNode(I); } +bool hasBranchWeightProvenance(const Instruction &I) { + auto *ProfileData = I.getMetadata(LLVMContext::MD_prof); + return hasBranchWeightProvenance(ProfileData); +} + +bool hasBranchWeightProvenance(const MDNode *ProfileData) { + if (!isBranchWeightMD(ProfileData)) + return false; + auto *ProfDataName = dyn_cast<MDString>(ProfileData->getOperand(1)); + // NOTE: if we ever have more types of branch weight provenance, + // we need to check the string value is "expected". For now, we + // supply a more generic API, and avoid the spurious comparisons. + return ProfDataName; +} + +unsigned getBranchWeightOffset(const MDNode *ProfileData) { + return hasBranchWeightProvenance(ProfileData) ? 2 : 1; +} + +unsigned getNumBranchWeights(const MDNode &ProfileData) { + return ProfileData.getNumOperands() - getBranchWeightOffset(&ProfileData); +} + MDNode *getBranchWeightMDNode(const Instruction &I) { auto *ProfileData = I.getMetadata(LLVMContext::MD_prof); if (!isBranchWeightMD(ProfileData)) @@ -115,7 +156,7 @@ MDNode *getBranchWeightMDNode(const Instruction &I) { MDNode *getValidBranchWeightMDNode(const Instruction &I) { auto *ProfileData = getBranchWeightMDNode(I); - if (ProfileData && ProfileData->getNumOperands() == 1 + I.getNumSuccessors()) + if (ProfileData && getNumBranchWeights(*ProfileData) == I.getNumSuccessors()) return ProfileData; return nullptr; } @@ -173,8 +214,9 @@ bool extractProfTotalWeight(const MDNode *ProfileData, uint64_t &TotalVal) { if (!ProfDataName) return false; - if (ProfDataName->getString() == "branch_weights") { - for (unsigned Idx = 1; Idx < ProfileData->getNumOperands(); Idx++) { + if (ProfDataName->getString().equals("branch_weights")) { + unsigned Offset = getBranchWeightOffset(ProfileData); + for (unsigned Idx = Offset; Idx < ProfileData->getNumOperands(); ++Idx) { auto *V = mdconst::dyn_extract<ConstantInt>(ProfileData->getOperand(Idx)); assert(V && "Malformed branch_weight in MD_prof node"); TotalVal += V->getValue().getZExtValue(); @@ -195,9 +237,10 @@ bool extractProfTotalWeight(const Instruction &I, uint64_t &TotalVal) { return extractProfTotalWeight(I.getMetadata(LLVMContext::MD_prof), TotalVal); } -void setBranchWeights(Instruction &I, ArrayRef<uint32_t> Weights) { +void setBranchWeights(Instruction &I, ArrayRef<uint32_t> Weights, + bool IsExpected) { MDBuilder MDB(I.getContext()); - MDNode *BranchWeights = MDB.createBranchWeights(Weights); + MDNode *BranchWeights = MDB.createBranchWeights(Weights, IsExpected); I.setMetadata(LLVMContext::MD_prof, BranchWeights); } diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp index 16ed167bd671..f4edf161c55e 100644 --- a/llvm/lib/IR/Verifier.cpp +++ b/llvm/lib/IR/Verifier.cpp @@ -104,6 +104,7 @@ #include "llvm/IR/Module.h" #include "llvm/IR/ModuleSlotTracker.h" #include "llvm/IR/PassManager.h" +#include "llvm/IR/ProfDataUtils.h" #include "llvm/IR/Statepoint.h" #include "llvm/IR/Type.h" #include "llvm/IR/Use.h" @@ -4785,9 +4786,10 @@ void Verifier::visitProfMetadata(Instruction &I, MDNode *MD) { StringRef ProfName = MDS->getString(); // Check consistency of !prof branch_weights metadata. - if (ProfName == "branch_weights") { + if (ProfName.equals("branch_weights")) { + unsigned NumBranchWeights = getNumBranchWeights(*MD); if (isa<InvokeInst>(&I)) { - Check(MD->getNumOperands() == 2 || MD->getNumOperands() == 3, + Check(NumBranchWeights == 1 || NumBranchWeights == 2, "Wrong number of InvokeInst branch_weights operands", MD); } else { unsigned ExpectedNumOperands = 0; @@ -4807,10 +4809,11 @@ void Verifier::visitProfMetadata(Instruction &I, MDNode *MD) { CheckFailed("!prof branch_weights are not allowed for this instruction", MD); - Check(MD->getNumOperands() == 1 + ExpectedNumOperands, + Check(NumBranchWeights == ExpectedNumOperands, "Wrong number of operands", MD); } - for (unsigned i = 1; i < MD->getNumOperands(); ++i) { + for (unsigned i = getBranchWeightOffset(MD); i < MD->getNumOperands(); + ++i) { auto &MDO = MD->getOperand(i); Check(MDO, "second operand should not be null", MD); Check(mdconst::dyn_extract<ConstantInt>(MDO), diff --git a/llvm/lib/Target/SystemZ/SystemZInstrInfo.cpp b/llvm/lib/Target/SystemZ/SystemZInstrInfo.cpp index 2b61cff727cd..b3517fb0ea77 100644 --- a/llvm/lib/Target/SystemZ/SystemZInstrInfo.cpp +++ b/llvm/lib/Target/SystemZ/SystemZInstrInfo.cpp @@ -866,6 +866,31 @@ void SystemZInstrInfo::copyPhysReg(MachineBasicBlock &MBB, return; } + if (SystemZ::GR128BitRegClass.contains(DestReg) && + SystemZ::VR128BitRegClass.contains(SrcReg)) { + MCRegister DestH64 = RI.getSubReg(DestReg, SystemZ::subreg_h64); + MCRegister DestL64 = RI.getSubReg(DestReg, SystemZ::subreg_l64); + + BuildMI(MBB, MBBI, DL, get(SystemZ::VLGVG), DestH64) + .addReg(SrcReg) + .addReg(SystemZ::NoRegister) + .addImm(0) + .addDef(DestReg, RegState::Implicit); + BuildMI(MBB, MBBI, DL, get(SystemZ::VLGVG), DestL64) + .addReg(SrcReg, getKillRegState(KillSrc)) + .addReg(SystemZ::NoRegister) + .addImm(1); + return; + } + + if (SystemZ::VR128BitRegClass.contains(DestReg) && + SystemZ::GR128BitRegClass.contains(SrcReg)) { + BuildMI(MBB, MBBI, DL, get(SystemZ::VLVGP), DestReg) + .addReg(RI.getSubReg(SrcReg, SystemZ::subreg_h64)) + .addReg(RI.getSubReg(SrcReg, SystemZ::subreg_l64)); + return; + } + // Everything else needs only one instruction. unsigned Opcode; if (SystemZ::GR64BitRegClass.contains(DestReg, SrcReg)) diff --git a/llvm/lib/Transforms/IPO/SampleProfile.cpp b/llvm/lib/Transforms/IPO/SampleProfile.cpp index 6cbd138842c8..403d6cb111ba 100644 --- a/llvm/lib/Transforms/IPO/SampleProfile.cpp +++ b/llvm/lib/Transforms/IPO/SampleProfile.cpp @@ -1661,7 +1661,8 @@ void SampleProfileLoader::generateMDProfMetadata(Function &F) { else if (OverwriteExistingWeights) I.setMetadata(LLVMContext::MD_prof, nullptr); } else if (!isa<IntrinsicInst>(&I)) { - setBranchWeights(I, {static_cast<uint32_t>(BlockWeights[BB])}); + setBranchWeights(I, {static_cast<uint32_t>(BlockWeights[BB])}, + /*IsExpected=*/false); } } } else if (OverwriteExistingWeights || ProfileSampleBlockAccurate) { @@ -1672,7 +1673,7 @@ void SampleProfileLoader::generateMDProfMetadata(Function &F) { if (cast<CallBase>(I).isIndirectCall()) { I.setMetadata(LLVMContext::MD_prof, nullptr); } else { - setBranchWeights(I, {uint32_t(0)}); + setBranchWeights(I, {uint32_t(0)}, /*IsExpected=*/false); } } } @@ -1753,7 +1754,7 @@ void SampleProfileLoader::generateMDProfMetadata(Function &F) { if (MaxWeight > 0 && (!TI->extractProfTotalWeight(TempWeight) || OverwriteExistingWeights)) { LLVM_DEBUG(dbgs() << "SUCCESS. Found non-zero weights.\n"); - setBranchWeights(*TI, Weights); + setBranchWeights(*TI, Weights, /*IsExpected=*/false); ORE->emit([&]() { return OptimizationRemark(DEBUG_TYPE, "PopularDest", MaxDestInst) << "most popular destination for conditional branches at " diff --git a/llvm/lib/Transforms/Instrumentation/ControlHeightReduction.cpp b/llvm/lib/Transforms/Instrumentation/ControlHeightReduction.cpp index 0a3d8d6000cf..731104d4fcef 100644 --- a/llvm/lib/Transforms/Instrumentation/ControlHeightReduction.cpp +++ b/llvm/lib/Transforms/Instrumentation/ControlHeightReduction.cpp @@ -1878,7 +1878,7 @@ void CHR::fixupBranchesAndSelects(CHRScope *Scope, static_cast<uint32_t>(CHRBranchBias.scale(1000)), static_cast<uint32_t>(CHRBranchBias.getCompl().scale(1000)), }; - setBranchWeights(*MergedBR, Weights); + setBranchWeights(*MergedBR, Weights, /*IsExpected=*/false); CHR_DEBUG(dbgs() << "CHR branch bias " << Weights[0] << ":" << Weights[1] << "\n"); } diff --git a/llvm/lib/Transforms/Instrumentation/IndirectCallPromotion.cpp b/llvm/lib/Transforms/Instrumentation/IndirectCallPromotion.cpp index 23a7c6a20aec..6db76ca78b21 100644 --- a/llvm/lib/Transforms/Instrumentation/IndirectCallPromotion.cpp +++ b/llvm/lib/Transforms/Instrumentation/IndirectCallPromotion.cpp @@ -259,7 +259,8 @@ CallBase &llvm::pgo::promoteIndirectCall(CallBase &CB, Function *DirectCallee, promoteCallWithIfThenElse(CB, DirectCallee, BranchWeights); if (AttachProfToDirectCall) { - setBranchWeights(NewInst, {static_cast<uint32_t>(Count)}); + setBranchWeights(NewInst, {static_cast<uint32_t>(Count)}, + /*IsExpected=*/false); } using namespace ore; diff --git a/llvm/lib/Transforms/Instrumentation/PGOInstrumentation.cpp b/llvm/lib/Transforms/Instrumentation/PGOInstrumentation.cpp index a7b7556685e4..88808e9862c8 100644 --- a/llvm/lib/Transforms/Instrumentation/PGOInstrumentation.cpp +++ b/llvm/lib/Transforms/Instrumentation/PGOInstrumentation.cpp @@ -1422,7 +1422,8 @@ void PGOUseFunc::populateCoverage(IndexedInstrProfReader *PGOReader) { for (auto *Succ : successors(&BB)) Weights.push_back((Coverage[Succ] || !Coverage[&BB]) ? 1 : 0); if (Weights.size() >= 2) - llvm::setBranchWeights(*BB.getTerminator(), Weights); + llvm::setBranchWeights(*BB.getTerminator(), Weights, + /*IsExpected=*/false); } unsigned NumCorruptCoverage = 0; @@ -2206,7 +2207,7 @@ void llvm::setProfMetadata(Module *M, Instruction *TI, misexpect::checkExpectAnnotations(*TI, Weights, /*IsFrontend=*/false); - setBranchWeights(*TI, Weights); + setBranchWeights(*TI, Weights, /*IsExpected=*/false); if (EmitBranchProbability) { std::string BrCondStr = getBranchCondString(TI); if (BrCondStr.empty()) diff --git a/llvm/lib/Transforms/Scalar/JumpThreading.cpp b/llvm/lib/Transforms/Scalar/JumpThreading.cpp index 08d82fa66da3..d552b8aabb99 100644 --- a/llvm/lib/Transforms/Scalar/JumpThreading.cpp +++ b/llvm/lib/Transforms/Scalar/JumpThreading.cpp @@ -231,7 +231,7 @@ static void updatePredecessorProfileMetadata(PHINode *PN, BasicBlock *BB) { Weights[0] = BP.getCompl().getNumerator(); Weights[1] = BP.getNumerator(); } - setBranchWeights(*PredBr, Weights); + setBranchWeights(*PredBr, Weights, hasBranchWeightProvenance(*PredBr)); } } @@ -2612,7 +2612,7 @@ void JumpThreadingPass::updateBlockFreqAndEdgeWeight(BasicBlock *PredBB, Weights.push_back(Prob.getNumerator()); auto TI = BB->getTerminator(); - setBranchWeights(*TI, Weights); + setBranchWeights(*TI, Weights, hasBranchWeightProvenance(*TI)); } } diff --git a/llvm/lib/Transforms/Scalar/LowerExpectIntrinsic.cpp b/llvm/lib/Transforms/Scalar/LowerExpectIntrinsic.cpp index 6f87e4d91d2c..17c5a4ee1fd0 100644 --- a/llvm/lib/Transforms/Scalar/LowerExpectIntrinsic.cpp +++ b/llvm/lib/Transforms/Scalar/LowerExpectIntrinsic.cpp @@ -102,7 +102,7 @@ static bool handleSwitchExpect(SwitchInst &SI) { misexpect::checkExpectAnnotations(SI, Weights, /*IsFrontend=*/true); SI.setCondition(ArgValue); - setBranchWeights(SI, Weights); + setBranchWeights(SI, Weights, /*IsExpected=*/true); return true; } @@ -262,11 +262,13 @@ static void handlePhiDef(CallInst *Expect) { if (IsOpndComingFromSuccessor(BI->getSuccessor(1))) BI->setMetadata(LLVMContext::MD_prof, MDB.createBranchWeights(LikelyBranchWeightVal, - UnlikelyBranchWeightVal)); + UnlikelyBranchWeightVal, + /*IsExpected=*/true)); else if (IsOpndComingFromSuccessor(BI->getSuccessor(0))) BI->setMetadata(LLVMContext::MD_prof, MDB.createBranchWeights(UnlikelyBranchWeightVal, - LikelyBranchWeightVal)); + LikelyBranchWeightVal, + /*IsExpected=*/true)); } } @@ -331,12 +333,12 @@ template <class BrSelInst> static bool handleBrSelExpect(BrSelInst &BSI) { SmallVector<uint32_t, 4> ExpectedWeights; if ((ExpectedValue->getZExtValue() == ValueComparedTo) == (Predicate == CmpInst::ICMP_EQ)) { - Node = - MDB.createBranchWeights(LikelyBranchWeightVal, UnlikelyBranchWeightVal); + Node = MDB.createBranchWeights( + LikelyBranchWeightVal, UnlikelyBranchWeightVal, /*IsExpected=*/true); ExpectedWeights = {LikelyBranchWeightVal, UnlikelyBranchWeightVal}; } else { - Node = - MDB.createBranchWeights(UnlikelyBranchWeightVal, LikelyBranchWeightVal); + Node = MDB.createBranchWeights(UnlikelyBranchWeightVal, + LikelyBranchWeightVal, /*IsExpected=*/true); ExpectedWeights = {UnlikelyBranchWeightVal, LikelyBranchWeightVal}; } diff --git a/llvm/lib/Transforms/Utils/Local.cpp b/llvm/lib/Transforms/Utils/Local.cpp index f3cd3104c312..63b61043d507 100644 --- a/llvm/lib/Transforms/Utils/Local.cpp +++ b/llvm/lib/Transforms/Utils/Local.cpp @@ -231,7 +231,7 @@ bool llvm::ConstantFoldTerminator(BasicBlock *BB, bool DeleteDeadConditions, // Remove weight for this case. std::swap(Weights[Idx + 1], Weights.back()); Weights.pop_back(); - setBranchWeights(*SI, Weights); + setBranchWeights(*SI, Weights, hasBranchWeightProvenance(MD)); } // Remove this entry. BasicBlock *ParentBB = SI->getParent(); diff --git a/llvm/lib/Transforms/Utils/LoopPeel.cpp b/llvm/lib/Transforms/Utils/LoopPeel.cpp index f76fa3bb6c61..c0f7dff5fb10 100644 --- a/llvm/lib/Transforms/Utils/LoopPeel.cpp +++ b/llvm/lib/Transforms/Utils/LoopPeel.cpp @@ -640,7 +640,7 @@ struct WeightInfo { /// To avoid dealing with division rounding we can just multiple both part /// of weights to E and use weight as (F - I * E, E). static void updateBranchWeights(Instruction *Term, WeightInfo &Info) { - setBranchWeights(*Term, Info.Weights); + setBranchWeights(*Term, Info.Weights, /*IsExpected=*/false); for (auto [Idx, SubWeight] : enumerate(Info.SubWeights)) if (SubWeight != 0) // Don't set the probability of taking the edge from latch to loop header @@ -1033,7 +1033,7 @@ bool llvm::peelLoop(Loop *L, unsigned PeelCount, LoopInfo *LI, } for (const auto &[Term, Info] : Weights) { - setBranchWeights(*Term, Info.Weights); + setBranchWeights(*Term, Info.Weights, /*IsExpected=*/false); } // Update Metadata for count of peeled off iterations. diff --git a/llvm/lib/Transforms/Utils/LoopRotationUtils.cpp b/llvm/lib/Transforms/Utils/LoopRotationUtils.cpp index 5cd96412a322..143677f1d14b 100644 --- a/llvm/lib/Transforms/Utils/LoopRotationUtils.cpp +++ b/llvm/lib/Transforms/Utils/LoopRotationUtils.cpp @@ -390,13 +390,13 @@ static void updateBranchWeights(BranchInst &PreHeaderBI, BranchInst &LoopBI, SuccsSwapped ? LoopBackWeight : ExitWeight1, SuccsSwapped ? ExitWeight1 : LoopBackWeight, }; - setBranchWeights(LoopBI, LoopBIWeights); + setBranchWeights(LoopBI, LoopBIWeights, /*IsExpected=*/false); if (HasConditionalPreHeader) { const uint32_t PreHeaderBIWeights[] = { SuccsSwapped ? EnterWeight : ExitWeight0, SuccsSwapped ? ExitWeight0 : EnterWeight, }; - setBranchWeights(PreHeaderBI, PreHeaderBIWeights); + setBranchWeights(PreHeaderBI, PreHeaderBIWeights, /*IsExpected=*/false); } } diff --git a/llvm/lib/Transforms/Utils/MisExpect.cpp b/llvm/lib/Transforms/Utils/MisExpect.cpp index 6f5a25a26821..9cb7c54e0c8c 100644 --- a/llvm/lib/Transforms/Utils/MisExpect.cpp +++ b/llvm/lib/Transforms/Utils/MisExpect.cpp @@ -150,15 +150,9 @@ void verifyMisExpect(Instruction &I, ArrayRef<uint32_t> RealWeights, uint64_t TotalBranchWeight = LikelyBranchWeight + (UnlikelyBranchWeight * NumUnlikelyTargets); - // FIXME: When we've addressed sample profiling, restore the assertion - // - // We cannot calculate branch probability if either of these invariants aren't - // met. However, MisExpect diagnostics should not prevent code from compiling, - // so we simply forgo emitting diagnostics here, and return early. - // assert((TotalBranchWeight >= LikelyBranchWeight) && (TotalBranchWeight > 0) - // && "TotalBranchWeight is less than the Likely branch weight"); - if ((TotalBranchWeight == 0) || (TotalBranchWeight <= LikelyBranchWeight)) - return; + // Failing this assert means that we have corrupted metadata. + assert((TotalBranchWeight >= LikelyBranchWeight) && (TotalBranchWeight > 0) && + "TotalBranchWeight is less than the Likely branch weight"); // To determine our threshold value we need to obtain the branch probability // for the weights added by llvm.expect and use that proportion to calculate @@ -185,6 +179,13 @@ void verifyMisExpect(Instruction &I, ArrayRef<uint32_t> RealWeights, void checkBackendInstrumentation(Instruction &I, const ArrayRef<uint32_t> RealWeights) { + // Backend checking assumes any existing weight comes from an `llvm.expect` + // intrinsic. However, SampleProfiling + ThinLTO add branch weights multiple + // times, leading to an invalid assumption in our checking. Backend checks + // should only operate on branch weights that carry the "!expected" field, + // since they are guaranteed to be added by the LowerExpectIntrinsic pass. + if (!hasBranchWeightProvenance(I)) + return; SmallVector<uint32_t> ExpectedWeights; if (!extractBranchWeights(I, ExpectedWeights)) return; diff --git a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp index 5a44a11ecfd2..b891eea0f341 100644 --- a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp +++ b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp @@ -861,26 +861,28 @@ static bool ValuesOverlap(std::vector<ValueEqualityComparisonCase> &C1, // Set branch weights on SwitchInst. This sets the metadata if there is at // least one non-zero weight. -static void setBranchWeights(SwitchInst *SI, ArrayRef<uint32_t> Weights) { +static void setBranchWeights(SwitchInst *SI, ArrayRef<uint32_t> Weights, + bool IsExpected) { // Check that there is at least one non-zero weight. Otherwise, pass // nullptr to setMetadata which will erase the existing metadata. MDNode *N = nullptr; if (llvm::any_of(Weights, [](uint32_t W) { return W != 0; })) - N = MDBuilder(SI->getParent()->getContext()).createBranchWeights(Weights); + N = MDBuilder(SI->getParent()->getContext()) + .createBranchWeights(Weights, IsExpected); SI->setMetadata(LLVMContext::MD_prof, N); } // Similar to the above, but for branch and select instructions that take // exactly 2 weights. static void setBranchWeights(Instruction *I, uint32_t TrueWeight, - uint32_t FalseWeight) { + uint32_t FalseWeight, bool IsExpected) { assert(isa<BranchInst>(I) || isa<SelectInst>(I)); // Check that there is at least one non-zero weight. Otherwise, pass // nullptr to setMetadata which will erase the existing metadata. MDNode *N = nullptr; if (TrueWeight || FalseWeight) N = MDBuilder(I->getParent()->getContext()) - .createBranchWeights(TrueWeight, FalseWeight); + .createBranchWeights(TrueWeight, FalseWeight, IsExpected); I->setMetadata(LLVMContext::MD_prof, N); } @@ -1339,7 +1341,7 @@ bool SimplifyCFGOpt::PerformValueComparisonIntoPredecessorFolding( SmallVector<uint32_t, 8> MDWeights(Weights.begin(), Weights.end()); - setBranchWeights(NewSI, MDWeights); + setBranchWeights(NewSI, MDWeights, /*IsExpected=*/false); } EraseTerminatorAndDCECond(PTI); @@ -3832,7 +3834,7 @@ static bool performBranchToCommonDestFolding(BranchInst *BI, BranchInst *PBI, FitWeights(NewWeights); SmallVector<uint32_t, 8> MDWeights(NewWeights.begin(), NewWeights.end()); - setBranchWeights(PBI, MDWeights[0], MDWeights[1]); + setBranchWeights(PBI, MDWeights[0], MDWeights[1], /*IsExpected=*/false); // TODO: If BB is reachable from all paths through PredBlock, then we // could replace PBI's branch probabilities with BI's. @@ -4569,7 +4571,7 @@ static bool SimplifyCondBranchToCondBranch(BranchInst *PBI, BranchInst *BI, // Halve the weights if any of them cannot fit in an uint32_t FitWeights(NewWeights); - setBranchWeights(PBI, NewWeights[0], NewWeights[1]); + setBranchWeights(PBI, NewWeights[0], NewWeights[1], /*IsExpected=*/false); } // OtherDest may have phi nodes. If so, add an entry from PBI's @@ -4605,7 +4607,8 @@ static bool SimplifyCondBranchToCondBranch(BranchInst *PBI, BranchInst *BI, FitWeights(NewWeights); - setBranchWeights(NV, NewWeights[0], NewWeights[1]); + setBranchWeights(NV, NewWeights[0], NewWeights[1], + /*IsExpected=*/false); } } } @@ -4668,7 +4671,7 @@ bool SimplifyCFGOpt::SimplifyTerminatorOnSelect(Instruction *OldTerm, // Create a conditional branch sharing the condition of the select. BranchInst *NewBI = Builder.CreateCondBr(Cond, TrueBB, FalseBB); if (TrueWeight != FalseWeight) - setBranchWeights(NewBI, TrueWeight, FalseWeight); + setBranchWeights(NewBI, TrueWeight, FalseWeight, /*IsExpected=*/false); } } else if (KeepEdge1 && (KeepEdge2 || TrueBB == FalseBB)) { // Neither of the selected blocks were successors, so this @@ -5615,7 +5618,7 @@ bool SimplifyCFGOpt::TurnSwitchRangeIntoICmp(SwitchInst *SI, TrueWeight /= 2; FalseWeight /= 2; } - setBranchWeights(NewBI, TrueWeight, FalseWeight); + setBranchWeights(NewBI, TrueWeight, FalseWeight, /*IsExpected=*/false); } } diff --git a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp index c44d90f0998e..40b245fd4c44 100644 --- a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp +++ b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp @@ -2151,7 +2151,7 @@ public: BranchInst &BI = *BranchInst::Create(Bypass, LoopVectorPreHeader, Cond); if (AddBranchWeights) - setBranchWeights(BI, SCEVCheckBypassWeights); + setBranchWeights(BI, SCEVCheckBypassWeights, /*IsExpected=*/false); ReplaceInstWithInst(SCEVCheckBlock->getTerminator(), &BI); return SCEVCheckBlock; } @@ -2179,7 +2179,7 @@ public: BranchInst &BI = *BranchInst::Create(Bypass, LoopVectorPreHeader, MemRuntimeCheckCond); if (AddBranchWeights) { - setBranchWeights(BI, MemCheckBypassWeights); + setBranchWeights(BI, MemCheckBypassWeights, /*IsExpected=*/false); } ReplaceInstWithInst(MemCheckBlock->getTerminator(), &BI); MemCheckBlock->getTerminator()->setDebugLoc( @@ -2895,7 +2895,7 @@ void InnerLoopVectorizer::emitIterationCountCheck(BasicBlock *Bypass) { BranchInst &BI = *BranchInst::Create(Bypass, LoopVectorPreHeader, CheckMinIters); if (hasBranchWeightMD(*OrigLoop->getLoopLatch()->getTerminator())) - setBranchWeights(BI, MinItersBypassWeights); + setBranchWeights(BI, MinItersBypassWeights, /*IsExpected=*/false); ReplaceInstWithInst(TCCheckBlock->getTerminator(), &BI); LoopBypassBlocks.push_back(TCCheckBlock); } @@ -3135,7 +3135,7 @@ BasicBlock *InnerLoopVectorizer::completeLoopSkeleton() { unsigned TripCount = UF * VF.getKnownMinValue(); assert(TripCount > 0 && "trip count should not be zero"); const uint32_t Weights[] = {1, TripCount - 1}; - setBranchWeights(BI, Weights); + setBranchWeights(BI, Weights, /*IsExpected=*/false); } } @@ -7757,7 +7757,7 @@ EpilogueVectorizerMainLoop::emitIterationCountCheck(BasicBlock *Bypass, BranchInst &BI = *BranchInst::Create(Bypass, LoopVectorPreHeader, CheckMinIters); if (hasBranchWeightMD(*OrigLoop->getLoopLatch()->getTerminator())) - setBranchWeights(BI, MinItersBypassWeights); + setBranchWeights(BI, MinItersBypassWeights, /*IsExpected=*/false); ReplaceInstWithInst(TCCheckBlock->getTerminator(), &BI); return TCCheckBlock; @@ -7915,7 +7915,7 @@ EpilogueVectorizerEpilogueLoop::emitMinimumVectorEpilogueIterCountCheck( unsigned EstimatedSkipCount = std::min(MainLoopStep, EpilogueLoopStep); const uint32_t Weights[] = {EstimatedSkipCount, MainLoopStep - EstimatedSkipCount}; - setBranchWeights(BI, Weights); + setBranchWeights(BI, Weights, /*IsExpected=*/false); } ReplaceInstWithInst(Insert->getTerminator(), &BI); diff --git a/llvm/test/CodeGen/SystemZ/copy-phys-reg-gr128-to-vr128.mir b/llvm/test/CodeGen/SystemZ/copy-phys-reg-gr128-to-vr128.mir new file mode 100644 index 000000000000..a2a07ac5c7f5 --- /dev/null +++ b/llvm/test/CodeGen/SystemZ/copy-phys-reg-gr128-to-vr128.mir @@ -0,0 +1,78 @@ +# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 4 +# RUN: llc -mtriple=s390x-ibm-linux -mcpu=z13 -run-pass=postrapseudos -o - %s | FileCheck %s + +--- +name: copy_gr128_to_vr128__r0q_to_v0 +tracksRegLiveness: true +body: | + bb.0: + liveins: $r0q + ; CHECK-LABEL: name: copy_gr128_to_vr128__r0q_to_v0 + ; CHECK: liveins: $r0q + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: $v0 = VLVGP $r0d, $r1d + ; CHECK-NEXT: Return implicit $v0 + $v0 = COPY $r0q + Return implicit $v0 +... + +--- +name: copy_gr128_to_vr128__r0q_to_v0_killed +tracksRegLiveness: true +body: | + bb.0: + liveins: $r0q + ; CHECK-LABEL: name: copy_gr128_to_vr128__r0q_to_v0_killed + ; CHECK: liveins: $r0q + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: $v0 = VLVGP $r0d, $r1d + ; CHECK-NEXT: Return implicit $v0 + $v0 = COPY killed $r0q + Return implicit $v0 +... + +--- +name: copy_gr128_to_vr128__r0q_to_v0_undef +tracksRegLiveness: true +body: | + bb.0: + liveins: $r0q + ; CHECK-LABEL: name: copy_gr128_to_vr128__r0q_to_v0_undef + ; CHECK: liveins: $r0q + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: $v0 = KILL undef $r0q + ; CHECK-NEXT: Return implicit $v0 + $v0 = COPY undef $r0q + Return implicit $v0 +... + +--- +name: copy_gr128_to_vr128__r0q_to_v0_subreg0 +tracksRegLiveness: true +body: | + bb.0: + liveins: $r0d + ; CHECK-LABEL: name: copy_gr128_to_vr128__r0q_to_v0_subreg0 + ; CHECK: liveins: $r0d + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: $v0 = VLVGP $r0d, $r1d + ; CHECK-NEXT: Return implicit $v0 + $v0 = COPY $r0q + Return implicit $v0 +... + +--- +name: copy_gr128_to_vr128__r0q_to_v0_subreg1 +tracksRegLiveness: true +body: | + bb.0: + liveins: $r1d + ; CHECK-LABEL: name: copy_gr128_to_vr128__r0q_to_v0_subreg1 + ; CHECK: liveins: $r1d + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: $v0 = VLVGP $r0d, $r1d + ; CHECK-NEXT: Return implicit $v0 + $v0 = COPY $r0q + Return implicit $v0 +... + diff --git a/llvm/test/CodeGen/SystemZ/copy-phys-reg-vr128-to-gr128.mir b/llvm/test/CodeGen/SystemZ/copy-phys-reg-vr128-to-gr128.mir new file mode 100644 index 000000000000..c1141aaf7a2e --- /dev/null +++ b/llvm/test/CodeGen/SystemZ/copy-phys-reg-vr128-to-gr128.mir @@ -0,0 +1,70 @@ +# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 4 +# RUN: llc -mtriple=s390x-ibm-linux -mcpu=z13 -run-pass=postrapseudos -o - %s | FileCheck %s + +--- +name: copy_vr128_to_gr128__v0_to_r0q +tracksRegLiveness: true +body: | + bb.0: + liveins: $v0 + ; CHECK-LABEL: name: copy_vr128_to_gr128__v0_to_r0q + ; CHECK: liveins: $v0 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: $r0d = VLGVG $v0, $noreg, 0, implicit-def $r0q + ; CHECK-NEXT: $r1d = VLGVG $v0, $noreg, 1 + ; CHECK-NEXT: Return implicit $r0q + $r0q = COPY $v0 + Return implicit $r0q +... + +--- +name: copy_vr128_to_gr128__v0_to_r0q_killed +tracksRegLiveness: true +body: | + bb.0: + liveins: $v0 + ; CHECK-LABEL: name: copy_vr128_to_gr128__v0_to_r0q_killed + ; CHECK: liveins: $v0 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: $r0d = VLGVG $v0, $noreg, 0, implicit-def $r0q + ; CHECK-NEXT: $r1d = VLGVG killed $v0, $noreg, 1 + ; CHECK-NEXT: Return implicit $r0q + $r0q = COPY killed $v0 + Return implicit $r0q +... + +--- +name: copy_vr128_to_gr128__v0_to_r0q_undef +tracksRegLiveness: true +body: | + bb.0: + ; CHECK-LABEL: name: copy_vr128_to_gr128__v0_to_r0q_undef + ; CHECK: $r0q = KILL undef $v0 + ; CHECK-NEXT: Return implicit $r0q + $r0q = COPY undef $v0 + Return implicit $r0q +... + +--- +name: copy_vr128_to_gr128__v0_to_r0q_undef_use_subreg0 +tracksRegLiveness: true +body: | + bb.0: + ; CHECK-LABEL: name: copy_vr128_to_gr128__v0_to_r0q_undef_use_subreg0 + ; CHECK: $r0q = KILL undef $v0 + ; CHECK-NEXT: Return implicit $r0d + $r0q = COPY undef $v0 + Return implicit $r0d +... + +--- +name: copy_vr128_to_gr128__v0_to_r0q_undef_use_subreg1 +tracksRegLiveness: true +body: | + bb.0: + ; CHECK-LABEL: name: copy_vr128_to_gr128__v0_to_r0q_undef_use_subreg1 + ; CHECK: $r0q = KILL undef $v0 + ; CHECK-NEXT: Return implicit $r1d + $r0q = COPY undef $v0 + Return implicit $r1d +... diff --git a/llvm/test/Transforms/LowerExpectIntrinsic/basic.ll b/llvm/test/Transforms/LowerExpectIntrinsic/basic.ll index 0abca5b38322..8e06cd57a100 100644 --- a/llvm/test/Transforms/LowerExpectIntrinsic/basic.ll +++ b/llvm/test/Transforms/LowerExpectIntrinsic/basic.ll @@ -284,7 +284,7 @@ define i32 @test10(i64 %t6) { declare i1 @llvm.expect.i1(i1, i1) nounwind readnone -; CHECK: !0 = !{!"branch_weights", i32 2000, i32 1} -; CHECK: !1 = !{!"branch_weights", i32 1, i32 2000} -; CHECK: !2 = !{!"branch_weights", i32 1, i32 1, i32 2000} -; CHECK: !3 = !{!"branch_weights", i32 2000, i32 1, i32 1} +; CHECK: !0 = !{!"branch_weights", !"expected", i32 2000, i32 1} +; CHECK: !1 = !{!"branch_weights", !"expected", i32 1, i32 2000} +; CHECK: !2 = !{!"branch_weights", !"expected", i32 1, i32 1, i32 2000} +; CHECK: !3 = !{!"branch_weights", !"expected", i32 2000, i32 1, i32 1} diff --git a/llvm/test/Transforms/LowerExpectIntrinsic/expect-with-probability.ll b/llvm/test/Transforms/LowerExpectIntrinsic/expect-with-probability.ll index 64293557050c..40571278ca93 100644 --- a/llvm/test/Transforms/LowerExpectIntrinsic/expect-with-probability.ll +++ b/llvm/test/Transforms/LowerExpectIntrinsic/expect-with-probability.ll @@ -284,7 +284,7 @@ define i32 @test10(i64 %t6) { declare i1 @llvm.expect.with.probability.i1(i1, i1, double) nounwind readnone -; CHECK: !0 = !{!"branch_weights", i32 1717986918, i32 429496731} -; CHECK: !1 = !{!"branch_weights", i32 429496731, i32 1717986918} -; CHECK: !2 = !{!"branch_weights", i32 214748366, i32 214748366, i32 1717986918} -; CHECK: !3 = !{!"branch_weights", i32 1717986918, i32 214748366, i32 214748366} +; CHECK: !0 = !{!"branch_weights", !"expected", i32 1717986918, i32 429496731} +; CHECK: !1 = !{!"branch_weights", !"expected", i32 429496731, i32 1717986918} +; CHECK: !2 = !{!"branch_weights", !"expected", i32 214748366, i32 214748366, i32 1717986918} +; CHECK: !3 = !{!"branch_weights", !"expected", i32 1717986918, i32 214748366, i32 214748366} diff --git a/llvm/test/Transforms/LowerExpectIntrinsic/expect_nonboolean.ll b/llvm/test/Transforms/LowerExpectIntrinsic/expect_nonboolean.ll index 2bcfb1e064be..458a7758fa97 100644 --- a/llvm/test/Transforms/LowerExpectIntrinsic/expect_nonboolean.ll +++ b/llvm/test/Transforms/LowerExpectIntrinsic/expect_nonboolean.ll @@ -99,6 +99,5 @@ attributes #1 = { nounwind readnone } !0 = !{i32 1, !"wchar_size", i32 4} !1 = !{!"clang version 5.0.0 (trunk 304373)"} -; CHECK: [[LIKELY]] = !{!"branch_weights", i32 2000, i32 1} -; CHECK: [[UNLIKELY]] = !{!"branch_weights", i32 1, i32 2000} - +; CHECK: [[LIKELY]] = !{!"branch_weights", !"expected", i32 2000, i32 1} +; CHECK: [[UNLIKELY]] = !{!"branch_weights", !"expected", i32 1, i32 2000} diff --git a/llvm/test/Transforms/LowerExpectIntrinsic/phi_merge.ll b/llvm/test/Transforms/LowerExpectIntrinsic/phi_merge.ll index 32ae9b0b2f15..9b9d9a746dd3 100644 --- a/llvm/test/Transforms/LowerExpectIntrinsic/phi_merge.ll +++ b/llvm/test/Transforms/LowerExpectIntrinsic/phi_merge.ll @@ -352,5 +352,5 @@ declare i64 @llvm.expect.i64(i64, i64) !llvm.ident = !{!0} !0 = !{!"clang version 5.0.0 (trunk 302965)"} -; CHECK: [[WEIGHT]] = !{!"branch_weights", i32 2000, i32 1} -; CHECK: [[WEIGHT2]] = !{!"branch_weights", i32 1, i32 2000} +; CHECK: [[WEIGHT]] = !{!"branch_weights", !"expected", i32 2000, i32 1} +; CHECK: [[WEIGHT2]] = !{!"branch_weights", !"expected", i32 1, i32 2000} diff --git a/llvm/test/Transforms/LowerExpectIntrinsic/phi_or.ll b/llvm/test/Transforms/LowerExpectIntrinsic/phi_or.ll index 1efa63241c2c..e9a843225993 100644 --- a/llvm/test/Transforms/LowerExpectIntrinsic/phi_or.ll +++ b/llvm/test/Transforms/LowerExpectIntrinsic/phi_or.ll @@ -99,5 +99,5 @@ declare i64 @llvm.expect.i64(i64, i64) !0 = !{!"clang version 5.0.0 (trunk 302965)"} -; CHECK: [[WEIGHT]] = !{!"branch_weights", i32 2000, i32 1} -; CHECK: [[WEIGHT2]] = !{!"branch_weights", i32 1, i32 2000} +; CHECK: [[WEIGHT]] = !{!"branch_weights", !"expected", i32 2000, i32 1} +; CHECK: [[WEIGHT2]] = !{!"branch_weights", !"expected", i32 1, i32 2000} diff --git a/llvm/test/Transforms/LowerExpectIntrinsic/phi_tern.ll b/llvm/test/Transforms/LowerExpectIntrinsic/phi_tern.ll index 9cbaca8d13dc..13db2c394bab 100644 --- a/llvm/test/Transforms/LowerExpectIntrinsic/phi_tern.ll +++ b/llvm/test/Transforms/LowerExpectIntrinsic/phi_tern.ll @@ -53,4 +53,4 @@ declare i64 @llvm.expect.i64(i64, i64) !0 = !{!"clang version 5.0.0 (trunk 302965)"} -; CHECK: [[WEIGHT]] = !{!"branch_weights", i32 1, i32 2000} +; CHECK: [[WEIGHT]] = !{!"branch_weights", !"expected", i32 1, i32 2000} diff --git a/llvm/test/Transforms/LowerExpectIntrinsic/phi_unexpect.ll b/llvm/test/Transforms/LowerExpectIntrinsic/phi_unexpect.ll index 2bad66343b76..275731d61889 100644 --- a/llvm/test/Transforms/LowerExpectIntrinsic/phi_unexpect.ll +++ b/llvm/test/Transforms/LowerExpectIntrinsic/phi_unexpect.ll @@ -235,5 +235,5 @@ block5: ret void } -; CHECK: !0 = !{!"branch_weights", i32 2147483647, i32 1} -; CHECK: !1 = !{!"branch_weights", i32 1, i32 2147483647} +; CHECK: !0 = !{!"branch_weights", !"expected", i32 2147483647, i32 1} +; CHECK: !1 = !{!"branch_weights", !"expected", i32 1, i32 2147483647} diff --git a/openmp/runtime/src/z_Linux_util.cpp b/openmp/runtime/src/z_Linux_util.cpp index 11ce083f4801..affb577a5393 100644 --- a/openmp/runtime/src/z_Linux_util.cpp +++ b/openmp/runtime/src/z_Linux_util.cpp @@ -29,7 +29,9 @@ #include <semaphore.h> #endif // KMP_OS_LINUX #include <sys/resource.h> -#if !KMP_OS_AIX +#if KMP_OS_AIX +#include <sys/ldr.h> +#else #include <sys/syscall.h> #endif #include <sys/time.h> @@ -2338,9 +2340,48 @@ int __kmp_is_address_mapped(void *addr) { found = (int)addr < (__builtin_wasm_memory_size(0) * PAGESIZE); #elif KMP_OS_AIX - (void)rc; - // FIXME(AIX): Implement this - found = 1; + uint32_t loadQueryBufSize = 4096u; // Default loadquery buffer size. + char *loadQueryBuf; + + for (;;) { + loadQueryBuf = (char *)KMP_INTERNAL_MALLOC(loadQueryBufSize); + if (loadQueryBuf == NULL) { + return 0; + } + + rc = loadquery(L_GETXINFO | L_IGNOREUNLOAD, loadQueryBuf, loadQueryBufSize); + if (rc < 0) { + KMP_INTERNAL_FREE(loadQueryBuf); + if (errno != ENOMEM) { + return 0; + } + // errno == ENOMEM; double the size. + loadQueryBufSize <<= 1; + continue; + } + // Obtained the load info successfully. + break; + } + + struct ld_xinfo *curLdInfo = (struct ld_xinfo *)loadQueryBuf; + + // Loop through the load info to find if there is a match. + for (;;) { + uintptr_t curDataStart = (uintptr_t)curLdInfo->ldinfo_dataorg; + uintptr_t curDataEnd = curDataStart + curLdInfo->ldinfo_datasize; + + // The data segment is readable and writable. + if (curDataStart <= (uintptr_t)addr && (uintptr_t)addr < curDataEnd) { + found = 1; + break; + } + if (curLdInfo->ldinfo_next == 0u) { + // Reached the end of load info. + break; + } + curLdInfo = (struct ld_xinfo *)((char *)curLdInfo + curLdInfo->ldinfo_next); + } + KMP_INTERNAL_FREE(loadQueryBuf); #else |