Skip to content

Commit 2e4e9d5

Browse files
Jenkinsnicebert
authored andcommitted
merge main into amd-staging
Change-Id: I287786152fda5935fe506c753ee19493583bf8f1
2 parents 938dad3 + c9d1266 commit 2e4e9d5

File tree

31 files changed

+2664
-692
lines changed

31 files changed

+2664
-692
lines changed

clang/test/Driver/aarch64-sve.c

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,11 @@
66
// RUN: %clang --target=aarch64 -march=armv8.6a -### -c %s 2>&1 | FileCheck -check-prefix=GENERICV8A-NOSVE %s
77
// GENERICV8A-NOSVE-NOT: "-target-feature" "+sve"
88

9-
// The 32-bit floating point matrix multiply extension is enabled by default
10-
// for armv8.6-a targets (or later) with SVE, and can optionally be enabled for
11-
// any target from armv8.2a onwards (we don't enforce not using it with earlier
12-
// targets).
9+
// The 32-bit floating point matrix multiply extension is an optional feature
10+
// that can be used for any target from armv8.2a and onwards. This can be
11+
// enabled using the `+f32mm` option.`.
1312
// RUN: %clang --target=aarch64 -march=armv8.6a -### -c %s 2>&1 | FileCheck -check-prefix=NO-F32MM %s
14-
// RUN: %clang --target=aarch64 -march=armv8.6a+sve -### -c %s 2>&1 | FileCheck -check-prefix=F32MM %s
13+
// RUN: %clang --target=aarch64 -march=armv8.6a+sve+f32mm -### -c %s 2>&1 | FileCheck -check-prefix=F32MM %s
1514
// RUN: %clang --target=aarch64 -march=armv8.5a+f32mm -### -c %s 2>&1 | FileCheck -check-prefix=F32MM %s
1615
// NO-F32MM-NOT: "-target-feature" "+f32mm"
1716
// F32MM: "-target-feature" "+f32mm"

clang/test/Preprocessor/aarch64-target-features.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@
196196
// CHECK-8_6-NOT: __ARM_FEATURE_SHA3 1
197197
// CHECK-8_6-NOT: __ARM_FEATURE_SM4 1
198198

199-
// RUN: %clang -target aarch64-none-linux-gnu -march=armv8.6-a+sve -x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-SVE-8_6 %s
199+
// RUN: %clang -target aarch64-none-linux-gnu -march=armv8.6-a+sve+f32mm -x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-SVE-8_6 %s
200200
// CHECK-SVE-8_6: __ARM_FEATURE_SVE 1
201201
// CHECK-SVE-8_6: __ARM_FEATURE_SVE_BF16 1
202202
// CHECK-SVE-8_6: __ARM_FEATURE_SVE_MATMUL_FP32 1

