diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td b/clang/include/clang/CIR/Dialect/IR/CIROps.td index 1feb631bfcdf..0cd870fafb28 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIROps.td +++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td @@ -3857,7 +3857,7 @@ def CallOp : CIR_CallOp<"call", [NoRegionArguments]> { CArg<"mlir::UnitAttr", "{}">:$exception), [{ $_state.addOperands(ValueRange{ind_target}); $_state.addOperands(operands); - if (!fn_type.isVoid()) + if (!fn_type.hasVoidReturn()) $_state.addTypes(fn_type.getReturnType()); $_state.addAttribute("calling_conv", CallingConvAttr::get($_builder.getContext(), callingConv)); @@ -3943,7 +3943,7 @@ def TryCallOp : CIR_CallOp<"try_call", finalCallOperands.append(operands.begin(), operands.end()); $_state.addOperands(finalCallOperands); - if (!fn_type.isVoid()) + if (!fn_type.hasVoidReturn()) $_state.addTypes(fn_type.getReturnType()); $_state.addAttribute("calling_conv", diff --git a/clang/include/clang/CIR/Dialect/IR/CIRTypes.h b/clang/include/clang/CIR/Dialect/IR/CIRTypes.h index 171ffda0b691..221090f25d9e 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIRTypes.h +++ b/clang/include/clang/CIR/Dialect/IR/CIRTypes.h @@ -154,6 +154,7 @@ class StructType case RecordKind::Struct: return "struct"; } + llvm_unreachable("Invalid value for StructType::getKind()"); } std::string getPrefixedName() { return getKindAsStr() + "." + getName().getValue().str(); diff --git a/clang/include/clang/CIR/Dialect/IR/CIRTypes.td b/clang/include/clang/CIR/Dialect/IR/CIRTypes.td index 6f30f0188802..3a0451175f30 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIRTypes.td +++ b/clang/include/clang/CIR/Dialect/IR/CIRTypes.td @@ -379,10 +379,10 @@ def CIR_FuncType : CIR_Type<"Func", "func"> { ```mlir !cir.func<()> - !cir.func + !cir.func<() -> !bool> !cir.func<(!s8i, !s8i)> - !cir.func - !cir.func + !cir.func<(!s8i, !s8i) -> !s32i> + !cir.func<(!s32i, ...) -> !s32i> ``` }]; @@ -390,23 +390,27 @@ def CIR_FuncType : CIR_Type<"Func", "func"> { "mlir::Type":$optionalReturnType, "bool":$varArg); // Use a custom parser to handle the optional return and argument types - // without an optional anchor. let assemblyFormat = [{ `<` custom($optionalReturnType, $inputs, $varArg) `>` }]; let builders = [ - // Construct with an actual return type or explicit !cir.void + // Create a FuncType, converting the return type from C-style to + // MLIR-style. If the given return type is `cir::VoidType`, ignore it + // and create the FuncType with no return type, which is how MLIR + // represents function types. TypeBuilderWithInferredContext<(ins "llvm::ArrayRef":$inputs, "mlir::Type":$returnType, CArg<"bool", "false">:$isVarArg), [{ - return $_get(returnType.getContext(), inputs, - mlir::isa(returnType) ? nullptr - : returnType, - isVarArg); + return $_get(returnType.getContext(), inputs, + mlir::isa(returnType) ? nullptr + : returnType, + isVarArg); }]> ]; + let genVerifyDecl = 1; + let extraClassDeclaration = [{ /// Returns whether the function is variadic. bool isVarArg() const { return getVarArg(); } @@ -417,16 +421,17 @@ def CIR_FuncType : CIR_Type<"Func", "func"> { /// Returns the number of arguments to the function. unsigned getNumInputs() const { return getInputs().size(); } - /// Returns the result type of the function as an actual return type or - /// explicit !cir.void + /// Get the C-style return type of the function, which is !cir.void if the + /// function returns nothing and the actual return type otherwise. mlir::Type getReturnType() const; - /// Returns the result type of the function as an ArrayRef, enabling better - /// integration with generic MLIR utilities. + /// Get the MLIR-style return type of the function, which is an empty + /// ArrayRef if the function returns nothing and a single-element ArrayRef + /// with the actual return type otherwise. llvm::ArrayRef getReturnTypes() const; - /// Returns whether the function returns void. - bool isVoid() const; + /// Does the fuction type return nothing? + bool hasVoidReturn() const; /// Returns a clone of this function type with the given argument /// and result types. diff --git a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp index 18e4adf19d53..22e144738783 100644 --- a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp +++ b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp @@ -2739,15 +2739,15 @@ verifyCallCommInSymbolUses(Operation *op, SymbolTableCollection &symbolTable) { << stringifyCallingConv(callIf.getCallingConv()); // Void function must not return any results. - if (fnType.isVoid() && op->getNumResults() != 0) + if (fnType.hasVoidReturn() && op->getNumResults() != 0) return op->emitOpError("callee returns void but call has results"); // Non-void function calls must return exactly one result. - if (!fnType.isVoid() && op->getNumResults() != 1) + if (!fnType.hasVoidReturn() && op->getNumResults() != 1) return op->emitOpError("incorrect number of results for callee"); // Parent function and return value types must match. - if (!fnType.isVoid() && + if (!fnType.hasVoidReturn() && op->getResultTypes().front() != fnType.getReturnType()) { return op->emitOpError("result type mismatch: expected ") << fnType.getReturnType() << ", but provided " diff --git a/clang/lib/CIR/Dialect/IR/CIRTypes.cpp b/clang/lib/CIR/Dialect/IR/CIRTypes.cpp index b22b5707a793..e35d60293f41 100644 --- a/clang/lib/CIR/Dialect/IR/CIRTypes.cpp +++ b/clang/lib/CIR/Dialect/IR/CIRTypes.cpp @@ -937,66 +937,51 @@ FuncType FuncType::clone(TypeRange inputs, TypeRange results) const { // type. static mlir::ParseResult parseFuncTypeReturn(mlir::AsmParser &p, mlir::Type &optionalReturnType) { - if (succeeded(p.parseOptionalLParen())) { - // If we have already a '(', the function has no return type - optionalReturnType = {}; - return mlir::success(); + if (succeeded(p.parseOptionalArrow())) { + // `->` found. It must be followed by the return type. + return p.parseType(optionalReturnType); } - mlir::Type type; - if (p.parseType(type)) - return mlir::failure(); - if (isa(type)) - // An explicit !cir.void means also no return type. - optionalReturnType = {}; - else - // Otherwise use the actual type. - optionalReturnType = type; - return p.parseLParen(); + // Function has `void` return in C++, no return in MLIR. + optionalReturnType = {}; + return success(); } // A special pretty-printer for function returning or not a result. static void printFuncTypeReturn(mlir::AsmPrinter &p, mlir::Type optionalReturnType) { if (optionalReturnType) - p << optionalReturnType << ' '; - p << '('; + p << " -> " << optionalReturnType; } static mlir::ParseResult parseFuncTypeArgs(mlir::AsmParser &p, llvm::SmallVector ¶ms, bool &isVarArg) { isVarArg = false; - // `(` `)` - if (succeeded(p.parseOptionalRParen())) + if (failed(p.parseLParen())) + return failure(); + if (succeeded(p.parseOptionalRParen())) { + // `()` empty argument list return mlir::success(); - - // `(` `...` `)` - if (succeeded(p.parseOptionalEllipsis())) { - isVarArg = true; - return p.parseRParen(); } - - // type (`,` type)* (`,` `...`)? - mlir::Type type; - if (p.parseType(type)) - return mlir::failure(); - params.push_back(type); - while (succeeded(p.parseOptionalComma())) { + do { if (succeeded(p.parseOptionalEllipsis())) { + // `...`, which must be the last thing in the list. isVarArg = true; - return p.parseRParen(); + break; + } else { + mlir::Type argType; + if (failed(p.parseType(argType))) + return failure(); + params.push_back(argType); } - if (p.parseType(type)) - return mlir::failure(); - params.push_back(type); - } - + } while (succeeded(p.parseOptionalComma())); return p.parseRParen(); } static void printFuncTypeArgs(mlir::AsmPrinter &p, mlir::ArrayRef params, bool isVarArg) { + p << '('; llvm::interleaveComma(params, p, [&p](mlir::Type type) { p.printType(type); }); if (isVarArg) { @@ -1010,45 +995,52 @@ static void printFuncTypeArgs(mlir::AsmPrinter &p, // Use a custom parser to handle the optional return and argument types without // an optional anchor. static mlir::ParseResult parseFuncType(mlir::AsmParser &p, - mlir::Type &optionalReturnTypes, + mlir::Type &optionalReturnType, llvm::SmallVector ¶ms, bool &isVarArg) { - if (failed(parseFuncTypeReturn(p, optionalReturnTypes))) + if (failed(parseFuncTypeArgs(p, params, isVarArg))) return failure(); - return parseFuncTypeArgs(p, params, isVarArg); + return parseFuncTypeReturn(p, optionalReturnType); } -static void printFuncType(mlir::AsmPrinter &p, mlir::Type optionalReturnTypes, +static void printFuncType(mlir::AsmPrinter &p, mlir::Type optionalReturnType, mlir::ArrayRef params, bool isVarArg) { - printFuncTypeReturn(p, optionalReturnTypes); printFuncTypeArgs(p, params, isVarArg); + printFuncTypeReturn(p, optionalReturnType); } -// Return the actual return type or an explicit !cir.void if the function does -// not return anything +/// Get the C-style return type of the function, which is !cir.void if the +/// function returns nothing and the actual return type otherwise. mlir::Type FuncType::getReturnType() const { - if (isVoid()) + if (hasVoidReturn()) return cir::VoidType::get(getContext()); - return static_cast(getImpl())->optionalReturnType; + return getOptionalReturnType(); } -/// Returns the result type of the function as an ArrayRef, enabling better -/// integration with generic MLIR utilities. +/// Get the MLIR-style return type of the function, which is an empty +/// ArrayRef if the function returns nothing and a single-element ArrayRef +/// with the actual return type otherwise. llvm::ArrayRef FuncType::getReturnTypes() const { - if (isVoid()) + if (hasVoidReturn()) return {}; - return static_cast(getImpl())->optionalReturnType; -} - -// Whether the function returns void -bool FuncType::isVoid() const { - auto rt = - static_cast(getImpl())->optionalReturnType; - assert(!rt || - !mlir::isa(rt) && - "The return type for a function returning void should be empty " - "instead of a real !cir.void"); - return !rt; + // Can't use getOptionalReturnType() here because llvm::ArrayRef hold a + // pointer to its elements and doesn't do lifetime extension. That would + // result in returning a pointer to a temporary that has gone out of scope. + return getImpl()->optionalReturnType; +} + +// Does the fuction type return nothing? +bool FuncType::hasVoidReturn() const { return !getOptionalReturnType(); } + +mlir::LogicalResult +FuncType::verify(llvm::function_ref emitError, + llvm::ArrayRef argTypes, mlir::Type returnType, + bool isVarArg) { + if (returnType && mlir::isa(returnType)) { + emitError() << "!cir.func cannot have an explicit 'void' return type"; + return mlir::failure(); + } + return mlir::success(); } //===----------------------------------------------------------------------===// diff --git a/clang/test/CIR/CallConvLowering/AArch64/ptr-fields.c b/clang/test/CIR/CallConvLowering/AArch64/ptr-fields.c index 8fc121e9bf9b..e5f06757c2ef 100644 --- a/clang/test/CIR/CallConvLowering/AArch64/ptr-fields.c +++ b/clang/test/CIR/CallConvLowering/AArch64/ptr-fields.c @@ -15,9 +15,9 @@ int foo(int x) { return x; } // CIR: %[[#V0:]] = cir.alloca !ty_A, !cir.ptr, [""] {alignment = 4 : i64} // CIR: %[[#V1:]] = cir.cast(bitcast, %[[#V0]] : !cir.ptr), !cir.ptr // CIR: cir.store %arg0, %[[#V1]] : !u64i, !cir.ptr -// CIR: %[[#V2:]] = cir.get_global @foo : !cir.ptr> -// CIR: %[[#V3:]] = cir.get_member %[[#V0]][0] {name = "f"} : !cir.ptr -> !cir.ptr>> -// CIR: cir.store %[[#V2]], %[[#V3]] : !cir.ptr>, !cir.ptr>> +// CIR: %[[#V2:]] = cir.get_global @foo : !cir.ptr !s32i>> +// CIR: %[[#V3:]] = cir.get_member %[[#V0]][0] {name = "f"} : !cir.ptr -> !cir.ptr !s32i>>> +// CIR: cir.store %[[#V2]], %[[#V3]] : !cir.ptr !s32i>>, !cir.ptr !s32i>>> // CIR: cir.return // LLVM: void @passA(i64 %[[#V0:]]) diff --git a/clang/test/CIR/CallConvLowering/x86_64/fptrs.c b/clang/test/CIR/CallConvLowering/x86_64/fptrs.c index f2a7538919c2..e7d15528da19 100644 --- a/clang/test/CIR/CallConvLowering/x86_64/fptrs.c +++ b/clang/test/CIR/CallConvLowering/x86_64/fptrs.c @@ -10,10 +10,10 @@ typedef int (*myfptr)(S); int foo(S s) { return 42 + s.a; } // CHECK: cir.func {{.*@bar}} -// CHECK: %[[#V0:]] = cir.alloca !cir.ptr>, !cir.ptr>>, ["a", init] -// CHECK: %[[#V1:]] = cir.get_global @foo : !cir.ptr> -// CHECK: %[[#V2:]] = cir.cast(bitcast, %[[#V1]] : !cir.ptr>), !cir.ptr> -// CHECK: cir.store %[[#V2]], %[[#V0]] : !cir.ptr>, !cir.ptr>> +// CHECK: %[[#V0:]] = cir.alloca !cir.ptr !s32i>>, !cir.ptr !s32i>>>, ["a", init] +// CHECK: %[[#V1:]] = cir.get_global @foo : !cir.ptr !s32i>> +// CHECK: %[[#V2:]] = cir.cast(bitcast, %[[#V1]] : !cir.ptr !s32i>>), !cir.ptr !s32i>> +// CHECK: cir.store %[[#V2]], %[[#V0]] : !cir.ptr !s32i>>, !cir.ptr !s32i>>> void bar() { myfptr a = foo; } @@ -22,15 +22,15 @@ void bar() { // CHECK: %[[#V0:]] = cir.alloca !ty_S, !cir.ptr, [""] {alignment = 4 : i64} // CHECK: %[[#V1:]] = cir.cast(bitcast, %[[#V0]] : !cir.ptr), !cir.ptr // CHECK: cir.store %arg0, %[[#V1]] : !s32i, !cir.ptr -// CHECK: %[[#V2:]] = cir.alloca !cir.ptr>, !cir.ptr>>, ["a", init] -// CHECK: %[[#V3:]] = cir.get_global @foo : !cir.ptr> -// CHECK: %[[#V4:]] = cir.cast(bitcast, %[[#V3]] : !cir.ptr>), !cir.ptr> -// CHECK: cir.store %[[#V4]], %[[#V2]] : !cir.ptr>, !cir.ptr>> -// CHECK: %[[#V5:]] = cir.load %[[#V2]] : !cir.ptr>>, !cir.ptr> +// CHECK: %[[#V2:]] = cir.alloca !cir.ptr !s32i>>, !cir.ptr !s32i>>>, ["a", init] +// CHECK: %[[#V3:]] = cir.get_global @foo : !cir.ptr !s32i>> +// CHECK: %[[#V4:]] = cir.cast(bitcast, %[[#V3]] : !cir.ptr !s32i>>), !cir.ptr !s32i>> +// CHECK: cir.store %[[#V4]], %[[#V2]] : !cir.ptr !s32i>>, !cir.ptr !s32i>>> +// CHECK: %[[#V5:]] = cir.load %[[#V2]] : !cir.ptr !s32i>>>, !cir.ptr !s32i>> // CHECK: %[[#V6:]] = cir.cast(bitcast, %[[#V0]] : !cir.ptr), !cir.ptr // CHECK: %[[#V7:]] = cir.load %[[#V6]] : !cir.ptr, !s32i -// CHECK: %[[#V8:]] = cir.cast(bitcast, %[[#V5]] : !cir.ptr>), !cir.ptr> -// CHECK: %[[#V9:]] = cir.call %[[#V8]](%[[#V7]]) : (!cir.ptr>, !s32i) -> !s32i +// CHECK: %[[#V8:]] = cir.cast(bitcast, %[[#V5]] : !cir.ptr !s32i>>), !cir.ptr !s32i>> +// CHECK: %[[#V9:]] = cir.call %[[#V8]](%[[#V7]]) : (!cir.ptr !s32i>>, !s32i) -> !s32i // LLVM: define dso_local void @baz(i32 %0) // LLVM: %[[#V1:]] = alloca %struct.S, i64 1 diff --git a/clang/test/CIR/CodeGen/coro-task.cpp b/clang/test/CIR/CodeGen/coro-task.cpp index 01f30de810e8..c3ed24c9ea33 100644 --- a/clang/test/CIR/CodeGen/coro-task.cpp +++ b/clang/test/CIR/CodeGen/coro-task.cpp @@ -359,19 +359,19 @@ folly::coro::Task go4() { // CHECK: %17 = cir.alloca !ty_anon2E2_, !cir.ptr, ["ref.tmp1"] {alignment = 1 : i64} // Get the lambda invoker ptr via `lambda operator folly::coro::Task (*)(int const&)()` -// CHECK: %18 = cir.call @_ZZ3go4vENK3$_0cvPFN5folly4coro4TaskIiEERKiEEv(%17) : (!cir.ptr) -> !cir.ptr)>> -// CHECK: %19 = cir.unary(plus, %18) : !cir.ptr)>>, !cir.ptr)>> -// CHECK: cir.yield %19 : !cir.ptr)>> +// CHECK: %18 = cir.call @_ZZ3go4vENK3$_0cvPFN5folly4coro4TaskIiEERKiEEv(%17) : (!cir.ptr) -> !cir.ptr) -> ![[IntTask]]>> +// CHECK: %19 = cir.unary(plus, %18) : !cir.ptr) -> ![[IntTask]]>>, !cir.ptr) -> ![[IntTask]]>> +// CHECK: cir.yield %19 : !cir.ptr) -> ![[IntTask]]>> // CHECK: } -// CHECK: cir.store %12, %3 : !cir.ptr)>>, !cir.ptr)>>> +// CHECK: cir.store %12, %3 : !cir.ptr) -> ![[IntTask]]>>, !cir.ptr) -> ![[IntTask]]>>> // CHECK: cir.scope { // CHECK: %17 = cir.alloca !s32i, !cir.ptr, ["ref.tmp2", init] {alignment = 4 : i64} -// CHECK: %18 = cir.load %3 : !cir.ptr)>>>, !cir.ptr)>> +// CHECK: %18 = cir.load %3 : !cir.ptr) -> ![[IntTask]]>>>, !cir.ptr) -> ![[IntTask]]>> // CHECK: %19 = cir.const #cir.int<3> : !s32i // CHECK: cir.store %19, %17 : !s32i, !cir.ptr // Call invoker, which calls operator() indirectly. -// CHECK: %20 = cir.call %18(%17) : (!cir.ptr)>>, !cir.ptr) -> ![[IntTask]] +// CHECK: %20 = cir.call %18(%17) : (!cir.ptr) -> ![[IntTask]]>>, !cir.ptr) -> ![[IntTask]] // CHECK: cir.store %20, %4 : ![[IntTask]], !cir.ptr // CHECK: } diff --git a/clang/test/CIR/CodeGen/derived-to-base.cpp b/clang/test/CIR/CodeGen/derived-to-base.cpp index 879d09f58c34..c6dc92d3ac7b 100644 --- a/clang/test/CIR/CodeGen/derived-to-base.cpp +++ b/clang/test/CIR/CodeGen/derived-to-base.cpp @@ -118,11 +118,11 @@ void vcall(C1 &c1) { // CHECK: %5 = cir.load %2 : !cir.ptr, !s32i // CHECK: cir.call @_ZN5buffyC2ERKS_(%3, %1) : (!cir.ptr, !cir.ptr) -> () // CHECK: %6 = cir.load %3 : !cir.ptr, !ty_buffy -// CHECK: %7 = cir.cast(bitcast, %4 : !cir.ptr), !cir.ptr, !s32i, !ty_buffy)>>>> -// CHECK: %8 = cir.load %7 : !cir.ptr, !s32i, !ty_buffy)>>>>, !cir.ptr, !s32i, !ty_buffy)>>> -// CHECK: %9 = cir.vtable.address_point( %8 : !cir.ptr, !s32i, !ty_buffy)>>>, vtable_index = 0, address_point_index = 2) : !cir.ptr, !s32i, !ty_buffy)>>> -// CHECK: %10 = cir.load align(8) %9 : !cir.ptr, !s32i, !ty_buffy)>>>, !cir.ptr, !s32i, !ty_buffy)>> -// CHECK: %11 = cir.call %10(%4, %5, %6) : (!cir.ptr, !s32i, !ty_buffy)>>, !cir.ptr, !s32i, !ty_buffy) -> !s32i +// CHECK: %7 = cir.cast(bitcast, %4 : !cir.ptr), !cir.ptr, !s32i, !ty_buffy) -> !s32i>>>> +// CHECK: %8 = cir.load %7 : !cir.ptr, !s32i, !ty_buffy) -> !s32i>>>>, !cir.ptr, !s32i, !ty_buffy) -> !s32i>>> +// CHECK: %9 = cir.vtable.address_point( %8 : !cir.ptr, !s32i, !ty_buffy) -> !s32i>>>, vtable_index = 0, address_point_index = 2) : !cir.ptr, !s32i, !ty_buffy) -> !s32i>>> +// CHECK: %10 = cir.load align(8) %9 : !cir.ptr, !s32i, !ty_buffy) -> !s32i>>>, !cir.ptr, !s32i, !ty_buffy) -> !s32i>> +// CHECK: %11 = cir.call %10(%4, %5, %6) : (!cir.ptr, !s32i, !ty_buffy) -> !s32i>>, !cir.ptr, !s32i, !ty_buffy) -> !s32i // CHECK: cir.return // CHECK: } diff --git a/clang/test/CIR/CodeGen/dtors.cpp b/clang/test/CIR/CodeGen/dtors.cpp index 60c330d53b78..f432d61d86c4 100644 --- a/clang/test/CIR/CodeGen/dtors.cpp +++ b/clang/test/CIR/CodeGen/dtors.cpp @@ -36,7 +36,7 @@ class B : public A }; // Class A -// CHECK: ![[ClassA:ty_.*]] = !cir.struct>>} #cir.record.decl.ast> +// CHECK: ![[ClassA:ty_.*]] = !cir.struct !u32i>>>} #cir.record.decl.ast> // Class B // CHECK: ![[ClassB:ty_.*]] = !cir.struct diff --git a/clang/test/CIR/CodeGen/dynamic-cast-exact.cpp b/clang/test/CIR/CodeGen/dynamic-cast-exact.cpp index cf5a9f9f6f64..829a3829ccd1 100644 --- a/clang/test/CIR/CodeGen/dynamic-cast-exact.cpp +++ b/clang/test/CIR/CodeGen/dynamic-cast-exact.cpp @@ -16,10 +16,10 @@ struct Derived final : Base1 {}; Derived *ptr_cast(Base1 *ptr) { return dynamic_cast(ptr); // CHECK: %[[#SRC:]] = cir.load %{{.+}} : !cir.ptr>, !cir.ptr - // CHECK-NEXT: %[[#EXPECTED_VPTR:]] = cir.vtable.address_point(@_ZTV7Derived, vtable_index = 0, address_point_index = 2) : !cir.ptr>> - // CHECK-NEXT: %[[#SRC_VPTR_PTR:]] = cir.cast(bitcast, %[[#SRC]] : !cir.ptr), !cir.ptr>>> - // CHECK-NEXT: %[[#SRC_VPTR:]] = cir.load %[[#SRC_VPTR_PTR]] : !cir.ptr>>>, !cir.ptr>> - // CHECK-NEXT: %[[#SUCCESS:]] = cir.cmp(eq, %[[#SRC_VPTR]], %[[#EXPECTED_VPTR]]) : !cir.ptr>>, !cir.bool + // CHECK-NEXT: %[[#EXPECTED_VPTR:]] = cir.vtable.address_point(@_ZTV7Derived, vtable_index = 0, address_point_index = 2) : !cir.ptr !u32i>>> + // CHECK-NEXT: %[[#SRC_VPTR_PTR:]] = cir.cast(bitcast, %[[#SRC]] : !cir.ptr), !cir.ptr !u32i>>>> + // CHECK-NEXT: %[[#SRC_VPTR:]] = cir.load %[[#SRC_VPTR_PTR]] : !cir.ptr !u32i>>>>, !cir.ptr !u32i>>> + // CHECK-NEXT: %[[#SUCCESS:]] = cir.cmp(eq, %[[#SRC_VPTR]], %[[#EXPECTED_VPTR]]) : !cir.ptr !u32i>>>, !cir.bool // CHECK-NEXT: %{{.+}} = cir.ternary(%[[#SUCCESS]], true { // CHECK-NEXT: %[[#RES:]] = cir.cast(bitcast, %[[#SRC]] : !cir.ptr), !cir.ptr // CHECK-NEXT: cir.yield %[[#RES]] : !cir.ptr @@ -39,10 +39,10 @@ Derived *ptr_cast(Base1 *ptr) { Derived &ref_cast(Base1 &ref) { return dynamic_cast(ref); // CHECK: %[[#SRC:]] = cir.load %{{.+}} : !cir.ptr>, !cir.ptr - // CHECK-NEXT: %[[#EXPECTED_VPTR:]] = cir.vtable.address_point(@_ZTV7Derived, vtable_index = 0, address_point_index = 2) : !cir.ptr>> - // CHECK-NEXT: %[[#SRC_VPTR_PTR:]] = cir.cast(bitcast, %[[#SRC]] : !cir.ptr), !cir.ptr>>> - // CHECK-NEXT: %[[#SRC_VPTR:]] = cir.load %[[#SRC_VPTR_PTR]] : !cir.ptr>>>, !cir.ptr>> - // CHECK-NEXT: %[[#SUCCESS:]] = cir.cmp(eq, %[[#SRC_VPTR]], %[[#EXPECTED_VPTR]]) : !cir.ptr>>, !cir.bool + // CHECK-NEXT: %[[#EXPECTED_VPTR:]] = cir.vtable.address_point(@_ZTV7Derived, vtable_index = 0, address_point_index = 2) : !cir.ptr !u32i>>> + // CHECK-NEXT: %[[#SRC_VPTR_PTR:]] = cir.cast(bitcast, %[[#SRC]] : !cir.ptr), !cir.ptr !u32i>>>> + // CHECK-NEXT: %[[#SRC_VPTR:]] = cir.load %[[#SRC_VPTR_PTR]] : !cir.ptr !u32i>>>>, !cir.ptr !u32i>>> + // CHECK-NEXT: %[[#SUCCESS:]] = cir.cmp(eq, %[[#SRC_VPTR]], %[[#EXPECTED_VPTR]]) : !cir.ptr !u32i>>>, !cir.bool // CHECK-NEXT: %[[#FAILED:]] = cir.unary(not, %[[#SUCCESS]]) : !cir.bool, !cir.bool // CHECK-NEXT: cir.if %[[#FAILED]] { // CHECK-NEXT: cir.call @__cxa_bad_cast() : () -> () diff --git a/clang/test/CIR/CodeGen/fun-ptr.c b/clang/test/CIR/CodeGen/fun-ptr.c index 0f9a98300e32..087164c7b474 100644 --- a/clang/test/CIR/CodeGen/fun-ptr.c +++ b/clang/test/CIR/CodeGen/fun-ptr.c @@ -17,7 +17,7 @@ typedef struct A { fun_typ fun; } A; -// CIR: !ty_A = !cir.struct>)>>} #cir.record.decl.ast> +// CIR: !ty_A = !cir.struct>) -> !s32i>>} #cir.record.decl.ast> A a = {(fun_typ)0}; int extract_a(Data* d) { @@ -27,15 +27,15 @@ int extract_a(Data* d) { // CIR: cir.func {{@.*foo.*}}(%arg0: !cir.ptr // CIR: [[TMP0:%.*]] = cir.alloca !cir.ptr, !cir.ptr>, ["d", init] // CIR: [[TMP1:%.*]] = cir.alloca !s32i, !cir.ptr, ["__retval"] -// CIR: [[TMP2:%.*]] = cir.alloca !cir.ptr)>>, !cir.ptr)>>>, ["f", init] +// CIR: [[TMP2:%.*]] = cir.alloca !cir.ptr) -> !s32i>>, !cir.ptr) -> !s32i>>>, ["f", init] // CIR: cir.store %arg0, [[TMP0]] : !cir.ptr, !cir.ptr> -// CIR: [[TMP3:%.*]] = cir.const #cir.ptr : !cir.ptr)>> -// CIR: cir.store [[TMP3]], [[TMP2]] : !cir.ptr)>>, !cir.ptr)>>> -// CIR: [[TMP4:%.*]] = cir.get_global {{@.*extract_a.*}} : !cir.ptr)>> -// CIR: cir.store [[TMP4]], [[TMP2]] : !cir.ptr)>>, !cir.ptr)>>> -// CIR: [[TMP5:%.*]] = cir.load [[TMP2]] : !cir.ptr)>>>, !cir.ptr)>> +// CIR: [[TMP3:%.*]] = cir.const #cir.ptr : !cir.ptr) -> !s32i>> +// CIR: cir.store [[TMP3]], [[TMP2]] : !cir.ptr) -> !s32i>>, !cir.ptr) -> !s32i>>> +// CIR: [[TMP4:%.*]] = cir.get_global {{@.*extract_a.*}} : !cir.ptr) -> !s32i>> +// CIR: cir.store [[TMP4]], [[TMP2]] : !cir.ptr) -> !s32i>>, !cir.ptr) -> !s32i>>> +// CIR: [[TMP5:%.*]] = cir.load [[TMP2]] : !cir.ptr) -> !s32i>>>, !cir.ptr) -> !s32i>> // CIR: [[TMP6:%.*]] = cir.load [[TMP0]] : !cir.ptr>, !cir.ptr -// CIR: [[TMP7:%.*]] = cir.call [[TMP5]]([[TMP6]]) : (!cir.ptr)>>, !cir.ptr) -> !s32i +// CIR: [[TMP7:%.*]] = cir.call [[TMP5]]([[TMP6]]) : (!cir.ptr) -> !s32i>>, !cir.ptr) -> !s32i // CIR: cir.store [[TMP7]], [[TMP1]] : !s32i, !cir.ptr // LLVM: define dso_local i32 {{@.*foo.*}}(ptr %0) diff --git a/clang/test/CIR/CodeGen/hello.c b/clang/test/CIR/CodeGen/hello.c index 8fb49131784c..3454b40afeed 100644 --- a/clang/test/CIR/CodeGen/hello.c +++ b/clang/test/CIR/CodeGen/hello.c @@ -11,7 +11,7 @@ int main (void) { // CHECK: cir.global "private" constant cir_private dsolocal @".str" = #cir.const_array<"Hello, world!\0A\00" : !cir.array> : !cir.array {alignment = 1 : i64} // CHECK: cir.func @main() -> !s32i // CHECK: %0 = cir.alloca !s32i, !cir.ptr, ["__retval"] {alignment = 4 : i64} -// CHECK: %1 = cir.get_global @printf : !cir.ptr, ...)>> +// CHECK: %1 = cir.get_global @printf : !cir.ptr, ...) -> !s32i>> // CHECK: %2 = cir.get_global @".str" : !cir.ptr> // CHECK: %3 = cir.cast(array_to_ptrdecay, %2 : !cir.ptr>), !cir.ptr // CHECK: %4 = cir.call @printf(%3) : (!cir.ptr) -> !s32i diff --git a/clang/test/CIR/CodeGen/lambda.cpp b/clang/test/CIR/CodeGen/lambda.cpp index 680cd2e122f1..59f5c5e8c3ce 100644 --- a/clang/test/CIR/CodeGen/lambda.cpp +++ b/clang/test/CIR/CodeGen/lambda.cpp @@ -207,27 +207,27 @@ int g3() { // CHECK-LABEL: @_Z2g3v() // CHECK: %0 = cir.alloca !s32i, !cir.ptr, ["__retval"] {alignment = 4 : i64} -// CHECK: %1 = cir.alloca !cir.ptr)>>, !cir.ptr)>>>, ["fn", init] {alignment = 8 : i64} +// CHECK: %1 = cir.alloca !cir.ptr) -> !s32i>>, !cir.ptr) -> !s32i>>>, ["fn", init] {alignment = 8 : i64} // CHECK: %2 = cir.alloca !s32i, !cir.ptr, ["task", init] {alignment = 4 : i64} // 1. Use `operator int (*)(int const&)()` to retrieve the fnptr to `__invoke()`. // CHECK: %3 = cir.scope { // CHECK: %7 = cir.alloca !ty_anon2E5_, !cir.ptr, ["ref.tmp0"] {alignment = 1 : i64} -// CHECK: %8 = cir.call @_ZZ2g3vENK3$_0cvPFiRKiEEv(%7) : (!cir.ptr) -> !cir.ptr)>> -// CHECK: %9 = cir.unary(plus, %8) : !cir.ptr)>>, !cir.ptr)>> -// CHECK: cir.yield %9 : !cir.ptr)>> +// CHECK: %8 = cir.call @_ZZ2g3vENK3$_0cvPFiRKiEEv(%7) : (!cir.ptr) -> !cir.ptr) -> !s32i>> +// CHECK: %9 = cir.unary(plus, %8) : !cir.ptr) -> !s32i>>, !cir.ptr) -> !s32i>> +// CHECK: cir.yield %9 : !cir.ptr) -> !s32i>> // CHECK: } // 2. Load ptr to `__invoke()`. -// CHECK: cir.store %3, %1 : !cir.ptr)>>, !cir.ptr)>>> +// CHECK: cir.store %3, %1 : !cir.ptr) -> !s32i>>, !cir.ptr) -> !s32i>>> // CHECK: %4 = cir.scope { // CHECK: %7 = cir.alloca !s32i, !cir.ptr, ["ref.tmp1", init] {alignment = 4 : i64} -// CHECK: %8 = cir.load %1 : !cir.ptr)>>>, !cir.ptr)>> +// CHECK: %8 = cir.load %1 : !cir.ptr) -> !s32i>>>, !cir.ptr) -> !s32i>> // CHECK: %9 = cir.const #cir.int<3> : !s32i // CHECK: cir.store %9, %7 : !s32i, !cir.ptr // 3. Call `__invoke()`, which effectively executes `operator()`. -// CHECK: %10 = cir.call %8(%7) : (!cir.ptr)>>, !cir.ptr) -> !s32i +// CHECK: %10 = cir.call %8(%7) : (!cir.ptr) -> !s32i>>, !cir.ptr) -> !s32i // CHECK: cir.yield %10 : !s32i // CHECK: } diff --git a/clang/test/CIR/CodeGen/multi-vtable.cpp b/clang/test/CIR/CodeGen/multi-vtable.cpp index 8b709a3ddeaf..6fe6680d2ca3 100644 --- a/clang/test/CIR/CodeGen/multi-vtable.cpp +++ b/clang/test/CIR/CodeGen/multi-vtable.cpp @@ -34,14 +34,14 @@ int main() { // CIR: ![[VTableTypeMother:ty_.*]] = !cir.struct x 4>}> // CIR: ![[VTableTypeFather:ty_.*]] = !cir.struct x 3>}> // CIR: ![[VTableTypeChild:ty_.*]] = !cir.struct x 4>, !cir.array x 3>}> -// CIR: !ty_Father = !cir.struct>>} #cir.record.decl.ast> -// CIR: !ty_Mother = !cir.struct>>} #cir.record.decl.ast> +// CIR: !ty_Father = !cir.struct !u32i>>>} #cir.record.decl.ast> +// CIR: !ty_Mother = !cir.struct !u32i>>>} #cir.record.decl.ast> // CIR: !ty_Child = !cir.struct // CIR: cir.func linkonce_odr @_ZN6MotherC2Ev(%arg0: !cir.ptr -// CIR: %{{[0-9]+}} = cir.vtable.address_point(@_ZTV6Mother, vtable_index = 0, address_point_index = 2) : !cir.ptr>> -// CIR: %{{[0-9]+}} = cir.cast(bitcast, %{{[0-9]+}} : !cir.ptr), !cir.ptr>>> -// CIR: cir.store %2, %{{[0-9]+}} : !cir.ptr>>, !cir.ptr>>> +// CIR: %{{[0-9]+}} = cir.vtable.address_point(@_ZTV6Mother, vtable_index = 0, address_point_index = 2) : !cir.ptr !u32i>>> +// CIR: %{{[0-9]+}} = cir.cast(bitcast, %{{[0-9]+}} : !cir.ptr), !cir.ptr !u32i>>>> +// CIR: cir.store %2, %{{[0-9]+}} : !cir.ptr !u32i>>>, !cir.ptr !u32i>>>> // CIR: cir.return // CIR: } @@ -51,13 +51,13 @@ int main() { // LLVM-DAG: } // CIR: cir.func linkonce_odr @_ZN5ChildC2Ev(%arg0: !cir.ptr -// CIR: %{{[0-9]+}} = cir.vtable.address_point(@_ZTV5Child, vtable_index = 0, address_point_index = 2) : !cir.ptr>> -// CIR: %{{[0-9]+}} = cir.cast(bitcast, %{{[0-9]+}} : !cir.ptr), !cir.ptr>>> -// CIR: cir.store %{{[0-9]+}}, %{{[0-9]+}} : !cir.ptr>>, !cir.ptr>>> -// CIR: %{{[0-9]+}} = cir.vtable.address_point(@_ZTV5Child, vtable_index = 1, address_point_index = 2) : !cir.ptr>> +// CIR: %{{[0-9]+}} = cir.vtable.address_point(@_ZTV5Child, vtable_index = 0, address_point_index = 2) : !cir.ptr !u32i>>> +// CIR: %{{[0-9]+}} = cir.cast(bitcast, %{{[0-9]+}} : !cir.ptr), !cir.ptr !u32i>>>> +// CIR: cir.store %{{[0-9]+}}, %{{[0-9]+}} : !cir.ptr !u32i>>>, !cir.ptr !u32i>>>> +// CIR: %{{[0-9]+}} = cir.vtable.address_point(@_ZTV5Child, vtable_index = 1, address_point_index = 2) : !cir.ptr !u32i>>> // CIR: %7 = cir.base_class_addr(%1 : !cir.ptr nonnull) [8] -> !cir.ptr -// CIR: %8 = cir.cast(bitcast, %7 : !cir.ptr), !cir.ptr>>> loc(#loc8) -// CIR: cir.store %{{[0-9]+}}, %{{[0-9]+}} : !cir.ptr>>, !cir.ptr>>> +// CIR: %8 = cir.cast(bitcast, %7 : !cir.ptr), !cir.ptr !u32i>>>> loc(#loc8) +// CIR: cir.store %{{[0-9]+}}, %{{[0-9]+}} : !cir.ptr !u32i>>>, !cir.ptr !u32i>>>> // CIR: cir.return // CIR: } diff --git a/clang/test/CIR/CodeGen/no-prototype.c b/clang/test/CIR/CodeGen/no-prototype.c index c119304ce54d..ad647de0f590 100644 --- a/clang/test/CIR/CodeGen/no-prototype.c +++ b/clang/test/CIR/CodeGen/no-prototype.c @@ -35,8 +35,8 @@ int test1(int x) { int noProto2(); int test2(int x) { return noProto2(x); - // CHECK: [[GGO:%.*]] = cir.get_global @noProto2 : !cir.ptr> - // CHECK: {{.*}} = cir.call [[GGO]](%{{[0-9]+}}) : (!cir.ptr>, !s32i) -> !s32i + // CHECK: [[GGO:%.*]] = cir.get_global @noProto2 : !cir.ptr !s32i>> + // CHECK: {{.*}} = cir.call [[GGO]](%{{[0-9]+}}) : (!cir.ptr !s32i>>, !s32i) -> !s32i } int noProto2(int x) { return x; } // CHECK: cir.func no_proto @noProto2(%arg0: !s32i {{.+}}) -> !s32i @@ -50,9 +50,9 @@ int noProto3(); int test3(int x) { // CHECK: cir.func @test3 return noProto3(x); - // CHECK: [[GGO:%.*]] = cir.get_global @noProto3 : !cir.ptr> - // CHECK: [[CAST:%.*]] = cir.cast(bitcast, [[GGO]] : !cir.ptr>), !cir.ptr> - // CHECK: {{%.*}} = cir.call [[CAST]](%{{[0-9]+}}) : (!cir.ptr>, !s32i) -> !s32i + // CHECK: [[GGO:%.*]] = cir.get_global @noProto3 : !cir.ptr !s32i>> + // CHECK: [[CAST:%.*]] = cir.cast(bitcast, [[GGO]] : !cir.ptr !s32i>>), !cir.ptr !s32i>> + // CHECK: {{%.*}} = cir.call [[CAST]](%{{[0-9]+}}) : (!cir.ptr !s32i>>, !s32i) -> !s32i } @@ -67,18 +67,18 @@ int noProto4() { return 0; } // cir.func private no_proto @noProto4() -> !s32i int test4(int x) { return noProto4(x); // Even if we know the definition, this should compile. - // CHECK: [[GGO:%.*]] = cir.get_global @noProto4 : !cir.ptr> - // CHECK: [[CAST:%.*]] = cir.cast(bitcast, [[GGO]] : !cir.ptr>), !cir.ptr> - // CHECK: {{%.*}} = cir.call [[CAST]]({{%.*}}) : (!cir.ptr>, !s32i) -> !s32i + // CHECK: [[GGO:%.*]] = cir.get_global @noProto4 : !cir.ptr !s32i>> + // CHECK: [[CAST:%.*]] = cir.cast(bitcast, [[GGO]] : !cir.ptr !s32i>>), !cir.ptr !s32i>> + // CHECK: {{%.*}} = cir.call [[CAST]]({{%.*}}) : (!cir.ptr !s32i>>, !s32i) -> !s32i } // No-proto definition followed by an incorrect call due to lack of args. int noProto5(); int test5(int x) { return noProto5(); - // CHECK: [[GGO:%.*]] = cir.get_global @noProto5 : !cir.ptr> - // CHECK: [[CAST:%.*]] = cir.cast(bitcast, [[GGO]] : !cir.ptr>), !cir.ptr> - // CHECK: {{%.*}} = cir.call [[CAST]]() : (!cir.ptr>) -> !s32i + // CHECK: [[GGO:%.*]] = cir.get_global @noProto5 : !cir.ptr !s32i>> + // CHECK: [[CAST:%.*]] = cir.cast(bitcast, [[GGO]] : !cir.ptr !s32i>>), !cir.ptr !s32i>> + // CHECK: {{%.*}} = cir.call [[CAST]]() : (!cir.ptr !s32i>>) -> !s32i } int noProto5(int x) { return x; } // CHECK: cir.func no_proto @noProto5(%arg0: !s32i {{.+}}) -> !s32i diff --git a/clang/test/CIR/CodeGen/store.c b/clang/test/CIR/CodeGen/store.c index 9a94e6578129..2d2fc6029ce9 100644 --- a/clang/test/CIR/CodeGen/store.c +++ b/clang/test/CIR/CodeGen/store.c @@ -24,7 +24,7 @@ void storeNoArgsFn() { // CHECK: cir.func {{.*@storeNoArgsFn}} // CHECK: %0 = cir.alloca -// CHECK: %1 = cir.get_global @get42 : !cir.ptr> -// CHECK: %2 = cir.cast(bitcast, %1 : !cir.ptr>), !cir.ptr> -// CHECK: cir.store %2, %0 : !cir.ptr>, !cir.ptr>> +// CHECK: %1 = cir.get_global @get42 : !cir.ptr !s32i>> +// CHECK: %2 = cir.cast(bitcast, %1 : !cir.ptr !s32i>>), !cir.ptr !s32i>> +// CHECK: cir.store %2, %0 : !cir.ptr !s32i>>, !cir.ptr !s32i>>> diff --git a/clang/test/CIR/CodeGen/struct.cpp b/clang/test/CIR/CodeGen/struct.cpp index 91acb833a706..b3c502e66534 100644 --- a/clang/test/CIR/CodeGen/struct.cpp +++ b/clang/test/CIR/CodeGen/struct.cpp @@ -32,7 +32,7 @@ void yoyo(incomplete *i) {} // CHECK-DAG: !ty_Foo = !cir.struct // CHECK-DAG: !ty_Mandalore = !cir.struct, !s32i} #cir.record.decl.ast> // CHECK-DAG: !ty_Adv = !cir.struct -// CHECK-DAG: !ty_Entry = !cir.struct, !cir.ptr)>>}> +// CHECK-DAG: !ty_Entry = !cir.struct, !cir.ptr) -> !u32i>>}> // CHECK: cir.func linkonce_odr @_ZN3Bar6methodEv(%arg0: !cir.ptr // CHECK-NEXT: %0 = cir.alloca !cir.ptr, !cir.ptr>, ["this", init] {alignment = 8 : i64} @@ -172,4 +172,4 @@ void ppp() { Entry x; } // CHECK: cir.func linkonce_odr @_ZN5EntryC2Ev(%arg0: !cir.ptr -// CHECK: cir.get_member %1[0] {name = "procAddr"} : !cir.ptr -> !cir.ptr, !cir.ptr)>>> +// CHECK: cir.get_member %1[0] {name = "procAddr"} : !cir.ptr -> !cir.ptr, !cir.ptr) -> !u32i>>> diff --git a/clang/test/CIR/CodeGen/vtable-rtti.cpp b/clang/test/CIR/CodeGen/vtable-rtti.cpp index e11e80bd5b4f..3c8a5253c526 100644 --- a/clang/test/CIR/CodeGen/vtable-rtti.cpp +++ b/clang/test/CIR/CodeGen/vtable-rtti.cpp @@ -27,8 +27,8 @@ class B : public A // RTTI_DISABLED: ![[VTableTypeA:ty_.*]] = !cir.struct x 5>}> // Class A -// CHECK: ![[ClassA:ty_.*]] = !cir.struct>>} #cir.record.decl.ast> -// RTTI_DISABLED: ![[ClassA:ty_.*]] = !cir.struct>>} #cir.record.decl.ast> +// CHECK: ![[ClassA:ty_.*]] = !cir.struct !u32i>>>} #cir.record.decl.ast> +// RTTI_DISABLED: ![[ClassA:ty_.*]] = !cir.struct !u32i>>>} #cir.record.decl.ast> // Class B // CHECK: ![[ClassB:ty_.*]] = !cir.struct @@ -45,9 +45,9 @@ class B : public A // CHECK: %1 = cir.load %0 : !cir.ptr>, !cir.ptr // CHECK: %2 = cir.base_class_addr(%1 : !cir.ptr nonnull) [0] -> !cir.ptr // CHECK: cir.call @_ZN1AC2Ev(%2) : (!cir.ptr) -> () -// CHECK: %3 = cir.vtable.address_point(@_ZTV1B, vtable_index = 0, address_point_index = 2) : !cir.ptr>> -// CHECK: %4 = cir.cast(bitcast, %1 : !cir.ptr), !cir.ptr>>> -// CHECK: cir.store %3, %4 : !cir.ptr>>, !cir.ptr>>> +// CHECK: %3 = cir.vtable.address_point(@_ZTV1B, vtable_index = 0, address_point_index = 2) : !cir.ptr !u32i>>> +// CHECK: %4 = cir.cast(bitcast, %1 : !cir.ptr), !cir.ptr !u32i>>>> +// CHECK: cir.store %3, %4 : !cir.ptr !u32i>>>, !cir.ptr !u32i>>>> // CHECK: cir.return // CHECK: } @@ -73,9 +73,9 @@ class B : public A // CHECK: %0 = cir.alloca !cir.ptr, !cir.ptr>, ["this", init] {alignment = 8 : i64} // CHECK: cir.store %arg0, %0 : !cir.ptr, !cir.ptr> // CHECK: %1 = cir.load %0 : !cir.ptr>, !cir.ptr -// CHECK: %2 = cir.vtable.address_point(@_ZTV1A, vtable_index = 0, address_point_index = 2) : !cir.ptr>> -// CHECK: %3 = cir.cast(bitcast, %1 : !cir.ptr), !cir.ptr>>> -// CHECK: cir.store %2, %3 : !cir.ptr>>, !cir.ptr>>> +// CHECK: %2 = cir.vtable.address_point(@_ZTV1A, vtable_index = 0, address_point_index = 2) : !cir.ptr !u32i>>> +// CHECK: %3 = cir.cast(bitcast, %1 : !cir.ptr), !cir.ptr !u32i>>>> +// CHECK: cir.store %2, %3 : !cir.ptr !u32i>>>, !cir.ptr !u32i>>>> // CHECK: cir.return // CHECK: } diff --git a/clang/test/CIR/CodeGen/vtt.cpp b/clang/test/CIR/CodeGen/vtt.cpp index c32e242737cf..6404f306327e 100644 --- a/clang/test/CIR/CodeGen/vtt.cpp +++ b/clang/test/CIR/CodeGen/vtt.cpp @@ -38,9 +38,9 @@ int f() { // Class A constructor // CIR: cir.func linkonce_odr @_ZN1AC2Ev(%arg0: !cir.ptr -// CIR: %{{[0-9]+}} = cir.vtable.address_point(@_ZTV1A, vtable_index = 0, address_point_index = 2) : !cir.ptr>> -// CIR: %{{[0-9]+}} = cir.cast(bitcast, %{{[0-9]+}} : !cir.ptr), !cir.ptr>>> -// CIR: cir.store %{{[0-9]+}}, %{{[0-9]+}} : !cir.ptr>>, !cir.ptr>>> +// CIR: %{{[0-9]+}} = cir.vtable.address_point(@_ZTV1A, vtable_index = 0, address_point_index = 2) : !cir.ptr !u32i>>> +// CIR: %{{[0-9]+}} = cir.cast(bitcast, %{{[0-9]+}} : !cir.ptr), !cir.ptr !u32i>>>> +// CIR: cir.store %{{[0-9]+}}, %{{[0-9]+}} : !cir.ptr !u32i>>>, !cir.ptr !u32i>>>> // CIR: } // Vtable of Class D @@ -115,19 +115,19 @@ int f() { // CIR: %[[VTT_D_TO_C:.*]] = cir.vtt.address_point @_ZTT1D, offset = 3 -> !cir.ptr> // CIR: cir.call @_ZN1CC2Ev(%[[C_PTR]], %[[VTT_D_TO_C]]) : (!cir.ptr, !cir.ptr>) -> () -// CIR: %{{[0-9]+}} = cir.vtable.address_point(@_ZTV1D, vtable_index = 0, address_point_index = 3) : !cir.ptr>> -// CIR: %{{[0-9]+}} = cir.cast(bitcast, %{{[0-9]+}} : !cir.ptr), !cir.ptr>>> -// CIR: cir.store %{{[0-9]+}}, %{{[0-9]+}} : !cir.ptr>>, !cir.ptr>>> -// CIR: %{{[0-9]+}} = cir.vtable.address_point(@_ZTV1D, vtable_index = 2, address_point_index = 3) : !cir.ptr>> +// CIR: %{{[0-9]+}} = cir.vtable.address_point(@_ZTV1D, vtable_index = 0, address_point_index = 3) : !cir.ptr !u32i>>> +// CIR: %{{[0-9]+}} = cir.cast(bitcast, %{{[0-9]+}} : !cir.ptr), !cir.ptr !u32i>>>> +// CIR: cir.store %{{[0-9]+}}, %{{[0-9]+}} : !cir.ptr !u32i>>>, !cir.ptr !u32i>>>> +// CIR: %{{[0-9]+}} = cir.vtable.address_point(@_ZTV1D, vtable_index = 2, address_point_index = 3) : !cir.ptr !u32i>>> // CIR: %{{[0-9]+}} = cir.base_class_addr(%{{[0-9]+}} : !cir.ptr nonnull) [40] -> !cir.ptr -// CIR: %{{[0-9]+}} = cir.cast(bitcast, %{{[0-9]+}} : !cir.ptr), !cir.ptr>>> -// CIR: cir.store %{{[0-9]+}}, %{{[0-9]+}} : !cir.ptr>>, !cir.ptr>>> -// CIR: %{{[0-9]+}} = cir.vtable.address_point(@_ZTV1D, vtable_index = 1, address_point_index = 3) : !cir.ptr>> +// CIR: %{{[0-9]+}} = cir.cast(bitcast, %{{[0-9]+}} : !cir.ptr), !cir.ptr !u32i>>>> +// CIR: cir.store %{{[0-9]+}}, %{{[0-9]+}} : !cir.ptr !u32i>>>, !cir.ptr !u32i>>>> +// CIR: %{{[0-9]+}} = cir.vtable.address_point(@_ZTV1D, vtable_index = 1, address_point_index = 3) : !cir.ptr !u32i>>> // CIR: cir.base_class_addr(%{{[0-9]+}} : !cir.ptr nonnull) [16] -> !cir.ptr -// CIR: cir.cast(bitcast, %{{[0-9]+}} : !cir.ptr), !cir.ptr>>> -// CIR: cir.store %{{[0-9]+}}, %{{[0-9]+}} : !cir.ptr>>, !cir.ptr>>> +// CIR: cir.cast(bitcast, %{{[0-9]+}} : !cir.ptr), !cir.ptr !u32i>>>> +// CIR: cir.store %{{[0-9]+}}, %{{[0-9]+}} : !cir.ptr !u32i>>>, !cir.ptr !u32i>>>> // CIR: cir.return // CIR: } @@ -174,4 +174,4 @@ namespace other { // CIR: %[[VAL_4:.*]] = cir.base_class_addr(%[[VAL_2]] : !cir.ptr nonnull) [0] -> !cir.ptr // CIR: cir.call @_ZN5other1AD2Ev(%[[VAL_4]]) : (!cir.ptr) -> () // CIR: cir.return -// CIR: } \ No newline at end of file +// CIR: } diff --git a/clang/test/CIR/IR/being_and_nothingness.cir b/clang/test/CIR/IR/being_and_nothingness.cir index 076c75a5b192..8dff3ba723b7 100644 --- a/clang/test/CIR/IR/being_and_nothingness.cir +++ b/clang/test/CIR/IR/being_and_nothingness.cir @@ -1,12 +1,12 @@ // RUN: cir-opt %s | FileCheck %s // Exercise different ways to encode a function returning void +// This test is less useful that it used to be, because a redundant `!cir.void` +// as a function return type is no longer supported. !s32i = !cir.int !f = !cir.func<()> -!f2 = !cir.func +!f2 = !cir.func<() -> !s32i> !void = !cir.void !fnptr2 = !cir.ptr> -// Try some useless !void -!fnptr3 = !cir.ptr> module { cir.func @ind2(%fnptr: !fnptr2, %a : !s32i) { // CHECK: cir.func @ind2(%arg0: !cir.ptr>, %arg1: !s32i) { @@ -16,13 +16,4 @@ module { // CHECK: cir.func @f2() { cir.return } - // Try with a lot of useless !void - cir.func @ind3(%fnptr: !fnptr3, %a : !s32i) -> !void { - // CHECK: cir.func @ind3(%arg0: !cir.ptr>, %arg1: !s32i) { - cir.return - } - cir.func @f3() -> !cir.void { - // CHECK: cir.func @f3() { - cir.return - } } diff --git a/clang/test/CIR/IR/call-op-call-conv.cir b/clang/test/CIR/IR/call-op-call-conv.cir index b47e1226e10b..bf13cb76d947 100644 --- a/clang/test/CIR/IR/call-op-call-conv.cir +++ b/clang/test/CIR/IR/call-op-call-conv.cir @@ -2,7 +2,7 @@ // RUN: FileCheck --input-file=%t.cir %s !s32i = !cir.int -!fnptr = !cir.ptr> +!fnptr = !cir.ptr !s32i>> module { cir.func @my_add(%a: !s32i, %b: !s32i) -> !s32i cc(spir_function) { @@ -22,6 +22,6 @@ module { } } -// CHECK: %{{[0-9]+}} = cir.call %arg0(%arg1) : (!cir.ptr>, !s32i) -> !s32i cc(spir_kernel) -// CHECK: %{{[0-9]+}} = cir.call %arg0(%arg1) : (!cir.ptr>, !s32i) -> !s32i cc(spir_function) +// CHECK: %{{[0-9]+}} = cir.call %arg0(%arg1) : (!cir.ptr !s32i>>, !s32i) -> !s32i cc(spir_kernel) +// CHECK: %{{[0-9]+}} = cir.call %arg0(%arg1) : (!cir.ptr !s32i>>, !s32i) -> !s32i cc(spir_function) // CHECK: %{{[0-9]+}} = cir.try_call @my_add(%{{[0-9]+}}, %{{[0-9]+}}) ^{{.+}}, ^{{.+}} : (!s32i, !s32i) -> !s32i cc(spir_function) diff --git a/clang/test/CIR/IR/call.cir b/clang/test/CIR/IR/call.cir index 0b1fc68622f8..abd2fe9ba878 100644 --- a/clang/test/CIR/IR/call.cir +++ b/clang/test/CIR/IR/call.cir @@ -1,7 +1,7 @@ // RUN: cir-opt %s | FileCheck %s !s32i = !cir.int -!fnptr = !cir.ptr> +!fnptr = !cir.ptr !s32i>> #fn_attr = #cir, optnone = #cir.optnone})> #fn_attr1 = #cir @@ -16,7 +16,7 @@ module { cir.func @ind(%fnptr: !fnptr, %a : !s32i) { %r = cir.call %fnptr(%a) : (!fnptr, !s32i) -> !s32i -// CHECK: %0 = cir.call %arg0(%arg1) : (!cir.ptr>, !s32i) -> !s32i +// CHECK: %0 = cir.call %arg0(%arg1) : (!cir.ptr !s32i>>, !s32i) -> !s32i // Check parse->pretty-print round-trip on extra() attribute %7 = cir.call @_ZNSt5arrayIiLm8192EEixEm(%a) : (!s32i) -> !s32i extra(#fn_attr1) // CHECK: %1 = cir.call @_ZNSt5arrayIiLm8192EEixEm(%arg1) : (!s32i) -> !s32i extra(#fn_attr1) diff --git a/clang/test/CIR/IR/func.cir b/clang/test/CIR/IR/func.cir index a1468e6462f4..87e21efb9e66 100644 --- a/clang/test/CIR/IR/func.cir +++ b/clang/test/CIR/IR/func.cir @@ -28,7 +28,7 @@ module { // Should parse custom assembly format. cir.func @parse_func_type() -> () { - %1 = cir.alloca !cir.ptr>, !cir.ptr>>, ["fn", init] {alignment = 8 : i64} + %1 = cir.alloca !cir.ptr !s32i>>, !cir.ptr !s32i>>>, ["fn", init] {alignment = 8 : i64} cir.return } diff --git a/clang/test/CIR/IR/invalid.cir b/clang/test/CIR/IR/invalid.cir index c628e3c2b46b..58178e7c0b9a 100644 --- a/clang/test/CIR/IR/invalid.cir +++ b/clang/test/CIR/IR/invalid.cir @@ -1159,8 +1159,8 @@ cir.func @bad_long_double(%arg0 : !cir.long_double) -> () { !u8i = !cir.int !void = !cir.void -!Base = !cir.struct ()>>>}> -!Derived = !cir.struct ()>>>}>}> +!Base = !cir.struct !cir.int>>>}> +!Derived = !cir.struct !cir.int>>>}>}> module { cir.global "private" constant external @_ZTI4Base : !cir.ptr @@ -1181,8 +1181,8 @@ module { !u8i = !cir.int !void = !cir.void -!Base = !cir.struct ()>>>}> -!Derived = !cir.struct ()>>>}>}> +!Base = !cir.struct !cir.int>>>}> +!Derived = !cir.struct !cir.int>>>}>}> module { cir.global "private" constant external @_ZTI4Base : !cir.ptr @@ -1490,3 +1490,13 @@ cir.func @cast0(%arg0: !s32i, %arg1: !s32i) { %1 = cir.cmp(eq, %arg0, %arg1): !s32i, !s32i cir.return } + +// ----- + +// Verify that void-returning functions have no return type listed in +// MLIR assembly. + +!s32i = !cir.int +// expected-error @below {{!cir.func cannot have an explicit 'void' return type}} +// expected-error @below {{failed to parse CIR_PointerType parameter}} +cir.global external dsolocal @vfp = #cir.ptr : !cir.ptr !cir.void>> diff --git a/clang/test/CIR/Lowering/ThroughMLIR/vtable.cir b/clang/test/CIR/Lowering/ThroughMLIR/vtable.cir index 66eb06629793..1cb4c0b672ae 100644 --- a/clang/test/CIR/Lowering/ThroughMLIR/vtable.cir +++ b/clang/test/CIR/Lowering/ThroughMLIR/vtable.cir @@ -13,9 +13,9 @@ !ty_anon_struct2 = !cir.struct> x 4>}> !ty_anon_struct3 = !cir.struct> x 3>}> !ty_anon_struct4 = !cir.struct> x 4>, !cir.array> x 3>}> -!ty_Father = !cir.struct ()>>>} #cir.record.decl.ast> -!ty_Mother = !cir.struct ()>>>} #cir.record.decl.ast> -!ty_Child = !cir.struct ()>>>} #cir.record.decl.ast>, !cir.struct ()>>>} #cir.record.decl.ast>} #cir.record.decl.ast> +!ty_Father = !cir.struct !cir.int>>>} #cir.record.decl.ast> +!ty_Mother = !cir.struct !cir.int>>>} #cir.record.decl.ast> +!ty_Child = !cir.struct !cir.int>>>} #cir.record.decl.ast>, !cir.struct !cir.int>>>} #cir.record.decl.ast>} #cir.record.decl.ast> module { cir.func linkonce_odr @_ZN6Mother6simpleEv(%arg0: !cir.ptr) { @@ -70,4 +70,4 @@ module { // MLIR: %{{[0-9]+}} = llvm.insertvalue %{{[0-9]+}}, %{{[0-9]+}}[2] : !llvm.array<3 x ptr> // MLIR: %{{[0-9]+}} = llvm.insertvalue %{{[0-9]+}}, %{{[0-9]+}}[1] : !llvm.struct<(array<4 x ptr>, array<3 x ptr>)> // MLIR: llvm.return %{{[0-9]+}} : !llvm.struct<(array<4 x ptr>, array<3 x ptr>)> -// MLIR: } \ No newline at end of file +// MLIR: } diff --git a/clang/test/CIR/Lowering/call-op-call-conv.cir b/clang/test/CIR/Lowering/call-op-call-conv.cir index 21e9e01c14ae..92f0028e7bae 100644 --- a/clang/test/CIR/Lowering/call-op-call-conv.cir +++ b/clang/test/CIR/Lowering/call-op-call-conv.cir @@ -2,7 +2,7 @@ // RUN: FileCheck --input-file=%t.ll %s --check-prefix=LLVM !s32i = !cir.int -!fnptr = !cir.ptr> +!fnptr = !cir.ptr !s32i>> module { cir.func private @my_add(%a: !s32i, %b: !s32i) -> !s32i cc(spir_function) diff --git a/clang/test/CIR/Lowering/call.cir b/clang/test/CIR/Lowering/call.cir index ed4916d55e14..51dea3ef1008 100644 --- a/clang/test/CIR/Lowering/call.cir +++ b/clang/test/CIR/Lowering/call.cir @@ -38,11 +38,11 @@ module { } // check indirect call lowering - cir.global "private" external @fp : !cir.ptr> + cir.global "private" external @fp : !cir.ptr !s32i>> cir.func @callIndirect(%arg: !s32i) -> !s32i { - %fpp = cir.get_global @fp : !cir.ptr>> - %fp = cir.load %fpp : !cir.ptr>>, !cir.ptr> - %retval = cir.call %fp(%arg) : (!cir.ptr>, !s32i) -> !s32i + %fpp = cir.get_global @fp : !cir.ptr !s32i>>> + %fp = cir.load %fpp : !cir.ptr !s32i>>>, !cir.ptr !s32i>> + %retval = cir.call %fp(%arg) : (!cir.ptr !s32i>>, !s32i) -> !s32i cir.return %retval : !s32i } @@ -77,12 +77,12 @@ module { // LLVM-NEXT: ret i32 %1 // check indirect vararg call lowering - cir.global "private" external @varargfp : !cir.ptr> + cir.global "private" external @varargfp : !cir.ptr !s32i>> cir.func @varargCallIndirect() -> !s32i { - %fpp = cir.get_global @varargfp : !cir.ptr>> - %fp = cir.load %fpp : !cir.ptr>>, !cir.ptr> + %fpp = cir.get_global @varargfp : !cir.ptr !s32i>>> + %fp = cir.load %fpp : !cir.ptr !s32i>>>, !cir.ptr !s32i>> %zero = cir.const #cir.int<0> : !s32i - %retval = cir.call %fp(%zero, %zero) : (!cir.ptr>, !s32i, !s32i) -> !s32i + %retval = cir.call %fp(%zero, %zero) : (!cir.ptr !s32i>>, !s32i, !s32i) -> !s32i cir.return %retval : !s32i } diff --git a/clang/test/CIR/Lowering/func.cir b/clang/test/CIR/Lowering/func.cir index 76e6d4f0d181..241fdc364c02 100644 --- a/clang/test/CIR/Lowering/func.cir +++ b/clang/test/CIR/Lowering/func.cir @@ -6,11 +6,11 @@ module { cir.func no_proto private @noProto3(...) -> !s32i // MLIR: llvm.func @noProto3(...) -> i32 cir.func @test3(%arg0: !s32i) { - %3 = cir.get_global @noProto3 : !cir.ptr> + %3 = cir.get_global @noProto3 : !cir.ptr !s32i>> // MLIR: %[[#FN_PTR:]] = llvm.mlir.addressof @noProto3 : !llvm.ptr - %4 = cir.cast(bitcast, %3 : !cir.ptr>), !cir.ptr> + %4 = cir.cast(bitcast, %3 : !cir.ptr !s32i>>), !cir.ptr !s32i>> // MLIR: %[[#FUNC:]] = llvm.bitcast %[[#FN_PTR]] : !llvm.ptr to !llvm.ptr - %5 = cir.call %4(%arg0) : (!cir.ptr>, !s32i) -> !s32i + %5 = cir.call %4(%arg0) : (!cir.ptr !s32i>>, !s32i) -> !s32i // MLIR: %{{.+}} = llvm.call %[[#FUNC]](%{{.+}}) : !llvm.ptr, (i32) -> i32 cir.return } diff --git a/clang/test/CIR/Lowering/globals.cir b/clang/test/CIR/Lowering/globals.cir index 0108b56b8a7b..3f99fd102efd 100644 --- a/clang/test/CIR/Lowering/globals.cir +++ b/clang/test/CIR/Lowering/globals.cir @@ -15,7 +15,7 @@ !ty_Bar = !cir.struct !ty_StringStruct = !cir.struct, !cir.array, !cir.array} #cir.record.decl.ast> !ty_StringStructPtr = !cir.struct} #cir.record.decl.ast> -!ty_anon2E1_ = !cir.struct)>>} #cir.record.decl.ast> +!ty_anon2E1_ = !cir.struct)>>} #cir.record.decl.ast> module { cir.global external @a = #cir.int<3> : !s32i @@ -164,7 +164,7 @@ module { // MLIR: } // LLVM: @undefStruct = global %struct.Bar undef - cir.global "private" internal @Handlers = #cir.const_array<[#cir.const_struct<{#cir.global_view<@myfun> : !cir.ptr>}> : !ty_anon2E1_]> : !cir.array + cir.global "private" internal @Handlers = #cir.const_array<[#cir.const_struct<{#cir.global_view<@myfun> : !cir.ptr>}> : !ty_anon2E1_]> : !cir.array cir.func internal private @myfun(%arg0: !s32i) { %0 = cir.alloca !s32i, !cir.ptr, ["a", init] {alignment = 4 : i64} cir.store %arg0, %0 : !s32i, !cir.ptr @@ -179,10 +179,10 @@ module { %3 = cir.load %0 : !cir.ptr, !s32i %4 = cir.cast(array_to_ptrdecay, %2 : !cir.ptr>), !cir.ptr %5 = cir.ptr_stride(%4 : !cir.ptr, %3 : !s32i), !cir.ptr - %6 = cir.get_member %5[0] {name = "func"} : !cir.ptr -> !cir.ptr>> - %7 = cir.load %6 : !cir.ptr>>, !cir.ptr> + %6 = cir.get_member %5[0] {name = "func"} : !cir.ptr -> !cir.ptr>> + %7 = cir.load %6 : !cir.ptr>>, !cir.ptr> %8 = cir.load %1 : !cir.ptr, !s32i - cir.call %7(%8) : (!cir.ptr>, !s32i) -> () + cir.call %7(%8) : (!cir.ptr>, !s32i) -> () cir.return } //MLIR-LABEL: @foo diff --git a/clang/test/CIR/Lowering/hello.cir b/clang/test/CIR/Lowering/hello.cir index 868261307b87..361fa7ed36af 100644 --- a/clang/test/CIR/Lowering/hello.cir +++ b/clang/test/CIR/Lowering/hello.cir @@ -8,7 +8,7 @@ module @"/tmp/test.raw" attributes {cir.lang = #cir.lang, cir.sob = #cir.sign cir.global "private" constant internal @".str" = #cir.const_array<"Hello, world!\0A\00" : !cir.array> : !cir.array {alignment = 1 : i64} cir.func @main() -> !s32i { %0 = cir.alloca !s32i, !cir.ptr, ["__retval"] {alignment = 4 : i64} - %1 = cir.get_global @printf : !cir.ptr, ...)>> + %1 = cir.get_global @printf : !cir.ptr, ...) -> !s32i>> %2 = cir.get_global @".str" : !cir.ptr> %3 = cir.cast(array_to_ptrdecay, %2 : !cir.ptr>), !cir.ptr %4 = cir.call @printf(%3) : (!cir.ptr) -> !s32i