From c4ad0314fd9c9f51d6cfaf9468271a6bb5223b38 Mon Sep 17 00:00:00 2001 From: Chuanqi Xu Date: Tue, 26 Nov 2024 15:36:33 +0800 Subject: [PATCH] [CIR] Remove InavalidUnionFieldAttr and remove a check in array attr --- .../include/clang/CIR/Dialect/IR/CIRAttrs.td | 15 ------ clang/lib/CIR/CodeGen/CIRGenBuilder.h | 3 -- clang/lib/CIR/CodeGen/CIRGenExprConst.cpp | 28 +--------- clang/lib/CIR/Dialect/IR/CIRDialect.cpp | 16 +----- .../CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp | 8 --- clang/test/CIR/CodeGen/nested-union-array.c | 33 ------------ clang/test/CIR/CodeGen/union-init.c | 13 +++-- clang/test/CIR/IR/invalid.cir | 3 +- clang/test/CIR/Lowering/nested-union-array.c | 28 ++++++++++ .../test/CIR/Lowering/union-in-struct-init.c | 51 +++++++++++++++++++ 10 files changed, 89 insertions(+), 109 deletions(-) delete mode 100644 clang/test/CIR/CodeGen/nested-union-array.c create mode 100644 clang/test/CIR/Lowering/nested-union-array.c create mode 100644 clang/test/CIR/Lowering/union-in-struct-init.c diff --git a/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td index d0ac1d00c4b5..71d8439e175a 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td +++ b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td @@ -92,21 +92,6 @@ def CIR_BoolAttr : CIR_Attr<"Bool", "bool", [TypedAttrInterface]> { }]; } -//===----------------------------------------------------------------------===// -// InactiveUnionFieldAttr -//===----------------------------------------------------------------------===// - -def InactiveUnionFieldAttr : CIR_Attr<"InactiveUnionField", "inactive_field", [TypedAttrInterface]> { - let summary = "Attribute to represent an uninitialized field for a union."; - let description = [{ - The InactiveUnionFieldAttr is used to represent an uninitialized field - for a union. - }]; - - let parameters = (ins AttributeSelfTypeParameter<"">:$type); - let assemblyFormat = [{}]; -} - //===----------------------------------------------------------------------===// // ZeroAttr //===----------------------------------------------------------------------===// diff --git a/clang/lib/CIR/CodeGen/CIRGenBuilder.h b/clang/lib/CIR/CodeGen/CIRGenBuilder.h index ea5fb980cc40..28be733f62d7 100644 --- a/clang/lib/CIR/CodeGen/CIRGenBuilder.h +++ b/clang/lib/CIR/CodeGen/CIRGenBuilder.h @@ -297,9 +297,6 @@ class CIRGenBuilderTy : public cir::CIRBaseBuilderTy { return true; } - if (mlir::isa(attr)) - return true; - llvm_unreachable("NYI"); } diff --git a/clang/lib/CIR/CodeGen/CIRGenExprConst.cpp b/clang/lib/CIR/CodeGen/CIRGenExprConst.cpp index deea4159ff36..67eee98667bc 100644 --- a/clang/lib/CIR/CodeGen/CIRGenExprConst.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenExprConst.cpp @@ -377,31 +377,7 @@ mlir::Attribute ConstantAggregateBuilder::buildFrom( CharUnits AlignedSize = Size.alignTo(Align); bool Packed = false; - ArrayRef UnpackedElems; - - // Fill the init elements for union. This comes from a fundamental - // difference between CIR and LLVM IR. In LLVM IR, the union is simply a - // struct with the largest member. So it is fine to have only one init - // element. But in CIR, the union has the information for all members. So if - // we only pass a single init element, we may be in trouble. We solve the - // problem by appending placeholder attribute for the uninitialized fields. - llvm::SmallVector UnionElemsStorage; - if (auto desired = dyn_cast(DesiredTy); - desired && desired.isUnion() && - Elems.size() != desired.getNumElements()) { - for (auto elemTy : desired.getMembers()) { - if (auto Ty = mlir::dyn_cast(Elems.back()); - Ty && Ty.getType() == elemTy) - UnionElemsStorage.push_back(Elems.back()); - else - UnionElemsStorage.push_back(cir::InactiveUnionFieldAttr::get( - CGM.getBuilder().getContext(), elemTy)); - } - - UnpackedElems = UnionElemsStorage; - } else { - UnpackedElems = Elems; - } + ArrayRef UnpackedElems = Elems; llvm::SmallVector UnpackedElemStorage; if (DesiredSize < AlignedSize || DesiredSize.alignTo(Align) != DesiredSize) { @@ -1048,8 +1024,6 @@ class ConstExprEmitter return {}; if (i == 0) CommonElementType = C.getType(); - else if (C.getType() != CommonElementType) - CommonElementType = nullptr; Elts.push_back(std::move(C)); } diff --git a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp index 78a8ed9c5c6f..71639fbc8ebe 100644 --- a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp +++ b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp @@ -3197,21 +3197,7 @@ LogicalResult cir::ConstArrayAttr::verify( // Make sure both number of elements and subelement types match type. if (at.getSize() != arrayAttr.size() + trailingZerosNum) return emitError() << "constant array size should match type size"; - LogicalResult eltTypeCheck = success(); - arrayAttr.walkImmediateSubElements( - [&](Attribute attr) { - // Once we find a mismatch, stop there. - if (eltTypeCheck.failed()) - return; - auto typedAttr = mlir::dyn_cast(attr); - if (!typedAttr || typedAttr.getType() != at.getEltType()) { - eltTypeCheck = failure(); - emitError() - << "constant array element should match array element type"; - } - }, - [&](Type type) {}); - return eltTypeCheck; + return success(); } ::mlir::Attribute cir::ConstArrayAttr::parse(::mlir::AsmParser &parser, diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp index ad97f2a9b56d..2ea5ce3c0f32 100644 --- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp +++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp @@ -436,14 +436,6 @@ lowerCirAttrAsValue(mlir::Operation *parentOp, cir::ConstStructAttr constStruct, // Iteratively lower each constant element of the struct. for (auto [idx, elt] : llvm::enumerate(constStruct.getMembers())) { - if (auto constStructType = dyn_cast(constStruct.getType()); - constStructType && constStructType.isUnion()) { - if (isa(elt)) - continue; - - idx = 0; - } - mlir::Value init = lowerCirAttrAsValue(parentOp, elt, rewriter, converter); result = rewriter.create(loc, result, init, idx); } diff --git a/clang/test/CIR/CodeGen/nested-union-array.c b/clang/test/CIR/CodeGen/nested-union-array.c deleted file mode 100644 index 7684e3c951c7..000000000000 --- a/clang/test/CIR/CodeGen/nested-union-array.c +++ /dev/null @@ -1,33 +0,0 @@ -// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o %t.cir -// RUN: FileCheck --input-file=%t.cir %s --check-prefix=CIR -// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm %s -o %t.ll -// RUN: FileCheck --input-file=%t.ll %s --check-prefix=LLVM - -struct nested -{ - union { - const char *single; - const char *const *multi; - } output; -}; -static const char * const test[] = { - "test", -}; -const struct nested data[] = -{ - { - { - .multi = test, - }, - }, - { - { - .single = "hello", - }, - }, -}; - -// CIR: ![[ANON_TY:.+]] = !cir.struct, !cir.ptr> -// CIR: ![[NESTED_TY:.+]] = !cir.struct, #cir.global_view<@test> : !cir.ptr>}> : ![[ANON_TY]]}> : ![[NESTED_TY:.+]], #cir.const_struct<{#cir.const_struct<{#cir.global_view<@".str"> : !cir.ptr, #cir.inactive_field : !cir.ptr>}> : ![[ANON_TY]]}> : ![[NESTED_TY:.+]]]> : !cir.array -// LLVM: @data = constant [2 x {{.*}}] diff --git a/clang/test/CIR/CodeGen/union-init.c b/clang/test/CIR/CodeGen/union-init.c index d6f2e949b16e..122999de23c2 100644 --- a/clang/test/CIR/CodeGen/union-init.c +++ b/clang/test/CIR/CodeGen/union-init.c @@ -12,12 +12,10 @@ void foo(int x) { A a = {.x = x}; } -// CHECK-DAG: ![[TY_U:.*]] = !cir.struct -// CHECK-DAG: ![[anon0:.*]] = !cir.struct +// CHECK-DAG: ![[anon:.*]] = !cir.struct // CHECK-DAG: #[[bfi_x:.*]] = #cir.bitfield_info // CHECK-DAG: #[[bfi_y:.*]] = #cir.bitfield_info -// CHECK-DAG: ![[TY_A:.*]] = !cir.struct // CHECK-DAG: ![[anon1:.*]] = !cir.struct} // CHECK-LABEL: cir.func @foo( @@ -34,7 +32,7 @@ void foo(int x) { // CHECK: cir.return union { int i; float f; } u = { }; -// CHECK: cir.global external @u = #cir.zero : ![[TY_u]] +// CHECK: cir.global external @u = #cir.zero : ![[anon]] unsigned is_little(void) { const union { @@ -45,8 +43,9 @@ unsigned is_little(void) { } // CHECK: cir.func @is_little -// CHECK: %[[VAL_1:.*]] = cir.get_global @is_little.one : !cir.ptr -// CHECK: %[[VAL_2:.*]] = cir.get_member %[[VAL_1]][1] {name = "c"} : !cir.ptr -> !cir.ptr> +// CHECK: %[[VAL_1:.*]] = cir.get_global @is_little.one : !cir.ptr +// CHECK: %[[VAL_2:.*]] = cir.cast(bitcast, %[[VAL_1]] : !cir.ptr), !cir.ptr +// CHECK: %[[VAL_3:.*]] = cir.get_member %[[VAL_2]][1] {name = "c"} : !cir.ptr -> !cir.ptr> typedef union { int x; diff --git a/clang/test/CIR/IR/invalid.cir b/clang/test/CIR/IR/invalid.cir index 01828fbe22b4..80fe6e114127 100644 --- a/clang/test/CIR/IR/invalid.cir +++ b/clang/test/CIR/IR/invalid.cir @@ -328,7 +328,8 @@ cir.func @cast27(%p : !u64i) { !u32i = !cir.int !u8i = !cir.int module { - // expected-error@+1 {{constant array element should match array element type}} + // FIXME: The check for equality of the array element type is currently disabled due to https://github.com/llvm/clangir/pull/1007 + // expected error {{constant array element should match array element type}} cir.global external @a = #cir.const_array<[#cir.int<0> : !u8i, #cir.int<23> : !u8i, #cir.int<33> : !u8i] : !cir.array> } diff --git a/clang/test/CIR/Lowering/nested-union-array.c b/clang/test/CIR/Lowering/nested-union-array.c new file mode 100644 index 000000000000..f48f687dc2ab --- /dev/null +++ b/clang/test/CIR/Lowering/nested-union-array.c @@ -0,0 +1,28 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm %s -o %t.ll +// RUN: FileCheck --input-file=%t.ll %s --check-prefix=LLVM + +struct nested +{ + union { + const char *single; + const char *const *multi; + } output; +}; +static const char * const test[] = { + "test", +}; +const struct nested data[] = +{ + { + { + .multi = test, + }, + }, + { + { + .single = "hello", + }, + }, +}; + +// LLVM: @data = constant [2 x {{.*}}] diff --git a/clang/test/CIR/Lowering/union-in-struct-init.c b/clang/test/CIR/Lowering/union-in-struct-init.c new file mode 100644 index 000000000000..80b5ed32ad75 --- /dev/null +++ b/clang/test/CIR/Lowering/union-in-struct-init.c @@ -0,0 +1,51 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm %s -o %t.ll +// RUN: FileCheck --input-file=%t.ll %s --check-prefix=LLVM +typedef struct { + union { + int a; + long b; + }; +} S; + +S s = { .a = 1 }; + +// LLVM: @s = global { { i32, [4 x i8] } } { { i32, [4 x i8] } { i32 1, [4 x i8] zeroinitializer } } + +typedef struct { + union { + int a; + long b; + }; +} S2; + +S2 s2 = { .b = 1 }; + +// LLVM: @s2 = global { { i64 } } { { i64 } { i64 1 } } + +typedef struct { + union { + int a; + long b; + long double c; + }; +} S3; + +S3 s3 = { .a = 1 }; + +// LLVM: @s3 = global { { i32, [12 x i8] } } { { i32, [12 x i8] } { i32 1, [12 x i8] zeroinitializer } } + +typedef struct { + int a, b, c, d; +} T; + +typedef union { + struct { + int a; + long b; + }; + T c; +} S4; + +S4 s4 = {.c = {1, 2, 3, 4}}; + +// LLVM: @s4 = global { %struct.T } { %struct.T { i32 1, i32 2, i32 3, i32 4 } }