lld/COFF/Config.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ enum class EmitKind { Obj, LLVM, ASM };
5454
struct Export {
5555
StringRef name; // N in /export:N or /export:E=N
5656
StringRef extName; // E in /export:E=N
57+
StringRef exportAs; // E in /export:N,EXPORTAS,E
5758
StringRef aliasTarget; // GNU specific: N in "alias == N"
5859
Symbol *sym = nullptr;
5960
uint16_t ordinal = 0;
@@ -73,10 +74,9 @@ struct Export {
7374
StringRef exportName; // Name in DLL
7475

7576
bool operator==(const Export &e) const {
76-
return (name == e.name && extName == e.extName &&
77-
aliasTarget == e.aliasTarget &&
78-
ordinal == e.ordinal && noname == e.noname &&
79-
data == e.data && isPrivate == e.isPrivate);
77+
return (name == e.name && extName == e.extName && exportAs == e.exportAs &&
78+
aliasTarget == e.aliasTarget && ordinal == e.ordinal &&
79+
noname == e.noname && data == e.data && isPrivate == e.isPrivate);
8080
}
8181
};
8282

lld/COFF/Driver.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -945,6 +945,7 @@ void LinkerDriver::createImportLibrary(bool asLib) {
945945
e2.Name = std::string(e1.name);
946946
e2.SymbolName = std::string(e1.symbolName);
947947
e2.ExtName = std::string(e1.extName);
948+
e2.ExportAs = std::string(e1.exportAs);
948949
e2.AliasTarget = std::string(e1.aliasTarget);
949950
e2.Ordinal = e1.ordinal;
950951
e2.Noname = e1.noname;
@@ -1044,6 +1045,7 @@ void LinkerDriver::parseModuleDefs(StringRef path) {
10441045
e2.name = saver().save(e1.Name);
10451046
e2.extName = saver().save(e1.ExtName);
10461047
}
1048+
e2.exportAs = saver().save(e1.ExportAs);
10471049
e2.aliasTarget = saver().save(e1.AliasTarget);
10481050
e2.ordinal = e1.Ordinal;
10491051
e2.noname = e1.Noname;

lld/COFF/DriverUtils.cpp

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -585,7 +585,8 @@ Export LinkerDriver::parseExport(StringRef arg) {
585585
}
586586
}
587587

588-
// Optional parameters "[,@ordinal[,NONAME]][,DATA][,PRIVATE]"
588+
// Optional parameters
589+
// "[,@ordinal[,NONAME]][,DATA][,PRIVATE][,EXPORTAS,exportname]"
589590
while (!rest.empty()) {
590591
StringRef tok;
591592
std::tie(tok, rest) = rest.split(",");
@@ -607,6 +608,13 @@ Export LinkerDriver::parseExport(StringRef arg) {
607608
e.isPrivate = true;
608609
continue;
609610
}
611+
if (tok.equals_insensitive("exportas")) {
612+
if (!rest.empty() && !rest.contains(','))
613+
e.exportAs = rest;
614+
else
615+
error("invalid EXPORTAS value: " + rest);
616+
break;
617+
}
610618
if (tok.starts_with("@")) {
611619
int32_t ord;
612620
if (tok.substr(1).getAsInteger(0, ord))
@@ -683,7 +691,9 @@ void LinkerDriver::fixupExports() {
683691
}
684692

685693
for (Export &e : ctx.config.exports) {
686-
if (!e.forwardTo.empty()) {
694+
if (!e.exportAs.empty()) {
695+
e.exportName = e.exportAs;
696+
} else if (!e.forwardTo.empty()) {
687697
e.exportName = undecorate(ctx, e.name);
688698
} else {
689699
e.exportName = undecorate(ctx, e.extName.empty() ? e.name : e.extName);

lld/test/COFF/exportas.test

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,77 @@ RUN: lld-link -out:out1.dll -dll -noentry test.obj test.lib
99
RUN: llvm-readobj --coff-imports out1.dll | FileCheck --check-prefix=IMPORT %s
1010
IMPORT: Symbol: expfunc
1111

12+
Pass -export argument with EXPORTAS.
13+
14+
RUN: llvm-mc -filetype=obj -triple=x86_64-windows func.s -o func.obj
15+
RUN: lld-link -out:out2.dll -dll -noentry func.obj -export:func,EXPORTAS,expfunc
16+
RUN: llvm-readobj --coff-exports out2.dll | FileCheck --check-prefix=EXPORT %s
17+
EXPORT: Name: expfunc
18+
19+
RUN: llvm-readobj out2.lib | FileCheck --check-prefix=IMPLIB %s
20+
IMPLIB: Name type: export as
21+
IMPLIB-NEXT: Export name: expfunc
22+
IMPLIB-NEXT: Symbol: __imp_func
23+
IMPLIB-NEXT: Symbol: func
24+
25+
Use .drectve section with EXPORTAS.
26+
27+
RUN: llvm-mc -filetype=obj -triple=x86_64-windows drectve.s -o drectve.obj
28+
RUN: lld-link -out:out3.dll -dll -noentry func.obj drectve.obj
29+
RUN: llvm-readobj --coff-exports out3.dll | FileCheck --check-prefix=EXPORT %s
30+
RUN: llvm-readobj out3.lib | FileCheck --check-prefix=IMPLIB %s
31+
32+
Use a .def file with EXPORTAS.
33+
34+
RUN: lld-link -out:out4.dll -dll -noentry func.obj -def:test.def
35+
RUN: llvm-readobj --coff-exports out4.dll | FileCheck --check-prefix=EXPORT %s
36+
RUN: llvm-readobj out4.lib | FileCheck --check-prefix=IMPLIB %s
37+
38+
Use a .def file with EXPORTAS in a forwarding export.
39+
40+
RUN: lld-link -out:out5.dll -dll -noentry func.obj -def:test2.def
41+
RUN: llvm-readobj --coff-exports out5.dll | FileCheck --check-prefix=FORWARD-EXPORT %s
42+
FORWARD-EXPORT: Export {
43+
FORWARD-EXPORT-NEXT: Ordinal: 1
44+
FORWARD-EXPORT-NEXT: Name: expfunc
45+
FORWARD-EXPORT-NEXT: ForwardedTo: otherdll.otherfunc
46+
FORWARD-EXPORT-NEXT: }
47+
48+
RUN: llvm-readobj out5.lib | FileCheck --check-prefix=FORWARD-IMPLIB %s
49+
FORWARD-IMPLIB: Name type: export as
50+
FORWARD-IMPLIB-NEXT: Export name: expfunc
51+
FORWARD-IMPLIB-NEXT: Symbol: __imp_func
52+
FORWARD-IMPLIB-NEXT: Symbol: func
53+
54+
Pass -export argument with EXPORTAS in a forwarding export.
55+
56+
RUN: lld-link -out:out6.dll -dll -noentry func.obj -export:func=otherdll.otherfunc,EXPORTAS,expfunc
57+
RUN: llvm-readobj --coff-exports out6.dll | FileCheck --check-prefix=FORWARD-EXPORT %s
58+
RUN: llvm-readobj out6.lib | FileCheck --check-prefix=FORWARD-IMPLIB %s
59+
60+
Pass -export argument with EXPORTAS in a data export.
61+
62+
RUN: lld-link -out:out7.dll -dll -noentry func.obj -export:func,DATA,@5,EXPORTAS,expfunc
63+
RUN: llvm-readobj --coff-exports out7.dll | FileCheck --check-prefix=ORD %s
64+
ORD: Ordinal: 5
65+
ORD-NEXT: Name: expfunc
66+
67+
RUN: llvm-readobj out7.lib | FileCheck --check-prefix=ORD-IMPLIB %s
68+
ORD-IMPLIB: Type: data
69+
ORD-IMPLIB-NEXT: Name type: export as
70+
ORD-IMPLIB-NEXT: Export name: expfunc
71+
ORD-IMPLIB-NEXT: Symbol: __imp_func
72+
73+
Check invalid EXPORTAS syntax.
74+
75+
RUN: not lld-link -out:err1.dll -dll -noentry func.obj -export:func,EXPORTAS, 2>&1 | \
76+
RUN: FileCheck --check-prefix=ERR1 %s
77+
ERR1: error: invalid EXPORTAS value: {{$}}
78+
79+
RUN: not lld-link -out:err2.dll -dll -noentry func.obj -export:func,EXPORTAS,expfunc,DATA 2>&1 | \
80+
RUN: FileCheck --check-prefix=ERR2 %s
81+
ERR2: error: invalid EXPORTAS value: expfunc,DATA
82+
1283
#--- test.s
1384
.section ".test", "rd"
1485
.rva __imp_func
@@ -17,3 +88,20 @@ IMPORT: Symbol: expfunc
1788
LIBRARY test.dll
1889
EXPORTS
1990
func EXPORTAS expfunc
91+
92+
#--- test2.def
93+
LIBRARY test.dll
94+
EXPORTS
95+
func=otherdll.otherfunc EXPORTAS expfunc
96+
97+
#--- func.s
98+
.text
99+
.globl func
100+
.p2align 2, 0x0
101+
func:
102+
movl $1, %eax
103+
retq
104+
105+
#--- drectve.s
106+
.section .drectve, "yn"
107+
.ascii " -export:func,EXPORTAS,expfunc"

llvm/docs/ReleaseNotes.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ Changes to the AMDGPU Backend
7676

7777
Changes to the ARM Backend
7878
--------------------------
79+
* FEAT_F32MM is no longer activated by default when using `+sve` on v8.6-A or greater. The feature is still available and can be used by adding `+f32mm` to the command line options.
7980

8081
Changes to the AVR Backend
8182
--------------------------

llvm/include/llvm/IR/Verifier.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ class TBAAVerifier {
7777
/// Visit an instruction and return true if it is valid, return false if an
7878
/// invalid TBAA is attached.
7979
bool visitTBAAMetadata(Instruction &I, const MDNode *MD);
80+
bool visitTBAAStructMetadata(Instruction &I, const MDNode *MD);
8081
};
8182

8283
/// Check a function for errors, useful for use when debugging a

llvm/lib/IR/Verifier.cpp

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5172,6 +5172,9 @@ void Verifier::visitInstruction(Instruction &I) {
51725172
if (MDNode *TBAA = I.getMetadata(LLVMContext::MD_tbaa))
51735173
TBAAVerifyHelper.visitTBAAMetadata(I, TBAA);
51745174

5175+
if (MDNode *TBAA = I.getMetadata(LLVMContext::MD_tbaa_struct))
5176+
TBAAVerifyHelper.visitTBAAStructMetadata(I, TBAA);
5177+
51755178
if (MDNode *MD = I.getMetadata(LLVMContext::MD_noalias))
51765179
visitAliasScopeListMetadata(MD);
51775180
if (MDNode *MD = I.getMetadata(LLVMContext::MD_alias_scope))
@@ -7526,6 +7529,35 @@ bool TBAAVerifier::visitTBAAMetadata(Instruction &I, const MDNode *MD) {
75267529
return true;
75277530
}
75287531

7532+
bool TBAAVerifier::visitTBAAStructMetadata(Instruction &I, const MDNode *MD) {
7533+
CheckTBAA(MD->getNumOperands() % 3 == 0,
7534+
"tbaa.struct operands must occur in groups of three", &I, MD);
7535+
7536+
// Each group of three operands must consist of two integers and a
7537+
// tbaa node. Moreover, the regions described by the offset and size
7538+
// operands must be non-overlapping.
7539+
std::optional<APInt> NextFree;
7540+
for (unsigned int Idx = 0; Idx < MD->getNumOperands(); Idx += 3) {
7541+
auto *OffsetCI =
7542+
mdconst::dyn_extract_or_null<ConstantInt>(MD->getOperand(Idx));
7543+
CheckTBAA(OffsetCI, "Offset must be a constant integer", &I, MD);
7544+
7545+
auto *SizeCI =
7546+
mdconst::dyn_extract_or_null<ConstantInt>(MD->getOperand(Idx + 1));
7547+
CheckTBAA(SizeCI, "Size must be a constant integer", &I, MD);
7548+
7549+
MDNode *TBAA = dyn_cast_or_null<MDNode>(MD->getOperand(Idx + 2));
7550+
CheckTBAA(TBAA, "TBAA tag missing", &I, MD);
7551+
visitTBAAMetadata(I, TBAA);
7552+
7553+
bool NonOverlapping = !NextFree || NextFree->ule(OffsetCI->getValue());
7554+
CheckTBAA(NonOverlapping, "Overlapping tbaa.struct regions", &I, MD);
7555+
7556+
NextFree = OffsetCI->getValue() + SizeCI->getValue();
7557+
}
7558+
return true;
7559+
}
7560+
75297561
char VerifierLegacyPass::ID = 0;
75307562
INITIALIZE_PASS(VerifierLegacyPass, "verify", "Module Verifier", false, false)
75317563

llvm/lib/Object/COFFImportFile.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -690,12 +690,12 @@ Error writeImportLibrary(StringRef ImportName, StringRef Path,
690690
if (ImportType == IMPORT_CODE && isArm64EC(M)) {
691691
if (std::optional<std::string> MangledName =
692692
getArm64ECMangledFunctionName(Name)) {
693-
if (ExportName.empty()) {
693+
if (!E.Noname && ExportName.empty()) {
694694
NameType = IMPORT_NAME_EXPORTAS;
695695
ExportName.swap(Name);
696696
}
697697
Name = std::move(*MangledName);
698-
} else if (ExportName.empty()) {
698+
} else if (!E.Noname && ExportName.empty()) {
699699
NameType = IMPORT_NAME_EXPORTAS;
700700
ExportName = std::move(*getArm64ECDemangledFunctionName(Name));
701701
}

llvm/lib/Target/RISCV/RISCVTargetTransformInfo.cpp

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -909,23 +909,33 @@ InstructionCost RISCVTTIImpl::getCastInstrCost(unsigned Opcode, Type *Dst,
909909
if (!IsTypeLegal)
910910
return BaseT::getCastInstrCost(Opcode, Dst, Src, CCH, CostKind, I);
911911

912+
std::pair<InstructionCost, MVT> DstLT = getTypeLegalizationCost(Dst);
913+
912914
int ISD = TLI->InstructionOpcodeToISD(Opcode);
913915
assert(ISD && "Invalid opcode");
914916

915-
// FIXME: Need to consider vsetvli and lmul.
916917
int PowDiff = (int)Log2_32(Dst->getScalarSizeInBits()) -
917918
(int)Log2_32(Src->getScalarSizeInBits());
918919
switch (ISD) {
919920
case ISD::SIGN_EXTEND:
920-
case ISD::ZERO_EXTEND:
921-
if (Src->getScalarSizeInBits() == 1) {
921+
case ISD::ZERO_EXTEND: {
922+
const unsigned SrcEltSize = Src->getScalarSizeInBits();
923+
if (SrcEltSize == 1) {
922924
// We do not use vsext/vzext to extend from mask vector.
923925
// Instead we use the following instructions to extend from mask vector:
924926
// vmv.v.i v8, 0
925927
// vmerge.vim v8, v8, -1, v0
926-
return 2;
928+
return getRISCVInstructionCost({RISCV::VMV_V_I, RISCV::VMERGE_VIM},
929+
DstLT.second, CostKind);
927930
}
928-
return 1;
931+
if ((PowDiff < 1) || (PowDiff > 3))
932+
return BaseT::getCastInstrCost(Opcode, Dst, Src, CCH, CostKind, I);
933+
unsigned SExtOp[] = {RISCV::VSEXT_VF2, RISCV::VSEXT_VF4, RISCV::VSEXT_VF8};
934+
unsigned ZExtOp[] = {RISCV::VZEXT_VF2, RISCV::VZEXT_VF4, RISCV::VZEXT_VF8};
935+
unsigned Op =
936+
(ISD == ISD::SIGN_EXTEND) ? SExtOp[PowDiff - 1] : ZExtOp[PowDiff - 1];
937+
return getRISCVInstructionCost(Op, DstLT.second, CostKind);
938+
}
929939
case ISD::TRUNCATE:
930940
if (Dst->getScalarSizeInBits() == 1) {
931941
// We do not use several vncvt to truncate to mask vector. So we could

llvm/lib/TargetParser/AArch64TargetParser.cpp

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -186,11 +186,6 @@ void AArch64::ExtensionSet::enable(ArchExtKind E) {
186186
// Special cases for dependencies which vary depending on the base
187187
// architecture version.
188188
if (BaseArch) {
189-
// +sve implies +f32mm if the base architecture is v8.6A+ or v9.1A+
190-
// It isn't the case in general that sve implies both f64mm and f32mm
191-
if (E == AEK_SVE && BaseArch->is_superset(ARMV8_6A))
192-
enable(AEK_F32MM);
193-
194189
// +fp16 implies +fp16fml for v8.4A+, but not v9.0-A+
195190
if (E == AEK_FP16 && BaseArch->is_superset(ARMV8_4A) &&
196191
!BaseArch->is_superset(ARMV9A))

llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -611,6 +611,18 @@ Instruction *InstCombinerImpl::foldPowiReassoc(BinaryOperator &I) {
611611
Y->getType() == Z->getType())
612612
return createPowiExpr(I, *this, X, Y, Z);
613613

614+
// powi(X, Y) / X --> powi(X, Y-1)
615+
// This is legal when (Y - 1) can't wraparound, in which case reassoc and nnan
616+
// are required.
617+
// TODO: Multi-use may be also better off creating Powi(x,y-1)
618+
if (I.hasAllowReassoc() && I.hasNoNaNs() &&
619+
match(Op0, m_OneUse(m_AllowReassoc(m_Intrinsic<Intrinsic::powi>(
620+
m_Specific(Op1), m_Value(Y))))) &&
621+
willNotOverflowSignedSub(Y, ConstantInt::get(Y->getType(), 1), I)) {
622+
Constant *NegOne = ConstantInt::getAllOnesValue(Y->getType());
623+
return createPowiExpr(I, *this, Op1, Y, NegOne);
624+
}
625+
614626
return nullptr;
615627
}
616628

@@ -1904,20 +1916,8 @@ Instruction *InstCombinerImpl::visitFDiv(BinaryOperator &I) {
19041916
return replaceInstUsesWith(I, Pow);
19051917
}
19061918

1907-
// powi(X, Y) / X --> powi(X, Y-1)
1908-
// This is legal when (Y - 1) can't wraparound, in which case reassoc and nnan
1909-
// are required.
1910-
// TODO: Multi-use may be also better off creating Powi(x,y-1)
1911-
if (I.hasAllowReassoc() && I.hasNoNaNs() &&
1912-
match(Op0, m_OneUse(m_Intrinsic<Intrinsic::powi>(m_Specific(Op1),
1913-
m_Value(Y)))) &&
1914-
willNotOverflowSignedSub(Y, ConstantInt::get(Y->getType(), 1), I)) {
1915-
Constant *NegOne = ConstantInt::getAllOnesValue(Y->getType());
1916-
Value *Y1 = Builder.CreateAdd(Y, NegOne);
1917-
Type *Types[] = {Op1->getType(), Y1->getType()};
1918-
Value *Pow = Builder.CreateIntrinsic(Intrinsic::powi, Types, {Op1, Y1}, &I);
1919-
return replaceInstUsesWith(I, Pow);
1920-
}
1919+
if (Instruction *FoldedPowi = foldPowiReassoc(I))
1920+
return FoldedPowi;
19211921

19221922
return nullptr;
19231923
}

0 commit comments

Comments
 (0)