Skip to content

Commit

Permalink
[CIR][CIRGen] Add dsolocal attribute to GlobalOp and FuncOp (llvm#686)
Browse files Browse the repository at this point in the history
as title. In this PR
1.   make setDSOLocal an interface function.
2. implemented shouldAssumeDSOLocal function in CIRGenModule, using the
same skeleton as shouldAssumeDSOLocal in OG's CodeGenModule.cpp.
3. added call sites of setDSOLocal within CIRGenModule, like what's in
OG's CodeGenModule.
4.  fixed printing format 
5.  LLVM lowering
6. keep CIRGenModule::setDSOLocal(mlir::Operation *Op) wrapper at call
sites, so if we make changes to interface, we don't have to touch call
sites since there are many.

We don't have LLVM test for this PR yet, and it will be addressed by the
next PR,:
**TODO in the next PR:**
1. Implement setNonAliasAttributes in CIRGenModule.cpp, which should be
called by CIRGenModule::buildGlobalFunctionDefinition. That way, we will
set dso_local correctly for all func ops who have defs in the module.
That way we should have LLVM test case in this next PR. detailed
explanation below:

Since LLVM asm printer omits dso_local in
[isImplicitDSOLocal](https://github.com/llvm/clangir/blob/main/llvm/lib/IR/AsmWriter.cpp#L3689)(),
and all we cover so far in CIR all fall into this category, we're not
able to have a LLVM test.
However, the case
[isDeclarationForLinker()](https://github.com/llvm/clangir/blob/c28908396a3ba7bda6345907233e4f5c4e53a33e/clang/lib/CodeGen/CodeGenModule.cpp#L1655)
should have a lot of test examples as all func defs should have
dso_local, We don't have it CIR is because
A to-do in our CG.
When OG is building func def, after code is generated, it will call
setDSOLocal again via
setNonAliasAttributes—>SetCommonAttributes—>setGVProperties. The key
difference is now GV is not declaration anymore. so satisfies the test
if (!GV->isDeclarationForLinker())
    return true;

https://github.com/llvm/clangir/blob/f78f9a55e7cd6b9e350556e35097616676cf1f3e/clang/lib/CodeGen/CodeGenModule.cpp#L5864
But our CG missed this step of calling setNonAliasAttributes so it won’t
give setDSOLocal another chance to get it right

https://github.com/llvm/clangir/blob/c28908396a3ba7bda6345907233e4f5c4e53a33e/clang/lib/CIR/CodeGen/CIRGenModule.cpp#L496


**TODO in the next next PR** 
2. add call to setDSOLocal in other parts of CG other than CIRGenModule.
3. implement DefaultVisibility check, didn't do in this PR as
LLVM::DefaultVisibility has no direct counterpart in
[MLIR::](mlir::SymbolTable::Visibility). Therefore, it takes care
examination of cases to see what is the best emulation of
hasDefaultVisibility in MLIR/CIR context as far as dsolocal is
concerned.

**TODO in future**
other than DefaultVisibility check, we didn't implement
canBenefitFromLocalAlias as it depends on other missing features like
setComDat.










There is a lot of cases we need to cover, so this is just the first
step!
  • Loading branch information
ghehg authored Jun 25, 2024
1 parent c289083 commit d2f2fde
Show file tree
Hide file tree
Showing 21 changed files with 182 additions and 36 deletions.
3 changes: 3 additions & 0 deletions clang/include/clang/CIR/Dialect/IR/CIROps.td
Original file line number Diff line number Diff line change
Expand Up @@ -1924,6 +1924,7 @@ def GlobalOp : CIR_Op<"global",
// Note this can also be a FlatSymbolRefAttr
OptionalAttr<AnyAttr>:$initial_value,
UnitAttr:$constant,
UnitAttr:$dsolocal,
OptionalAttr<I64Attr>:$alignment,
OptionalAttr<ASTVarDeclInterface>:$ast,
OptionalAttr<StrAttr>:$section
Expand All @@ -1934,6 +1935,7 @@ def GlobalOp : CIR_Op<"global",
(`constant` $constant^)?
$linkage
($tls_model^)?
(`dsolocal` $dsolocal^)?
$sym_name
custom<GlobalOpTypeAndInitialValue>($sym_type, $initial_value, $ctorRegion, $dtorRegion)
attr-dict
Expand Down Expand Up @@ -2671,6 +2673,7 @@ def FuncOp : CIR_Op<"func", [
UnitAttr:$coroutine,
UnitAttr:$lambda,
UnitAttr:$no_proto,
UnitAttr:$dsolocal,
DefaultValuedAttr<GlobalLinkageKind,
"GlobalLinkageKind::ExternalLinkage">:$linkage,
ExtraFuncAttr:$extra_attrs,
Expand Down
1 change: 1 addition & 0 deletions clang/include/clang/CIR/Interfaces/CIROpInterfaces.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include "clang/AST/Attr.h"
#include "clang/AST/DeclTemplate.h"
#include "clang/AST/Mangle.h"
#include "clang/CIR/Dialect/IR/CIROpsEnums.h"

namespace mlir {
namespace cir {} // namespace cir
Expand Down
21 changes: 21 additions & 0 deletions clang/include/clang/CIR/Interfaces/CIROpInterfaces.td
Original file line number Diff line number Diff line change
Expand Up @@ -46,14 +46,35 @@ let cppNamespace = "::mlir::cir" in {
/*defaultImplementation=*/[{ return false; }]
>,
InterfaceMethod<"",
"bool", "hasLocalLinkage", (ins), [{}],
/*defaultImplementation=*/[{
return mlir::cir::isLocalLinkage($_op.getLinkage());
}]
>,
InterfaceMethod<"",
"bool", "hasExternalWeakLinkage", (ins), [{}],
/*defaultImplementation=*/[{
return mlir::cir::isExternalWeakLinkage($_op.getLinkage());
}]
>,
InterfaceMethod<"",
"bool", "isDeclarationForLinker", (ins), [{}],
/*defaultImplementation=*/[{
if ($_op.hasAvailableExternallyLinkage())
return true;
return $_op.isDeclaration();
}]
>,
InterfaceMethod<"",
"void", "setDSOLocal", (ins "bool":$val), [{}],
/*defaultImplementation=*/[{
$_op.setDsolocal(val);
}]
>,
];
let extraClassDeclaration = [{
bool canBenefitFromLocalAlias() const;
}];
}

} // namespace mlir::cir
Expand Down
2 changes: 2 additions & 0 deletions clang/include/clang/CIR/MissingFeatures.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ struct MissingFeatures {
static bool hiddenVisibility() { return false; }
static bool protectedVisibility() { return false; }
static bool addCompilerUsedGlobal() { return false; }
static bool supportIFuncAttr() { return false; }
static bool setDefaultVisibility() { return false; }

// Sanitizers
static bool reportGlobalToASan() { return false; }
Expand Down
103 changes: 102 additions & 1 deletion clang/lib/CIR/CodeGen/CIRGenModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -364,6 +364,103 @@ bool CIRGenModule::MayBeEmittedEagerly(const ValueDecl *Global) {
return true;
}

static bool hasDefaultVisibility(CIRGlobalValueInterface GV) {
// TODO: we need to have a precise definition of what is a default visibility.
// in the context of MILR and CIR, now we default to
assert(!MissingFeatures::setDefaultVisibility());
return true;
}

static bool shouldAssumeDSOLocal(const CIRGenModule &CGM,
CIRGlobalValueInterface GV) {
if (GV.hasLocalLinkage())
return true;

if (!hasDefaultVisibility(GV) && !GV.hasExternalWeakLinkage()) {
return true;
}

// DLLImport explicitly marks the GV as external.
// so it shouldn't be dso_local
// But we don't have the info set now
assert(!MissingFeatures::setDLLImportDLLExport());

const llvm::Triple &TT = CGM.getTriple();
const auto &CGOpts = CGM.getCodeGenOpts();
if (TT.isWindowsGNUEnvironment()) {
// In MinGW, variables without DLLImport can still be automatically
// imported from a DLL by the linker; don't mark variables that
// potentially could come from another DLL as DSO local.

// With EmulatedTLS, TLS variables can be autoimported from other DLLs
// (and this actually happens in the public interface of libstdc++), so
// such variables can't be marked as DSO local. (Native TLS variables
// can't be dllimported at all, though.)
llvm_unreachable("MinGW not supported here");
}

// On COFF, don't mark 'extern_weak' symbols as DSO local. If these symbols
// remain unresolved in the link, they can be resolved to zero, which is
// outside the current DSO.
if (TT.isOSBinFormatCOFF() && GV.hasExternalWeakLinkage())
return false;

// Every other GV is local on COFF.
// Make an exception for windows OS in the triple: Some firmware builds use
// *-win32-macho triples. This (accidentally?) produced windows relocations
// without GOT tables in older clang versions; Keep this behaviour.
// FIXME: even thread local variables?
if (TT.isOSBinFormatCOFF() || (TT.isOSWindows() && TT.isOSBinFormatMachO()))
return true;

// Only handle COFF and ELF for now.
if (!TT.isOSBinFormatELF())
return false;

llvm::Reloc::Model RM = CGOpts.RelocationModel;
const auto &LOpts = CGM.getLangOpts();
if (RM != llvm::Reloc::Static && !LOpts.PIE) {
// On ELF, if -fno-semantic-interposition is specified and the target
// supports local aliases, there will be neither CC1
// -fsemantic-interposition nor -fhalf-no-semantic-interposition. Set
// dso_local on the function if using a local alias is preferable (can avoid
// PLT indirection).
if (!(isa<mlir::cir::FuncOp>(GV) && GV.canBenefitFromLocalAlias())) {
return false;
}
return !(CGM.getLangOpts().SemanticInterposition ||
CGM.getLangOpts().HalfNoSemanticInterposition);
}

// A definition cannot be preempted from an executable.
if (!GV.isDeclarationForLinker())
return true;

// Most PIC code sequences that assume that a symbol is local cannot produce a
// 0 if it turns out the symbol is undefined. While this is ABI and relocation
// depended, it seems worth it to handle it here.
if (RM == llvm::Reloc::PIC_ && GV.hasExternalWeakLinkage())
return false;

// PowerPC64 prefers TOC indirection to avoid copy relocations.
if (TT.isPPC64())
return false;

if (CGOpts.DirectAccessExternalData) {
llvm_unreachable("-fdirect-access-external-data not supported");
}

// If we can use copy relocations we can assume it is local.

// Otherwise don't assume it is local.

return false;
}

void CIRGenModule::setDSOLocal(CIRGlobalValueInterface GV) const {
GV.setDSOLocal(shouldAssumeDSOLocal(*this, GV));
}

void CIRGenModule::buildGlobal(GlobalDecl GD) {
const auto *Global = cast<ValueDecl>(GD.getDecl());

Expand Down Expand Up @@ -1272,7 +1369,6 @@ generateStringLiteral(mlir::Location loc, mlir::TypedAttr C,
GV.setLinkageAttr(
mlir::cir::GlobalLinkageKindAttr::get(CGM.getBuilder().getContext(), LT));
CIRGenModule::setInitializer(GV, C);

// TODO(cir)
assert(!cir::MissingFeatures::threadLocal() && "NYI");
assert(!cir::MissingFeatures::unnamedAddr() && "NYI");
Expand Down Expand Up @@ -1326,6 +1422,7 @@ CIRGenModule::getAddrOfConstantStringFromLiteral(const StringLiteral *S,
llvm_unreachable("this should never be untyped at this point");
GV = generateStringLiteral(loc, typedC, LT, *this, GlobalVariableName,
Alignment);
setDSOLocal(static_cast<mlir::Operation *>(GV));
ConstantStringMap[C] = GV;

assert(!cir::MissingFeatures::reportGlobalToASan() && "NYI");
Expand Down Expand Up @@ -1979,6 +2076,9 @@ void CIRGenModule::setGlobalVisibility(mlir::Operation *GV,

void CIRGenModule::setDSOLocal(mlir::Operation *Op) const {
assert(!MissingFeatures::setDSOLocal());
if (auto globalValue = dyn_cast<mlir::cir::CIRGlobalValueInterface>(Op)) {
setDSOLocal(globalValue);
}
}

void CIRGenModule::setGVProperties(mlir::Operation *Op,
Expand Down Expand Up @@ -2750,6 +2850,7 @@ mlir::cir::GlobalOp CIRGenModule::createOrReplaceCXXRuntimeVariable(
assert(!MissingFeatures::setComdat());

GV.setAlignmentAttr(getSize(Alignment));
setDSOLocal(static_cast<mlir::Operation *>(GV));
return GV;
}

Expand Down
3 changes: 3 additions & 0 deletions clang/lib/CIR/CodeGen/CIRGenModule.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#include "clang/CIR/Dialect/IR/CIRDialect.h"
#include "clang/CIR/Dialect/IR/CIROpsEnums.h"
#include "clang/CIR/Dialect/IR/CIRTypes.h"
#include "clang/CIR/Interfaces/CIROpInterfaces.h"

#include "llvm/ADT/ScopedHashTable.h"
#include "llvm/ADT/SmallPtrSet.h"
Expand Down Expand Up @@ -281,6 +282,8 @@ class CIRGenModule : public CIRGenTypeCache {
void buildDeferredVTables();
bool shouldOpportunisticallyEmitVTables();

void setDSOLocal(mlir::cir::CIRGlobalValueInterface GV) const;

/// Return the appropriate linkage for the vtable, VTT, and type information
/// of the given class.
mlir::cir::GlobalLinkageKind getVTableLinkage(const CXXRecordDecl *RD);
Expand Down
4 changes: 4 additions & 0 deletions clang/lib/CIR/Dialect/IR/CIRDialect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2116,6 +2116,9 @@ void cir::FuncOp::print(OpAsmPrinter &p) {
if (vis != mlir::SymbolTable::Visibility::Public)
p << vis << " ";

if (getDsolocal())
p << "dsolocal ";

// Print function name, signature, and control.
p.printSymbolName(getSymName());
auto fnType = getFunctionType();
Expand All @@ -2134,6 +2137,7 @@ void cir::FuncOp::print(OpAsmPrinter &p) {
getAliaseeAttrName(),
getBuiltinAttrName(),
getCoroutineAttrName(),
getDsolocalAttrName(),
getExtraAttrsAttrName(),
getFunctionTypeAttrName(),
getGlobalCtorAttrName(),
Expand Down
9 changes: 9 additions & 0 deletions clang/lib/CIR/Interfaces/CIROpInterfaces.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,18 @@
//===----------------------------------------------------------------------===//
#include "clang/CIR/Interfaces/CIROpInterfaces.h"

#include "clang/CIR/Dialect/IR/CIROpsEnums.h"
#include "llvm/ADT/SmallVector.h"

using namespace mlir::cir;

/// Include the generated type qualifiers interfaces.
#include "clang/CIR/Interfaces/CIROpInterfaces.cpp.inc"

#include "clang/CIR/MissingFeatures.h"

bool CIRGlobalValueInterface::canBenefitFromLocalAlias() const {
assert(!::cir::MissingFeatures::supportIFuncAttr());
assert(!::cir::MissingFeatures::setComdat());
return false;
}
6 changes: 4 additions & 2 deletions clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1512,6 +1512,7 @@ class CIRFuncLowering : public mlir::OpConversionPattern<mlir::cir::FuncOp> {
mlir::ConversionPatternRewriter &rewriter) const override {

auto fnType = op.getFunctionType();
auto isDsoLocal = op.getDsolocal();
mlir::TypeConverter::SignatureConversion signatureConversion(
fnType.getNumInputs());

Expand Down Expand Up @@ -1545,7 +1546,7 @@ class CIRFuncLowering : public mlir::OpConversionPattern<mlir::cir::FuncOp> {
filterFuncAttributes(op, /*filterArgAndResAttrs=*/false, attributes);

auto fn = rewriter.create<mlir::LLVM::LLVMFuncOp>(
Loc, op.getName(), llvmFnTy, linkage, false, mlir::LLVM::CConv::C,
Loc, op.getName(), llvmFnTy, linkage, isDsoLocal, mlir::LLVM::CConv::C,
mlir::SymbolRefAttr(), attributes);

rewriter.inlineRegionBefore(op.getBody(), fn.getBody(), fn.end());
Expand Down Expand Up @@ -1654,6 +1655,7 @@ class CIRGlobalOpLowering
// Fetch required values to create LLVM op.
const auto llvmType = getTypeConverter()->convertType(op.getSymType());
const auto isConst = op.getConstant();
const auto isDsoLocal = op.getDsolocal();
const auto linkage = convertLinkage(op.getLinkage());
const auto symbol = op.getSymName();
const auto loc = op.getLoc();
Expand All @@ -1670,7 +1672,7 @@ class CIRGlobalOpLowering
rewriter.replaceOpWithNewOp<mlir::LLVM::GlobalOp>(
op, llvmType, isConst, linkage, symbol, mlir::Attribute(),
/*alignment*/ 0, /*addrSpace*/ 0,
/*dsoLocal*/ false, /*threadLocal*/ (bool)op.getTlsModelAttr(),
/*dsoLocal*/ isDsoLocal, /*threadLocal*/ (bool)op.getTlsModelAttr(),
/*comdat*/ mlir::SymbolRefAttr(), attributes);
return mlir::success();
}
Expand Down
2 changes: 1 addition & 1 deletion clang/test/CIR/CodeGen/array.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ void local_stringlit() {
const char *s = "whatnow";
}

// CHECK: cir.global "private" constant internal @".str" = #cir.const_array<"whatnow\00" : !cir.array<!s8i x 8>> : !cir.array<!s8i x 8> {alignment = 1 : i64}
// CHECK: cir.global "private" constant internal dsolocal @".str" = #cir.const_array<"whatnow\00" : !cir.array<!s8i x 8>> : !cir.array<!s8i x 8> {alignment = 1 : i64}
// CHECK: cir.func @_Z15local_stringlitv()
// CHECK-NEXT: %0 = cir.alloca !cir.ptr<!s8i>, !cir.ptr<!cir.ptr<!s8i>>, ["s", init] {alignment = 8 : i64}
// CHECK-NEXT: %1 = cir.get_global @".str" : !cir.ptr<!cir.array<!s8i x 8>>
Expand Down
2 changes: 1 addition & 1 deletion clang/test/CIR/CodeGen/const-array.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ void bar() {
const int arr[1] = {1};
}

// CHECK: cir.global "private" constant internal @bar.arr = #cir.const_array<[#cir.int<1> : !s32i]> : !cir.array<!s32i x 1> {alignment = 4 : i64}
// CHECK: cir.global "private" constant internal dsolocal @bar.arr = #cir.const_array<[#cir.int<1> : !s32i]> : !cir.array<!s32i x 1> {alignment = 4 : i64}
// CHECK: cir.func no_proto @bar()
// CHECK: {{.*}} = cir.get_global @bar.arr : !cir.ptr<!cir.array<!s32i x 1>>

Expand Down
2 changes: 1 addition & 1 deletion clang/test/CIR/CodeGen/coro-task.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -338,7 +338,7 @@ folly::coro::Task<int> go1_lambda() {
co_return co_await task;
}

// CHECK: cir.func coroutine lambda internal private @_ZZ10go1_lambdavENK3$_0clEv{{.*}}22 extra{{.*}}{
// CHECK: cir.func coroutine lambda internal private dsolocal @_ZZ10go1_lambdavENK3$_0clEv{{.*}}22 extra{{.*}}{
// CHECK: cir.func coroutine @_Z10go1_lambdav() {{.*}}22 extra{{.*}}{

folly::coro::Task<int> go4() {
Expand Down
4 changes: 2 additions & 2 deletions clang/test/CIR/CodeGen/globals.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,10 @@ int use_func() { return func<int>(); }
// CHECK-NEXT: cir.global external @rgb = #cir.const_array<[#cir.int<0> : !u8i, #cir.int<233> : !u8i, #cir.int<33> : !u8i]> : !cir.array<!u8i x 3>
// CHECK-NEXT: cir.global external @alpha = #cir.const_array<"abc\00" : !cir.array<!s8i x 4>> : !cir.array<!s8i x 4>

// CHECK-NEXT: cir.global "private" constant internal @".str" = #cir.const_array<"example\00" : !cir.array<!s8i x 8>> : !cir.array<!s8i x 8> {alignment = 1 : i64}
// CHECK-NEXT: cir.global "private" constant internal dsolocal @".str" = #cir.const_array<"example\00" : !cir.array<!s8i x 8>> : !cir.array<!s8i x 8> {alignment = 1 : i64}
// CHECK-NEXT: cir.global external @s = #cir.global_view<@".str"> : !cir.ptr<!s8i>

// CHECK-NEXT: cir.global "private" constant internal @".str1" = #cir.const_array<"example1\00" : !cir.array<!s8i x 9>> : !cir.array<!s8i x 9> {alignment = 1 : i64}
// CHECK-NEXT: cir.global "private" constant internal dsolocal @".str1" = #cir.const_array<"example1\00" : !cir.array<!s8i x 9>> : !cir.array<!s8i x 9> {alignment = 1 : i64}
// CHECK-NEXT: cir.global external @s1 = #cir.global_view<@".str1"> : !cir.ptr<!s8i>

// CHECK-NEXT: cir.global external @s2 = #cir.global_view<@".str"> : !cir.ptr<!s8i>
Expand Down
2 changes: 1 addition & 1 deletion clang/test/CIR/CodeGen/hello.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ int main (void) {
}

// CHECK: cir.func private @printf(!cir.ptr<!s8i>, ...) -> !s32i
// CHECK: cir.global "private" constant internal @".str" = #cir.const_array<"Hello, world!\0A\00" : !cir.array<!s8i x 15>> : !cir.array<!s8i x 15> {alignment = 1 : i64}
// CHECK: cir.global "private" constant internal dsolocal @".str" = #cir.const_array<"Hello, world!\0A\00" : !cir.array<!s8i x 15>> : !cir.array<!s8i x 15> {alignment = 1 : i64}
// CHECK: cir.func @main() -> !s32i
// CHECK: %0 = cir.alloca !s32i, !cir.ptr<!s32i>, ["__retval"] {alignment = 4 : i64}
// CHECK: %1 = cir.get_global @printf : !cir.ptr<!cir.func<!s32i (!cir.ptr<!s8i>, ...)>>
Expand Down
10 changes: 5 additions & 5 deletions clang/test/CIR/CodeGen/lambda.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ void fn() {
// CHECK: !ty_22anon2E222 = !cir.struct<class "anon.2" {!cir.int<u, 8>}>
// CHECK-DAG: module

// CHECK: cir.func lambda internal private @_ZZ2fnvENK3$_0clEv{{.*}}) extra
// CHECK: cir.func lambda internal private dsolocal @_ZZ2fnvENK3$_0clEv{{.*}}) extra

// CHECK: cir.func @_Z2fnv()
// CHECK-NEXT: %0 = cir.alloca !ty_22anon2E222, !cir.ptr<!ty_22anon2E222>, ["a"]
Expand All @@ -21,7 +21,7 @@ void l0() {
a();
}

// CHECK: cir.func lambda internal private @_ZZ2l0vENK3$_0clEv({{.*}}) extra
// CHECK: cir.func lambda internal private dsolocal @_ZZ2l0vENK3$_0clEv({{.*}}) extra

// CHECK: %0 = cir.alloca !cir.ptr<!ty_22anon2E422>, !cir.ptr<!cir.ptr<!ty_22anon2E422>>, ["this", init] {alignment = 8 : i64}
// CHECK: cir.store %arg0, %0 : !cir.ptr<!ty_22anon2E422>, !cir.ptr<!cir.ptr<!ty_22anon2E422>>
Expand Down Expand Up @@ -99,13 +99,13 @@ int g3() {
}

// lambda operator()
// CHECK: cir.func lambda internal private @_ZZ2g3vENK3$_0clERKi{{.*}}!s32i extra
// CHECK: cir.func lambda internal private dsolocal @_ZZ2g3vENK3$_0clERKi{{.*}}!s32i extra

// lambda __invoke()
// CHECK: cir.func internal private @_ZZ2g3vEN3$_08__invokeERKi
// CHECK: cir.func internal private dsolocal @_ZZ2g3vEN3$_08__invokeERKi

// lambda operator int (*)(int const&)()
// CHECK: cir.func internal private @_ZZ2g3vENK3$_0cvPFiRKiEEv
// CHECK: cir.func internal private dsolocal @_ZZ2g3vENK3$_0cvPFiRKiEEv

// CHECK: cir.func @_Z2g3v() -> !s32i
// CHECK: %0 = cir.alloca !s32i, !cir.ptr<!s32i>, ["__retval"] {alignment = 4 : i64}
Expand Down
Loading

0 comments on commit d2f2fde

Please sign in to comment.