https://github.com/Men-cotton updated https://github.com/llvm/llvm-project/pull/224239
>From a7bae76cc55812dddf19f102384aeab0bb3ba8ff Mon Sep 17 00:00:00 2001 From: mencotton <[email protected]> Date: Tue, 15 Sep 2026 20:52:07 +0900 Subject: [PATCH] [CIR] Reject language address spaces in DirectToLLVM pointer conversion Reject unlowered language address spaces in pointer types when bypassing TargetLowering. Guard pointer-producing lowerings, including generated patterns, so failed conversions report legalization failures instead of silently selecting address space zero or constructing invalid LLVM operations. Assisted-by: Codex / GPT-6 --- .../CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp | 64 ++ .../CIR/Lowering/unlowered-address-spaces.cir | 545 ++++++++++++++++++ clang/utils/TableGen/CIRLoweringEmitter.cpp | 2 + 3 files changed, 611 insertions(+) diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp index b9f12aeabd329..07e9af7439124 100644 --- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp +++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp @@ -46,6 +46,7 @@ #include "clang/CIR/LoweringHelpers.h" #include "clang/CIR/MissingFeatures.h" #include "clang/CIR/Passes.h" +#include "llvm/ADT/DenseSet.h" #include "llvm/ADT/MapVector.h" #include "llvm/ADT/StringMap.h" #include "llvm/ADT/TypeSwitch.h" @@ -2040,6 +2041,8 @@ mlir::LogicalResult CIRToLLVMBaseClassAddrOpLowering::matchAndRewrite( mlir::ConversionPatternRewriter &rewriter) const { const mlir::Type resultType = getTypeConverter()->convertType(baseClassOp.getType()); + if (!resultType) + return mlir::failure(); mlir::Value derivedAddr = adaptor.getDerivedAddr(); llvm::SmallVector<mlir::LLVM::GEPArg, 1> offset = { adaptor.getOffset().getZExtValue()}; @@ -2072,6 +2075,8 @@ mlir::LogicalResult CIRToLLVMDerivedClassAddrOpLowering::matchAndRewrite( mlir::ConversionPatternRewriter &rewriter) const { const mlir::Type resultType = getTypeConverter()->convertType(derivedClassOp.getType()); + if (!resultType) + return mlir::failure(); mlir::Value baseAddr = adaptor.getBaseAddr(); // The offset is set in the operation as an unsigned value, but it must be // applied as a negative offset. @@ -2146,6 +2151,8 @@ mlir::LogicalResult CIRToLLVMAllocaOpLowering::matchAndRewrite( << "NYI: lowering alloca of a type with no memory representation"; mlir::Type resultTy = convertTypeForMemory(*getTypeConverter(), dataLayout, op.getType()); + if (!resultTy) + return mlir::failure(); assert(!cir::MissingFeatures::addressSpace()); assert(!cir::MissingFeatures::opAllocaAnnotations()); @@ -2403,6 +2410,8 @@ mlir::LogicalResult CIRToLLVMFrameAddrOpLowering::matchAndRewrite( cir::FrameAddrOp op, OpAdaptor adaptor, mlir::ConversionPatternRewriter &rewriter) const { const mlir::Type llvmPtrTy = getTypeConverter()->convertType(op.getType()); + if (!llvmPtrTy) + return mlir::failure(); replaceOpWithCallLLVMIntrinsicOp(rewriter, op, "llvm.frameaddress", llvmPtrTy, adaptor.getOperands()); return mlir::success(); @@ -2425,6 +2434,8 @@ mlir::LogicalResult CIRToLLVMAddrOfReturnAddrOpLowering::matchAndRewrite( cir::AddrOfReturnAddrOp op, OpAdaptor adaptor, mlir::ConversionPatternRewriter &rewriter) const { const mlir::Type llvmPtrTy = getTypeConverter()->convertType(op.getType()); + if (!llvmPtrTy) + return mlir::failure(); replaceOpWithCallLLVMIntrinsicOp(rewriter, op, "llvm.addressofreturnaddress", llvmPtrTy, adaptor.getOperands()); return mlir::success(); @@ -2974,6 +2985,8 @@ mlir::LogicalResult CIRToLLVMGetGlobalOpLowering::matchAndRewrite( } mlir::Type type = getTypeConverter()->convertType(op.getType()); + if (!type) + return mlir::failure(); mlir::Operation *newop = mlir::LLVM::AddressOfOp::create( rewriter, op.getLoc(), type, op.getName()); @@ -4001,12 +4014,51 @@ mlir::LogicalResult CIRToLLVMSelectOpLowering::matchAndRewrite( return mlir::success(); } +static bool +containsLangAddressSpace(mlir::Type type, + llvm::SmallDenseSet<mlir::Type, 4> &visited) { + if (!visited.insert(type).second) + return false; + + if (auto ptrTy = mlir::dyn_cast<cir::PointerType>(type)) + return mlir::isa_and_present<cir::LangAddressSpaceAttr>( + ptrTy.getAddrSpace()) || + containsLangAddressSpace(ptrTy.getPointee(), visited); + if (auto arrayTy = mlir::dyn_cast<cir::ArrayType>(type)) + return containsLangAddressSpace(arrayTy.getElementType(), visited); + if (auto vectorTy = mlir::dyn_cast<cir::VectorType>(type)) + return containsLangAddressSpace(vectorTy.getElementType(), visited); + if (auto funcTy = mlir::dyn_cast<cir::FuncType>(type)) + return llvm::any_of(funcTy.getInputs(), + [&](mlir::Type input) { + return containsLangAddressSpace(input, visited); + }) || + containsLangAddressSpace(funcTy.getReturnType(), visited); + if (auto dataMemberTy = mlir::dyn_cast<cir::DataMemberType>(type)) + return containsLangAddressSpace(dataMemberTy.getMemberTy(), visited); + if (auto methodTy = mlir::dyn_cast<cir::MethodType>(type)) + return containsLangAddressSpace(methodTy.getMemberFuncTy(), visited); + if (auto recordTy = mlir::dyn_cast<cir::RecordType>(type)) + return llvm::any_of(recordTy.getMembers(), [&](mlir::Type member) { + return containsLangAddressSpace(member, visited); + }); + return false; +} + +static bool containsLangAddressSpace(mlir::Type type) { + llvm::SmallDenseSet<mlir::Type, 4> visited; + return containsLangAddressSpace(type, visited); +} + static void prepareTypeConverter(mlir::LLVMTypeConverter &converter, mlir::DataLayout &dataLayout) { converter.addConversion([&](cir::PointerType type) -> mlir::Type { mlir::ptr::MemorySpaceAttrInterface addrSpaceAttr = type.getAddrSpace(); unsigned numericAS = 0; + if (containsLangAddressSpace(type)) + return {}; + if (auto targetAsAttr = mlir::dyn_cast_if_present<cir::TargetAddressSpaceAttr>( addrSpaceAttr)) @@ -4042,6 +4094,8 @@ static void prepareTypeConverter(mlir::LLVMTypeConverter &converter, intTy && intTy.isBitInt()) return {}; const mlir::Type ty = converter.convertType(type.getElementType()); + if (!ty) + return {}; return mlir::VectorType::get(type.getSize(), ty, {type.getIsScalable()}); }); converter.addConversion([&](cir::BoolType type) -> mlir::Type { @@ -4611,6 +4665,8 @@ mlir::LogicalResult CIRToLLVMGetMemberOpLowering::matchAndRewrite( cir::GetMemberOp op, OpAdaptor adaptor, mlir::ConversionPatternRewriter &rewriter) const { mlir::Type llResTy = getTypeConverter()->convertType(op.getType()); + if (!llResTy) + return mlir::failure(); mlir::Type pointee = op.getAddrTy().getPointee(); if (mlir::isa<cir::UnionType>(pointee)) { @@ -4999,6 +5055,8 @@ mlir::LogicalResult CIRToLLVMVTableGetVirtualFnAddrOpLowering::matchAndRewrite( cir::VTableGetVirtualFnAddrOp op, OpAdaptor adaptor, mlir::ConversionPatternRewriter &rewriter) const { mlir::Type targetType = getTypeConverter()->convertType(op.getType()); + if (!targetType) + return mlir::failure(); auto eltType = mlir::LLVM::LLVMPointerType::get(rewriter.getContext()); llvm::SmallVector<mlir::LLVM::GEPArg> offsets = llvm::SmallVector<mlir::LLVM::GEPArg>{op.getIndex()}; @@ -5012,6 +5070,8 @@ mlir::LogicalResult CIRToLLVMVTTAddrPointOpLowering::matchAndRewrite( cir::VTTAddrPointOp op, OpAdaptor adaptor, mlir::ConversionPatternRewriter &rewriter) const { const mlir::Type resultType = getTypeConverter()->convertType(op.getType()); + if (!resultType) + return mlir::failure(); llvm::SmallVector<mlir::LLVM::GEPArg> offsets; mlir::Type eltType; mlir::Value llvmAddr = adaptor.getSymAddr(); @@ -5502,6 +5562,8 @@ mlir::LogicalResult CIRToLLVMComplexImagPtrOpLowering::matchAndRewrite( mlir::ConversionPatternRewriter &rewriter) const { cir::PointerType operandTy = op.getOperand().getType(); mlir::Type resultLLVMTy = getTypeConverter()->convertType(op.getType()); + if (!resultLLVMTy) + return mlir::failure(); mlir::Type elementLLVMTy = getTypeConverter()->convertType(operandTy.getPointee()); @@ -5519,6 +5581,8 @@ mlir::LogicalResult CIRToLLVMComplexRealPtrOpLowering::matchAndRewrite( mlir::ConversionPatternRewriter &rewriter) const { cir::PointerType operandTy = op.getOperand().getType(); mlir::Type resultLLVMTy = getTypeConverter()->convertType(op.getType()); + if (!resultLLVMTy) + return mlir::failure(); mlir::Type elementLLVMTy = getTypeConverter()->convertType(operandTy.getPointee()); diff --git a/clang/test/CIR/Lowering/unlowered-address-spaces.cir b/clang/test/CIR/Lowering/unlowered-address-spaces.cir index 0faf18e5d0067..4a09e4b296b77 100644 --- a/clang/test/CIR/Lowering/unlowered-address-spaces.cir +++ b/clang/test/CIR/Lowering/unlowered-address-spaces.cir @@ -2,8 +2,553 @@ !s32i = !cir.int<s, 32> +module attributes {cir.triple = "spirv64-unknown-unknown"} { + // expected-error @below {{failed to legalize operation 'cir.func'}} + cir.func @language_address_space(%arg0: !cir.ptr<!s32i, lang_address_space(offload_global)>) { + cir.return + } +} + +// ----- + +!s32i = !cir.int<s, 32> + +module attributes {cir.triple = "spirv64-unknown-unknown"} { + // expected-error @below {{failed to legalize operation 'cir.func'}} + cir.func private @language_address_space_return() -> !cir.ptr<!s32i, lang_address_space(offload_global)> +} + +// ----- + +!s32i = !cir.int<s, 32> + +module attributes {cir.triple = "spirv64-unknown-unknown"} { + // expected-error @below {{failed to legalize operation 'cir.func'}} + cir.func @nested_language_address_space(%arg0: !cir.ptr<!cir.ptr<!s32i, lang_address_space(offload_local)>>) { + cir.return + } +} + +// ----- + +!s32i = !cir.int<s, 32> + +module attributes {cir.triple = "spirv64-unknown-unknown"} { + // expected-error @below {{failed to legalize operation 'cir.func'}} + cir.func @function_and_array_language_address_space( + %arg0: !cir.ptr<!cir.func<(!cir.ptr<!cir.array<!cir.ptr<!s32i, lang_address_space(offload_constant)> x 4>>)>>) { + cir.return + } +} + +// ----- + +!s32i = !cir.int<s, 32> +// Keep walking after the recursive member to find the language address space. +!rec_Node = !cir.struct<"Node" {data !cir.ptr<!cir.struct<"Node">>, data !cir.ptr<!s32i, lang_address_space(offload_global)>}> + +module attributes {cir.triple = "spirv64-unknown-unknown"} { + // expected-error @below {{failed to legalize operation 'cir.func'}} + cir.func @recursive_struct_language_address_space(%arg0: !cir.ptr<!rec_Node>) { + cir.return + } +} + +// ----- + +!s32i = !cir.int<s, 32> +!rec_U = !cir.union<"U" {data !s32i, data !cir.ptr<!s32i, lang_address_space(offload_global)>}> + +module attributes {cir.triple = "spirv64-unknown-unknown"} { + // expected-error @below {{failed to legalize operation 'cir.func'}} + cir.func @union_language_address_space(%arg0: !cir.ptr<!rec_U>) { + cir.return + } +} + +// ----- + +!s32i = !cir.int<s, 32> +!rec_Foo = !cir.struct<"Foo" {data !s32i}> + +module attributes {cir.triple = "spirv64-unknown-unknown"} { + // expected-error @below {{failed to legalize operation 'cir.func'}} + cir.func @data_member_language_address_space( + %arg0: !cir.ptr<!cir.data_member<!cir.ptr<!s32i, lang_address_space(offload_global)> in !rec_Foo>>) { + cir.return + } +} + +// ----- + +!s32i = !cir.int<s, 32> +!rec_Foo = !cir.struct<"Foo" {data !s32i}> + +module attributes {cir.triple = "spirv64-unknown-unknown"} { + // expected-error @below {{failed to legalize operation 'cir.func'}} + cir.func @method_language_address_space( + %arg0: !cir.ptr<!cir.method<!cir.func<(!cir.ptr<!s32i, lang_address_space(offload_global)>)> in !rec_Foo>>) { + cir.return + } +} + +// ----- + +!s32i = !cir.int<s, 32> + module attributes {cir.triple = "spirv64-unknown-unknown"} { // expected-error @below {{cannot lower a global with a language address space}} // expected-error @below {{failed to legalize operation 'cir.global'}} cir.global external lang_address_space(offload_global) @global = #cir.int<1> : !s32i } + +// ----- + +!s64i = !cir.int<s, 64> +!langptr = !cir.ptr<!cir.void, lang_address_space(offload_global)> +!rec_U = !cir.union<"U" {data !s64i, data !langptr}> + +module attributes {cir.triple = "x86_64-unknown-linux-gnu"} { + // The union's integer storage converts, but its active initializer does not. + // expected-error @below {{failed to legalize operation 'cir.global'}} + cir.global external @union_active_initializer_language_address_space = #cir.const_record<{#cir.ptr<null> : !langptr}> : !rec_U +} + +// ----- + +!s32i = !cir.int<s, 32> + +module attributes {cir.triple = "spirv64-unknown-unknown"} { + // Unlike direct cir.func lowering, a global view can request FuncType + // conversion before its referenced function is lowered. + cir.global external @function_pointer = #cir.global_view<@global_view_callee> : !cir.ptr<!cir.void> + + // expected-error @below {{failed to legalize operation 'cir.func'}} + cir.func private @global_view_callee() -> !cir.ptr<!s32i, lang_address_space(offload_global)> +} + +// ----- + +!s32i = !cir.int<s, 32> +!langptr = !cir.ptr<!s32i, lang_address_space(offload_global)> +!array = !cir.array<!langptr x 1> + +module attributes {cir.triple = "x86_64-unknown-linux-gnu"} { + // Keep the view before its target so the initializer is lowered first. + // expected-error @below {{failed to legalize operation 'cir.global'}} + cir.global external @view = #cir.global_view<@target, [0 : i32]> : !cir.ptr<!cir.void> + + cir.global external @target = #cir.zero : !array +} + +// ----- + +!langptr = !cir.ptr<!cir.int<s, 32>, lang_address_space(offload_global)> +!array = !cir.array<!langptr x 1> +!ptr = !cir.ptr<!cir.void> +!ptrarray = !cir.array<!ptr x 1> + +module attributes {cir.triple = "x86_64-unknown-linux-gnu"} { + // Lower the view before its target, including through enclosing attributes. + // expected-error @below {{failed to legalize operation 'cir.global'}} + cir.global external @view = #cir.const_array<[#cir.global_view<@target, [0 : i32]> : !ptr]> : !ptrarray + + cir.global external @target = #cir.zero : !array +} + +// ----- + +!langptr = !cir.ptr<!cir.int<s, 32>, lang_address_space(offload_global)> +!array = !cir.array<!langptr x 1> +!ptr = !cir.ptr<!cir.void> +!record = !cir.struct<{data !ptr}> + +module attributes {cir.triple = "x86_64-unknown-linux-gnu"} { + // Lower the view before its target, including through enclosing attributes. + // expected-error @below {{failed to legalize operation 'cir.global'}} + cir.global external @view = #cir.const_record<{#cir.global_view<@target, [0 : i32]> : !ptr}> : !record + + cir.global external @target = #cir.zero : !array +} + +// ----- + +!langptr = !cir.ptr<!cir.int<s, 32>, lang_address_space(offload_global)> +!array = !cir.array<!langptr x 1> +!ptr = !cir.ptr<!cir.void> +!record = !cir.struct<{data !ptr}> + +module attributes {cir.triple = "x86_64-unknown-linux-gnu"} { + // Lower the view before its target, including through enclosing attributes. + // expected-error @below {{failed to legalize operation 'cir.global'}} + cir.global external @view = #cir.typeinfo<{#cir.global_view<@target, [0 : i32]> : !ptr}> : !record + + cir.global external @target = #cir.zero : !array +} + +// ----- + +!langptr = !cir.ptr<!cir.int<s, 32>, lang_address_space(offload_global)> +!array = !cir.array<!langptr x 1> +!ptr = !cir.ptr<!cir.void> +!ptrarray = !cir.array<!ptr x 1> +!vtable = !cir.struct<{data !ptrarray}> + +module attributes {cir.triple = "x86_64-unknown-linux-gnu"} { + // Lower the view before its target, including through enclosing attributes. + // expected-error @below {{failed to legalize operation 'cir.global'}} + cir.global external @view = #cir.vtable<{#cir.const_array<[#cir.global_view<@target, [0 : i32]> : !ptr]> : !ptrarray}> : !vtable + + cir.global external @target = #cir.zero : !array +} + +// ----- + +!s32i = !cir.int<s, 32> + +module attributes {cir.triple = "spirv64-unknown-unknown"} { + // Keep the function before the global so get_global is lowered first. + cir.func @get_global_language_address_space() { + // expected-error @below {{failed to legalize operation 'cir.get_global'}} + %0 = cir.get_global @global : !cir.ptr<!s32i, lang_address_space(offload_global)> + %1 = cir.load %0 : !cir.ptr<!s32i, lang_address_space(offload_global)>, !s32i + cir.return + } + + cir.global external lang_address_space(offload_global) @global = #cir.int<1> : !s32i +} + +// ----- + +!s32i = !cir.int<s, 32> + +module attributes {cir.triple = "spirv64-unknown-unknown"} { + cir.func @alloca_language_address_space() { + // expected-error @below {{failed to legalize operation 'cir.alloca'}} + %0 = cir.alloca "x" align(4) : !cir.ptr<!s32i, lang_address_space(offload_private)> + cir.return + } +} + +// ----- + +!s32i = !cir.int<s, 32> + +module attributes {cir.triple = "spirv64-unknown-unknown"} { + cir.func @null_constant_language_address_space() { + // expected-error @below {{failed to legalize operation 'cir.const'}} + %0 = cir.const #cir.ptr<null> : !cir.ptr<!s32i, lang_address_space(offload_global)> + cir.return + } +} + +// ----- + +!langptr = !cir.ptr<!cir.int<s, 32>, lang_address_space(offload_global)> +!array = !cir.array<!langptr x 1> +!ptr = !cir.ptr<!cir.void> + +module attributes {cir.triple = "x86_64-unknown-linux-gnu"} { + // Lower the view before its target, including through enclosing attributes. + cir.func @constant_global_view_language_address_space() { + // expected-error @below {{failed to legalize operation 'cir.const'}} + %0 = cir.const #cir.global_view<@target, [0 : i32]> : !ptr + cir.return + } + + cir.global external @target = #cir.zero : !array +} + +// ----- + +!langptr = !cir.ptr<!cir.int<s, 32>, lang_address_space(offload_global)> +!array = !cir.array<!langptr x 1> +!ptr = !cir.ptr<!cir.void> + +module attributes {cir.triple = "x86_64-unknown-linux-gnu"} { + // Lower the view before its target, including through enclosing attributes. + cir.func @constant_array_global_view_language_address_space() { + // expected-error @below {{failed to legalize operation 'cir.const'}} + %0 = cir.const #cir.const_array<[#cir.global_view<@target, [0 : i32]> : !ptr]> : !cir.array<!ptr x 1> + cir.return + } + + cir.global external @target = #cir.zero : !array +} + +// ----- + +!langptr = !cir.ptr<!cir.int<s, 32>, lang_address_space(offload_global)> +!array = !cir.array<!langptr x 1> +!ptr = !cir.ptr<!cir.void> + +module attributes {cir.triple = "x86_64-unknown-linux-gnu"} { + // Lower the view before its target, including through enclosing attributes. + cir.func @constant_record_global_view_language_address_space() { + // expected-error @below {{failed to legalize operation 'cir.const'}} + %0 = cir.const #cir.const_record<{#cir.global_view<@target, [0 : i32]> : !ptr}> : !cir.struct<{data !ptr}> + cir.return + } + + cir.global external @target = #cir.zero : !array +} + +// ----- + +!s64i = !cir.int<s, 64> +!langptr = !cir.ptr<!cir.void, lang_address_space(offload_global)> +!rec_U = !cir.union<"U" {data !s64i, data !langptr}> + +module attributes {cir.triple = "x86_64-unknown-linux-gnu"} { + cir.func @constant_union_active_initializer_language_address_space() { + // expected-error @below {{failed to legalize operation 'cir.const'}} + %0 = cir.const #cir.const_record<{#cir.ptr<null> : !langptr}> : !rec_U + cir.return + } +} + +// ----- + +!s64i = !cir.int<s, 64> +!langptr = !cir.ptr<!cir.void, lang_address_space(offload_global)> +!rec_U = !cir.union<"U" {data !s64i, data !langptr}> +!rec_Outer = !cir.union<"Outer" {data !s64i, data !rec_U}> +!rec_S = !cir.struct<"S" {data !rec_Outer}> + +module attributes {cir.triple = "x86_64-unknown-linux-gnu"} { + // Propagate adjustment failure through both the enclosing union and struct. + cir.func @constant_nested_union_initializer_language_address_space() { + // expected-error @below {{failed to legalize operation 'cir.const'}} + %0 = cir.const #cir.const_record<{#cir.const_record<{#cir.const_record<{#cir.ptr<null> : !langptr}> : !rec_U}> : !rec_Outer}> : !rec_S + cir.return + } +} + +// ----- + +!s64i = !cir.int<s, 64> +!langptr = !cir.ptr<!cir.void, lang_address_space(offload_global)> +!rec_U = !cir.union<"U" {data !s64i, data !langptr}> +!array = !cir.array<!rec_U x 1> + +module attributes {cir.triple = "x86_64-unknown-linux-gnu"} { + cir.func @constant_union_array_initializer_language_address_space() { + // expected-error @below {{failed to legalize operation 'cir.const'}} + %0 = cir.const #cir.const_array<[#cir.const_record<{#cir.ptr<null> : !langptr}> : !rec_U]> : !array + cir.return + } +} + +// ----- + +!s32i = !cir.int<s, 32> + +module attributes {cir.triple = "spirv64-unknown-unknown"} { + cir.func @int_to_ptr_language_address_space(%arg0: !s32i) { + // expected-error @below {{failed to legalize operation 'cir.cast'}} + %0 = cir.cast int_to_ptr %arg0 : !s32i -> !cir.ptr<!s32i, lang_address_space(offload_global)> + cir.return + } +} + +// ----- + +!s32i = !cir.int<s, 32> + +module attributes {cir.triple = "spirv64-unknown-unknown"} { + cir.func @address_space_cast_language_address_space(%arg0: !cir.ptr<!s32i>) { + // expected-error @below {{failed to legalize operation 'cir.cast'}} + %0 = cir.cast address_space %arg0 : !cir.ptr<!s32i> -> !cir.ptr<!s32i, lang_address_space(offload_global)> + cir.return + } +} + +// ----- + +!s32i = !cir.int<s, 32> +!rec_Base = !cir.struct<"Base" {data !s32i}> +!rec_Derived = !cir.struct<"Derived" {data !rec_Base}> + +module attributes {cir.triple = "x86_64-unknown-linux-gnu"} { + // The operand remains convertible; only the result needs rejection. + cir.func @base_class_addr_language_address_space(%derived: !cir.ptr<!rec_Derived>) { + // expected-error @below {{failed to legalize operation 'cir.base_class_addr'}} + %base = cir.base_class_addr %derived : !cir.ptr<!rec_Derived> nonnull [0] -> !cir.ptr<!rec_Base, lang_address_space(offload_private)> + cir.return + } +} + +// ----- + +!s32i = !cir.int<s, 32> +!rec_Base = !cir.struct<"Base" {data !s32i}> +!rec_Derived = !cir.struct<"Derived" {data !cir.ptr<!s32i, lang_address_space(offload_global)>, data !rec_Base}> + +module attributes {cir.triple = "x86_64-unknown-linux-gnu"} { + cir.func @derived_class_addr_language_address_space() { + %base = cir.alloca "base" align(4) : !cir.ptr<!rec_Base> + // expected-error @below {{failed to legalize operation 'cir.derived_class_addr'}} + %derived = cir.derived_class_addr %base : !cir.ptr<!rec_Base> nonnull [4] -> !cir.ptr<!rec_Derived> + cir.return + } +} + +// ----- + +!s32i = !cir.int<s, 32> +!rec_S = !cir.struct<"S" {data !s32i}> + +module attributes {cir.triple = "x86_64-unknown-linux-gnu"} { + cir.func @get_struct_member_language_address_space(%record: !cir.ptr<!rec_S>) { + // expected-error @below {{failed to legalize operation 'cir.get_member'}} + %member = cir.get_member %record[0] {name = "member"} : !cir.ptr<!rec_S> -> !cir.ptr<!s32i, lang_address_space(offload_private)> + cir.return + } +} + +// ----- + +!s32i = !cir.int<s, 32> +!rec_U = !cir.union<"U" {data !s32i}> + +module attributes {cir.triple = "x86_64-unknown-linux-gnu"} { + cir.func @get_union_member_language_address_space(%record: !cir.ptr<!rec_U>) { + // expected-error @below {{failed to legalize operation 'cir.get_member'}} + %member = cir.get_member %record[0] {name = "member"} : !cir.ptr<!rec_U> -> !cir.ptr<!s32i, lang_address_space(offload_private)> + cir.return + } +} + +// ----- + +module attributes {cir.triple = "x86_64-unknown-linux-gnu"} { + cir.func @complex_real_ptr_language_address_space(%ptr: !cir.ptr<!cir.complex<!cir.double>>) { + // expected-error @below {{failed to legalize operation 'cir.complex.real_ptr'}} + %real = cir.complex.real_ptr %ptr : !cir.ptr<!cir.complex<!cir.double>> -> !cir.ptr<!cir.double, lang_address_space(offload_private)> + cir.return + } +} + +// ----- + +module attributes {cir.triple = "x86_64-unknown-linux-gnu"} { + cir.func @complex_imag_ptr_language_address_space(%ptr: !cir.ptr<!cir.complex<!cir.double>>) { + // expected-error @below {{failed to legalize operation 'cir.complex.imag_ptr'}} + %imag = cir.complex.imag_ptr %ptr : !cir.ptr<!cir.complex<!cir.double>> -> !cir.ptr<!cir.double, lang_address_space(offload_private)> + cir.return + } +} + +// ----- + +!langptr = !cir.ptr<!cir.int<s, 32>, lang_address_space(offload_global)> +!array = !cir.array<!langptr x 1> + +module attributes {cir.triple = "x86_64-unknown-linux-gnu"} { + // Lower the address point before its referenced global. + cir.func @vtable_symbol_language_address_space() { + // expected-error @below {{failed to legalize operation 'cir.vtable.address_point'}} + %0 = cir.vtable.address_point(@target, address_point = <index = 0, offset = 0>) : !cir.vptr + cir.return + } + + cir.global "private" external @target : !cir.struct<{data !array}> +} + +// ----- + +!s32i = !cir.int<s, 32> +!langptr = !cir.ptr<!s32i, lang_address_space(offload_global)> +!fn = !cir.func<() -> !langptr> +!fnptr = !cir.ptr<!fn> +!fnptrptr = !cir.ptr<!fnptr> + +module attributes {cir.triple = "x86_64-unknown-linux-gnu"} { + cir.func @virtual_fn_addr_language_address_space(%vptr: !cir.vptr) { + // expected-error @below {{failed to legalize operation 'cir.vtable.get_virtual_fn_addr'}} + %0 = cir.vtable.get_virtual_fn_addr %vptr[0] : !cir.vptr -> !fnptrptr + cir.return + } +} + +// ----- + +module attributes {cir.triple = "x86_64-unknown-linux-gnu"} { + cir.func @vtt_address_point_language_address_space( + %vtt: !cir.ptr<!cir.ptr<!cir.void>>) { + // expected-error @below {{failed to legalize operation 'cir.vtt.address_point'}} + %0 = cir.vtt.address_point %vtt : !cir.ptr<!cir.ptr<!cir.void>>, offset = 1 -> !cir.ptr<!cir.ptr<!cir.void>, lang_address_space(offload_global)> + cir.return + } +} + +// ----- + +!langptr = !cir.ptr<!cir.int<s, 32>, lang_address_space(offload_global)> +!array = !cir.array<!langptr x 1> +!ptr = !cir.ptr<!cir.void> + +module attributes {cir.triple = "x86_64-unknown-linux-gnu"} { + // Lower the address point before its referenced global. + cir.func @vtt_symbol_language_address_space() { + // expected-error @below {{failed to legalize operation 'cir.vtt.address_point'}} + %0 = cir.vtt.address_point @target, offset = 0 -> !cir.ptr<!ptr> + cir.return + } + + cir.global "private" external @target : !array +} + +// ----- + +!u8i = !cir.int<u, 8> +!u32i = !cir.int<u, 32> + +module attributes {cir.triple = "x86_64-unknown-linux-gnu"} { + cir.func @frame_address_language_address_space() { + %level = cir.const #cir.int<0> : !u32i + // expected-error @below {{failed to legalize operation 'cir.frame_address'}} + %0 = cir.frame_address(%level) : !cir.ptr<!u8i, lang_address_space(offload_global)> + cir.return + } +} + +// ----- + +!u8i = !cir.int<u, 8> + +module attributes {cir.triple = "x86_64-unknown-linux-gnu"} { + cir.func @address_of_return_address_language_address_space() { + // expected-error @below {{failed to legalize operation 'cir.address_of_return_address'}} + %0 = cir.address_of_return_address : !cir.ptr<!u8i, lang_address_space(offload_global)> + cir.return + } +} + +// ----- + +!u8i = !cir.int<u, 8> + +module attributes {cir.triple = "x86_64-unknown-linux-gnu"} { + cir.func @stacksave_language_address_space() { + // expected-error @below {{failed to legalize operation 'cir.stacksave'}} + %0 = cir.stacksave : !cir.ptr<!u8i, lang_address_space(offload_global)> + cir.return + } +} + +// ----- + +!s32i = !cir.int<s, 32> + +module attributes {cir.triple = "x86_64-unknown-linux-gnu"} { + cir.func @inline_asm_language_address_space() { + // expected-error @below {{failed to legalize operation 'cir.asm'}} + %0 = cir.asm(x86_att, + out = [], + in = [], + in_out = [], + {"" "=r"}) -> !cir.ptr<!s32i, lang_address_space(offload_global)> + cir.return + } +} diff --git a/clang/utils/TableGen/CIRLoweringEmitter.cpp b/clang/utils/TableGen/CIRLoweringEmitter.cpp index 756b6265b90f4..df38bea8ed013 100644 --- a/clang/utils/TableGen/CIRLoweringEmitter.cpp +++ b/clang/utils/TableGen/CIRLoweringEmitter.cpp @@ -232,6 +232,8 @@ void GenerateLLVMLoweringPattern( } else { Code << " mlir::Type resTy = " "typeConverter->convertType(op.getType());\n"; + Code << " if (!resTy)\n"; + Code << " return mlir::failure();\n"; Code << " rewriter.replaceOpWithNewOp<mlir::LLVM::" << LLVMOp << ">(op, mlir::TypeRange{resTy}, adaptor.getOperands(), " << Properties << ");\n"; _______________________________________________ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
