git: a4e0cb2fd99a - main - devel/llvm18: fix host dependent compiler output for i386
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Thu, 25 Jul 2024 22:00:39 UTC
The branch main has been updated by brooks: URL: https://cgit.FreeBSD.org/ports/commit/?id=a4e0cb2fd99adef4cbd4f778be729a079a5f2dea commit a4e0cb2fd99adef4cbd4f778be729a079a5f2dea Author: Brooks Davis <brooks@FreeBSD.org> AuthorDate: 2024-07-25 22:00:32 +0000 Commit: Brooks Davis <brooks@FreeBSD.org> CommitDate: 2024-07-25 22:00:32 +0000 devel/llvm18: fix host dependent compiler output for i386 Merge fixes for a couple cases where the compiler generated different i386 code depending on the host. In the base system this showed up as very small differences in a couple object files in buildworld for i386 depending on the host architecture (i386 or amd64). PR: 276961 --- devel/llvm18/Makefile | 2 +- .../files/patch-backport-freebsd-397c2693fa6 | 43 +++++++ .../files/patch-backport-freebsd-55a2a91c5e1 | 128 +++++++++++++++++++++ 3 files changed, 172 insertions(+), 1 deletion(-) diff --git a/devel/llvm18/Makefile b/devel/llvm18/Makefile index 5148732975be..7f85ff1cdd4f 100644 --- a/devel/llvm18/Makefile +++ b/devel/llvm18/Makefile @@ -1,6 +1,6 @@ PORTNAME= llvm DISTVERSION= 18.1.8 -PORTREVISION= 0 +PORTREVISION= 1 CATEGORIES= devel lang MASTER_SITES= https://github.com/llvm/llvm-project/releases/download/llvmorg-${DISTVERSION:S/rc/-rc/}/ PKGNAMESUFFIX= ${LLVM_SUFFIX} diff --git a/devel/llvm18/files/patch-backport-freebsd-397c2693fa6 b/devel/llvm18/files/patch-backport-freebsd-397c2693fa6 new file mode 100644 index 000000000000..f000829474ba --- /dev/null +++ b/devel/llvm18/files/patch-backport-freebsd-397c2693fa6 @@ -0,0 +1,43 @@ +commit 397c2693fa66508cb5e6b173650a1f3bc6c4dd4f +Author: Dimitry Andric <dim@FreeBSD.org> +Date: Sun Jul 21 22:37:27 2024 +0200 + + Fix llvm register allocator for native/cross build differences + + Work around an issue in LLVM's register allocator, which can cause + slightly different i386 object files, when produced by a native or cross + build of clang. + + This adds another volatile qualifier to a float variable declaration in + the weightCalcHelper() function, which otherwise produces slightly + different float results on amd64 and i386 hosts. In turn, this can lead + to different (but equivalent) register choices, and thus non-identical + assembly code. + + See https://github.com/llvm/llvm-project/issues/99396 for more details. + + Note this is a temporary fix, meant to merge in time for 13.4. As soon + as upstream has a permanent solution we will import that. + + PR: 276961 + Reported by: cperciva + MFC after: 3 days + +diff --git llvm/lib/CodeGen/CalcSpillWeights.cpp llvm/lib/CodeGen/CalcSpillWeights.cpp +index f3cb7fa5af61..afde8d001f88 100644 +--- llvm/lib/CodeGen/CalcSpillWeights.cpp ++++ llvm/lib/CodeGen/CalcSpillWeights.cpp +@@ -256,7 +256,12 @@ float VirtRegAuxInfo::weightCalcHelper(LiveInterval &LI, SlotIndex *Start, + return -1.0f; + } + +- float Weight = 1.0f; ++ // FreeBSD customization: similar to the HWeight declaration below, add a ++ // volatile qualifier to avoid slightly different weight results on amd64 ++ // and i386 hosts, and possibly choosing different registers in the register ++ // allocator. See <https://github.com/llvm/llvm-project/issues/99396> for ++ // more details. ++ volatile float Weight = 1.0f; + if (IsSpillable) { + // Get loop info for mi. + if (MI->getParent() != MBB) { diff --git a/devel/llvm18/files/patch-backport-freebsd-55a2a91c5e1 b/devel/llvm18/files/patch-backport-freebsd-55a2a91c5e1 new file mode 100644 index 000000000000..8843d3749348 --- /dev/null +++ b/devel/llvm18/files/patch-backport-freebsd-55a2a91c5e1 @@ -0,0 +1,128 @@ +commit 55a2a91c5e1bb39dd625ba56597608883fbcb318 +Author: Dimitry Andric <dim@FreeBSD.org> +Date: Thu Jul 25 13:13:45 2024 +0200 + + Merge commit 28a2b85602a5 from llvm-project (by Kazu Hirata): + + [DeadStoreElimination] Use SmallSetVector (NFC) (#79410) + + The use of SmallSetVector saves 0.58% of heap allocations during the + compilation of a large preprocessed file, namely X86ISelLowering.cpp, + for the X86 target. During the experiment, the final size of ToCheck + was 8 or less 88% of the time. + + Merge commit 9e95c4947d31 from llvm-project (by Nikita Popov): + + [DSE] Fix non-determinism due to address reuse (#84943) + + The malloc->calloc fold creates a new MemoryAccess, which may end of at + the same address as a previously deleted access inside SkipStores. + + To the most part, this is not a problem, because SkipStores is normally + only used together with MemDefs. Neither the old malloc access nor the + new calloc access will be part of MemDefs, so there is no problem here. + + However, SkipStores is also used in one more place: In the main DSE + loop, ToCheck entries are checked against it. Fix this by not using + SkipStores here, and instead using a separate set to track deletions + inside this loop. This way it is not affected by the calloc optimization + that happens outside it. + + This is all pretty ugly, but I haven't found another good way to fix it. + Suggestions welcome. + + No test case as I don't have a reliable DSE-only test-case for this. + + Fixes https://github.com/llvm/llvm-project/issues/84458. + + This fixes another possible difference in output when building i386 + object files with a native or cross build of clang. (Specifically, the + file sbin/ipf/ipmon/ipmon.o.) + + PR: 276961 + Reported by: cperciva + MFC after: 3 days + +diff --git llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp +index 380d65836553..f0f0f5f28025 100644 +--- llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp ++++ llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp +@@ -1697,7 +1697,9 @@ struct DSEState { + + /// Delete dead memory defs and recursively add their operands to ToRemove if + /// they became dead. +- void deleteDeadInstruction(Instruction *SI) { ++ void ++ deleteDeadInstruction(Instruction *SI, ++ SmallPtrSetImpl<MemoryAccess *> *Deleted = nullptr) { + MemorySSAUpdater Updater(&MSSA); + SmallVector<Instruction *, 32> NowDeadInsts; + NowDeadInsts.push_back(SI); +@@ -1718,6 +1720,8 @@ struct DSEState { + if (IsMemDef) { + auto *MD = cast<MemoryDef>(MA); + SkipStores.insert(MD); ++ if (Deleted) ++ Deleted->insert(MD); + if (auto *SI = dyn_cast<StoreInst>(MD->getMemoryInst())) { + if (SI->getValueOperand()->getType()->isPointerTy()) { + const Value *UO = getUnderlyingObject(SI->getValueOperand()); +@@ -2111,7 +2115,12 @@ static bool eliminateDeadStores(Function &F, AliasAnalysis &AA, MemorySSA &MSSA, + unsigned WalkerStepLimit = MemorySSAUpwardsStepLimit; + unsigned PartialLimit = MemorySSAPartialStoreLimit; + // Worklist of MemoryAccesses that may be killed by KillingDef. +- SetVector<MemoryAccess *> ToCheck; ++ SmallSetVector<MemoryAccess *, 8> ToCheck; ++ // Track MemoryAccesses that have been deleted in the loop below, so we can ++ // skip them. Don't use SkipStores for this, which may contain reused ++ // MemoryAccess addresses. ++ SmallPtrSet<MemoryAccess *, 8> Deleted; ++ [[maybe_unused]] unsigned OrigNumSkipStores = State.SkipStores.size(); + ToCheck.insert(KillingDef->getDefiningAccess()); + + bool Shortend = false; +@@ -2119,7 +2128,7 @@ static bool eliminateDeadStores(Function &F, AliasAnalysis &AA, MemorySSA &MSSA, + // Check if MemoryAccesses in the worklist are killed by KillingDef. + for (unsigned I = 0; I < ToCheck.size(); I++) { + MemoryAccess *Current = ToCheck[I]; +- if (State.SkipStores.count(Current)) ++ if (Deleted.contains(Current)) + continue; + + std::optional<MemoryAccess *> MaybeDeadAccess = State.getDomMemoryDef( +@@ -2166,7 +2175,7 @@ static bool eliminateDeadStores(Function &F, AliasAnalysis &AA, MemorySSA &MSSA, + continue; + LLVM_DEBUG(dbgs() << "DSE: Remove Dead Store:\n DEAD: " << *DeadI + << "\n KILLER: " << *KillingI << '\n'); +- State.deleteDeadInstruction(DeadI); ++ State.deleteDeadInstruction(DeadI, &Deleted); + ++NumFastStores; + MadeChange = true; + } else { +@@ -2203,7 +2212,7 @@ static bool eliminateDeadStores(Function &F, AliasAnalysis &AA, MemorySSA &MSSA, + Shortend = true; + // Remove killing store and remove any outstanding overlap + // intervals for the updated store. +- State.deleteDeadInstruction(KillingSI); ++ State.deleteDeadInstruction(KillingSI, &Deleted); + auto I = State.IOLs.find(DeadSI->getParent()); + if (I != State.IOLs.end()) + I->second.erase(DeadSI); +@@ -2215,13 +2224,16 @@ static bool eliminateDeadStores(Function &F, AliasAnalysis &AA, MemorySSA &MSSA, + if (OR == OW_Complete) { + LLVM_DEBUG(dbgs() << "DSE: Remove Dead Store:\n DEAD: " << *DeadI + << "\n KILLER: " << *KillingI << '\n'); +- State.deleteDeadInstruction(DeadI); ++ State.deleteDeadInstruction(DeadI, &Deleted); + ++NumFastStores; + MadeChange = true; + } + } + } + ++ assert(State.SkipStores.size() - OrigNumSkipStores == Deleted.size() && ++ "SkipStores and Deleted out of sync?"); ++ + // Check if the store is a no-op. + if (!Shortend && State.storeIsNoop(KillingDef, KillingUndObj)) { + LLVM_DEBUG(dbgs() << "DSE: Remove No-Op Store:\n DEAD: " << *KillingI