Skip to content

Commit d169505

Browse files
dkolsen-pgilanza
authored andcommitted
[CIR] New assembly format for function type return (#1391)
Change the assembly format for `cir::FuncType` from ``` !cir.func<!returnType (!argType)> ``` to ``` !cir.func<(!argType) -> !returnType> ``` This change (1) is easier to parse because it doesn't require lookahead, (2) is consistent with the format of ClangIR `FuncOp` assembly, and (3) is consistent with function types in other MLIR dialects. Change all the tests to use or to expect the new format for function types. The contents and the semantics of `cir::FuncType` are unchanged. Only the assembly format is being changed. Functions that return `void` in C or C++ are still represented in MLIR as having no return type. Most of the changes are in `parseFuncType` and `printFuncType` and the functions they call in `CIRTypes.cpp`. A `FuncType::verify` function was added to check that an explicit return type is not `cir::VoidType`. `FuncType::isVoid()` was renamed to `FuncType::hasVoidReturn()` Some comments for `FuncType` were improved. An `llvm_unreachable` was added to `StructType::getKindAsStr` to suppress a compiler warning and to catch a memory error that corrupts the `RecordKind` field. (This was a drive-by fix and has nothing to do with the rest of this change.)
1 parent 10059b9 commit d169505

31 files changed

+220
-221
lines changed

clang/include/clang/CIR/Dialect/IR/CIROps.td

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3897,7 +3897,7 @@ def CallOp : CIR_CallOp<"call", [NoRegionArguments]> {
38973897
CArg<"mlir::UnitAttr", "{}">:$exception), [{
38983898
$_state.addOperands(ValueRange{ind_target});
38993899
$_state.addOperands(operands);
3900-
if (!fn_type.isVoid())
3900+
if (!fn_type.hasVoidReturn())
39013901
$_state.addTypes(fn_type.getReturnType());
39023902
$_state.addAttribute("calling_conv",
39033903
CallingConvAttr::get($_builder.getContext(), callingConv));
@@ -3983,7 +3983,7 @@ def TryCallOp : CIR_CallOp<"try_call",
39833983
finalCallOperands.append(operands.begin(), operands.end());
39843984
$_state.addOperands(finalCallOperands);
39853985

3986-
if (!fn_type.isVoid())
3986+
if (!fn_type.hasVoidReturn())
39873987
$_state.addTypes(fn_type.getReturnType());
39883988

39893989
$_state.addAttribute("calling_conv",

clang/include/clang/CIR/Dialect/IR/CIRTypes.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,7 @@ class StructType
154154
case RecordKind::Struct:
155155
return "struct";
156156
}
157+
llvm_unreachable("Invalid value for StructType::getKind()");
157158
}
158159
std::string getPrefixedName() {
159160
return getKindAsStr() + "." + getName().getValue().str();

clang/include/clang/CIR/Dialect/IR/CIRTypes.td

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -379,34 +379,38 @@ def CIR_FuncType : CIR_Type<"Func", "func"> {
379379

380380
```mlir
381381
!cir.func<()>
382-
!cir.func<!bool ()>
382+
!cir.func<() -> !bool>
383383
!cir.func<(!s8i, !s8i)>
384-
!cir.func<!s32i (!s8i, !s8i)>
385-
!cir.func<!s32i (!s32i, ...)>
384+
!cir.func<(!s8i, !s8i) -> !s32i>
385+
!cir.func<(!s32i, ...) -> !s32i>
386386
```
387387
}];
388388

389389
let parameters = (ins ArrayRefParameter<"mlir::Type">:$inputs,
390390
"mlir::Type":$optionalReturnType,
391391
"bool":$varArg);
392392
// Use a custom parser to handle the optional return and argument types
393-
// without an optional anchor.
394393
let assemblyFormat = [{
395394
`<` custom<FuncType>($optionalReturnType, $inputs, $varArg) `>`
396395
}];
397396

398397
let builders = [
399-
// Construct with an actual return type or explicit !cir.void
398+
// Create a FuncType, converting the return type from C-style to
399+
// MLIR-style. If the given return type is `cir::VoidType`, ignore it
400+
// and create the FuncType with no return type, which is how MLIR
401+
// represents function types.
400402
TypeBuilderWithInferredContext<(ins
401403
"llvm::ArrayRef<mlir::Type>":$inputs, "mlir::Type":$returnType,
402404
CArg<"bool", "false">:$isVarArg), [{
403-
return $_get(returnType.getContext(), inputs,
404-
mlir::isa<cir::VoidType>(returnType) ? nullptr
405-
: returnType,
406-
isVarArg);
405+
return $_get(returnType.getContext(), inputs,
406+
mlir::isa<cir::VoidType>(returnType) ? nullptr
407+
: returnType,
408+
isVarArg);
407409
}]>
408410
];
409411

412+
let genVerifyDecl = 1;
413+
410414
let extraClassDeclaration = [{
411415
/// Returns whether the function is variadic.
412416
bool isVarArg() const { return getVarArg(); }
@@ -417,16 +421,17 @@ def CIR_FuncType : CIR_Type<"Func", "func"> {
417421
/// Returns the number of arguments to the function.
418422
unsigned getNumInputs() const { return getInputs().size(); }
419423

420-
/// Returns the result type of the function as an actual return type or
421-
/// explicit !cir.void
424+
/// Get the C-style return type of the function, which is !cir.void if the
425+
/// function returns nothing and the actual return type otherwise.
422426
mlir::Type getReturnType() const;
423427

424-
/// Returns the result type of the function as an ArrayRef, enabling better
425-
/// integration with generic MLIR utilities.
428+
/// Get the MLIR-style return type of the function, which is an empty
429+
/// ArrayRef if the function returns nothing and a single-element ArrayRef
430+
/// with the actual return type otherwise.
426431
llvm::ArrayRef<mlir::Type> getReturnTypes() const;
427432

428-
/// Returns whether the function returns void.
429-
bool isVoid() const;
433+
/// Does the fuction type return nothing?
434+
bool hasVoidReturn() const;
430435

431436
/// Returns a clone of this function type with the given argument
432437
/// and result types.

clang/lib/CIR/Dialect/IR/CIRDialect.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2746,15 +2746,15 @@ verifyCallCommInSymbolUses(Operation *op, SymbolTableCollection &symbolTable) {
27462746
<< stringifyCallingConv(callIf.getCallingConv());
27472747

27482748
// Void function must not return any results.
2749-
if (fnType.isVoid() && op->getNumResults() != 0)
2749+
if (fnType.hasVoidReturn() && op->getNumResults() != 0)
27502750
return op->emitOpError("callee returns void but call has results");
27512751

27522752
// Non-void function calls must return exactly one result.
2753-
if (!fnType.isVoid() && op->getNumResults() != 1)
2753+
if (!fnType.hasVoidReturn() && op->getNumResults() != 1)
27542754
return op->emitOpError("incorrect number of results for callee");
27552755

27562756
// Parent function and return value types must match.
2757-
if (!fnType.isVoid() &&
2757+
if (!fnType.hasVoidReturn() &&
27582758
op->getResultTypes().front() != fnType.getReturnType()) {
27592759
return op->emitOpError("result type mismatch: expected ")
27602760
<< fnType.getReturnType() << ", but provided "

clang/lib/CIR/Dialect/IR/CIRTypes.cpp

Lines changed: 52 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -837,66 +837,51 @@ FuncType FuncType::clone(TypeRange inputs, TypeRange results) const {
837837
// type.
838838
static mlir::ParseResult parseFuncTypeReturn(mlir::AsmParser &p,
839839
mlir::Type &optionalReturnType) {
840-
if (succeeded(p.parseOptionalLParen())) {
841-
// If we have already a '(', the function has no return type
842-
optionalReturnType = {};
843-
return mlir::success();
840+
if (succeeded(p.parseOptionalArrow())) {
841+
// `->` found. It must be followed by the return type.
842+
return p.parseType(optionalReturnType);
844843
}
845-
mlir::Type type;
846-
if (p.parseType(type))
847-
return mlir::failure();
848-
if (isa<cir::VoidType>(type))
849-
// An explicit !cir.void means also no return type.
850-
optionalReturnType = {};
851-
else
852-
// Otherwise use the actual type.
853-
optionalReturnType = type;
854-
return p.parseLParen();
844+
// Function has `void` return in C++, no return in MLIR.
845+
optionalReturnType = {};
846+
return success();
855847
}
856848

857849
// A special pretty-printer for function returning or not a result.
858850
static void printFuncTypeReturn(mlir::AsmPrinter &p,
859851
mlir::Type optionalReturnType) {
860852
if (optionalReturnType)
861-
p << optionalReturnType << ' ';
862-
p << '(';
853+
p << " -> " << optionalReturnType;
863854
}
864855

865856
static mlir::ParseResult
866857
parseFuncTypeArgs(mlir::AsmParser &p, llvm::SmallVector<mlir::Type> &params,
867858
bool &isVarArg) {
868859
isVarArg = false;
869-
// `(` `)`
870-
if (succeeded(p.parseOptionalRParen()))
860+
if (failed(p.parseLParen()))
861+
return failure();
862+
if (succeeded(p.parseOptionalRParen())) {
863+
// `()` empty argument list
871864
return mlir::success();
872-
873-
// `(` `...` `)`
874-
if (succeeded(p.parseOptionalEllipsis())) {
875-
isVarArg = true;
876-
return p.parseRParen();
877865
}
878-
879-
// type (`,` type)* (`,` `...`)?
880-
mlir::Type type;
881-
if (p.parseType(type))
882-
return mlir::failure();
883-
params.push_back(type);
884-
while (succeeded(p.parseOptionalComma())) {
866+
do {
885867
if (succeeded(p.parseOptionalEllipsis())) {
868+
// `...`, which must be the last thing in the list.
886869
isVarArg = true;
887-
return p.parseRParen();
870+
break;
871+
} else {
872+
mlir::Type argType;
873+
if (failed(p.parseType(argType)))
874+
return failure();
875+
params.push_back(argType);
888876
}
889-
if (p.parseType(type))
890-
return mlir::failure();
891-
params.push_back(type);
892-
}
893-
877+
} while (succeeded(p.parseOptionalComma()));
894878
return p.parseRParen();
895879
}
896880

897881
static void printFuncTypeArgs(mlir::AsmPrinter &p,
898882
mlir::ArrayRef<mlir::Type> params,
899883
bool isVarArg) {
884+
p << '(';
900885
llvm::interleaveComma(params, p,
901886
[&p](mlir::Type type) { p.printType(type); });
902887
if (isVarArg) {
@@ -910,45 +895,52 @@ static void printFuncTypeArgs(mlir::AsmPrinter &p,
910895
// Use a custom parser to handle the optional return and argument types without
911896
// an optional anchor.
912897
static mlir::ParseResult parseFuncType(mlir::AsmParser &p,
913-
mlir::Type &optionalReturnTypes,
898+
mlir::Type &optionalReturnType,
914899
llvm::SmallVector<mlir::Type> &params,
915900
bool &isVarArg) {
916-
if (failed(parseFuncTypeReturn(p, optionalReturnTypes)))
901+
if (failed(parseFuncTypeArgs(p, params, isVarArg)))
917902
return failure();
918-
return parseFuncTypeArgs(p, params, isVarArg);
903+
return parseFuncTypeReturn(p, optionalReturnType);
919904
}
920905

921-
static void printFuncType(mlir::AsmPrinter &p, mlir::Type optionalReturnTypes,
906+
static void printFuncType(mlir::AsmPrinter &p, mlir::Type optionalReturnType,
922907
mlir::ArrayRef<mlir::Type> params, bool isVarArg) {
923-
printFuncTypeReturn(p, optionalReturnTypes);
924908
printFuncTypeArgs(p, params, isVarArg);
909+
printFuncTypeReturn(p, optionalReturnType);
925910
}
926911

927-
// Return the actual return type or an explicit !cir.void if the function does
928-
// not return anything
912+
/// Get the C-style return type of the function, which is !cir.void if the
913+
/// function returns nothing and the actual return type otherwise.
929914
mlir::Type FuncType::getReturnType() const {
930-
if (isVoid())
915+
if (hasVoidReturn())
931916
return cir::VoidType::get(getContext());
932-
return static_cast<detail::FuncTypeStorage *>(getImpl())->optionalReturnType;
917+
return getOptionalReturnType();
933918
}
934919

935-
/// Returns the result type of the function as an ArrayRef, enabling better
936-
/// integration with generic MLIR utilities.
920+
/// Get the MLIR-style return type of the function, which is an empty
921+
/// ArrayRef if the function returns nothing and a single-element ArrayRef
922+
/// with the actual return type otherwise.
937923
llvm::ArrayRef<mlir::Type> FuncType::getReturnTypes() const {
938-
if (isVoid())
924+
if (hasVoidReturn())
939925
return {};
940-
return static_cast<detail::FuncTypeStorage *>(getImpl())->optionalReturnType;
941-
}
942-
943-
// Whether the function returns void
944-
bool FuncType::isVoid() const {
945-
auto rt =
946-
static_cast<detail::FuncTypeStorage *>(getImpl())->optionalReturnType;
947-
assert(!rt ||
948-
!mlir::isa<cir::VoidType>(rt) &&
949-
"The return type for a function returning void should be empty "
950-
"instead of a real !cir.void");
951-
return !rt;
926+
// Can't use getOptionalReturnType() here because llvm::ArrayRef hold a
927+
// pointer to its elements and doesn't do lifetime extension. That would
928+
// result in returning a pointer to a temporary that has gone out of scope.
929+
return getImpl()->optionalReturnType;
930+
}
931+
932+
// Does the fuction type return nothing?
933+
bool FuncType::hasVoidReturn() const { return !getOptionalReturnType(); }
934+
935+
mlir::LogicalResult
936+
FuncType::verify(llvm::function_ref<mlir::InFlightDiagnostic()> emitError,
937+
llvm::ArrayRef<mlir::Type> argTypes, mlir::Type returnType,
938+
bool isVarArg) {
939+
if (returnType && mlir::isa<cir::VoidType>(returnType)) {
940+
emitError() << "!cir.func cannot have an explicit 'void' return type";
941+
return mlir::failure();
942+
}
943+
return mlir::success();
952944
}
953945

954946
//===----------------------------------------------------------------------===//

clang/test/CIR/CallConvLowering/AArch64/ptr-fields.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@ int foo(int x) { return x; }
1515
// CIR: %[[#V0:]] = cir.alloca !ty_A, !cir.ptr<!ty_A>, [""] {alignment = 4 : i64}
1616
// CIR: %[[#V1:]] = cir.cast(bitcast, %[[#V0]] : !cir.ptr<!ty_A>), !cir.ptr<!u64i>
1717
// CIR: cir.store %arg0, %[[#V1]] : !u64i, !cir.ptr<!u64i>
18-
// CIR: %[[#V2:]] = cir.get_global @foo : !cir.ptr<!cir.func<!s32i (!s32i)>>
19-
// CIR: %[[#V3:]] = cir.get_member %[[#V0]][0] {name = "f"} : !cir.ptr<!ty_A> -> !cir.ptr<!cir.ptr<!cir.func<!s32i (!s32i)>>>
20-
// CIR: cir.store %[[#V2]], %[[#V3]] : !cir.ptr<!cir.func<!s32i (!s32i)>>, !cir.ptr<!cir.ptr<!cir.func<!s32i (!s32i)>>>
18+
// CIR: %[[#V2:]] = cir.get_global @foo : !cir.ptr<!cir.func<(!s32i) -> !s32i>>
19+
// CIR: %[[#V3:]] = cir.get_member %[[#V0]][0] {name = "f"} : !cir.ptr<!ty_A> -> !cir.ptr<!cir.ptr<!cir.func<(!s32i) -> !s32i>>>
20+
// CIR: cir.store %[[#V2]], %[[#V3]] : !cir.ptr<!cir.func<(!s32i) -> !s32i>>, !cir.ptr<!cir.ptr<!cir.func<(!s32i) -> !s32i>>>
2121
// CIR: cir.return
2222

2323
// LLVM: void @passA(i64 %[[#V0:]])

clang/test/CIR/CallConvLowering/x86_64/fptrs.c

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,10 @@ typedef int (*myfptr)(S);
1010
int foo(S s) { return 42 + s.a; }
1111

1212
// CHECK: cir.func {{.*@bar}}
13-
// CHECK: %[[#V0:]] = cir.alloca !cir.ptr<!cir.func<!s32i (!ty_S)>>, !cir.ptr<!cir.ptr<!cir.func<!s32i (!ty_S)>>>, ["a", init]
14-
// CHECK: %[[#V1:]] = cir.get_global @foo : !cir.ptr<!cir.func<!s32i (!s32i)>>
15-
// CHECK: %[[#V2:]] = cir.cast(bitcast, %[[#V1]] : !cir.ptr<!cir.func<!s32i (!s32i)>>), !cir.ptr<!cir.func<!s32i (!ty_S)>>
16-
// CHECK: cir.store %[[#V2]], %[[#V0]] : !cir.ptr<!cir.func<!s32i (!ty_S)>>, !cir.ptr<!cir.ptr<!cir.func<!s32i (!ty_S)>>>
13+
// CHECK: %[[#V0:]] = cir.alloca !cir.ptr<!cir.func<(!ty_S) -> !s32i>>, !cir.ptr<!cir.ptr<!cir.func<(!ty_S) -> !s32i>>>, ["a", init]
14+
// CHECK: %[[#V1:]] = cir.get_global @foo : !cir.ptr<!cir.func<(!s32i) -> !s32i>>
15+
// CHECK: %[[#V2:]] = cir.cast(bitcast, %[[#V1]] : !cir.ptr<!cir.func<(!s32i) -> !s32i>>), !cir.ptr<!cir.func<(!ty_S) -> !s32i>>
16+
// CHECK: cir.store %[[#V2]], %[[#V0]] : !cir.ptr<!cir.func<(!ty_S) -> !s32i>>, !cir.ptr<!cir.ptr<!cir.func<(!ty_S) -> !s32i>>>
1717
void bar() {
1818
myfptr a = foo;
1919
}
@@ -22,15 +22,15 @@ void bar() {
2222
// CHECK: %[[#V0:]] = cir.alloca !ty_S, !cir.ptr<!ty_S>, [""] {alignment = 4 : i64}
2323
// CHECK: %[[#V1:]] = cir.cast(bitcast, %[[#V0]] : !cir.ptr<!ty_S>), !cir.ptr<!s32i>
2424
// CHECK: cir.store %arg0, %[[#V1]] : !s32i, !cir.ptr<!s32i>
25-
// CHECK: %[[#V2:]] = cir.alloca !cir.ptr<!cir.func<!s32i (!ty_S)>>, !cir.ptr<!cir.ptr<!cir.func<!s32i (!ty_S)>>>, ["a", init]
26-
// CHECK: %[[#V3:]] = cir.get_global @foo : !cir.ptr<!cir.func<!s32i (!s32i)>>
27-
// CHECK: %[[#V4:]] = cir.cast(bitcast, %[[#V3]] : !cir.ptr<!cir.func<!s32i (!s32i)>>), !cir.ptr<!cir.func<!s32i (!ty_S)>>
28-
// CHECK: cir.store %[[#V4]], %[[#V2]] : !cir.ptr<!cir.func<!s32i (!ty_S)>>, !cir.ptr<!cir.ptr<!cir.func<!s32i (!ty_S)>>>
29-
// CHECK: %[[#V5:]] = cir.load %[[#V2]] : !cir.ptr<!cir.ptr<!cir.func<!s32i (!ty_S)>>>, !cir.ptr<!cir.func<!s32i (!ty_S)>>
25+
// CHECK: %[[#V2:]] = cir.alloca !cir.ptr<!cir.func<(!ty_S) -> !s32i>>, !cir.ptr<!cir.ptr<!cir.func<(!ty_S) -> !s32i>>>, ["a", init]
26+
// CHECK: %[[#V3:]] = cir.get_global @foo : !cir.ptr<!cir.func<(!s32i) -> !s32i>>
27+
// CHECK: %[[#V4:]] = cir.cast(bitcast, %[[#V3]] : !cir.ptr<!cir.func<(!s32i) -> !s32i>>), !cir.ptr<!cir.func<(!ty_S) -> !s32i>>
28+
// CHECK: cir.store %[[#V4]], %[[#V2]] : !cir.ptr<!cir.func<(!ty_S) -> !s32i>>, !cir.ptr<!cir.ptr<!cir.func<(!ty_S) -> !s32i>>>
29+
// CHECK: %[[#V5:]] = cir.load %[[#V2]] : !cir.ptr<!cir.ptr<!cir.func<(!ty_S) -> !s32i>>>, !cir.ptr<!cir.func<(!ty_S) -> !s32i>>
3030
// CHECK: %[[#V6:]] = cir.cast(bitcast, %[[#V0]] : !cir.ptr<!ty_S>), !cir.ptr<!s32i>
3131
// CHECK: %[[#V7:]] = cir.load %[[#V6]] : !cir.ptr<!s32i>, !s32i
32-
// CHECK: %[[#V8:]] = cir.cast(bitcast, %[[#V5]] : !cir.ptr<!cir.func<!s32i (!ty_S)>>), !cir.ptr<!cir.func<!s32i (!s32i)>>
33-
// CHECK: %[[#V9:]] = cir.call %[[#V8]](%[[#V7]]) : (!cir.ptr<!cir.func<!s32i (!s32i)>>, !s32i) -> !s32i
32+
// CHECK: %[[#V8:]] = cir.cast(bitcast, %[[#V5]] : !cir.ptr<!cir.func<(!ty_S) -> !s32i>>), !cir.ptr<!cir.func<(!s32i) -> !s32i>>
33+
// CHECK: %[[#V9:]] = cir.call %[[#V8]](%[[#V7]]) : (!cir.ptr<!cir.func<(!s32i) -> !s32i>>, !s32i) -> !s32i
3434

3535
// LLVM: define dso_local void @baz(i32 %0)
3636
// LLVM: %[[#V1:]] = alloca %struct.S, i64 1

clang/test/CIR/CodeGen/coro-task.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -359,19 +359,19 @@ folly::coro::Task<int> go4() {
359359
// CHECK: %17 = cir.alloca !ty_anon2E2_, !cir.ptr<!ty_anon2E2_>, ["ref.tmp1"] {alignment = 1 : i64}
360360

361361
// Get the lambda invoker ptr via `lambda operator folly::coro::Task<int> (*)(int const&)()`
362-
// CHECK: %18 = cir.call @_ZZ3go4vENK3$_0cvPFN5folly4coro4TaskIiEERKiEEv(%17) : (!cir.ptr<!ty_anon2E2_>) -> !cir.ptr<!cir.func<![[IntTask]] (!cir.ptr<!s32i>)>>
363-
// CHECK: %19 = cir.unary(plus, %18) : !cir.ptr<!cir.func<![[IntTask]] (!cir.ptr<!s32i>)>>, !cir.ptr<!cir.func<![[IntTask]] (!cir.ptr<!s32i>)>>
364-
// CHECK: cir.yield %19 : !cir.ptr<!cir.func<![[IntTask]] (!cir.ptr<!s32i>)>>
362+
// CHECK: %18 = cir.call @_ZZ3go4vENK3$_0cvPFN5folly4coro4TaskIiEERKiEEv(%17) : (!cir.ptr<!ty_anon2E2_>) -> !cir.ptr<!cir.func<(!cir.ptr<!s32i>) -> ![[IntTask]]>>
363+
// CHECK: %19 = cir.unary(plus, %18) : !cir.ptr<!cir.func<(!cir.ptr<!s32i>) -> ![[IntTask]]>>, !cir.ptr<!cir.func<(!cir.ptr<!s32i>) -> ![[IntTask]]>>
364+
// CHECK: cir.yield %19 : !cir.ptr<!cir.func<(!cir.ptr<!s32i>) -> ![[IntTask]]>>
365365
// CHECK: }
366-
// CHECK: cir.store %12, %3 : !cir.ptr<!cir.func<![[IntTask]] (!cir.ptr<!s32i>)>>, !cir.ptr<!cir.ptr<!cir.func<![[IntTask]] (!cir.ptr<!s32i>)>>>
366+
// CHECK: cir.store %12, %3 : !cir.ptr<!cir.func<(!cir.ptr<!s32i>) -> ![[IntTask]]>>, !cir.ptr<!cir.ptr<!cir.func<(!cir.ptr<!s32i>) -> ![[IntTask]]>>>
367367
// CHECK: cir.scope {
368368
// CHECK: %17 = cir.alloca !s32i, !cir.ptr<!s32i>, ["ref.tmp2", init] {alignment = 4 : i64}
369-
// CHECK: %18 = cir.load %3 : !cir.ptr<!cir.ptr<!cir.func<![[IntTask]] (!cir.ptr<!s32i>)>>>, !cir.ptr<!cir.func<![[IntTask]] (!cir.ptr<!s32i>)>>
369+
// CHECK: %18 = cir.load %3 : !cir.ptr<!cir.ptr<!cir.func<(!cir.ptr<!s32i>) -> ![[IntTask]]>>>, !cir.ptr<!cir.func<(!cir.ptr<!s32i>) -> ![[IntTask]]>>
370370
// CHECK: %19 = cir.const #cir.int<3> : !s32i
371371
// CHECK: cir.store %19, %17 : !s32i, !cir.ptr<!s32i>
372372

373373
// Call invoker, which calls operator() indirectly.
374-
// CHECK: %20 = cir.call %18(%17) : (!cir.ptr<!cir.func<![[IntTask]] (!cir.ptr<!s32i>)>>, !cir.ptr<!s32i>) -> ![[IntTask]]
374+
// CHECK: %20 = cir.call %18(%17) : (!cir.ptr<!cir.func<(!cir.ptr<!s32i>) -> ![[IntTask]]>>, !cir.ptr<!s32i>) -> ![[IntTask]]
375375
// CHECK: cir.store %20, %4 : ![[IntTask]], !cir.ptr<![[IntTask]]>
376376
// CHECK: }
377377

clang/test/CIR/CodeGen/derived-to-base.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -118,11 +118,11 @@ void vcall(C1 &c1) {
118118
// CHECK: %5 = cir.load %2 : !cir.ptr<!s32i>, !s32i
119119
// CHECK: cir.call @_ZN5buffyC2ERKS_(%3, %1) : (!cir.ptr<!ty_buffy>, !cir.ptr<!ty_buffy>) -> ()
120120
// CHECK: %6 = cir.load %3 : !cir.ptr<!ty_buffy>, !ty_buffy
121-
// CHECK: %7 = cir.cast(bitcast, %4 : !cir.ptr<!ty_C1_>), !cir.ptr<!cir.ptr<!cir.ptr<!cir.func<!s32i (!cir.ptr<!ty_C1_>, !s32i, !ty_buffy)>>>>
122-
// CHECK: %8 = cir.load %7 : !cir.ptr<!cir.ptr<!cir.ptr<!cir.func<!s32i (!cir.ptr<!ty_C1_>, !s32i, !ty_buffy)>>>>, !cir.ptr<!cir.ptr<!cir.func<!s32i (!cir.ptr<!ty_C1_>, !s32i, !ty_buffy)>>>
123-
// CHECK: %9 = cir.vtable.address_point( %8 : !cir.ptr<!cir.ptr<!cir.func<!s32i (!cir.ptr<!ty_C1_>, !s32i, !ty_buffy)>>>, vtable_index = 0, address_point_index = 2) : !cir.ptr<!cir.ptr<!cir.func<!s32i (!cir.ptr<!ty_C1_>, !s32i, !ty_buffy)>>>
124-
// CHECK: %10 = cir.load align(8) %9 : !cir.ptr<!cir.ptr<!cir.func<!s32i (!cir.ptr<!ty_C1_>, !s32i, !ty_buffy)>>>, !cir.ptr<!cir.func<!s32i (!cir.ptr<!ty_C1_>, !s32i, !ty_buffy)>>
125-
// CHECK: %11 = cir.call %10(%4, %5, %6) : (!cir.ptr<!cir.func<!s32i (!cir.ptr<!ty_C1_>, !s32i, !ty_buffy)>>, !cir.ptr<!ty_C1_>, !s32i, !ty_buffy) -> !s32i
121+
// CHECK: %7 = cir.cast(bitcast, %4 : !cir.ptr<!ty_C1_>), !cir.ptr<!cir.ptr<!cir.ptr<!cir.func<(!cir.ptr<!ty_C1_>, !s32i, !ty_buffy) -> !s32i>>>>
122+
// CHECK: %8 = cir.load %7 : !cir.ptr<!cir.ptr<!cir.ptr<!cir.func<(!cir.ptr<!ty_C1_>, !s32i, !ty_buffy) -> !s32i>>>>, !cir.ptr<!cir.ptr<!cir.func<(!cir.ptr<!ty_C1_>, !s32i, !ty_buffy) -> !s32i>>>
123+
// CHECK: %9 = cir.vtable.address_point( %8 : !cir.ptr<!cir.ptr<!cir.func<(!cir.ptr<!ty_C1_>, !s32i, !ty_buffy) -> !s32i>>>, vtable_index = 0, address_point_index = 2) : !cir.ptr<!cir.ptr<!cir.func<(!cir.ptr<!ty_C1_>, !s32i, !ty_buffy) -> !s32i>>>
124+
// CHECK: %10 = cir.load align(8) %9 : !cir.ptr<!cir.ptr<!cir.func<(!cir.ptr<!ty_C1_>, !s32i, !ty_buffy) -> !s32i>>>, !cir.ptr<!cir.func<(!cir.ptr<!ty_C1_>, !s32i, !ty_buffy) -> !s32i>>
125+
// CHECK: %11 = cir.call %10(%4, %5, %6) : (!cir.ptr<!cir.func<(!cir.ptr<!ty_C1_>, !s32i, !ty_buffy) -> !s32i>>, !cir.ptr<!ty_C1_>, !s32i, !ty_buffy) -> !s32i
126126
// CHECK: cir.return
127127
// CHECK: }
128128

clang/test/CIR/CodeGen/dtors.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ class B : public A
3636
};
3737

3838
// Class A
39-
// CHECK: ![[ClassA:ty_.*]] = !cir.struct<class "A" {!cir.ptr<!cir.ptr<!cir.func<!u32i ()>>>} #cir.record.decl.ast>
39+
// CHECK: ![[ClassA:ty_.*]] = !cir.struct<class "A" {!cir.ptr<!cir.ptr<!cir.func<() -> !u32i>>>} #cir.record.decl.ast>
4040

4141
// Class B
4242
// CHECK: ![[ClassB:ty_.*]] = !cir.struct<class "B" {![[ClassA]]}>

0 commit comments

Comments
 (0)