commit b1bb03faca8182a20434c9021d76b4adc504af50 Author: tigro Date: Mon Nov 4 22:22:47 2024 +0300 import llvm11-11.1.0-6.el9 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d275078 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +SOURCES/llvm-11.1.0.src.tar.xz diff --git a/.llvm11.metadata b/.llvm11.metadata new file mode 100644 index 0000000..a0e5787 --- /dev/null +++ b/.llvm11.metadata @@ -0,0 +1 @@ +89c1aabaca65f00fd03db1b69d65fa64fcb2b812 SOURCES/llvm-11.1.0.src.tar.xz diff --git a/SOURCES/0001-Deactivate-markdown-doc.patch b/SOURCES/0001-Deactivate-markdown-doc.patch new file mode 100644 index 0000000..92e048d --- /dev/null +++ b/SOURCES/0001-Deactivate-markdown-doc.patch @@ -0,0 +1,25 @@ +diff -Naur a/llvm/docs/conf.py b/llvm/docs/conf.py +--- a/llvm/docs/conf.py 2020-09-15 09:12:24.318287611 +0000 ++++ b/llvm/docs/conf.py 2020-09-15 15:01:00.025893199 +0000 +@@ -36,20 +36,7 @@ + '.rst': 'restructuredtext', + } + +-try: +- import recommonmark +-except ImportError: +- # manpages do not use any .md sources +- if not tags.has('builder-man'): +- raise +-else: +- import sphinx +- if sphinx.version_info >= (3, 0): +- # This requires 0.5 or later. +- extensions.append('recommonmark') +- else: +- source_parsers = {'.md': 'recommonmark.parser.CommonMarkParser'} +- source_suffix['.md'] = 'markdown' ++import sphinx + + # The encoding of source files. + #source_encoding = 'utf-8-sig' diff --git a/SOURCES/0001-MemCpyOpt-Correctly-merge-alias-scopes-during-call-s.patch b/SOURCES/0001-MemCpyOpt-Correctly-merge-alias-scopes-during-call-s.patch new file mode 100644 index 0000000..411d94f --- /dev/null +++ b/SOURCES/0001-MemCpyOpt-Correctly-merge-alias-scopes-during-call-s.patch @@ -0,0 +1,373 @@ +From e804574cad8efa1b7a660848ef7adc871a7f850e Mon Sep 17 00:00:00 2001 +From: modimo +Date: Thu, 3 Dec 2020 09:23:37 -0800 +Subject: [PATCH] [MemCpyOpt] Correctly merge alias scopes during call slot + optimization + +When MemCpyOpt performs call slot optimization it will concatenate the `alias.scope` metadata between the function call and the memcpy. However, scoped AA relies on the domains in metadata to be maintained in a caller-callee relationship. Naive concatenation breaks this assumption leading to bad AA results. + +The fix is to take the intersection of domains then union the scopes within those domains. + +The original bug came from a case of rust bad codegen which uses this bad aliasing to perform additional memcpy optimizations. As show in the added test case `%src` got forwarded past its lifetime leading to a dereference of garbage data. + +Testing +ninja check-llvm + +Reviewed By: jeroen.dobbelaere + +Differential Revision: https://reviews.llvm.org/D91576 + +(cherry picked from commit 18603319321a6c1b158800bcc60035ee01549516) +--- + llvm/include/llvm/Analysis/ScopedNoAliasAA.h | 21 ++++++++++ + llvm/lib/Analysis/ScopedNoAliasAA.cpp | 25 ------------ + llvm/lib/IR/Metadata.cpp | 28 ++++++++++++- + .../ScopedNoAliasAA/alias-scope-merging.ll | 37 ++++++++++++++++++ + llvm/test/Transforms/GVN/noalias.ll | 29 +++++++------- + .../InstCombine/fold-phi-load-metadata.ll | 4 +- + .../Transforms/MemCpyOpt/callslot_badaa.ll | 39 +++++++++++++++++++ + llvm/test/Transforms/NewGVN/noalias.ll | 29 +++++++------- + 8 files changed, 156 insertions(+), 56 deletions(-) + create mode 100644 llvm/test/Analysis/ScopedNoAliasAA/alias-scope-merging.ll + create mode 100644 llvm/test/Transforms/MemCpyOpt/callslot_badaa.ll + +diff --git a/llvm/include/llvm/Analysis/ScopedNoAliasAA.h b/llvm/include/llvm/Analysis/ScopedNoAliasAA.h +index c55228eace4b..562640647918 100644 +--- a/llvm/include/llvm/Analysis/ScopedNoAliasAA.h ++++ b/llvm/include/llvm/Analysis/ScopedNoAliasAA.h +@@ -25,6 +25,27 @@ class Function; + class MDNode; + class MemoryLocation; + ++/// This is a simple wrapper around an MDNode which provides a higher-level ++/// interface by hiding the details of how alias analysis information is encoded ++/// in its operands. ++class AliasScopeNode { ++ const MDNode *Node = nullptr; ++ ++public: ++ AliasScopeNode() = default; ++ explicit AliasScopeNode(const MDNode *N) : Node(N) {} ++ ++ /// Get the MDNode for this AliasScopeNode. ++ const MDNode *getNode() const { return Node; } ++ ++ /// Get the MDNode for this AliasScopeNode's domain. ++ const MDNode *getDomain() const { ++ if (Node->getNumOperands() < 2) ++ return nullptr; ++ return dyn_cast_or_null(Node->getOperand(1)); ++ } ++}; ++ + /// A simple AA result which uses scoped-noalias metadata to answer queries. + class ScopedNoAliasAAResult : public AAResultBase { + friend AAResultBase; +diff --git a/llvm/lib/Analysis/ScopedNoAliasAA.cpp b/llvm/lib/Analysis/ScopedNoAliasAA.cpp +index 8928678d6ab2..22e0501b28f4 100644 +--- a/llvm/lib/Analysis/ScopedNoAliasAA.cpp ++++ b/llvm/lib/Analysis/ScopedNoAliasAA.cpp +@@ -50,31 +50,6 @@ using namespace llvm; + static cl::opt EnableScopedNoAlias("enable-scoped-noalias", + cl::init(true), cl::Hidden); + +-namespace { +- +-/// This is a simple wrapper around an MDNode which provides a higher-level +-/// interface by hiding the details of how alias analysis information is encoded +-/// in its operands. +-class AliasScopeNode { +- const MDNode *Node = nullptr; +- +-public: +- AliasScopeNode() = default; +- explicit AliasScopeNode(const MDNode *N) : Node(N) {} +- +- /// Get the MDNode for this AliasScopeNode. +- const MDNode *getNode() const { return Node; } +- +- /// Get the MDNode for this AliasScopeNode's domain. +- const MDNode *getDomain() const { +- if (Node->getNumOperands() < 2) +- return nullptr; +- return dyn_cast_or_null(Node->getOperand(1)); +- } +-}; +- +-} // end anonymous namespace +- + AliasResult ScopedNoAliasAAResult::alias(const MemoryLocation &LocA, + const MemoryLocation &LocB, + AAQueryInfo &AAQI) { +diff --git a/llvm/lib/IR/Metadata.cpp b/llvm/lib/IR/Metadata.cpp +index ce89009e86eb..5826464206d6 100644 +--- a/llvm/lib/IR/Metadata.cpp ++++ b/llvm/lib/IR/Metadata.cpp +@@ -26,6 +26,7 @@ + #include "llvm/ADT/StringMap.h" + #include "llvm/ADT/StringRef.h" + #include "llvm/ADT/Twine.h" ++#include "llvm/Analysis/ScopedNoAliasAA.h" + #include "llvm/IR/Argument.h" + #include "llvm/IR/BasicBlock.h" + #include "llvm/IR/Constant.h" +@@ -925,7 +926,32 @@ MDNode *MDNode::getMostGenericAliasScope(MDNode *A, MDNode *B) { + if (!A || !B) + return nullptr; + +- return concatenate(A, B); ++ // Take the intersection of domains then union the scopes ++ // within those domains ++ SmallPtrSet ADomains; ++ SmallPtrSet IntersectDomains; ++ SmallSetVector MDs; ++ for (const MDOperand &MDOp : A->operands()) ++ if (const MDNode *NAMD = dyn_cast(MDOp)) ++ if (const MDNode *Domain = AliasScopeNode(NAMD).getDomain()) ++ ADomains.insert(Domain); ++ ++ for (const MDOperand &MDOp : B->operands()) ++ if (const MDNode *NAMD = dyn_cast(MDOp)) ++ if (const MDNode *Domain = AliasScopeNode(NAMD).getDomain()) ++ if (ADomains.contains(Domain)) { ++ IntersectDomains.insert(Domain); ++ MDs.insert(MDOp); ++ } ++ ++ for (const MDOperand &MDOp : A->operands()) ++ if (const MDNode *NAMD = dyn_cast(MDOp)) ++ if (const MDNode *Domain = AliasScopeNode(NAMD).getDomain()) ++ if (IntersectDomains.contains(Domain)) ++ MDs.insert(MDOp); ++ ++ return MDs.empty() ? nullptr ++ : getOrSelfReference(A->getContext(), MDs.getArrayRef()); + } + + MDNode *MDNode::getMostGenericFPMath(MDNode *A, MDNode *B) { +diff --git a/llvm/test/Analysis/ScopedNoAliasAA/alias-scope-merging.ll b/llvm/test/Analysis/ScopedNoAliasAA/alias-scope-merging.ll +new file mode 100644 +index 000000000000..4c8369d30adb +--- /dev/null ++++ b/llvm/test/Analysis/ScopedNoAliasAA/alias-scope-merging.ll +@@ -0,0 +1,37 @@ ++; RUN: opt < %s -S -memcpyopt | FileCheck --match-full-lines %s ++ ++; Alias scopes are merged by taking the intersection of domains, then the union of the scopes within those domains ++define i8 @test(i8 %input) { ++ %tmp = alloca i8 ++ %dst = alloca i8 ++ %src = alloca i8 ++; CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %dst, i8* align 8 %src, i64 1, i1 false), !alias.scope ![[SCOPE:[0-9]+]] ++ call void @llvm.lifetime.start.p0i8(i64 8, i8* nonnull %src), !noalias !4 ++ store i8 %input, i8* %src ++ call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %tmp, i8* align 8 %src, i64 1, i1 false), !alias.scope !0 ++ call void @llvm.lifetime.end.p0i8(i64 8, i8* nonnull %src), !noalias !4 ++ call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %dst, i8* align 8 %tmp, i64 1, i1 false), !alias.scope !4 ++ %ret_value = load i8, i8* %dst ++ ret i8 %ret_value ++} ++ ++; Merged scope contains "callee0: %a" and "callee0 : %b" ++; CHECK-DAG: ![[CALLEE0_A:[0-9]+]] = distinct !{!{{[0-9]+}}, !{{[0-9]+}}, !"callee0: %a"} ++; CHECK-DAG: ![[CALLEE0_B:[0-9]+]] = distinct !{!{{[0-9]+}}, !{{[0-9]+}}, !"callee0: %b"} ++; CHECK-DAG: ![[SCOPE]] = !{![[CALLEE0_A]], ![[CALLEE0_B]]} ++ ++declare void @llvm.lifetime.start.p0i8(i64, i8* nocapture) ++declare void @llvm.lifetime.end.p0i8(i64, i8* nocapture) ++declare void @llvm.memcpy.p0i8.p0i8.i64(i8*, i8*, i64, i1) ++ ++!0 = !{!1, !7} ++!1 = distinct !{!1, !3, !"callee0: %a"} ++!2 = distinct !{!2, !3, !"callee0: %b"} ++!3 = distinct !{!3, !"callee0"} ++ ++!4 = !{!2, !5} ++!5 = distinct !{!5, !6, !"callee1: %a"} ++!6 = distinct !{!6, !"callee1"} ++ ++!7 = distinct !{!7, !8, !"callee2: %a"} ++!8 = distinct !{!8, !"callee2"} +diff --git a/llvm/test/Transforms/GVN/noalias.ll b/llvm/test/Transforms/GVN/noalias.ll +index 69c21f110b5e..67d48d768a91 100644 +--- a/llvm/test/Transforms/GVN/noalias.ll ++++ b/llvm/test/Transforms/GVN/noalias.ll +@@ -5,7 +5,7 @@ define i32 @test1(i32* %p, i32* %q) { + ; CHECK: load i32, i32* %p + ; CHECK-NOT: noalias + ; CHECK: %c = add i32 %a, %a +- %a = load i32, i32* %p, !noalias !0 ++ %a = load i32, i32* %p, !noalias !3 + %b = load i32, i32* %p + %c = add i32 %a, %b + ret i32 %c +@@ -13,31 +13,32 @@ define i32 @test1(i32* %p, i32* %q) { + + define i32 @test2(i32* %p, i32* %q) { + ; CHECK-LABEL: @test2(i32* %p, i32* %q) +-; CHECK: load i32, i32* %p, align 4, !alias.scope !0 ++; CHECK: load i32, i32* %p, align 4, !alias.scope ![[SCOPE1:[0-9]+]] + ; CHECK: %c = add i32 %a, %a +- %a = load i32, i32* %p, !alias.scope !0 +- %b = load i32, i32* %p, !alias.scope !0 ++ %a = load i32, i32* %p, !alias.scope !3 ++ %b = load i32, i32* %p, !alias.scope !3 + %c = add i32 %a, %b + ret i32 %c + } + +-; FIXME: In this case we can do better than intersecting the scopes, and can +-; concatenate them instead. Both loads are in the same basic block, the first +-; makes the second safe to speculatively execute, and there are no calls that may +-; throw in between. + define i32 @test3(i32* %p, i32* %q) { + ; CHECK-LABEL: @test3(i32* %p, i32* %q) +-; CHECK: load i32, i32* %p, align 4, !alias.scope !1 ++; CHECK: load i32, i32* %p, align 4, !alias.scope ![[SCOPE2:[0-9]+]] + ; CHECK: %c = add i32 %a, %a +- %a = load i32, i32* %p, !alias.scope !1 +- %b = load i32, i32* %p, !alias.scope !2 ++ %a = load i32, i32* %p, !alias.scope !4 ++ %b = load i32, i32* %p, !alias.scope !5 + %c = add i32 %a, %b + ret i32 %c + } + ++; CHECK: ![[SCOPE1]] = !{!{{[0-9]+}}} ++; CHECK: ![[SCOPE2]] = !{!{{[0-9]+}}, !{{[0-9]+}}} + declare i32 @foo(i32*) readonly + +-!0 = !{!0} +-!1 = !{!1} +-!2 = !{!0, !1} ++!0 = distinct !{!0, !2, !"callee0: %a"} ++!1 = distinct !{!1, !2, !"callee0: %b"} ++!2 = distinct !{!2, !"callee0"} + ++!3 = !{!0} ++!4 = !{!1} ++!5 = !{!0, !1} +diff --git a/llvm/test/Transforms/InstCombine/fold-phi-load-metadata.ll b/llvm/test/Transforms/InstCombine/fold-phi-load-metadata.ll +index e5a1aa7362a5..7fa26b46e25d 100644 +--- a/llvm/test/Transforms/InstCombine/fold-phi-load-metadata.ll ++++ b/llvm/test/Transforms/InstCombine/fold-phi-load-metadata.ll +@@ -40,10 +40,10 @@ return: ; preds = %if.end, %if.then + ; CHECK: ![[TBAA]] = !{![[TAG1:[0-9]+]], ![[TAG1]], i64 0} + ; CHECK: ![[TAG1]] = !{!"int", !{{[0-9]+}}, i64 0} + ; CHECK: ![[RANGE]] = !{i32 10, i32 25} +-; CHECK: ![[ALIAS_SCOPE]] = !{![[SCOPE0:[0-9]+]], ![[SCOPE2:[0-9]+]], ![[SCOPE1:[0-9]+]]} ++; CHECK: ![[ALIAS_SCOPE]] = !{![[SCOPE0:[0-9]+]], ![[SCOPE1:[0-9]+]], ![[SCOPE2:[0-9]+]]} + ; CHECK: ![[SCOPE0]] = distinct !{![[SCOPE0]], !{{[0-9]+}}, !"scope0"} +-; CHECK: ![[SCOPE2]] = distinct !{![[SCOPE2]], !{{[0-9]+}}, !"scope2"} + ; CHECK: ![[SCOPE1]] = distinct !{![[SCOPE1]], !{{[0-9]+}}, !"scope1"} ++; CHECK: ![[SCOPE2]] = distinct !{![[SCOPE2]], !{{[0-9]+}}, !"scope2"} + ; CHECK: ![[NOALIAS]] = !{![[SCOPE3:[0-9]+]]} + ; CHECK: ![[SCOPE3]] = distinct !{![[SCOPE3]], !{{[0-9]+}}, !"scope3"} + +diff --git a/llvm/test/Transforms/MemCpyOpt/callslot_badaa.ll b/llvm/test/Transforms/MemCpyOpt/callslot_badaa.ll +new file mode 100644 +index 000000000000..346546f72c4c +--- /dev/null ++++ b/llvm/test/Transforms/MemCpyOpt/callslot_badaa.ll +@@ -0,0 +1,39 @@ ++; RUN: opt < %s -S -memcpyopt | FileCheck --match-full-lines %s ++ ++; Make sure callslot optimization merges alias.scope metadata correctly when it merges instructions. ++; Merging here naively generates: ++; call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %dst, i8* align 8 %src, i64 1, i1 false), !alias.scope !3 ++; call void @llvm.lifetime.end.p0i8(i64 8, i8* nonnull %src), !noalias !0 ++; ... ++; !0 = !{!1} ++; !1 = distinct !{!1, !2, !"callee1: %a"} ++; !2 = distinct !{!2, !"callee1"} ++; !3 = !{!1, !4} ++; !4 = distinct !{!4, !5, !"callee0: %a"} ++; !5 = distinct !{!5, !"callee0"} ++; Which is incorrect because the lifetime.end of %src will now "noalias" the above memcpy. ++define i8 @test(i8 %input) { ++ %tmp = alloca i8 ++ %dst = alloca i8 ++ %src = alloca i8 ++; NOTE: we're matching the full line and looking for the lack of !alias.scope here ++; CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %dst, i8* align 8 %src, i64 1, i1 false) ++ call void @llvm.lifetime.start.p0i8(i64 8, i8* nonnull %src), !noalias !3 ++ store i8 %input, i8* %src ++ call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %tmp, i8* align 8 %src, i64 1, i1 false), !alias.scope !0 ++ call void @llvm.lifetime.end.p0i8(i64 8, i8* nonnull %src), !noalias !3 ++ call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 %dst, i8* align 8 %tmp, i64 1, i1 false), !alias.scope !3 ++ %ret_value = load i8, i8* %dst ++ ret i8 %ret_value ++} ++ ++declare void @llvm.lifetime.start.p0i8(i64, i8* nocapture) ++declare void @llvm.lifetime.end.p0i8(i64, i8* nocapture) ++declare void @llvm.memcpy.p0i8.p0i8.i64(i8*, i8*, i64, i1) ++ ++!0 = !{!1} ++!1 = distinct !{!1, !2, !"callee0: %a"} ++!2 = distinct !{!2, !"callee0"} ++!3 = !{!4} ++!4 = distinct !{!4, !5, !"callee1: %a"} ++!5 = distinct !{!5, !"callee1"} +diff --git a/llvm/test/Transforms/NewGVN/noalias.ll b/llvm/test/Transforms/NewGVN/noalias.ll +index c5f23bfad89a..2d90dc84d90b 100644 +--- a/llvm/test/Transforms/NewGVN/noalias.ll ++++ b/llvm/test/Transforms/NewGVN/noalias.ll +@@ -5,7 +5,7 @@ define i32 @test1(i32* %p, i32* %q) { + ; CHECK: load i32, i32* %p + ; CHECK-NOT: noalias + ; CHECK: %c = add i32 %a, %a +- %a = load i32, i32* %p, !noalias !0 ++ %a = load i32, i32* %p, !noalias !3 + %b = load i32, i32* %p + %c = add i32 %a, %b + ret i32 %c +@@ -13,31 +13,32 @@ define i32 @test1(i32* %p, i32* %q) { + + define i32 @test2(i32* %p, i32* %q) { + ; CHECK-LABEL: @test2(i32* %p, i32* %q) +-; CHECK: load i32, i32* %p, align 4, !alias.scope !0 ++; CHECK: load i32, i32* %p, align 4, !alias.scope ![[SCOPE1:[0-9]+]] + ; CHECK: %c = add i32 %a, %a +- %a = load i32, i32* %p, !alias.scope !0 +- %b = load i32, i32* %p, !alias.scope !0 ++ %a = load i32, i32* %p, !alias.scope !3 ++ %b = load i32, i32* %p, !alias.scope !3 + %c = add i32 %a, %b + ret i32 %c + } + +-; FIXME: In this case we can do better than intersecting the scopes, and can +-; concatenate them instead. Both loads are in the same basic block, the first +-; makes the second safe to speculatively execute, and there are no calls that may +-; throw in between. + define i32 @test3(i32* %p, i32* %q) { + ; CHECK-LABEL: @test3(i32* %p, i32* %q) +-; CHECK: load i32, i32* %p, align 4, !alias.scope !1 ++; CHECK: load i32, i32* %p, align 4, !alias.scope ![[SCOPE2:[0-9]+]] + ; CHECK: %c = add i32 %a, %a +- %a = load i32, i32* %p, !alias.scope !1 +- %b = load i32, i32* %p, !alias.scope !2 ++ %a = load i32, i32* %p, !alias.scope !4 ++ %b = load i32, i32* %p, !alias.scope !5 + %c = add i32 %a, %b + ret i32 %c + } + ++; CHECK: ![[SCOPE1]] = !{!{{[0-9]+}}} ++; CHECK: ![[SCOPE2]] = !{!{{[0-9]+}}, !{{[0-9]+}}} + declare i32 @foo(i32*) readonly + +-!0 = !{!0} +-!1 = !{!1} +-!2 = !{!0, !1} ++!0 = distinct !{!0, !2, !"callee0: %a"} ++!1 = distinct !{!1, !2, !"callee0: %b"} ++!2 = distinct !{!2, !"callee0"} + ++!3 = !{!0} ++!4 = !{!1} ++!5 = !{!0, !1} +-- +2.30.2 + diff --git a/SOURCES/0001-SystemZ-Assign-the-full-space-for-promoted-and-split.patch b/SOURCES/0001-SystemZ-Assign-the-full-space-for-promoted-and-split.patch new file mode 100644 index 0000000..db1b5e2 --- /dev/null +++ b/SOURCES/0001-SystemZ-Assign-the-full-space-for-promoted-and-split.patch @@ -0,0 +1,157 @@ +From c6f9d6db7b0c4677d1aae8977505fe6340a3aae2 Mon Sep 17 00:00:00 2001 +From: Josh Stone +Date: Wed, 10 Mar 2021 15:52:27 -0800 +Subject: [PATCH] [SystemZ] Assign the full space for promoted and split + outgoing args. (#95) + +When a large "irregular" (e.g. i96) integer call argument is converted to +indirect, 64-bit parts are stored to the stack. The full stack space +(e.g. i128) was not allocated prior to this patch, but rather just the exact +space of the original type. This caused neighboring values on the stack to be +overwritten. + +Thanks to Josh Stone for reporting this. + +Review: Ulrich Weigand +Fixes https://bugs.llvm.org/show_bug.cgi?id=49322 +Differential Revision: https://reviews.llvm.org/D97514 + +(cherry picked from commit 52bbbf4d4459239e0f461bc302ada89e2c5d07fc) + +Co-authored-by: Jonas Paulsson +--- + .../Target/SystemZ/SystemZISelLowering.cpp | 22 ++++++-- + llvm/test/CodeGen/SystemZ/args-11.ll | 54 +++++++++++++++++++ + 2 files changed, 72 insertions(+), 4 deletions(-) + create mode 100644 llvm/test/CodeGen/SystemZ/args-11.ll + +diff --git a/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp b/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp +index eb1e51341ec4..faf7b3eaef3c 100644 +--- a/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp ++++ b/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp +@@ -1543,6 +1543,7 @@ SystemZTargetLowering::LowerCall(CallLoweringInfo &CLI, + bool IsVarArg = CLI.IsVarArg; + MachineFunction &MF = DAG.getMachineFunction(); + EVT PtrVT = getPointerTy(MF.getDataLayout()); ++ LLVMContext &Ctx = *DAG.getContext(); + + // Detect unsupported vector argument and return types. + if (Subtarget.hasVector()) { +@@ -1552,7 +1553,7 @@ SystemZTargetLowering::LowerCall(CallLoweringInfo &CLI, + + // Analyze the operands of the call, assigning locations to each operand. + SmallVector ArgLocs; +- SystemZCCState ArgCCInfo(CallConv, IsVarArg, MF, ArgLocs, *DAG.getContext()); ++ SystemZCCState ArgCCInfo(CallConv, IsVarArg, MF, ArgLocs, Ctx); + ArgCCInfo.AnalyzeCallOperands(Outs, CC_SystemZ); + + // We don't support GuaranteedTailCallOpt, only automatically-detected +@@ -1577,14 +1578,25 @@ SystemZTargetLowering::LowerCall(CallLoweringInfo &CLI, + + if (VA.getLocInfo() == CCValAssign::Indirect) { + // Store the argument in a stack slot and pass its address. +- SDValue SpillSlot = DAG.CreateStackTemporary(Outs[I].ArgVT); ++ unsigned ArgIndex = Outs[I].OrigArgIndex; ++ EVT SlotVT; ++ if (I + 1 != E && Outs[I + 1].OrigArgIndex == ArgIndex) { ++ // Allocate the full stack space for a promoted (and split) argument. ++ Type *OrigArgType = CLI.Args[Outs[I].OrigArgIndex].Ty; ++ EVT OrigArgVT = getValueType(MF.getDataLayout(), OrigArgType); ++ MVT PartVT = getRegisterTypeForCallingConv(Ctx, CLI.CallConv, OrigArgVT); ++ unsigned N = getNumRegistersForCallingConv(Ctx, CLI.CallConv, OrigArgVT); ++ SlotVT = EVT::getIntegerVT(Ctx, PartVT.getSizeInBits() * N); ++ } else { ++ SlotVT = Outs[I].ArgVT; ++ } ++ SDValue SpillSlot = DAG.CreateStackTemporary(SlotVT); + int FI = cast(SpillSlot)->getIndex(); + MemOpChains.push_back( + DAG.getStore(Chain, DL, ArgValue, SpillSlot, + MachinePointerInfo::getFixedStack(MF, FI))); + // If the original argument was split (e.g. i128), we need + // to store all parts of it here (and pass just one address). +- unsigned ArgIndex = Outs[I].OrigArgIndex; + assert (Outs[I].PartOffset == 0); + while (I + 1 != E && Outs[I + 1].OrigArgIndex == ArgIndex) { + SDValue PartValue = OutVals[I + 1]; +@@ -1594,6 +1606,8 @@ SystemZTargetLowering::LowerCall(CallLoweringInfo &CLI, + MemOpChains.push_back( + DAG.getStore(Chain, DL, PartValue, Address, + MachinePointerInfo::getFixedStack(MF, FI))); ++ assert((PartOffset + PartValue.getValueType().getStoreSize() <= ++ SlotVT.getStoreSize()) && "Not enough space for argument part!"); + ++I; + } + ArgValue = SpillSlot; +@@ -1687,7 +1701,7 @@ SystemZTargetLowering::LowerCall(CallLoweringInfo &CLI, + + // Assign locations to each value returned by this call. + SmallVector RetLocs; +- CCState RetCCInfo(CallConv, IsVarArg, MF, RetLocs, *DAG.getContext()); ++ CCState RetCCInfo(CallConv, IsVarArg, MF, RetLocs, Ctx); + RetCCInfo.AnalyzeCallResult(Ins, RetCC_SystemZ); + + // Copy all of the result registers out of their specified physreg. +diff --git a/llvm/test/CodeGen/SystemZ/args-11.ll b/llvm/test/CodeGen/SystemZ/args-11.ll +new file mode 100644 +index 000000000000..b355f9d6da15 +--- /dev/null ++++ b/llvm/test/CodeGen/SystemZ/args-11.ll +@@ -0,0 +1,54 @@ ++; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ++; Test outgoing promoted arguments that are split (and passed by reference). ++; ++; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s ++ ++; The i96 arg is promoted to i128 and should get the full stack space. ++declare void @fn1(i96) ++define i32 @fn2() { ++; CHECK-LABEL: fn2: ++; CHECK: # %bb.0: ++; CHECK-NEXT: stmg %r14, %r15, 112(%r15) ++; CHECK-NEXT: .cfi_offset %r14, -48 ++; CHECK-NEXT: .cfi_offset %r15, -40 ++; CHECK-NEXT: aghi %r15, -184 ++; CHECK-NEXT: .cfi_def_cfa_offset 344 ++; CHECK-NEXT: mvhi 180(%r15), -1 ++; CHECK-NEXT: mvghi 168(%r15), 0 ++; CHECK-NEXT: la %r2, 160(%r15) ++; CHECK-NEXT: mvghi 160(%r15), 0 ++; CHECK-NEXT: brasl %r14, fn1@PLT ++; CHECK-NEXT: l %r2, 180(%r15) ++; CHECK-NEXT: lmg %r14, %r15, 296(%r15) ++; CHECK-NEXT: br %r14 ++ %1 = alloca i32 ++ store i32 -1, i32* %1 ++ call void @fn1(i96 0) ++ %2 = load i32, i32* %1 ++ ret i32 %2 ++} ++ ++declare void @fn3(i136) ++define i32 @fn4() { ++; CHECK-LABEL: fn4: ++; CHECK: # %bb.0: ++; CHECK-NEXT: stmg %r14, %r15, 112(%r15) ++; CHECK-NEXT: .cfi_offset %r14, -48 ++; CHECK-NEXT: .cfi_offset %r15, -40 ++; CHECK-NEXT: aghi %r15, -192 ++; CHECK-NEXT: .cfi_def_cfa_offset 352 ++; CHECK-NEXT: mvhi 188(%r15), -1 ++; CHECK-NEXT: mvghi 176(%r15), 0 ++; CHECK-NEXT: mvghi 168(%r15), 0 ++; CHECK-NEXT: la %r2, 160(%r15) ++; CHECK-NEXT: mvghi 160(%r15), 0 ++; CHECK-NEXT: brasl %r14, fn3@PLT ++; CHECK-NEXT: l %r2, 188(%r15) ++; CHECK-NEXT: lmg %r14, %r15, 304(%r15) ++; CHECK-NEXT: br %r14 ++ %1 = alloca i32 ++ store i32 -1, i32* %1 ++ call void @fn3(i136 0) ++ %2 = load i32, i32* %1 ++ ret i32 %2 ++} +-- +2.30.2 + diff --git a/SOURCES/0001-SystemZ-Use-LA-instead-of-AGR-in-eliminateFrameIndex.patch b/SOURCES/0001-SystemZ-Use-LA-instead-of-AGR-in-eliminateFrameIndex.patch new file mode 100644 index 0000000..80d6a1e --- /dev/null +++ b/SOURCES/0001-SystemZ-Use-LA-instead-of-AGR-in-eliminateFrameIndex.patch @@ -0,0 +1,166 @@ +From d851495f2fe614c4c860bda1bd3c80bfbe48360b Mon Sep 17 00:00:00 2001 +From: Jonas Paulsson +Date: Thu, 8 Oct 2020 13:18:29 +0200 +Subject: [PATCH] [SystemZ] Use LA instead of AGR in eliminateFrameIndex(). + +Since AGR clobbers CC it should not be used here. + +Fixes https://bugs.llvm.org/show_bug.cgi?id=47736. + +Review: Ulrich Weigand +Differential Revision: https://reviews.llvm.org/D89034 +--- + .../Target/SystemZ/SystemZRegisterInfo.cpp | 4 +-- + llvm/test/CodeGen/SystemZ/frame-14.ll | 26 +++++++++---------- + llvm/test/CodeGen/SystemZ/frame-16.ll | 4 +-- + 3 files changed, 17 insertions(+), 17 deletions(-) + +diff --git a/llvm/lib/Target/SystemZ/SystemZRegisterInfo.cpp b/llvm/lib/Target/SystemZ/SystemZRegisterInfo.cpp +index 53b06c6e7e6d..88212e52460f 100644 +--- a/llvm/lib/Target/SystemZ/SystemZRegisterInfo.cpp ++++ b/llvm/lib/Target/SystemZ/SystemZRegisterInfo.cpp +@@ -322,8 +322,8 @@ SystemZRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator MI, + // Load the high offset into the scratch register and use it as + // an index. + TII->loadImmediate(MBB, MI, ScratchReg, HighOffset); +- BuildMI(MBB, MI, DL, TII->get(SystemZ::AGR),ScratchReg) +- .addReg(ScratchReg, RegState::Kill).addReg(BasePtr); ++ BuildMI(MBB, MI, DL, TII->get(SystemZ::LA), ScratchReg) ++ .addReg(BasePtr, RegState::Kill).addImm(0).addReg(ScratchReg); + } + + // Use the scratch register as the base. It then dies here. +diff --git a/llvm/test/CodeGen/SystemZ/frame-14.ll b/llvm/test/CodeGen/SystemZ/frame-14.ll +index e70731249b42..193ff81123c5 100644 +--- a/llvm/test/CodeGen/SystemZ/frame-14.ll ++++ b/llvm/test/CodeGen/SystemZ/frame-14.ll +@@ -85,13 +85,13 @@ define void @f3() { + define void @f4() { + ; CHECK-NOFP-LABEL: f4: + ; CHECK-NOFP: llilh %r1, 8 +-; CHECK-NOFP: agr %r1, %r15 ++; CHECK-NOFP: la %r1, 0(%r1,%r15) + ; CHECK-NOFP: mvi 0(%r1), 42 + ; CHECK-NOFP: br %r14 + ; + ; CHECK-FP-LABEL: f4: + ; CHECK-FP: llilh %r1, 8 +-; CHECK-FP: agr %r1, %r11 ++; CHECK-FP: la %r1, 0(%r1,%r11) + ; CHECK-FP: mvi 0(%r1), 42 + ; CHECK-FP: br %r14 + %region1 = alloca [524104 x i8], align 8 +@@ -108,13 +108,13 @@ define void @f4() { + define void @f5() { + ; CHECK-NOFP-LABEL: f5: + ; CHECK-NOFP: llilh %r1, 8 +-; CHECK-NOFP: agr %r1, %r15 ++; CHECK-NOFP: la %r1, 0(%r1,%r15) + ; CHECK-NOFP: mvi 4095(%r1), 42 + ; CHECK-NOFP: br %r14 + ; + ; CHECK-FP-LABEL: f5: + ; CHECK-FP: llilh %r1, 8 +-; CHECK-FP: agr %r1, %r11 ++; CHECK-FP: la %r1, 0(%r1,%r11) + ; CHECK-FP: mvi 4095(%r1), 42 + ; CHECK-FP: br %r14 + %region1 = alloca [524104 x i8], align 8 +@@ -130,13 +130,13 @@ define void @f5() { + define void @f6() { + ; CHECK-NOFP-LABEL: f6: + ; CHECK-NOFP: llilh %r1, 8 +-; CHECK-NOFP: agr %r1, %r15 ++; CHECK-NOFP: la %r1, 0(%r1,%r15) + ; CHECK-NOFP: mviy 4096(%r1), 42 + ; CHECK-NOFP: br %r14 + ; + ; CHECK-FP-LABEL: f6: + ; CHECK-FP: llilh %r1, 8 +-; CHECK-FP: agr %r1, %r11 ++; CHECK-FP: la %r1, 0(%r1,%r11) + ; CHECK-FP: mviy 4096(%r1), 42 + ; CHECK-FP: br %r14 + %region1 = alloca [524104 x i8], align 8 +@@ -155,13 +155,13 @@ define void @f6() { + define void @f7() { + ; CHECK-NOFP-LABEL: f7: + ; CHECK-NOFP: llilh %r1, 23 +-; CHECK-NOFP: agr %r1, %r15 ++; CHECK-NOFP: la %r1, 0(%r1,%r15) + ; CHECK-NOFP: mviy 65535(%r1), 42 + ; CHECK-NOFP: br %r14 + ; + ; CHECK-FP-LABEL: f7: + ; CHECK-FP: llilh %r1, 23 +-; CHECK-FP: agr %r1, %r11 ++; CHECK-FP: la %r1, 0(%r1,%r11) + ; CHECK-FP: mviy 65535(%r1), 42 + ; CHECK-FP: br %r14 + %region1 = alloca [1048400 x i8], align 8 +@@ -178,13 +178,13 @@ define void @f7() { + define void @f8() { + ; CHECK-NOFP-LABEL: f8: + ; CHECK-NOFP: llilh %r1, 24 +-; CHECK-NOFP: agr %r1, %r15 ++; CHECK-NOFP: la %r1, 0(%r1,%r15) + ; CHECK-NOFP: mvi 7(%r1), 42 + ; CHECK-NOFP: br %r14 + ; + ; CHECK-FP-LABEL: f8: + ; CHECK-FP: llilh %r1, 24 +-; CHECK-FP: agr %r1, %r11 ++; CHECK-FP: la %r1, 0(%r1,%r11) + ; CHECK-FP: mvi 7(%r1), 42 + ; CHECK-FP: br %r14 + %region1 = alloca [1048408 x i8], align 8 +@@ -233,7 +233,7 @@ define void @f10(i32 *%vptr) { + ; CHECK-NOFP-LABEL: f10: + ; CHECK-NOFP: stg [[REGISTER:%r[1-9][0-4]?]], [[OFFSET:160|168]](%r15) + ; CHECK-NOFP: llilh [[REGISTER]], 8 +-; CHECK-NOFP: agr [[REGISTER]], %r15 ++; CHECK-NOFP: la [[REGISTER]], 0([[REGISTER]],%r15) + ; CHECK-NOFP: mvi 0([[REGISTER]]), 42 + ; CHECK-NOFP: lg [[REGISTER]], [[OFFSET]](%r15) + ; CHECK-NOFP: br %r14 +@@ -241,7 +241,7 @@ define void @f10(i32 *%vptr) { + ; CHECK-FP-LABEL: f10: + ; CHECK-FP: stg [[REGISTER:%r[1-9][0-4]?]], [[OFFSET:160|168]](%r11) + ; CHECK-FP: llilh [[REGISTER]], 8 +-; CHECK-FP: agr [[REGISTER]], %r11 ++; CHECK-FP: la [[REGISTER]], 0([[REGISTER]],%r11) + ; CHECK-FP: mvi 0([[REGISTER]]), 42 + ; CHECK-FP: lg [[REGISTER]], [[OFFSET]](%r11) + ; CHECK-FP: br %r14 +@@ -273,7 +273,7 @@ define void @f11(i32 *%vptr) { + ; CHECK-NOFP: stmg %r6, %r15, + ; CHECK-NOFP: stg [[REGISTER:%r[1-9][0-4]?]], [[OFFSET:160|168]](%r15) + ; CHECK-NOFP: llilh [[REGISTER]], 8 +-; CHECK-NOFP: agr [[REGISTER]], %r15 ++; CHECK-NOFP: la [[REGISTER]], 0([[REGISTER]],%r15) + ; CHECK-NOFP: mvi 0([[REGISTER]]), 42 + ; CHECK-NOFP: lg [[REGISTER]], [[OFFSET]](%r15) + ; CHECK-NOFP: lmg %r6, %r15, +diff --git a/llvm/test/CodeGen/SystemZ/frame-16.ll b/llvm/test/CodeGen/SystemZ/frame-16.ll +index ae8a041ae110..a95c58207afb 100644 +--- a/llvm/test/CodeGen/SystemZ/frame-16.ll ++++ b/llvm/test/CodeGen/SystemZ/frame-16.ll +@@ -311,13 +311,13 @@ define void @f11(i32 *%vptr, i8 %byte) { + define void @f12(i8 %byte, i64 %index) { + ; CHECK-NOFP-LABEL: f12: + ; CHECK-NOFP: llilh %r1, 8 +-; CHECK-NOFP: agr %r1, %r15 ++; CHECK-NOFP: la %r1, 0(%r1,%r15) + ; CHECK-NOFP: stc %r2, 0(%r3,%r1) + ; CHECK-NOFP: br %r14 + ; + ; CHECK-FP-LABEL: f12: + ; CHECK-FP: llilh %r1, 8 +-; CHECK-FP: agr %r1, %r11 ++; CHECK-FP: la %r1, 0(%r1,%r11) + ; CHECK-FP: stc %r2, 0(%r3,%r1) + ; CHECK-FP: br %r14 + %region1 = alloca [524104 x i8], align 8 +-- +2.26.2 + diff --git a/SOURCES/0001-gcc11.patch b/SOURCES/0001-gcc11.patch new file mode 100644 index 0000000..67629a3 --- /dev/null +++ b/SOURCES/0001-gcc11.patch @@ -0,0 +1,12 @@ +diff --git a/utils/benchmark/src/benchmark_register.h b/utils/benchmark/src/benchmark_register.h +index 0705e219..4caa5ad4 100644 +--- a/llvm/utils/benchmark/src/benchmark_register.h ++++ b/llvm/utils/benchmark/src/benchmark_register.h +@@ -1,6 +1,7 @@ + #ifndef BENCHMARK_REGISTER_H + #define BENCHMARK_REGISTER_H + ++#include + #include + + #include "check.h" diff --git a/SOURCES/llvm-11.1.0.src.tar.xz.sig b/SOURCES/llvm-11.1.0.src.tar.xz.sig new file mode 100644 index 0000000..31672d0 Binary files /dev/null and b/SOURCES/llvm-11.1.0.src.tar.xz.sig differ diff --git a/SOURCES/tstellar-gpg-key.asc b/SOURCES/tstellar-gpg-key.asc new file mode 100644 index 0000000..eba625c Binary files /dev/null and b/SOURCES/tstellar-gpg-key.asc differ diff --git a/SPECS/llvm11.spec b/SPECS/llvm11.spec new file mode 100644 index 0000000..a20728c --- /dev/null +++ b/SPECS/llvm11.spec @@ -0,0 +1,596 @@ +# Components enabled if supported by target architecture: +%define gold_arches %{ix86} x86_64 %{arm} aarch64 %{power64} s390x +%ifarch %{gold_arches} + %bcond_without gold +%else + %bcond_with gold +%endif + +%bcond_without compat_build + +%global llvm_libdir %{_libdir}/%{name} +%global build_llvm_libdir %{buildroot}%{llvm_libdir} +#global rc_ver 2 +%global baserelease 6 +%global llvm_srcdir llvm-%{version}%{?rc_ver:rc%{rc_ver}}.src +%global maj_ver 11 +%global min_ver 1 +%global patch_ver 0 + +%if %{with compat_build} +%global pkg_name llvm%{maj_ver} +%global exec_suffix -%{maj_ver} +%global install_prefix %{_libdir}/%{name} +%global install_bindir %{install_prefix}/bin +%global install_includedir %{install_prefix}/include +%global install_libdir %{install_prefix}/lib + +%global pkg_bindir %{install_bindir} +%global pkg_includedir %{_includedir}/%{name} +%global pkg_libdir %{install_libdir} +%else +%global pkg_name llvm +%global install_prefix /usr +%global install_libdir %{_libdir} +%global pkg_bindir %{_bindir} +%global pkg_libdir %{install_libdir} +%global exec_suffix %{nil} +%endif + +%global targets_to_build "all" +%global experimental_targets_to_build "AVR" + +%global build_install_prefix %{buildroot}%{install_prefix} + +Name: %{pkg_name} +Version: %{maj_ver}.%{min_ver}.%{patch_ver} +Release: %{?rc_ver:0.}%{baserelease}%{?rc_ver:.rc%{rc_ver}}%{?dist} +Summary: The Low Level Virtual Machine + +License: NCSA +URL: http://llvm.org +Source0: https://github.com/llvm/llvm-project/releases/download/llvmorg-%{version}%{?rc_ver:-rc%{rc_ver}}/%{llvm_srcdir}.tar.xz +Source1: https://github.com/llvm/llvm-project/releases/download/llvmorg-%{version}%{?rc_ver:-rc%{rc_ver}}/%{llvm_srcdir}.tar.xz.sig +Source2: tstellar-gpg-key.asc + +%if %{without compat_build} +Source3: run-lit-tests +Source4: lit.fedora.cfg.py +%endif + +# Fix coreos-installer test crash on s390x (rhbz#1883457), https://reviews.llvm.org/D89034 +Patch1: 0001-SystemZ-Use-LA-instead-of-AGR-in-eliminateFrameIndex.patch +Patch2: 0001-gcc11.patch +Patch3: 0001-SystemZ-Assign-the-full-space-for-promoted-and-split.patch +Patch4: 0001-MemCpyOpt-Correctly-merge-alias-scopes-during-call-s.patch + +# RHEL-specific patches +Patch101: 0001-Deactivate-markdown-doc.patch + +BuildRequires: gcc +BuildRequires: gcc-c++ +BuildRequires: cmake +BuildRequires: ninja-build +BuildRequires: zlib-devel +BuildRequires: libffi-devel +BuildRequires: ncurses-devel +BuildRequires: python3-sphinx +%if !0%{?rhel} +BuildRequires: python3-recommonmark +%endif +BuildRequires: multilib-rpm-config +%if %{with gold} +BuildRequires: binutils-devel +%endif +%ifarch %{valgrind_arches} +# Enable extra functionality when run the LLVM JIT under valgrind. +BuildRequires: valgrind-devel +%endif +# LLVM's LineEditor library will use libedit if it is available. +BuildRequires: libedit-devel +# We need python3-devel for pathfix.py. +BuildRequires: python3-devel +BuildRequires: python3-setuptools + +# For origin certification +BuildRequires: gnupg2 + + +Requires: %{name}-libs%{?_isa} = %{version}-%{release} + +Provides: llvm(major) = %{maj_ver} + +%description +LLVM is a compiler infrastructure designed for compile-time, link-time, +runtime, and idle-time optimization of programs from arbitrary programming +languages. The compiler infrastructure includes mirror sets of programming +tools as well as libraries with equivalent functionality. + +%package devel +Summary: Libraries and header files for LLVM +Requires: %{name}%{?_isa} = %{version}-%{release} +Requires: %{name}-libs%{?_isa} = %{version}-%{release} +# The installed LLVM cmake files will add -ledit to the linker flags for any +# app that requires the libLLVMLineEditor, so we need to make sure +# libedit-devel is available. +Requires: libedit-devel +# The installed cmake files reference binaries from llvm-test and llvm-static. +# We tried in the past to split the cmake exports for these binaries out into +# separate files, so that llvm-devel would not need to Require these packages, +# but this caused bugs (rhbz#1773678) and forced us to carry two non-upstream +# patches. +Requires: %{name}-static%{?_isa} = %{version}-%{release} +%if %{without compat_build} +Requires: %{name}-test%{?_isa} = %{version}-%{release} +%endif + + +Requires(post): %{_sbindir}/alternatives +Requires(postun): %{_sbindir}/alternatives + +Provides: llvm-devel(major) = %{maj_ver} + +%description devel +This package contains library and header files needed to develop new native +programs that use the LLVM infrastructure. + +%package doc +Summary: Documentation for LLVM +BuildArch: noarch +Requires: %{name} = %{version}-%{release} + +%description doc +Documentation for the LLVM compiler infrastructure. + +%package libs +Summary: LLVM shared libraries + +%description libs +Shared libraries for the LLVM compiler infrastructure. + +%package static +Summary: LLVM static libraries +Conflicts: %{name}-devel < 8 + +Provides: llvm-static(major) = %{maj_ver} + +%description static +Static libraries for the LLVM compiler infrastructure. + +%if %{without compat_build} + +%package test +Summary: LLVM regression tests +Requires: %{name}%{?_isa} = %{version}-%{release} +Requires: %{name}-libs%{?_isa} = %{version}-%{release} +Requires: python3-lit +# The regression tests need gold. +Requires: binutils +# This is for llvm-config +Requires: %{name}-devel%{?_isa} = %{version}-%{release} +# Bugpoint tests require gcc +Requires: gcc +Requires: findutils + +Provides: llvm-test(major) = %{maj_ver} + +%description test +LLVM regression tests. + +%package googletest +Summary: LLVM's modified googletest sources + +%description googletest +LLVM's modified googletest sources. + +%endif + +%prep +%{gpgverify} --keyring='%{SOURCE2}' --signature='%{SOURCE1}' --data='%{SOURCE0}' +%autosetup -n %{llvm_srcdir} -p2 + +%ifarch s390x +# 2 tests failing: +mv test/tools/llvm-objcopy/ELF/compress-debug-sections-zlib.test{,.DISABLED} +mv test/tools/llvm-objcopy/ELF/compress-debug-sections-zlib-gnu.test{,.DISABLED} +%endif + +pathfix.py -i %{__python3} -pn \ + test/BugPoint/compile-custom.ll.py \ + tools/opt-viewer/*.py \ + utils/update_cc_test_checks.py + +%build + +# Disable LTO on s390x, this causes some test failures: +# LLVM-Unit :: Target/AArch64/./AArch64Tests/InstSizes.Authenticated +# LLVM-Unit :: Target/AArch64/./AArch64Tests/InstSizes.PATCHPOINT +# LLVM-Unit :: Target/AArch64/./AArch64Tests/InstSizes.STACKMAP +# LLVM-Unit :: Target/AArch64/./AArch64Tests/InstSizes.TLSDESC_CALLSEQ +# On X86_64, LTO builds of TableGen crash. This can be reproduced by: +# %%cmake_build --target include/llvm/IR/IntrinsicsAArch64.h +# Because of these failures, lto is disabled for now. +%global _lto_cflags %{nil} + +%ifarch s390 %{arm} %ix86 +# Decrease debuginfo verbosity to reduce memory consumption during final library linking +%global optflags %(echo %{optflags} | sed 's/-g /-g1 /') +%endif + +# force off shared libs as cmake macros turns it on. +%cmake -G Ninja \ + -DBUILD_SHARED_LIBS:BOOL=OFF \ + -DLLVM_PARALLEL_LINK_JOBS=1 \ + -DCMAKE_BUILD_TYPE=RelWithDebInfo \ + -DCMAKE_SKIP_RPATH:BOOL=ON \ +%ifarch s390 %{arm} %ix86 + -DCMAKE_C_FLAGS_RELWITHDEBINFO="%{optflags} -DNDEBUG" \ + -DCMAKE_CXX_FLAGS_RELWITHDEBINFO="%{optflags} -DNDEBUG" \ +%endif +%if %{without compat_build} +%if 0%{?__isa_bits} == 64 + -DLLVM_LIBDIR_SUFFIX=64 \ +%else + -DLLVM_LIBDIR_SUFFIX= \ +%endif +%endif + \ + -DLLVM_TARGETS_TO_BUILD=%{targets_to_build} \ + -DLLVM_ENABLE_LIBCXX:BOOL=OFF \ + -DLLVM_ENABLE_ZLIB:BOOL=ON \ + -DLLVM_ENABLE_FFI:BOOL=ON \ + -DLLVM_ENABLE_RTTI:BOOL=ON \ +%if %{with gold} + -DLLVM_BINUTILS_INCDIR=%{_includedir} \ +%endif + -DLLVM_EXPERIMENTAL_TARGETS_TO_BUILD=%{experimental_targets_to_build} \ + \ + -DLLVM_BUILD_RUNTIME:BOOL=ON \ + \ + -DLLVM_INCLUDE_TOOLS:BOOL=ON \ + -DLLVM_BUILD_TOOLS:BOOL=ON \ + \ + -DLLVM_INCLUDE_TESTS:BOOL=ON \ + -DLLVM_BUILD_TESTS:BOOL=ON \ + \ + -DLLVM_INCLUDE_EXAMPLES:BOOL=ON \ + -DLLVM_BUILD_EXAMPLES:BOOL=OFF \ + \ + -DLLVM_INCLUDE_UTILS:BOOL=ON \ +%if %{with compat_build} + -DLLVM_INSTALL_UTILS:BOOL=OFF \ +%else + -DLLVM_INSTALL_UTILS:BOOL=ON \ + -DLLVM_UTILS_INSTALL_DIR:PATH=%{_bindir} \ + -DLLVM_TOOLS_INSTALL_DIR:PATH=bin \ +%endif + \ + -DLLVM_INCLUDE_DOCS:BOOL=ON \ + -DLLVM_BUILD_DOCS:BOOL=ON \ + -DLLVM_ENABLE_SPHINX:BOOL=ON \ + -DLLVM_ENABLE_DOXYGEN:BOOL=OFF \ + \ +%if %{without compat_build} + -DLLVM_VERSION_SUFFIX='' \ +%endif + -DLLVM_BUILD_LLVM_DYLIB:BOOL=ON \ + -DLLVM_DYLIB_EXPORT_ALL:BOOL=ON \ + -DLLVM_LINK_LLVM_DYLIB:BOOL=ON \ + -DLLVM_BUILD_EXTERNAL_COMPILER_RT:BOOL=ON \ + -DLLVM_INSTALL_TOOLCHAIN_ONLY:BOOL=OFF \ + \ + -DSPHINX_WARNINGS_AS_ERRORS=OFF \ + -DCMAKE_INSTALL_PREFIX=%{install_prefix} \ + -DLLVM_INSTALL_SPHINX_HTML_DIR=%{_pkgdocdir}/html \ + -DSPHINX_EXECUTABLE=%{_bindir}/sphinx-build-3 + +# Build libLLVM.so first. This ensures that when libLLVM.so is linking, there +# are no other compile jobs running. This will help reduce OOM errors on the +# builders without having to artificially limit the number of concurrent jobs. +%cmake_build --target LLVM +%cmake_build + +%install +%cmake_install + +mkdir -p %{buildroot}/%{_bindir} + +%if %{without compat_build} + +# Fix some man pages +ln -s llvm-config.1 %{buildroot}%{_mandir}/man1/llvm-config%{exec_suffix}-%{__isa_bits}.1 +mv %{buildroot}%{_mandir}/man1/*tblgen.1 %{buildroot}%{_mandir}/man1/llvm-tblgen.1 + +# Install binaries needed for lit tests +%global test_binaries llvm-isel-fuzzer llvm-opt-fuzzer + +for f in %{test_binaries} +do + install -m 0755 %{_vpath_builddir}/bin/$f %{buildroot}%{_bindir} +done + +# Remove testing of update utility tools +rm -rf test/tools/UpdateTestChecks + +%multilib_fix_c_header --file %{_includedir}/llvm/Config/llvm-config.h + +# Install libraries needed for unittests +%if 0%{?__isa_bits} == 64 +%global build_libdir %{_vpath_builddir}/lib64 +%else +%global build_libdir %{_vpath_builddir}/lib +%endif + +install %{build_libdir}/libLLVMTestingSupport.a %{buildroot}%{_libdir} + +%global install_srcdir %{buildroot}%{_datadir}/llvm/src +%global lit_cfg test/%{_arch}.site.cfg.py +%global lit_unit_cfg test/Unit/%{_arch}.site.cfg.py +%global lit_fedora_cfg %{_datadir}/llvm/lit.fedora.cfg.py + +# Install gtest sources so clang can use them for gtest +install -d %{install_srcdir} +install -d %{install_srcdir}/utils/ +cp -R utils/unittest %{install_srcdir}/utils/ + +# Clang needs these for running lit tests. +cp utils/update_cc_test_checks.py %{install_srcdir}/utils/ +cp -R utils/UpdateTestChecks %{install_srcdir}/utils/ + +# One of the lit tests references this file +install -d %{install_srcdir}/docs/CommandGuide/ +install -m 0644 docs/CommandGuide/dsymutil.rst %{install_srcdir}/docs/CommandGuide/ + +# Generate lit config files. Strip off the last lines that initiates the +# test run, so we can customize the configuration. +head -n -2 %{_vpath_builddir}/test/lit.site.cfg.py >> %{lit_cfg} +head -n -2 %{_vpath_builddir}/test/Unit/lit.site.cfg.py >> %{lit_unit_cfg} + +# Install custom fedora config file +cp %{SOURCE4} %{buildroot}%{lit_fedora_cfg} + +# Patch lit config files to load custom fedora config: +for f in %{lit_cfg} %{lit_unit_cfg}; do + echo "lit_config.load_config(config, '%{lit_fedora_cfg}')" >> $f +done + +install -d %{buildroot}%{_libexecdir}/tests/llvm +install -m 0755 %{SOURCE3} %{buildroot}%{_libexecdir}/tests/llvm + +# Install lit tests. We need to put these in a tarball otherwise rpm will complain +# about some of the test inputs having the wrong object file format. +install -d %{buildroot}%{_datadir}/llvm/ + +# The various tar options are there to make sur the archive is the same on 32 and 64 bit arch, i.e. +# the archive creation is reproducible. Move arch-specific content out of the tarball +mv %{lit_cfg} %{install_srcdir}/%{_arch}.site.cfg.py +mv %{lit_unit_cfg} %{install_srcdir}/%{_arch}.Unit.site.cfg.py +tar --sort=name --mtime='UTC 2020-01-01' -c test/ | gzip -n > %{install_srcdir}/test.tar.gz + +# Install the unit test binaries +mkdir -p %{build_llvm_libdir} +cp -R %{_vpath_builddir}/unittests %{build_llvm_libdir}/ +rm -rf `find %{build_llvm_libdir} -iname 'cmake*'` + +# Install libraries used for testing +install -m 0755 %{build_libdir}/BugpointPasses.so %{buildroot}%{_libdir} +install -m 0755 %{build_libdir}/LLVMHello.so %{buildroot}%{_libdir} + +# Install test inputs for PDB tests +echo "%{_datadir}/llvm/src/unittests/DebugInfo/PDB" > %{build_llvm_libdir}/unittests/DebugInfo/PDB/llvm.srcdir.txt +mkdir -p %{buildroot}%{_datadir}/llvm/src/unittests/DebugInfo/PDB/ +cp -R unittests/DebugInfo/PDB/Inputs %{buildroot}%{_datadir}/llvm/src/unittests/DebugInfo/PDB/ + +%if %{with gold} +# Add symlink to lto plugin in the binutils plugin directory. +%{__mkdir_p} %{buildroot}%{_libdir}/bfd-plugins/ +ln -s %{_libdir}/LLVMgold.so %{buildroot}%{_libdir}/bfd-plugins/ +%endif + +%else + +# Add version suffix to binaries +for f in %{buildroot}/%{install_bindir}/*; do + filename=`basename $f` + ln -s ../../../%{install_bindir}/$filename %{buildroot}/%{_bindir}/$filename%{exec_suffix} +done + +# Move header files +mkdir -p %{buildroot}/%{pkg_includedir} +ln -s ../../../%{install_includedir}/llvm %{buildroot}/%{pkg_includedir}/llvm +ln -s ../../../%{install_includedir}/llvm-c %{buildroot}/%{pkg_includedir}/llvm-c + +# Fix multi-lib +%multilib_fix_c_header --file %{install_includedir}/llvm/Config/llvm-config.h + +# Create ld.so.conf.d entry +mkdir -p %{buildroot}%{_sysconfdir}/ld.so.conf.d +cat >> %{buildroot}%{_sysconfdir}/ld.so.conf.d/%{name}-%{_arch}.conf << EOF +%{pkg_libdir} +EOF + +# Add version suffix to man pages and move them to mandir. +mkdir -p %{buildroot}/%{_mandir}/man1 +for f in %{build_install_prefix}/share/man/man1/*; do + filename=`basename $f | cut -f 1 -d '.'` + mv $f %{buildroot}%{_mandir}/man1/$filename%{exec_suffix}.1 +done + +# Remove opt-viewer, since this is just a compatibility package. +rm -Rf %{build_install_prefix}/share/opt-viewer + +%endif + +# llvm-config special casing. llvm-config is managed by update-alternatives. +# the original file must remain available for compatibility with the CMake +# infrastructure. Without compat, cmake points to the symlink, with compat it +# points to the original file. + +%if %{without compat_build} + +mv %{buildroot}/%{pkg_bindir}/llvm-config %{buildroot}/%{pkg_bindir}/llvm-config%{exec_suffix}-%{__isa_bits} + +%else + +rm %{buildroot}%{_bindir}/llvm-config%{exec_suffix} +(cd %{buildroot}/%{pkg_bindir} ; ln -s llvm-config llvm-config%{exec_suffix}-%{__isa_bits} ) + +%endif + +# ghost presence +touch %{buildroot}%{_bindir}/llvm-config%{exec_suffix} + + + +%check +# TODO: Fix the failures below +%ifarch %{arm} +rm test/tools/llvm-readobj/ELF/dependent-libraries.test +%endif + +# non reproducible errors +rm test/tools/dsymutil/X86/swift-interface.test + +# FIXME: use %%cmake_build instead of %%__ninja +LD_LIBRARY_PATH=%{buildroot}/%{pkg_libdir} %{__ninja} check-all -C %{_vpath_builddir} + +%ldconfig_scriptlets libs + +%post devel +%{_sbindir}/update-alternatives --install %{_bindir}/llvm-config%{exec_suffix} llvm-config%{exec_suffix} %{pkg_bindir}/llvm-config%{exec_suffix}-%{__isa_bits} %{__isa_bits} + +%postun devel +if [ $1 -eq 0 ]; then + %{_sbindir}/update-alternatives --remove llvm-config%{exec_suffix} %{pkg_bindir}/llvm-config%{exec_suffix}-%{__isa_bits} +fi + +%files +%license LICENSE.TXT +%exclude %{_mandir}/man1/llvm-config* +%{_mandir}/man1/* +%{_bindir}/* + +%exclude %{_bindir}/llvm-config%{exec_suffix} +%exclude %{pkg_bindir}/llvm-config%{exec_suffix}-%{__isa_bits} + +%if %{without compat_build} +%exclude %{_bindir}/not +%exclude %{_bindir}/count +%exclude %{_bindir}/yaml-bench +%exclude %{_bindir}/lli-child-target +%exclude %{_bindir}/llvm-isel-fuzzer +%exclude %{_bindir}/llvm-opt-fuzzer +%{_datadir}/opt-viewer +%else +%{pkg_bindir} +%endif + +%files libs +%license LICENSE.TXT +%{pkg_libdir}/libLLVM-%{maj_ver}.so +%if %{without compat_build} +%if %{with gold} +%{_libdir}/LLVMgold.so +%{_libdir}/bfd-plugins/LLVMgold.so +%endif +%{_libdir}/libLLVM-%{maj_ver}.%{min_ver}*.so +%{_libdir}/libLTO.so* +%else +%config(noreplace) %{_sysconfdir}/ld.so.conf.d/%{name}-%{_arch}.conf +%if %{with gold} +%{_libdir}/%{name}/lib/LLVMgold.so +%endif +%{pkg_libdir}/libLLVM-%{maj_ver}.%{min_ver}*.so +%{pkg_libdir}/libLTO.so* +%exclude %{pkg_libdir}/libLTO.so +%endif +%{pkg_libdir}/libRemarks.so* + +%files devel +%license LICENSE.TXT + +%ghost %{_bindir}/llvm-config%{exec_suffix} +%{pkg_bindir}/llvm-config%{exec_suffix}-%{__isa_bits} +%{_mandir}/man1/llvm-config* + +%if %{without compat_build} +%{_includedir}/llvm +%{_includedir}/llvm-c +%{_libdir}/libLLVM.so +%{_libdir}/cmake/llvm +%else +%{install_includedir}/llvm +%{install_includedir}/llvm-c +%{pkg_includedir}/llvm +%{pkg_includedir}/llvm-c +%{pkg_libdir}/libLTO.so +%{pkg_libdir}/libLLVM.so +%{pkg_libdir}/cmake/llvm +%endif + +%files doc +%license LICENSE.TXT +%doc %{_pkgdocdir}/html + +%files static +%license LICENSE.TXT +%if %{without compat_build} +%{_libdir}/*.a +%exclude %{_libdir}/libLLVMTestingSupport.a +%else +%{_libdir}/%{name}/lib/*.a +%endif + +%if %{without compat_build} + +%files test +%license LICENSE.TXT +%{_libexecdir}/tests/llvm/ +%{llvm_libdir}/unittests/ +%{_datadir}/llvm/src/unittests +%{_datadir}/llvm/src/test.tar.gz +%{_datadir}/llvm/src/%{_arch}.site.cfg.py +%{_datadir}/llvm/src/%{_arch}.Unit.site.cfg.py +%{_datadir}/llvm/lit.fedora.cfg.py +%{_datadir}/llvm/src/docs/CommandGuide/dsymutil.rst +%{_bindir}/not +%{_bindir}/count +%{_bindir}/yaml-bench +%{_bindir}/lli-child-target +%{_bindir}/llvm-isel-fuzzer +%{_bindir}/llvm-opt-fuzzer +%{_libdir}/BugpointPasses.so +%{_libdir}/LLVMHello.so + +%files googletest +%license LICENSE.TXT +%{_datadir}/llvm/src/utils +%{_libdir}/libLLVMTestingSupport.a + +%endif + +%changelog +* Mon Nov 04 2024 Arkady L. Shane - 11.1.0-6 +- Rebuilt for MSVSphere 9.5 + +* Sun Feb 6 2022 Jens Petersen - 11.1.0-6 +- Remove dependency on python3-recommonmark (like RHEL9 llvm) + +* Wed May 19 2021 sguelton@redhat.com - 11.1.0-5 +- Fix handling of llvm-config + +* Thu May 06 2021 sguelton@redhat.com - 11.1.0-4 +- Harmonize llvm-config handling with non-compat version + +* Tue Apr 27 2021 sguelton@redhat.com - 11.1.0-3 +- Fix llvm-config11 install path + +* Tue Apr 13 2021 sguelton@redhat.com - 11.1.0-2 +- Fix llvm-config-11 handling, see rhbz#1937816 + +* Tue Mar 23 2021 Josh Stone - 11.1.0-1 +- Update to 11.1.0 final +- Add fixes for rustc codegen + +* Wed Feb 03 2021 Serge Guelton - 11.1.0-0.1.rc2 +- 11.1.0-rc2 release