https://github.com/statham-arm updated https://github.com/llvm/llvm-project/pull/97827
>From 81d77bf87dd47684683492ab70cc45ab6eb4364e Mon Sep 17 00:00:00 2001 From: Simon Tatham <simon.tat...@arm.com> Date: Fri, 5 Jul 2024 11:57:19 +0100 Subject: [PATCH 1/2] [Clang][Driver] Skip empty strings in getAArch64MultilibFlags In a multilib setting, if you compile with a command line such as `clang --target=aarch64-none-elf -march=armv8.9-a+rcpc3`, `getAArch64MultilibFlags` returns an ill-formed string containing two consecutive `+` signs, of the form `...+rcpc++rcpc3+...`, causing later stages of multilib selection to get confused. The `++` arises from the entry in `AArch64::Extensions` for the SubtargetFeature `rcpc-immo`, which is a dependency of the `rcpc3` SubtargetFeature, but doesn't have an _extension_ name for the purposes of the `-march=foo+bar` option. So its `UserVisibleName` field is the empty string. To fix this, I've excluded extensions from consideration in `getAArch64MultilibFlags` if they have an empty `UserVisibleName`. Since the input to this function is not derived from a completely general set of SubtargetFeatures, but from a set that has only just been converted _from_ a clang driver command line, the only extensions skipped by this check should be cases like this one, where the anonymous extension was only included because it was a dependency of one mentioned explicitly. I've also made the analogous change in `getARMMultilibFlags`. I don't think it's necessary right now, because the architecture extensions for ARM (defined in `ARMTargetParser.def` rather than Tablegen) don't include any anonymous ones. But it seems sensible to add the check anyway, in case future refactoring introduces anonymous array elements in the same way that AArch64 did, and also in case someone writes a function for another platform by using either of these as example code. --- clang/lib/Driver/ToolChain.cpp | 20 ++++++++++++-------- clang/test/Driver/aarch64-multilib-rcpc3.c | 4 ++++ 2 files changed, 16 insertions(+), 8 deletions(-) create mode 100644 clang/test/Driver/aarch64-multilib-rcpc3.c diff --git a/clang/lib/Driver/ToolChain.cpp b/clang/lib/Driver/ToolChain.cpp index 977e08390800d..85ae4d2a26fee 100644 --- a/clang/lib/Driver/ToolChain.cpp +++ b/clang/lib/Driver/ToolChain.cpp @@ -195,11 +195,13 @@ static void getAArch64MultilibFlags(const Driver &D, UnifiedFeatures.end()); std::vector<std::string> MArch; for (const auto &Ext : AArch64::Extensions) - if (FeatureSet.contains(Ext.PosTargetFeature)) - MArch.push_back(Ext.UserVisibleName.str()); + if (!Ext.UserVisibleName.empty()) + if (FeatureSet.contains(Ext.PosTargetFeature)) + MArch.push_back(Ext.UserVisibleName.str()); for (const auto &Ext : AArch64::Extensions) - if (FeatureSet.contains(Ext.NegTargetFeature)) - MArch.push_back(("no" + Ext.UserVisibleName).str()); + if (!Ext.UserVisibleName.empty()) + if (FeatureSet.contains(Ext.NegTargetFeature)) + MArch.push_back(("no" + Ext.UserVisibleName).str()); StringRef ArchName; for (const auto &ArchInfo : AArch64::ArchInfos) if (FeatureSet.contains(ArchInfo->ArchFeature)) @@ -221,11 +223,13 @@ static void getARMMultilibFlags(const Driver &D, UnifiedFeatures.end()); std::vector<std::string> MArch; for (const auto &Ext : ARM::ARCHExtNames) - if (FeatureSet.contains(Ext.Feature)) - MArch.push_back(Ext.Name.str()); + if (!Ext.Name.empty()) + if (FeatureSet.contains(Ext.Feature)) + MArch.push_back(Ext.Name.str()); for (const auto &Ext : ARM::ARCHExtNames) - if (FeatureSet.contains(Ext.NegFeature)) - MArch.push_back(("no" + Ext.Name).str()); + if (!Ext.Name.empty()) + if (FeatureSet.contains(Ext.NegFeature)) + MArch.push_back(("no" + Ext.Name).str()); MArch.insert(MArch.begin(), ("-march=" + Triple.getArchName()).str()); Result.push_back(llvm::join(MArch, "+")); diff --git a/clang/test/Driver/aarch64-multilib-rcpc3.c b/clang/test/Driver/aarch64-multilib-rcpc3.c new file mode 100644 index 0000000000000..b839079e0442d --- /dev/null +++ b/clang/test/Driver/aarch64-multilib-rcpc3.c @@ -0,0 +1,4 @@ +// RUN: %clang --target=aarch64-none-elf -march=armv8.9-a+rcpc3 -print-multi-flags-experimental -c %s 2>&1 | FileCheck %s + +// CHECK: -march=armv8.9-a +// CHECK-SAME: +rcpc+rcpc3+ >From 7179fc771dcf15c4ab5be24b985fd7be56960cc9 Mon Sep 17 00:00:00 2001 From: Simon Tatham <simon.tat...@arm.com> Date: Mon, 8 Jul 2024 17:30:56 +0100 Subject: [PATCH 2/2] fixup! [Clang][Driver] Skip empty strings in getAArch64MultilibFlags --- clang/test/Driver/aarch64-multilib-rcpc3.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/clang/test/Driver/aarch64-multilib-rcpc3.c b/clang/test/Driver/aarch64-multilib-rcpc3.c index b839079e0442d..88b23de5a6510 100644 --- a/clang/test/Driver/aarch64-multilib-rcpc3.c +++ b/clang/test/Driver/aarch64-multilib-rcpc3.c @@ -1,4 +1,17 @@ // RUN: %clang --target=aarch64-none-elf -march=armv8.9-a+rcpc3 -print-multi-flags-experimental -c %s 2>&1 | FileCheck %s +// The purpose of this regression test is to make sure that when +// compile options are converted into multilib selection flags, no +// empty strings are accidentally included in the +// -march=armv8.9-a+foo+bar+baz string, leading to two consecutive + +// signs. With +rcpc3 in the input, this used to generate an empty +// string for the anonymous architecture extension corresponding to +// the SubtargetFeature 'rcpc-immo', which is a dependency of rcpc3 +// but has no separate extension name for use on command lines. So we +// check that the two named rcpc options appear, and that no ++ +// appears before or after. + // CHECK: -march=armv8.9-a +// CHECK-NOT: ++ // CHECK-SAME: +rcpc+rcpc3+ +// CHECK-NOT: ++ _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits