Skip to content

Commit af9a39d

Browse files
authored
[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 253fb9a commit af9a39d

31 files changed

+221
-222
lines changed

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3888,7 +3888,7 @@ def CallOp : CIR_CallOp<"call", [NoRegionArguments]> {
38883888
CArg<"mlir::UnitAttr", "{}">:$exception), [{
38893889
$_state.addOperands(ValueRange{ind_target});
38903890
$_state.addOperands(operands);
3891-
if (!fn_type.isVoid())
3891+
if (!fn_type.hasVoidReturn())
38923892
$_state.addTypes(fn_type.getReturnType());
38933893
$_state.addAttribute("calling_conv",
38943894
CallingConvAttr::get($_builder.getContext(), callingConv));
@@ -3974,7 +3974,7 @@ def TryCallOp : CIR_CallOp<"try_call",
39743974
finalCallOperands.append(operands.begin(), operands.end());
39753975
$_state.addOperands(finalCallOperands);
39763976

3977-
if (!fn_type.isVoid())
3977+
if (!fn_type.hasVoidReturn())
39783978
$_state.addTypes(fn_type.getReturnType());
39793979

39803980
$_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
@@ -2739,15 +2739,15 @@ verifyCallCommInSymbolUses(Operation *op, SymbolTableCollection &symbolTable) {
27392739
<< stringifyCallingConv(callIf.getCallingConv());
27402740

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

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

27492749
// Parent function and return value types must match.
2750-
if (!fnType.isVoid() &&
2750+
if (!fnType.hasVoidReturn() &&
27512751
op->getResultTypes().front() != fnType.getReturnType()) {
27522752
return op->emitOpError("result type mismatch: expected ")
27532753
<< 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
@@ -937,66 +937,51 @@ FuncType FuncType::clone(TypeRange inputs, TypeRange results) const {
937937
// type.
938938
static mlir::ParseResult parseFuncTypeReturn(mlir::AsmParser &p,
939939
mlir::Type &optionalReturnType) {
940-
if (succeeded(p.parseOptionalLParen())) {
941-
// If we have already a '(', the function has no return type
942-
optionalReturnType = {};
943-
return mlir::success();
940+
if (succeeded(p.parseOptionalArrow())) {
941+
// `->` found. It must be followed by the return type.
942+
return p.parseType(optionalReturnType);
944943
}
945-
mlir::Type type;
946-
if (p.parseType(type))
947-
return mlir::failure();
948-
if (isa<cir::VoidType>(type))
949-
// An explicit !cir.void means also no return type.
950-
optionalReturnType = {};
951-
else
952-
// Otherwise use the actual type.
953-
optionalReturnType = type;
954-
return p.parseLParen();
944+
// Function has `void` return in C++, no return in MLIR.
945+
optionalReturnType = {};
946+
return success();
955947
}
956948

957949
// A special pretty-printer for function returning or not a result.
958950
static void printFuncTypeReturn(mlir::AsmPrinter &p,
959951
mlir::Type optionalReturnType) {
960952
if (optionalReturnType)
961-
p << optionalReturnType << ' ';
962-
p << '(';
953+
p << " -> " << optionalReturnType;
963954
}
964955

965956
static mlir::ParseResult
966957
parseFuncTypeArgs(mlir::AsmParser &p, llvm::SmallVector<mlir::Type> &params,
967958
bool &isVarArg) {
968959
isVarArg = false;
969-
// `(` `)`
970-
if (succeeded(p.parseOptionalRParen()))
960+
if (failed(p.parseLParen()))
961+
return failure();
962+
if (succeeded(p.parseOptionalRParen())) {
963+
// `()` empty argument list
971964
return mlir::success();
972-
973-
// `(` `...` `)`
974-
if (succeeded(p.parseOptionalEllipsis())) {
975-
isVarArg = true;
976-
return p.parseRParen();
977965
}
978-
979-
// type (`,` type)* (`,` `...`)?
980-
mlir::Type type;
981-
if (p.parseType(type))
982-
return mlir::failure();
983-
params.push_back(type);
984-
while (succeeded(p.parseOptionalComma())) {
966+
do {
985967
if (succeeded(p.parseOptionalEllipsis())) {
968+
// `...`, which must be the last thing in the list.
986969
isVarArg = true;
987-
return p.parseRParen();
970+
break;
971+
} else {
972+
mlir::Type argType;
973+
if (failed(p.parseType(argType)))
974+
return failure();
975+
params.push_back(argType);
988976
}
989-
if (p.parseType(type))
990-
return mlir::failure();
991-
params.push_back(type);
992-
}
993-
977+
} while (succeeded(p.parseOptionalComma()));
994978
return p.parseRParen();
995979
}
996980

997981
static void printFuncTypeArgs(mlir::AsmPrinter &p,
998982
mlir::ArrayRef<mlir::Type> params,
999983
bool isVarArg) {
984+
p << '(';
1000985
llvm::interleaveComma(params, p,
1001986
[&p](mlir::Type type) { p.printType(type); });
1002987
if (isVarArg) {
@@ -1010,45 +995,52 @@ static void printFuncTypeArgs(mlir::AsmPrinter &p,
1010995
// Use a custom parser to handle the optional return and argument types without
1011996
// an optional anchor.
1012997
static mlir::ParseResult parseFuncType(mlir::AsmParser &p,
1013-
mlir::Type &optionalReturnTypes,
998+
mlir::Type &optionalReturnType,
1014999
llvm::SmallVector<mlir::Type> &params,
10151000
bool &isVarArg) {
1016-
if (failed(parseFuncTypeReturn(p, optionalReturnTypes)))
1001+
if (failed(parseFuncTypeArgs(p, params, isVarArg)))
10171002
return failure();
1018-
return parseFuncTypeArgs(p, params, isVarArg);
1003+
return parseFuncTypeReturn(p, optionalReturnType);
10191004
}
10201005

1021-
static void printFuncType(mlir::AsmPrinter &p, mlir::Type optionalReturnTypes,
1006+
static void printFuncType(mlir::AsmPrinter &p, mlir::Type optionalReturnType,
10221007
mlir::ArrayRef<mlir::Type> params, bool isVarArg) {
1023-
printFuncTypeReturn(p, optionalReturnTypes);
10241008
printFuncTypeArgs(p, params, isVarArg);
1009+
printFuncTypeReturn(p, optionalReturnType);
10251010
}
10261011

1027-
// Return the actual return type or an explicit !cir.void if the function does
1028-
// not return anything
1012+
/// Get the C-style return type of the function, which is !cir.void if the
1013+
/// function returns nothing and the actual return type otherwise.
10291014
mlir::Type FuncType::getReturnType() const {
1030-
if (isVoid())
1015+
if (hasVoidReturn())
10311016
return cir::VoidType::get(getContext());
1032-
return static_cast<detail::FuncTypeStorage *>(getImpl())->optionalReturnType;
1017+
return getOptionalReturnType();
10331018
}
10341019

1035-
/// Returns the result type of the function as an ArrayRef, enabling better
1036-
/// integration with generic MLIR utilities.
1020+
/// Get the MLIR-style return type of the function, which is an empty
1021+
/// ArrayRef if the function returns nothing and a single-element ArrayRef
1022+
/// with the actual return type otherwise.
10371023
llvm::ArrayRef<mlir::Type> FuncType::getReturnTypes() const {
1038-
if (isVoid())
1024+
if (hasVoidReturn())
10391025
return {};
1040-
return static_cast<detail::FuncTypeStorage *>(getImpl())->optionalReturnType;
1041-
}
1042-
1043-
// Whether the function returns void
1044-
bool FuncType::isVoid() const {
1045-
auto rt =
1046-
static_cast<detail::FuncTypeStorage *>(getImpl())->optionalReturnType;
1047-
assert(!rt ||
1048-
!mlir::isa<cir::VoidType>(rt) &&
1049-
"The return type for a function returning void should be empty "
1050-
"instead of a real !cir.void");
1051-
return !rt;
1026+
// Can't use getOptionalReturnType() here because llvm::ArrayRef hold a
1027+
// pointer to its elements and doesn't do lifetime extension. That would
1028+
// result in returning a pointer to a temporary that has gone out of scope.
1029+
return getImpl()->optionalReturnType;
1030+
}
1031+
1032+
// Does the fuction type return nothing?
1033+
bool FuncType::hasVoidReturn() const { return !getOptionalReturnType(); }
1034+
1035+
mlir::LogicalResult
1036+
FuncType::verify(llvm::function_ref<mlir::InFlightDiagnostic()> emitError,
1037+
llvm::ArrayRef<mlir::Type> argTypes, mlir::Type returnType,
1038+
bool isVarArg) {
1039+
if (returnType && mlir::isa<cir::VoidType>(returnType)) {
1040+
emitError() << "!cir.func cannot have an explicit 'void' return type";
1041+
return mlir::failure();
1042+
}
1043+
return mlir::success();
10521044
}
10531045

10541046
//===----------------------------------------------------------------------===//

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)