Skip to content

Commit 489de07

Browse files
keryelllanza
authored andcommitted
[CIR] Remove return !cir.void from IR and textual representation (#1249)
C/C++ functions returning void had an explicit !cir.void return type while not having any returned value, which was breaking a lot of MLIR invariants when the CIR dialect is used in a greater context, for example with the inliner. Now, a C/C++ function returning void has no return type and no return values, which does not break the MLIR invariant about the same number of return types and returned values. This change does not keeps the same parsing/pretty-printed syntax as before for compatibility like in #1203 because it requires some new features from the MLIR parser infrastructure itself, which is not great. This uses an optional type for function return type. The default MLIR parser for optional parameters requires an optional anchor we do not have in the syntax, so use a custom FuncType parser to handle the optional return type.
1 parent 4e37eb7 commit 489de07

File tree

15 files changed

+182
-68
lines changed

15 files changed

+182
-68
lines changed

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

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3474,8 +3474,6 @@ def FuncOp : CIR_Op<"func", [
34743474
/// Returns the results types that the callable region produces when
34753475
/// executed.
34763476
llvm::ArrayRef<mlir::Type> getCallableResults() {
3477-
if (::llvm::isa<cir::VoidType>(getFunctionType().getReturnType()))
3478-
return {};
34793477
return getFunctionType().getReturnTypes();
34803478
}
34813479

@@ -3492,10 +3490,15 @@ def FuncOp : CIR_Op<"func", [
34923490
}
34933491

34943492
/// Returns the argument types of this function.
3495-
llvm::ArrayRef<mlir::Type> getArgumentTypes() { return getFunctionType().getInputs(); }
3493+
llvm::ArrayRef<mlir::Type> getArgumentTypes() {
3494+
return getFunctionType().getInputs();
3495+
}
34963496

3497-
/// Returns the result types of this function.
3498-
llvm::ArrayRef<mlir::Type> getResultTypes() { return getFunctionType().getReturnTypes(); }
3497+
/// Returns 0 or 1 result type of this function (0 in the case of a function
3498+
/// returing void)
3499+
llvm::ArrayRef<mlir::Type> getResultTypes() {
3500+
return getFunctionType().getReturnTypes();
3501+
}
34993502

35003503
/// Hook for OpTrait::FunctionOpInterfaceTrait, called after verifying that
35013504
/// the 'type' attribute is present and checks if it holds a function type.

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

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -372,29 +372,38 @@ def CIR_VectorType : CIR_Type<"Vector", "vector",
372372
def CIR_FuncType : CIR_Type<"Func", "func"> {
373373
let summary = "CIR function type";
374374
let description = [{
375-
The `!cir.func` is a function type. It consists of a single return type, a
376-
list of parameter types and can optionally be variadic.
375+
The `!cir.func` is a function type. It consists of an optional return type,
376+
a list of parameter types and can optionally be variadic.
377377

378378
Example:
379379

380380
```mlir
381+
!cir.func<()>
381382
!cir.func<!bool ()>
383+
!cir.func<(!s8i, !s8i)>
382384
!cir.func<!s32i (!s8i, !s8i)>
383385
!cir.func<!s32i (!s32i, ...)>
384386
```
385387
}];
386388

387-
let parameters = (ins ArrayRefParameter<"mlir::Type">:$inputs, "mlir::Type":$returnType,
389+
let parameters = (ins ArrayRefParameter<"mlir::Type">:$inputs,
390+
"mlir::Type":$optionalReturnType,
388391
"bool":$varArg);
392+
// Use a custom parser to handle the optional return and argument types
393+
// without an optional anchor.
389394
let assemblyFormat = [{
390-
`<` $returnType ` ` `(` custom<FuncTypeArgs>($inputs, $varArg) `>`
395+
`<` custom<FuncType>($optionalReturnType, $inputs, $varArg) `>`
391396
}];
392397

393398
let builders = [
399+
// Construct with an actual return type or explicit !cir.void
394400
TypeBuilderWithInferredContext<(ins
395401
"llvm::ArrayRef<mlir::Type>":$inputs, "mlir::Type":$returnType,
396402
CArg<"bool", "false">:$isVarArg), [{
397-
return $_get(returnType.getContext(), inputs, returnType, isVarArg);
403+
return $_get(returnType.getContext(), inputs,
404+
mlir::isa<cir::VoidType>(returnType) ? nullptr
405+
: returnType,
406+
isVarArg);
398407
}]>
399408
];
400409

@@ -408,11 +417,15 @@ def CIR_FuncType : CIR_Type<"Func", "func"> {
408417
/// Returns the number of arguments to the function.
409418
unsigned getNumInputs() const { return getInputs().size(); }
410419

420+
/// Returns the result type of the function as an actual return type or
421+
/// explicit !cir.void
422+
mlir::Type getReturnType() const;
423+
411424
/// Returns the result type of the function as an ArrayRef, enabling better
412425
/// integration with generic MLIR utilities.
413426
llvm::ArrayRef<mlir::Type> getReturnTypes() const;
414427

415-
/// Returns whether the function is returns void.
428+
/// Returns whether the function returns void.
416429
bool isVoid() const;
417430

418431
/// Returns a clone of this function type with the given argument

clang/lib/CIR/CodeGen/CIRGenTypes.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -271,7 +271,7 @@ mlir::Type CIRGenTypes::convertFunctionTypeInternal(QualType QFT) {
271271
assert(QFT.isCanonical());
272272
const Type *Ty = QFT.getTypePtr();
273273
const FunctionType *FT = cast<FunctionType>(QFT.getTypePtr());
274-
// First, check whether we can build the full fucntion type. If the function
274+
// First, check whether we can build the full function type. If the function
275275
// type depends on an incomplete type (e.g. a struct or enum), we cannot lower
276276
// the function type.
277277
assert(isFuncTypeConvertible(FT) && "NYI");

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

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2490,13 +2490,8 @@ void cir::FuncOp::print(OpAsmPrinter &p) {
24902490
p.printSymbolName(getSymName());
24912491
auto fnType = getFunctionType();
24922492
llvm::SmallVector<Type, 1> resultTypes;
2493-
if (!fnType.isVoid())
2494-
function_interface_impl::printFunctionSignature(
2495-
p, *this, fnType.getInputs(), fnType.isVarArg(),
2496-
fnType.getReturnTypes());
2497-
else
2498-
function_interface_impl::printFunctionSignature(
2499-
p, *this, fnType.getInputs(), fnType.isVarArg(), {});
2493+
function_interface_impl::printFunctionSignature(
2494+
p, *this, fnType.getInputs(), fnType.isVarArg(), fnType.getReturnTypes());
25002495

25012496
if (mlir::ArrayAttr annotations = getAnnotationsAttr()) {
25022497
p << ' ';
@@ -2565,6 +2560,11 @@ LogicalResult cir::FuncOp::verifyType() {
25652560
if (!getNoProto() && type.isVarArg() && type.getNumInputs() == 0)
25662561
return emitError()
25672562
<< "prototyped function must have at least one non-variadic input";
2563+
if (auto rt = type.getReturnTypes();
2564+
!rt.empty() && mlir::isa<cir::VoidType>(rt.front()))
2565+
return emitOpError("The return type for a function returning void should "
2566+
"be empty instead of an explicit !cir.void");
2567+
25682568
return success();
25692569
}
25702570

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

Lines changed: 82 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
#include "llvm/ADT/TypeSwitch.h"
3434
#include "llvm/Support/ErrorHandling.h"
3535
#include "llvm/Support/MathExtras.h"
36+
#include <cassert>
3637
#include <optional>
3738

3839
using cir::MissingFeatures;
@@ -41,12 +42,13 @@ using cir::MissingFeatures;
4142
// CIR Custom Parser/Printer Signatures
4243
//===----------------------------------------------------------------------===//
4344

44-
static mlir::ParseResult
45-
parseFuncTypeArgs(mlir::AsmParser &p, llvm::SmallVector<mlir::Type> &params,
46-
bool &isVarArg);
47-
static void printFuncTypeArgs(mlir::AsmPrinter &p,
48-
mlir::ArrayRef<mlir::Type> params, bool isVarArg);
45+
static mlir::ParseResult parseFuncType(mlir::AsmParser &p,
46+
mlir::Type &optionalReturnTypes,
47+
llvm::SmallVector<mlir::Type> &params,
48+
bool &isVarArg);
4949

50+
static void printFuncType(mlir::AsmPrinter &p, mlir::Type optionalReturnTypes,
51+
mlir::ArrayRef<mlir::Type> params, bool isVarArg);
5052
static mlir::ParseResult parsePointerAddrSpace(mlir::AsmParser &p,
5153
mlir::Attribute &addrSpaceAttr);
5254
static void printPointerAddrSpace(mlir::AsmPrinter &p,
@@ -813,9 +815,38 @@ FuncType FuncType::clone(TypeRange inputs, TypeRange results) const {
813815
return get(llvm::to_vector(inputs), results[0], isVarArg());
814816
}
815817

816-
mlir::ParseResult parseFuncTypeArgs(mlir::AsmParser &p,
817-
llvm::SmallVector<mlir::Type> &params,
818-
bool &isVarArg) {
818+
// A special parser is needed for function returning void to handle the missing
819+
// type.
820+
static mlir::ParseResult parseFuncTypeReturn(mlir::AsmParser &p,
821+
mlir::Type &optionalReturnType) {
822+
if (succeeded(p.parseOptionalLParen())) {
823+
// If we have already a '(', the function has no return type
824+
optionalReturnType = {};
825+
return mlir::success();
826+
}
827+
mlir::Type type;
828+
if (p.parseType(type))
829+
return mlir::failure();
830+
if (isa<cir::VoidType>(type))
831+
// An explicit !cir.void means also no return type.
832+
optionalReturnType = {};
833+
else
834+
// Otherwise use the actual type.
835+
optionalReturnType = type;
836+
return p.parseLParen();
837+
}
838+
839+
// A special pretty-printer for function returning or not a result.
840+
static void printFuncTypeReturn(mlir::AsmPrinter &p,
841+
mlir::Type optionalReturnType) {
842+
if (optionalReturnType)
843+
p << optionalReturnType << ' ';
844+
p << '(';
845+
}
846+
847+
static mlir::ParseResult
848+
parseFuncTypeArgs(mlir::AsmParser &p, llvm::SmallVector<mlir::Type> &params,
849+
bool &isVarArg) {
819850
isVarArg = false;
820851
// `(` `)`
821852
if (succeeded(p.parseOptionalRParen()))
@@ -845,8 +876,9 @@ mlir::ParseResult parseFuncTypeArgs(mlir::AsmParser &p,
845876
return p.parseRParen();
846877
}
847878

848-
void printFuncTypeArgs(mlir::AsmPrinter &p, mlir::ArrayRef<mlir::Type> params,
849-
bool isVarArg) {
879+
static void printFuncTypeArgs(mlir::AsmPrinter &p,
880+
mlir::ArrayRef<mlir::Type> params,
881+
bool isVarArg) {
850882
llvm::interleaveComma(params, p,
851883
[&p](mlir::Type type) { p.printType(type); });
852884
if (isVarArg) {
@@ -857,11 +889,49 @@ void printFuncTypeArgs(mlir::AsmPrinter &p, mlir::ArrayRef<mlir::Type> params,
857889
p << ')';
858890
}
859891

892+
// Use a custom parser to handle the optional return and argument types without
893+
// an optional anchor.
894+
static mlir::ParseResult parseFuncType(mlir::AsmParser &p,
895+
mlir::Type &optionalReturnTypes,
896+
llvm::SmallVector<mlir::Type> &params,
897+
bool &isVarArg) {
898+
if (failed(parseFuncTypeReturn(p, optionalReturnTypes)))
899+
return failure();
900+
return parseFuncTypeArgs(p, params, isVarArg);
901+
}
902+
903+
static void printFuncType(mlir::AsmPrinter &p, mlir::Type optionalReturnTypes,
904+
mlir::ArrayRef<mlir::Type> params, bool isVarArg) {
905+
printFuncTypeReturn(p, optionalReturnTypes);
906+
printFuncTypeArgs(p, params, isVarArg);
907+
}
908+
909+
// Return the actual return type or an explicit !cir.void if the function does
910+
// not return anything
911+
mlir::Type FuncType::getReturnType() const {
912+
if (isVoid())
913+
return cir::VoidType::get(getContext());
914+
return static_cast<detail::FuncTypeStorage *>(getImpl())->optionalReturnType;
915+
}
916+
917+
/// Returns the result type of the function as an ArrayRef, enabling better
918+
/// integration with generic MLIR utilities.
860919
llvm::ArrayRef<mlir::Type> FuncType::getReturnTypes() const {
861-
return static_cast<detail::FuncTypeStorage *>(getImpl())->returnType;
920+
if (isVoid())
921+
return {};
922+
return static_cast<detail::FuncTypeStorage *>(getImpl())->optionalReturnType;
862923
}
863924

864-
bool FuncType::isVoid() const { return mlir::isa<VoidType>(getReturnType()); }
925+
// Whether the function returns void
926+
bool FuncType::isVoid() const {
927+
auto rt =
928+
static_cast<detail::FuncTypeStorage *>(getImpl())->optionalReturnType;
929+
assert(!rt ||
930+
!mlir::isa<cir::VoidType>(rt) &&
931+
"The return type for a function returning void should be empty "
932+
"instead of a real !cir.void");
933+
return !rt;
934+
}
865935

866936
//===----------------------------------------------------------------------===//
867937
// MethodType Definitions

clang/lib/CIR/Dialect/Transforms/TargetLowering/LowerTypes.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ FuncType LowerTypes::getFunctionType(const LowerFunctionInfo &FI) {
109109
}
110110
}
111111

112-
return FuncType::get(getMLIRContext(), ArgTypes, resultType, FI.isVariadic());
112+
return FuncType::get(ArgTypes, resultType, FI.isVariadic());
113113
}
114114

115115
/// Convert a CIR type to its ABI-specific default form.

clang/test/CIR/CodeGen/fun-ptr.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,10 +55,10 @@ int foo(Data* d) {
5555
return f(d);
5656
}
5757

58-
// CIR: cir.func private {{@.*test.*}}() -> !cir.ptr<!cir.func<!void ()>>
58+
// CIR: cir.func private {{@.*test.*}}() -> !cir.ptr<!cir.func<()>>
5959
// CIR: cir.func {{@.*bar.*}}()
60-
// CIR: [[RET:%.*]] = cir.call {{@.*test.*}}() : () -> !cir.ptr<!cir.func<!void ()>>
61-
// CIR: cir.call [[RET]]() : (!cir.ptr<!cir.func<!void ()>>) -> ()
60+
// CIR: [[RET:%.*]] = cir.call {{@.*test.*}}() : () -> !cir.ptr<!cir.func<()>>
61+
// CIR: cir.call [[RET]]() : (!cir.ptr<!cir.func<()>>) -> ()
6262
// CIR: cir.return
6363

6464
// LLVM: declare ptr {{@.*test.*}}()

clang/test/CIR/CodeGen/gnu-extension.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,5 @@ void bar(void) {
1515
}
1616

1717
//CHECK: cir.func @bar()
18-
//CHECK: {{.*}} = cir.get_global @bar : !cir.ptr<!cir.func<!void ()>>
18+
//CHECK: {{.*}} = cir.get_global @bar : !cir.ptr<!cir.func<()>>
1919
//CHECK: cir.return

clang/test/CIR/CodeGen/member-init-struct.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ C a, b(x), c(0, 2);
3434
// CHECK: %[[VAL_8:.*]] = cir.get_member %[[VAL_2]][2] {name = "d"} : !cir.ptr<!ty_C> -> !cir.ptr<!cir.array<!s32i x 10>>
3535
// CHECK: %[[VAL_9:.*]] = cir.const {{.*}} : !cir.array<!s32i x 10>
3636
// CHECK: cir.store %[[VAL_9]], %[[VAL_8]] : !cir.array<!s32i x 10>, !cir.ptr<!cir.array<!s32i x 10>>
37-
// CHECK: %[[VAL_10:.*]] = cir.get_member %[[VAL_2]][4] {name = "e"} : !cir.ptr<!ty_C> -> !cir.ptr<!cir.method<!cir.func<!void ()> in !ty_C>>
38-
// CHECK: %[[VAL_11:.*]] = cir.const #cir.method<null> : !cir.method<!cir.func<!void ()> in !ty_C>
39-
// CHECK: cir.store %[[VAL_11]], %[[VAL_10]] : !cir.method<!cir.func<!void ()> in !ty_C>, !cir.ptr<!cir.method<!cir.func<!void ()> in !ty_C>>
40-
// CHECK: cir.return
37+
// CHECK: %[[VAL_10:.*]] = cir.get_member %[[VAL_2]][4] {name = "e"} : !cir.ptr<!ty_C> -> !cir.ptr<!cir.method<!cir.func<()> in !ty_C>>
38+
// CHECK: %[[VAL_11:.*]] = cir.const #cir.method<null> : !cir.method<!cir.func<()> in !ty_C>
39+
// CHECK: cir.store %[[VAL_11]], %[[VAL_10]] : !cir.method<!cir.func<()> in !ty_C>, !cir.ptr<!cir.method<!cir.func<()> in !ty_C>>
40+
// CHECK: cir.return

clang/test/CIR/CodeGen/multi-vtable.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,9 +75,9 @@ int main() {
7575

7676
// CIR: cir.func @main() -> !s32i extra(#fn_attr) {
7777

78-
// CIR: %{{[0-9]+}} = cir.vtable.address_point( %{{[0-9]+}} : !cir.ptr<!cir.ptr<!cir.func<!void (!cir.ptr<!ty_Mother>)>>>, vtable_index = 0, address_point_index = 0) : !cir.ptr<!cir.ptr<!cir.func<!void (!cir.ptr<!ty_Mother>)>>>
78+
// CIR: %{{[0-9]+}} = cir.vtable.address_point( %{{[0-9]+}} : !cir.ptr<!cir.ptr<!cir.func<(!cir.ptr<!ty_Mother>)>>>, vtable_index = 0, address_point_index = 0) : !cir.ptr<!cir.ptr<!cir.func<(!cir.ptr<!ty_Mother>)>>>
7979

80-
// CIR: %{{[0-9]+}} = cir.vtable.address_point( %{{[0-9]+}} : !cir.ptr<!cir.ptr<!cir.func<!void (!cir.ptr<!ty_Child>)>>>, vtable_index = 0, address_point_index = 0) : !cir.ptr<!cir.ptr<!cir.func<!void (!cir.ptr<!ty_Child>)>>>
80+
// CIR: %{{[0-9]+}} = cir.vtable.address_point( %{{[0-9]+}} : !cir.ptr<!cir.ptr<!cir.func<(!cir.ptr<!ty_Child>)>>>, vtable_index = 0, address_point_index = 0) : !cir.ptr<!cir.ptr<!cir.func<(!cir.ptr<!ty_Child>)>>>
8181

8282
// CIR: }
8383

clang/test/CIR/CodeGen/no-proto-fun-ptr.c

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@ void check_noproto_ptr() {
77
}
88

99
// CHECK: cir.func no_proto @check_noproto_ptr()
10-
// CHECK: [[ALLOC:%.*]] = cir.alloca !cir.ptr<!cir.func<!void ()>>, !cir.ptr<!cir.ptr<!cir.func<!void ()>>>, ["fun", init] {alignment = 8 : i64}
11-
// CHECK: [[GGO:%.*]] = cir.get_global @empty : !cir.ptr<!cir.func<!void ()>>
12-
// CHECK: cir.store [[GGO]], [[ALLOC]] : !cir.ptr<!cir.func<!void ()>>, !cir.ptr<!cir.ptr<!cir.func<!void ()>>>
10+
// CHECK: [[ALLOC:%.*]] = cir.alloca !cir.ptr<!cir.func<()>>, !cir.ptr<!cir.ptr<!cir.func<()>>>, ["fun", init] {alignment = 8 : i64}
11+
// CHECK: [[GGO:%.*]] = cir.get_global @empty : !cir.ptr<!cir.func<()>>
12+
// CHECK: cir.store [[GGO]], [[ALLOC]] : !cir.ptr<!cir.func<()>>, !cir.ptr<!cir.ptr<!cir.func<()>>>
1313
// CHECK: cir.return
1414

1515
void empty(void) {}
@@ -20,8 +20,8 @@ void buz() {
2020
}
2121

2222
// CHECK: cir.func no_proto @buz()
23-
// CHECK: [[FNPTR_ALLOC:%.*]] = cir.alloca !cir.ptr<!cir.func<!void (...)>>, !cir.ptr<!cir.ptr<!cir.func<!void (...)>>>, ["func"] {alignment = 8 : i64}
24-
// CHECK: [[FNPTR:%.*]] = cir.load deref [[FNPTR_ALLOC]] : !cir.ptr<!cir.ptr<!cir.func<!void (...)>>>, !cir.ptr<!cir.func<!void (...)>>
25-
// CHECK: [[CAST:%.*]] = cir.cast(bitcast, %1 : !cir.ptr<!cir.func<!void (...)>>), !cir.ptr<!cir.func<!void ()>>
26-
// CHECK: cir.call [[CAST]]() : (!cir.ptr<!cir.func<!void ()>>) -> ()
23+
// CHECK: [[FNPTR_ALLOC:%.*]] = cir.alloca !cir.ptr<!cir.func<(...)>>, !cir.ptr<!cir.ptr<!cir.func<(...)>>>, ["func"] {alignment = 8 : i64}
24+
// CHECK: [[FNPTR:%.*]] = cir.load deref [[FNPTR_ALLOC]] : !cir.ptr<!cir.ptr<!cir.func<(...)>>>, !cir.ptr<!cir.func<(...)>>
25+
// CHECK: [[CAST:%.*]] = cir.cast(bitcast, %1 : !cir.ptr<!cir.func<(...)>>), !cir.ptr<!cir.func<()>>
26+
// CHECK: cir.call [[CAST]]() : (!cir.ptr<!cir.func<()>>) -> ()
2727
// CHECK: cir.return

clang/test/CIR/CodeGen/pointer-arith-ext.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,9 @@ void *f4_1(void *a, int b) { return (a -= b); }
5050

5151
FP f5(FP a, int b) { return a + b; }
5252
// CIR-LABEL: f5
53-
// CIR: %[[PTR:.*]] = cir.load {{.*}} : !cir.ptr<!cir.ptr<!cir.func<!void ()>>>, !cir.ptr<!cir.func<!void ()>>
53+
// CIR: %[[PTR:.*]] = cir.load {{.*}} : !cir.ptr<!cir.ptr<!cir.func<()>>>, !cir.ptr<!cir.func<()>>
5454
// CIR: %[[STRIDE:.*]] = cir.load {{.*}} : !cir.ptr<!s32i>, !s32i
55-
// CIR: cir.ptr_stride(%[[PTR]] : !cir.ptr<!cir.func<!void ()>>, %[[STRIDE]] : !s32i)
55+
// CIR: cir.ptr_stride(%[[PTR]] : !cir.ptr<!cir.func<()>>, %[[STRIDE]] : !s32i)
5656

5757
// LLVM-LABEL: f5
5858
// LLVM: %[[PTR:.*]] = load ptr, ptr {{.*}}, align 8
@@ -67,10 +67,10 @@ FP f6_1(int a, FP b) { return (a += b); }
6767

6868
FP f7(FP a, int b) { return a - b; }
6969
// CIR-LABEL: f7
70-
// CIR: %[[PTR:.*]] = cir.load {{.*}} : !cir.ptr<!cir.ptr<!cir.func<!void ()>>>, !cir.ptr<!cir.func<!void ()>>
70+
// CIR: %[[PTR:.*]] = cir.load {{.*}} : !cir.ptr<!cir.ptr<!cir.func<()>>>, !cir.ptr<!cir.func<()>>
7171
// CIR: %[[STRIDE:.*]] = cir.load {{.*}} : !cir.ptr<!s32i>, !s32i
7272
// CIR: %[[SUB:.*]] = cir.unary(minus, %[[STRIDE]]) : !s32i, !s32i
73-
// CIR: cir.ptr_stride(%[[PTR]] : !cir.ptr<!cir.func<!void ()>>, %[[SUB]] : !s32i)
73+
// CIR: cir.ptr_stride(%[[PTR]] : !cir.ptr<!cir.func<()>>, %[[SUB]] : !s32i)
7474

7575
// LLVM-LABEL: f7
7676
// LLVM: %[[PTR:.*]] = load ptr, ptr {{.*}}, align 8

0 commit comments

Comments
 (0)