Skip to content

Commit 4e37eb7

Browse files
committed
Revert "[CIR] Remove the !cir.void return type for functions returning void (#1203)"
This reverts commit 5c50ed9.
1 parent 11a0c26 commit 4e37eb7

File tree

17 files changed

+45
-194
lines changed

17 files changed

+45
-194
lines changed

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

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3474,6 +3474,8 @@ 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 {};
34773479
return getFunctionType().getReturnTypes();
34783480
}
34793481

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

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

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-
}
3497+
/// Returns the result types of this function.
3498+
llvm::ArrayRef<mlir::Type> getResultTypes() { return getFunctionType().getReturnTypes(); }
35023499

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

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

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -379,27 +379,22 @@ def CIR_FuncType : CIR_Type<"Func", "func"> {
379379

380380
```mlir
381381
!cir.func<!bool ()>
382-
!cir.func<!cir.void ()>
383382
!cir.func<!s32i (!s8i, !s8i)>
384383
!cir.func<!s32i (!s32i, ...)>
385384
```
386385
}];
387386

388-
let parameters = (ins ArrayRefParameter<"mlir::Type">:$inputs, ArrayRefParameter<"mlir::Type">:$returnTypes,
387+
let parameters = (ins ArrayRefParameter<"mlir::Type">:$inputs, "mlir::Type":$returnType,
389388
"bool":$varArg);
390389
let assemblyFormat = [{
391-
`<` custom<FuncType>($returnTypes, $inputs, $varArg) `>`
390+
`<` $returnType ` ` `(` custom<FuncTypeArgs>($inputs, $varArg) `>`
392391
}];
393392

394393
let builders = [
395-
// Construct with an actual return type or explicit !cir.void
396394
TypeBuilderWithInferredContext<(ins
397395
"llvm::ArrayRef<mlir::Type>":$inputs, "mlir::Type":$returnType,
398396
CArg<"bool", "false">:$isVarArg), [{
399-
return $_get(returnType.getContext(), inputs,
400-
::mlir::isa<::cir::VoidType>(returnType) ? llvm::ArrayRef<mlir::Type>{}
401-
: llvm::ArrayRef{returnType},
402-
isVarArg);
397+
return $_get(returnType.getContext(), inputs, returnType, isVarArg);
403398
}]>
404399
];
405400

@@ -413,11 +408,11 @@ def CIR_FuncType : CIR_Type<"Func", "func"> {
413408
/// Returns the number of arguments to the function.
414409
unsigned getNumInputs() const { return getInputs().size(); }
415410

416-
/// Returns the result type of the function as an actual return type or
417-
/// explicit !cir.void
418-
mlir::Type getReturnType() const;
411+
/// Returns the result type of the function as an ArrayRef, enabling better
412+
/// integration with generic MLIR utilities.
413+
llvm::ArrayRef<mlir::Type> getReturnTypes() const;
419414

420-
/// Returns whether the function returns void.
415+
/// Returns whether the function is returns void.
421416
bool isVoid() const;
422417

423418
/// 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 function type. If the function
274+
// First, check whether we can build the full fucntion 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: 10 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@
3535
#include "mlir/IR/OpImplementation.h"
3636
#include "mlir/IR/StorageUniquerSupport.h"
3737
#include "mlir/IR/TypeUtilities.h"
38-
#include "mlir/Interfaces/CallInterfaces.h"
3938
#include "mlir/Interfaces/DataLayoutInterfaces.h"
4039
#include "mlir/Interfaces/FunctionImplementation.h"
4140
#include "mlir/Interfaces/InferTypeOpInterface.h"
@@ -2226,26 +2225,6 @@ void cir::FuncOp::build(OpBuilder &builder, OperationState &result,
22262225
getResAttrsAttrName(result.name));
22272226
}
22282227

2229-
// A specific version of function_interface_impl::parseFunctionSignature able to
2230-
// handle the "-> !void" special fake return type.
2231-
static ParseResult
2232-
parseFunctionSignature(OpAsmParser &parser, bool allowVariadic,
2233-
SmallVectorImpl<OpAsmParser::Argument> &arguments,
2234-
bool &isVariadic, SmallVectorImpl<Type> &resultTypes,
2235-
SmallVectorImpl<DictionaryAttr> &resultAttrs) {
2236-
if (function_interface_impl::parseFunctionArgumentList(parser, allowVariadic,
2237-
arguments, isVariadic))
2238-
return failure();
2239-
if (succeeded(parser.parseOptionalArrow())) {
2240-
if (parser.parseOptionalExclamationKeyword("!void").succeeded())
2241-
// This is just an empty return type and attribute.
2242-
return success();
2243-
return call_interface_impl::parseFunctionResultList(parser, resultTypes,
2244-
resultAttrs);
2245-
}
2246-
return success();
2247-
}
2248-
22492228
ParseResult cir::FuncOp::parse(OpAsmParser &parser, OperationState &state) {
22502229
llvm::SMLoc loc = parser.getCurrentLocation();
22512230

@@ -2306,8 +2285,9 @@ ParseResult cir::FuncOp::parse(OpAsmParser &parser, OperationState &state) {
23062285

23072286
// Parse the function signature.
23082287
bool isVariadic = false;
2309-
if (parseFunctionSignature(parser, /*allowVariadic=*/true, arguments,
2310-
isVariadic, resultTypes, resultAttrs))
2288+
if (function_interface_impl::parseFunctionSignatureWithArguments(
2289+
parser, /*allowVariadic=*/false, arguments, isVariadic, resultTypes,
2290+
resultAttrs))
23112291
return failure();
23122292

23132293
for (auto &arg : arguments)
@@ -2510,8 +2490,13 @@ void cir::FuncOp::print(OpAsmPrinter &p) {
25102490
p.printSymbolName(getSymName());
25112491
auto fnType = getFunctionType();
25122492
llvm::SmallVector<Type, 1> resultTypes;
2513-
function_interface_impl::printFunctionSignature(
2514-
p, *this, fnType.getInputs(), fnType.isVarArg(), fnType.getReturnTypes());
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(), {});
25152500

25162501
if (mlir::ArrayAttr annotations = getAnnotationsAttr()) {
25172502
p << ' ';
@@ -2580,11 +2565,6 @@ LogicalResult cir::FuncOp::verifyType() {
25802565
if (!getNoProto() && type.isVarArg() && type.getNumInputs() == 0)
25812566
return emitError()
25822567
<< "prototyped function must have at least one non-variadic input";
2583-
if (auto rt = type.getReturnTypes();
2584-
!rt.empty() && mlir::isa<cir::VoidType>(rt.front()))
2585-
return emitOpError("The return type for a function returning void should "
2586-
"be empty instead of an explicit !cir.void");
2587-
25882568
return success();
25892569
}
25902570

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

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

3938
using cir::MissingFeatures;
@@ -43,16 +42,13 @@ using cir::MissingFeatures;
4342
//===----------------------------------------------------------------------===//
4443

4544
static mlir::ParseResult
46-
parseFuncType(mlir::AsmParser &p, llvm::SmallVector<mlir::Type> &returnTypes,
47-
llvm::SmallVector<mlir::Type> &params, bool &isVarArg);
48-
49-
static void printFuncType(mlir::AsmPrinter &p,
50-
mlir::ArrayRef<mlir::Type> returnTypes,
51-
mlir::ArrayRef<mlir::Type> params, bool isVarArg);
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);
5249

5350
static mlir::ParseResult parsePointerAddrSpace(mlir::AsmParser &p,
5451
mlir::Attribute &addrSpaceAttr);
55-
5652
static void printPointerAddrSpace(mlir::AsmPrinter &p,
5753
mlir::Attribute addrSpaceAttr);
5854

@@ -817,46 +813,9 @@ FuncType FuncType::clone(TypeRange inputs, TypeRange results) const {
817813
return get(llvm::to_vector(inputs), results[0], isVarArg());
818814
}
819815

820-
// A special parser is needed for function returning void to consume the "!void"
821-
// returned type in the case there is no alias defined.
822-
static mlir::ParseResult
823-
parseFuncTypeReturn(mlir::AsmParser &p,
824-
llvm::SmallVector<mlir::Type> &returnTypes) {
825-
if (p.parseOptionalExclamationKeyword("!void").succeeded())
826-
// !void means no return type.
827-
return p.parseLParen();
828-
if (succeeded(p.parseOptionalLParen()))
829-
// If we have already a '(', the function has no return type
830-
return mlir::success();
831-
832-
mlir::Type type;
833-
auto result = p.parseOptionalType(type);
834-
if (!result.has_value())
835-
return mlir::failure();
836-
if (failed(*result) || isa<cir::VoidType>(type))
837-
// No return type specified.
838-
return p.parseLParen();
839-
// Otherwise use the actual type.
840-
returnTypes.push_back(type);
841-
return p.parseLParen();
842-
}
843-
844-
// A special pretty-printer for function returning void to emit a "!void"
845-
// returned type. Note that there is no real type used here since it does not
846-
// appear in the IR and thus the alias might not be defined and cannot be
847-
// referred to. This is why this is a pure syntactic-sugar string which is used.
848-
static void printFuncTypeReturn(mlir::AsmPrinter &p,
849-
mlir::ArrayRef<mlir::Type> returnTypes) {
850-
if (returnTypes.empty())
851-
// Pretty-print no return type as "!void"
852-
p << "!void ";
853-
else
854-
p << returnTypes << ' ';
855-
}
856-
857-
static mlir::ParseResult
858-
parseFuncTypeArgs(mlir::AsmParser &p, llvm::SmallVector<mlir::Type> &params,
859-
bool &isVarArg) {
816+
mlir::ParseResult parseFuncTypeArgs(mlir::AsmParser &p,
817+
llvm::SmallVector<mlir::Type> &params,
818+
bool &isVarArg) {
860819
isVarArg = false;
861820
// `(` `)`
862821
if (succeeded(p.parseOptionalRParen()))
@@ -886,10 +845,8 @@ parseFuncTypeArgs(mlir::AsmParser &p, llvm::SmallVector<mlir::Type> &params,
886845
return p.parseRParen();
887846
}
888847

889-
static void printFuncTypeArgs(mlir::AsmPrinter &p,
890-
mlir::ArrayRef<mlir::Type> params,
891-
bool isVarArg) {
892-
p << '(';
848+
void printFuncTypeArgs(mlir::AsmPrinter &p, mlir::ArrayRef<mlir::Type> params,
849+
bool isVarArg) {
893850
llvm::interleaveComma(params, p,
894851
[&p](mlir::Type type) { p.printType(type); });
895852
if (isVarArg) {
@@ -900,37 +857,11 @@ static void printFuncTypeArgs(mlir::AsmPrinter &p,
900857
p << ')';
901858
}
902859

903-
static mlir::ParseResult
904-
parseFuncType(mlir::AsmParser &p, llvm::SmallVector<mlir::Type> &returnTypes,
905-
llvm::SmallVector<mlir::Type> &params, bool &isVarArg) {
906-
if (failed(parseFuncTypeReturn(p, returnTypes)))
907-
return failure();
908-
return parseFuncTypeArgs(p, params, isVarArg);
909-
}
910-
911-
static void printFuncType(mlir::AsmPrinter &p,
912-
mlir::ArrayRef<mlir::Type> returnTypes,
913-
mlir::ArrayRef<mlir::Type> params, bool isVarArg) {
914-
printFuncTypeReturn(p, returnTypes);
915-
printFuncTypeArgs(p, params, isVarArg);
860+
llvm::ArrayRef<mlir::Type> FuncType::getReturnTypes() const {
861+
return static_cast<detail::FuncTypeStorage *>(getImpl())->returnType;
916862
}
917863

918-
// Return the actual return type or an explicit !cir.void if the function does
919-
// not return anything
920-
mlir::Type FuncType::getReturnType() const {
921-
if (isVoid())
922-
return cir::VoidType::get(getContext());
923-
return static_cast<detail::FuncTypeStorage *>(getImpl())->returnTypes.front();
924-
}
925-
926-
bool FuncType::isVoid() const {
927-
auto rt = static_cast<detail::FuncTypeStorage *>(getImpl())->returnTypes;
928-
assert(rt.empty() ||
929-
!mlir::isa<cir::VoidType>(rt.front()) &&
930-
"The return type for a function returning void should be empty "
931-
"instead of a real !cir.void");
932-
return rt.empty();
933-
}
864+
bool FuncType::isVoid() const { return mlir::isa<VoidType>(getReturnType()); }
934865

935866
//===----------------------------------------------------------------------===//
936867
// MethodType Definitions

clang/lib/CIR/Dialect/IR/CMakeLists.txt

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,8 @@ add_clang_library(MLIRCIR
1919
LINK_LIBS PUBLIC
2020
MLIRIR
2121
MLIRCIRInterfaces
22-
MLIRCallInterfaces
2322
MLIRDLTIDialect
2423
MLIRDataLayoutInterfaces
25-
MLIRFunctionInterfaces
2624
MLIRFuncDialect
2725
MLIRLoopLikeInterface
2826
MLIRLLVMDialect

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(ArgTypes, resultType, FI.isVariadic());
112+
return FuncType::get(getMLIRContext(), ArgTypes, resultType, FI.isVariadic());
113113
}
114114

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

clang/test/CIR/IR/being_and_nothingness.cir

Lines changed: 0 additions & 35 deletions
This file was deleted.

clang/test/CIR/IR/func.cir

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
// RUN: cir-opt %s | FileCheck %s
2+
// XFAIL: *
23

34
!s32i = !cir.int<s, 32>
45
!u8i = !cir.int<u, 8>

clang/test/CIR/IR/invalid.cir

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
// Test attempts to build bogus CIR
22
// RUN: cir-opt %s -verify-diagnostics -split-input-file
3+
// XFAIL: *
34

45
!u32i = !cir.int<u, 32>
56

0 commit comments

Comments
 (0)