[llvm] [X86] Add regcall4 attribute to make a specific function respect regc… (PR #69628)
via llvm-commits
llvm-commits at lists.llvm.org
Fri Oct 20 01:53:27 PDT 2023
https://github.com/yubingex007-a11y updated https://github.com/llvm/llvm-project/pull/69628
>From 786b954e621ac53902ceff4640d1372ef1652699 Mon Sep 17 00:00:00 2001
From: Bing1 Yu <bing1.yu at intel.com>
Date: Fri, 20 Oct 2023 02:33:35 +0800
Subject: [PATCH 1/5] [X86] Add regcall4 attribute to make a specific function
respect regcall ABIv4
---
clang/include/clang/Basic/Attr.td | 5 +++++
clang/lib/AST/TypePrinter.cpp | 1 +
clang/lib/CodeGen/CGCall.cpp | 3 ++-
clang/lib/CodeGen/CodeGenModule.cpp | 3 +++
clang/test/CodeGen/regcall.c | 2 +-
llvm/lib/Target/X86/X86CallingConv.td | 2 +-
6 files changed, 13 insertions(+), 3 deletions(-)
diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td
index 5486b36133755cc..54d6d0619223f98 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -1524,6 +1524,11 @@ def RegCall : DeclOrTypeAttr {
let Documentation = [RegCallDocs];
}
+def RegCall4 : DeclOrTypeAttr {
+ let Spellings = [GCC<"regcall4">, CustomKeyword<"__regcall4">];
+ let Documentation = [RegCallDocs];
+}
+
def Final : InheritableAttr {
let Spellings = [CustomKeyword<"final">, CustomKeyword<"sealed">];
let Accessors = [Accessor<"isSpelledAsSealed", [CustomKeyword<"sealed">]>];
diff --git a/clang/lib/AST/TypePrinter.cpp b/clang/lib/AST/TypePrinter.cpp
index b9f6c0eeb450d2c..6ca95eefe4b0630 100644
--- a/clang/lib/AST/TypePrinter.cpp
+++ b/clang/lib/AST/TypePrinter.cpp
@@ -1861,6 +1861,7 @@ void TypePrinter::printAttributedAfter(const AttributedType *T,
case attr::MSABI: OS << "ms_abi"; break;
case attr::SysVABI: OS << "sysv_abi"; break;
case attr::RegCall: OS << "regcall"; break;
+ case attr::RegCall4: OS << "regcall4"; break;
case attr::Pcs: {
OS << "pcs(";
QualType t = T->getEquivalentType();
diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp
index 150450e9165900f..82d25a98a271db9 100644
--- a/clang/lib/CodeGen/CGCall.cpp
+++ b/clang/lib/CodeGen/CGCall.cpp
@@ -2458,7 +2458,8 @@ void CodeGenModule::ConstructAttributeList(StringRef Name,
// * LangOpts: -ffreestanding, -fno-builtin, -fno-builtin-<name>
// * FunctionDecl attributes: __attribute__((no_builtin(...)))
addNoBuiltinAttributes(FuncAttrs, getLangOpts(), NBA);
-
+ if (TargetDecl->hasAttr<RegCall4Attr>())
+ FuncAttrs.addAttribute("regcall4");
// Collect function IR attributes based on global settiings.
getDefaultFunctionAttributes(Name, HasOptnone, AttrOnCallSite, FuncAttrs);
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index b1a6683a66bd052..505167f5706fbaf 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -2317,6 +2317,9 @@ void CodeGenModule::SetLLVMFunctionAttributesForDefinition(const Decl *D,
return;
}
+ if (D->hasAttr<RegCall4Attr>())
+ B.addAttribute("regcall4");
+
// Handle SME attributes that apply to function definitions,
// rather than to function prototypes.
if (D->hasAttr<ArmLocallyStreamingAttr>())
diff --git a/clang/test/CodeGen/regcall.c b/clang/test/CodeGen/regcall.c
index f10da87353fa114..dc37c0545f27389 100644
--- a/clang/test/CodeGen/regcall.c
+++ b/clang/test/CodeGen/regcall.c
@@ -9,7 +9,7 @@ void __regcall v1(int a, int b) {}
// X86: define dso_local x86_regcallcc void @__regcall3__v1(i32 inreg noundef %a, i32 inreg noundef %b)
// X64: define dso_local x86_regcallcc void @__regcall3__v1(i32 noundef %a, i32 noundef %b)
-void __attribute__((regcall)) v1b(int a, int b) {}
+void __attribute__((regcall4)) v1b(int a, int b) {}
// X86: define dso_local x86_regcallcc void @__regcall3__v1b(i32 inreg noundef %a, i32 inreg noundef %b)
// X64: define dso_local x86_regcallcc void @__regcall3__v1b(i32 noundef %a, i32 noundef %b)
diff --git a/llvm/lib/Target/X86/X86CallingConv.td b/llvm/lib/Target/X86/X86CallingConv.td
index 19a295cd109627e..df9f48c777cfa8b 100644
--- a/llvm/lib/Target/X86/X86CallingConv.td
+++ b/llvm/lib/Target/X86/X86CallingConv.td
@@ -25,7 +25,7 @@ class CCIfNotSubtarget<string F, CCAction A>
/// CCIfRegCallv4 - Match if RegCall ABIv4 is respected.
class CCIfRegCallv4<CCAction A>
- : CCIf<"State.getMachineFunction().getFunction().getParent()->getModuleFlag(\"RegCallv4\")!=nullptr",
+ : CCIf<"State.getMachineFunction().getFunction().getParent()->getModuleFlag(\"RegCallv4\")!=nullptr || State.getMachineFunction().getFunction().hasFnAttribute("regcall4")",
A>;
/// CCIfIsVarArgOnWin - Match if isVarArg on Windows 32bits.
>From ed514a91cdc693242edd01356b6786b6e70d2343 Mon Sep 17 00:00:00 2001
From: Bing1 Yu <bing1.yu at intel.com>
Date: Fri, 20 Oct 2023 03:09:24 +0800
Subject: [PATCH 2/5] fix
---
clang/lib/CodeGen/CGCall.cpp | 4 ++--
clang/lib/Sema/SemaDeclAttr.cpp | 3 +++
llvm/lib/Target/X86/X86CallingConv.td | 2 +-
3 files changed, 6 insertions(+), 3 deletions(-)
diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp
index 82d25a98a271db9..140091bbaac2a89 100644
--- a/clang/lib/CodeGen/CGCall.cpp
+++ b/clang/lib/CodeGen/CGCall.cpp
@@ -2412,6 +2412,8 @@ void CodeGenModule::ConstructAttributeList(StringRef Name,
FuncAttrs.addAttribute("no_caller_saved_registers");
if (TargetDecl->hasAttr<AnyX86NoCfCheckAttr>())
FuncAttrs.addAttribute(llvm::Attribute::NoCfCheck);
+ if (TargetDecl->hasAttr<RegCall4Attr>())
+ FuncAttrs.addAttribute("regcall4");
if (TargetDecl->hasAttr<LeafAttr>())
FuncAttrs.addAttribute(llvm::Attribute::NoCallback);
@@ -2458,8 +2460,6 @@ void CodeGenModule::ConstructAttributeList(StringRef Name,
// * LangOpts: -ffreestanding, -fno-builtin, -fno-builtin-<name>
// * FunctionDecl attributes: __attribute__((no_builtin(...)))
addNoBuiltinAttributes(FuncAttrs, getLangOpts(), NBA);
- if (TargetDecl->hasAttr<RegCall4Attr>())
- FuncAttrs.addAttribute("regcall4");
// Collect function IR attributes based on global settiings.
getDefaultFunctionAttributes(Name, HasOptnone, AttrOnCallSite, FuncAttrs);
diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index 5adf058bea56a53..3edd06127652a20 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -9638,6 +9638,9 @@ ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, const ParsedAttr &AL,
case ParsedAttr::AT_UsingIfExists:
handleSimpleAttribute<UsingIfExistsAttr>(S, D, AL);
+
+ case ParsedAttr::AT_RegCall4:
+ handleSimpleAttribute<RegCall4Attr>(S, D, AL);
break;
}
}
diff --git a/llvm/lib/Target/X86/X86CallingConv.td b/llvm/lib/Target/X86/X86CallingConv.td
index df9f48c777cfa8b..99b2fc704206987 100644
--- a/llvm/lib/Target/X86/X86CallingConv.td
+++ b/llvm/lib/Target/X86/X86CallingConv.td
@@ -25,7 +25,7 @@ class CCIfNotSubtarget<string F, CCAction A>
/// CCIfRegCallv4 - Match if RegCall ABIv4 is respected.
class CCIfRegCallv4<CCAction A>
- : CCIf<"State.getMachineFunction().getFunction().getParent()->getModuleFlag(\"RegCallv4\")!=nullptr || State.getMachineFunction().getFunction().hasFnAttribute("regcall4")",
+ : CCIf<"State.getMachineFunction().getFunction().getParent()->getModuleFlag(\"RegCallv4\")!=nullptr || State.getMachineFunction().getFunction().hasFnAttribute(\"regcall4\")",
A>;
/// CCIfIsVarArgOnWin - Match if isVarArg on Windows 32bits.
>From 12f348a3f4a8e90f1ebf5cf1ad51b2b0533add40 Mon Sep 17 00:00:00 2001
From: Bing1 Yu <bing1.yu at intel.com>
Date: Fri, 20 Oct 2023 03:20:58 +0800
Subject: [PATCH 3/5] add mangling
---
clang/lib/CodeGen/CodeGenModule.cpp | 2 +-
clang/test/CodeGen/regcall.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index 505167f5706fbaf..c6d3cd89d725423 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -1742,7 +1742,7 @@ static std::string getMangledNameImpl(CodeGenModule &CGM, GlobalDecl GD,
if (FD &&
FD->getType()->castAs<FunctionType>()->getCallConv() == CC_X86RegCall) {
- if (CGM.getLangOpts().RegCall4)
+ if (CGM.getLangOpts().RegCall4 || FD->hasAttr<RegCall4Attr>())
Out << "__regcall4__" << II->getName();
else
Out << "__regcall3__" << II->getName();
diff --git a/clang/test/CodeGen/regcall.c b/clang/test/CodeGen/regcall.c
index dc37c0545f27389..ee8372c6f1312e1 100644
--- a/clang/test/CodeGen/regcall.c
+++ b/clang/test/CodeGen/regcall.c
@@ -9,7 +9,7 @@ void __regcall v1(int a, int b) {}
// X86: define dso_local x86_regcallcc void @__regcall3__v1(i32 inreg noundef %a, i32 inreg noundef %b)
// X64: define dso_local x86_regcallcc void @__regcall3__v1(i32 noundef %a, i32 noundef %b)
-void __attribute__((regcall4)) v1b(int a, int b) {}
+void __attribute__((regcall4, regcall)) v1b(int a, int b) {}
// X86: define dso_local x86_regcallcc void @__regcall3__v1b(i32 inreg noundef %a, i32 inreg noundef %b)
// X64: define dso_local x86_regcallcc void @__regcall3__v1b(i32 noundef %a, i32 noundef %b)
>From 6198c9c757b5a79dffe98be48637472f63c11c3a Mon Sep 17 00:00:00 2001
From: Bing1 Yu <bing1.yu at intel.com>
Date: Fri, 20 Oct 2023 16:40:58 +0800
Subject: [PATCH 4/5] add mangling and make regcall4 a independent attr from
regcall
---
clang/lib/AST/ItaniumMangle.cpp | 8 ++++----
clang/lib/AST/Mangle.cpp | 3 ++-
clang/lib/CodeGen/CGCall.cpp | 2 ++
clang/lib/CodeGen/CodeGenModule.cpp | 2 +-
clang/lib/Sema/SemaDeclAttr.cpp | 8 +++++++-
clang/lib/Sema/SemaType.cpp | 3 +++
clang/test/CodeGen/regcall.c | 2 +-
7 files changed, 20 insertions(+), 8 deletions(-)
diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp
index 8862f4d4fbd7bf9..1d456d2b9ddfa82 100644
--- a/clang/lib/AST/ItaniumMangle.cpp
+++ b/clang/lib/AST/ItaniumMangle.cpp
@@ -524,7 +524,7 @@ class CXXNameMangler {
void mangleUnscopedTemplateName(GlobalDecl GD, const DeclContext *DC,
const AbiTagList *AdditionalAbiTags);
void mangleSourceName(const IdentifierInfo *II);
- void mangleRegCallName(const IdentifierInfo *II);
+ void mangleRegCallName(const IdentifierInfo *II, const FunctionDecl* FD);
void mangleDeviceStubName(const IdentifierInfo *II);
void mangleSourceNameWithAbiTags(
const NamedDecl *ND, const AbiTagList *AdditionalAbiTags = nullptr);
@@ -1543,7 +1543,7 @@ void CXXNameMangler::mangleUnqualifiedName(
if (IsDeviceStub)
mangleDeviceStubName(II);
else if (IsRegCall)
- mangleRegCallName(II);
+ mangleRegCallName(II, FD);
else
mangleSourceName(II);
@@ -1739,11 +1739,11 @@ void CXXNameMangler::mangleUnqualifiedName(
}
}
-void CXXNameMangler::mangleRegCallName(const IdentifierInfo *II) {
+void CXXNameMangler::mangleRegCallName(const IdentifierInfo *II, const FunctionDecl* FD) {
// <source-name> ::= <positive length number> __regcall3__ <identifier>
// <number> ::= [n] <non-negative decimal integer>
// <identifier> ::= <unqualified source code identifier>
- if (getASTContext().getLangOpts().RegCall4)
+ if (getASTContext().getLangOpts().RegCall4 || FD->hasAttr<RegCall4Attr>())
Out << II->getLength() + sizeof("__regcall4__") - 1 << "__regcall4__"
<< II->getName();
else
diff --git a/clang/lib/AST/Mangle.cpp b/clang/lib/AST/Mangle.cpp
index 64c971912a91d07..31886465a07a9cb 100644
--- a/clang/lib/AST/Mangle.cpp
+++ b/clang/lib/AST/Mangle.cpp
@@ -199,7 +199,8 @@ void MangleContext::mangleName(GlobalDecl GD, raw_ostream &Out) {
else if (CC == CCM_Fast)
Out << '@';
else if (CC == CCM_RegCall) {
- if (getASTContext().getLangOpts().RegCall4)
+ if (getASTContext().getLangOpts().RegCall4 ||
+ cast<FunctionDecl>(D)->hasAttr<RegCall4Attr>())
Out << "__regcall4__";
else
Out << "__regcall3__";
diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp
index 140091bbaac2a89..7501bf30a865d1a 100644
--- a/clang/lib/CodeGen/CGCall.cpp
+++ b/clang/lib/CodeGen/CGCall.cpp
@@ -216,6 +216,8 @@ static CallingConv getCallingConventionForDecl(const ObjCMethodDecl *D,
if (D->hasAttr<RegCallAttr>())
return CC_X86RegCall;
+ if (D->hasAttr<RegCall4Attr>())
+ return CC_X86RegCall;
if (D->hasAttr<ThisCallAttr>())
return CC_X86ThisCall;
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index c6d3cd89d725423..f29513f6b6e9d4a 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -2316,7 +2316,7 @@ void CodeGenModule::SetLLVMFunctionAttributesForDefinition(const Decl *D,
F->addFnAttrs(B);
return;
}
-
+
if (D->hasAttr<RegCall4Attr>())
B.addAttribute("regcall4");
diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index 3edd06127652a20..2c1bfb8d91159d3 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -5177,6 +5177,10 @@ static void handleCallConvAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
case ParsedAttr::AT_RegCall:
D->addAttr(::new (S.Context) RegCallAttr(S.Context, AL));
return;
+ case ParsedAttr::AT_RegCall4:
+ D->addAttr(::new (S.Context) RegCallAttr(S.Context, AL));
+ D->addAttr(::new (S.Context) RegCall4Attr(S.Context, AL));
+ return;
case ParsedAttr::AT_Pcs: {
PcsAttr::PCSType PCS;
switch (CC) {
@@ -5374,6 +5378,7 @@ bool Sema::CheckCallingConvAttr(const ParsedAttr &Attrs, CallingConv &CC,
CC = CC_AMDGPUKernelCall;
break;
case ParsedAttr::AT_RegCall:
+ case ParsedAttr::AT_RegCall4:
CC = CC_X86RegCall;
break;
case ParsedAttr::AT_MSABI:
@@ -9347,6 +9352,7 @@ ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, const ParsedAttr &AL,
case ParsedAttr::AT_ThisCall:
case ParsedAttr::AT_Pascal:
case ParsedAttr::AT_RegCall:
+ //case ParsedAttr::AT_RegCall4:
case ParsedAttr::AT_SwiftCall:
case ParsedAttr::AT_SwiftAsyncCall:
case ParsedAttr::AT_VectorCall:
@@ -9638,7 +9644,7 @@ ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, const ParsedAttr &AL,
case ParsedAttr::AT_UsingIfExists:
handleSimpleAttribute<UsingIfExistsAttr>(S, D, AL);
-
+ break;
case ParsedAttr::AT_RegCall4:
handleSimpleAttribute<RegCall4Attr>(S, D, AL);
break;
diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp
index b1bdf670f17883c..d164944c3bdec14 100644
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/lib/Sema/SemaType.cpp
@@ -124,6 +124,7 @@ static void diagnoseBadTypeAttribute(Sema &S, const ParsedAttr &attr,
case ParsedAttr::AT_StdCall: \
case ParsedAttr::AT_ThisCall: \
case ParsedAttr::AT_RegCall: \
+ case ParsedAttr::AT_RegCall4: \
case ParsedAttr::AT_Pascal: \
case ParsedAttr::AT_SwiftCall: \
case ParsedAttr::AT_SwiftAsyncCall: \
@@ -7763,6 +7764,8 @@ static Attr *getCCTypeAttr(ASTContext &Ctx, ParsedAttr &Attr) {
return createSimpleAttr<ThisCallAttr>(Ctx, Attr);
case ParsedAttr::AT_RegCall:
return createSimpleAttr<RegCallAttr>(Ctx, Attr);
+ case ParsedAttr::AT_RegCall4:
+ return createSimpleAttr<RegCall4Attr>(Ctx, Attr);
case ParsedAttr::AT_Pascal:
return createSimpleAttr<PascalAttr>(Ctx, Attr);
case ParsedAttr::AT_SwiftCall:
diff --git a/clang/test/CodeGen/regcall.c b/clang/test/CodeGen/regcall.c
index ee8372c6f1312e1..dc37c0545f27389 100644
--- a/clang/test/CodeGen/regcall.c
+++ b/clang/test/CodeGen/regcall.c
@@ -9,7 +9,7 @@ void __regcall v1(int a, int b) {}
// X86: define dso_local x86_regcallcc void @__regcall3__v1(i32 inreg noundef %a, i32 inreg noundef %b)
// X64: define dso_local x86_regcallcc void @__regcall3__v1(i32 noundef %a, i32 noundef %b)
-void __attribute__((regcall4, regcall)) v1b(int a, int b) {}
+void __attribute__((regcall4)) v1b(int a, int b) {}
// X86: define dso_local x86_regcallcc void @__regcall3__v1b(i32 inreg noundef %a, i32 inreg noundef %b)
// X64: define dso_local x86_regcallcc void @__regcall3__v1b(i32 noundef %a, i32 noundef %b)
>From 83e01839777757e9afbcfdfaa57608bdb162d6f6 Mon Sep 17 00:00:00 2001
From: Bing1 Yu <bing1.yu at intel.com>
Date: Fri, 20 Oct 2023 16:53:07 +0800
Subject: [PATCH 5/5] add testcase clang/test/CodeGen/regcall4-attr.c
---
clang/test/CodeGen/regcall.c | 2 +-
clang/test/CodeGen/regcall4-attr.c | 13 +++++++++++++
2 files changed, 14 insertions(+), 1 deletion(-)
create mode 100644 clang/test/CodeGen/regcall4-attr.c
diff --git a/clang/test/CodeGen/regcall.c b/clang/test/CodeGen/regcall.c
index dc37c0545f27389..f10da87353fa114 100644
--- a/clang/test/CodeGen/regcall.c
+++ b/clang/test/CodeGen/regcall.c
@@ -9,7 +9,7 @@ void __regcall v1(int a, int b) {}
// X86: define dso_local x86_regcallcc void @__regcall3__v1(i32 inreg noundef %a, i32 inreg noundef %b)
// X64: define dso_local x86_regcallcc void @__regcall3__v1(i32 noundef %a, i32 noundef %b)
-void __attribute__((regcall4)) v1b(int a, int b) {}
+void __attribute__((regcall)) v1b(int a, int b) {}
// X86: define dso_local x86_regcallcc void @__regcall3__v1b(i32 inreg noundef %a, i32 inreg noundef %b)
// X64: define dso_local x86_regcallcc void @__regcall3__v1b(i32 noundef %a, i32 noundef %b)
diff --git a/clang/test/CodeGen/regcall4-attr.c b/clang/test/CodeGen/regcall4-attr.c
new file mode 100644
index 000000000000000..6c0f86cc077004e
--- /dev/null
+++ b/clang/test/CodeGen/regcall4-attr.c
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -emit-llvm %s -o - -ffreestanding -triple=i386-pc-win32 | FileCheck %s --check-prefixes=X86
+// RUN: %clang_cc1 -emit-llvm %s -o - -ffreestanding -triple=x86_64-pc-win32 | FileCheck %s --check-prefixes=X64
+// RUN: %clang_cc1 -emit-llvm %s -o - -ffreestanding -triple=i386-pc-linux-gnu | FileCheck %s --check-prefixes=X86
+// RUN: %clang_cc1 -emit-llvm %s -o - -ffreestanding -triple=x86_64-pc-linux-gnu | FileCheck %s --check-prefixes=X64
+
+#include <xmmintrin.h>
+
+
+void __attribute__((regcall4)) v1b(int a, int b) {}
+// X86: define dso_local x86_regcallcc void @__regcall4__v1b(i32 inreg noundef %a, i32 inreg noundef %b) #[[#ATTR:]]
+// X64: define dso_local x86_regcallcc void @__regcall4__v1b(i32 noundef %a, i32 noundef %b) #[[#ATTR:]]
+
+// X86: attributes #[[#ATTR:]] = { {{.*}}regcall4{{.*}} }
\ No newline at end of file
More information about the llvm-commits
mailing list