From 6a110312f2be0b21c1a94806cbdd3a9ba30c85e0 Mon Sep 17 00:00:00 2001 From: bruteforceboy Date: Tue, 17 Sep 2024 16:52:38 +0300 Subject: [PATCH 1/5] [CIR][Lowering] Fix lowering for multi dimensional array --- clang/lib/CIR/Lowering/LoweringHelpers.cpp | 10 ++++++++++ clang/test/CIR/Lowering/array-init.c | 11 +++++++++++ 2 files changed, 21 insertions(+) diff --git a/clang/lib/CIR/Lowering/LoweringHelpers.cpp b/clang/lib/CIR/Lowering/LoweringHelpers.cpp index debe7881d0c4..090106019eac 100644 --- a/clang/lib/CIR/Lowering/LoweringHelpers.cpp +++ b/clang/lib/CIR/Lowering/LoweringHelpers.cpp @@ -64,6 +64,16 @@ mlir::Type getNestedTypeAndElemQuantity(mlir::Type Ty, unsigned &elemQuantity) { template void convertToDenseElementsAttrImpl(mlir::cir::ConstArrayAttr attr, llvm::SmallVectorImpl &values) { + if (auto stringAttr = mlir::dyn_cast(attr.getElts())) { + if (auto arrayType = mlir::dyn_cast(attr.getType())) { + for (auto element : stringAttr) { + auto intAttr = mlir::cir::IntAttr::get(arrayType.getEltType(), element); + values.push_back(mlir::dyn_cast(intAttr).getValue()); + } + return; + } + } + auto arrayAttr = mlir::cast(attr.getElts()); for (auto eltAttr : arrayAttr) { if (auto valueAttr = mlir::dyn_cast(eltAttr)) { diff --git a/clang/test/CIR/Lowering/array-init.c b/clang/test/CIR/Lowering/array-init.c index ab0ddb4dd0ea..291282dd8184 100644 --- a/clang/test/CIR/Lowering/array-init.c +++ b/clang/test/CIR/Lowering/array-init.c @@ -8,3 +8,14 @@ void zeroInit() { int a[3] = {0, 0, 0}; } +// LLVM{LITERAL}: %1 = alloca [4 x [1 x i8]], i64 1, align 1, !dbg !9 +// LLVM{LITERAL}: store [4 x [1 x i8]] [[1 x i8] c"a", [1 x i8] c"b", [1 x i8] c"c", [1 x i8] c"d"], ptr %1, align 1, !dbg !9 +void charInit1() { + char arr[4][1] = {"a", "b", "c", "d"}; +} + +// LLVM{LITERAL}: %1 = alloca [4 x [2 x i8]], i64 1, align 1, !dbg !12 +// LLVM{LITERAL}: store [4 x [2 x i8]] [[2 x i8] c"ab", [2 x i8] c"cd", [2 x i8] c"ef", [2 x i8] c"gh"], ptr %1, align 1, !dbg !12 +void charInit2() { + char arr[4][2] = {"ab", "cd", "ef", "gh"}; +} \ No newline at end of file From 2694e254141c9cdfa5481ff06831dbb1c895a662 Mon Sep 17 00:00:00 2001 From: bruteforceboy Date: Wed, 18 Sep 2024 12:13:04 +0300 Subject: [PATCH 2/5] update array-init.c and extra test --- clang/lib/CIR/Lowering/LoweringHelpers.cpp | 27 ++++++++++++++-------- clang/test/CIR/Lowering/array-init.c | 18 ++++++++++----- 2 files changed, 29 insertions(+), 16 deletions(-) diff --git a/clang/lib/CIR/Lowering/LoweringHelpers.cpp b/clang/lib/CIR/Lowering/LoweringHelpers.cpp index 090106019eac..814ac4015b9c 100644 --- a/clang/lib/CIR/Lowering/LoweringHelpers.cpp +++ b/clang/lib/CIR/Lowering/LoweringHelpers.cpp @@ -61,6 +61,21 @@ mlir::Type getNestedTypeAndElemQuantity(mlir::Type Ty, unsigned &elemQuantity) { return nestTy; } +template +void fillTrailingZeros(mlir::cir::ConstArrayAttr attr, + llvm::SmallVectorImpl &values) { + auto numTrailingZeros = attr.getTrailingZerosNum(); + if (numTrailingZeros) { + auto localArrayTy = mlir::dyn_cast(attr.getType()); + assert(localArrayTy && "expected !cir.array"); + + auto nestTy = localArrayTy.getEltType(); + if (!mlir::isa(nestTy)) + values.insert(values.end(), numTrailingZeros, + getZeroInitFromType(nestTy)); + } +} + template void convertToDenseElementsAttrImpl(mlir::cir::ConstArrayAttr attr, llvm::SmallVectorImpl &values) { @@ -81,6 +96,7 @@ void convertToDenseElementsAttrImpl(mlir::cir::ConstArrayAttr attr, } else if (auto subArrayAttr = mlir::dyn_cast(eltAttr)) { convertToDenseElementsAttrImpl(subArrayAttr, values); + fillTrailingZeros(subArrayAttr, values); } else if (auto zeroAttr = mlir::dyn_cast(eltAttr)) { unsigned numStoredZeros = 0; auto nestTy = @@ -94,16 +110,7 @@ void convertToDenseElementsAttrImpl(mlir::cir::ConstArrayAttr attr, // Only fill in trailing zeros at the local cir.array level where the element // type isn't another array (for the mult-dim case). - auto numTrailingZeros = attr.getTrailingZerosNum(); - if (numTrailingZeros) { - auto localArrayTy = mlir::dyn_cast(attr.getType()); - assert(localArrayTy && "expected !cir.array"); - - auto nestTy = localArrayTy.getEltType(); - if (!mlir::isa(nestTy)) - values.insert(values.end(), numTrailingZeros, - getZeroInitFromType(nestTy)); - } + fillTrailingZeros(attr, values); } template diff --git a/clang/test/CIR/Lowering/array-init.c b/clang/test/CIR/Lowering/array-init.c index 291282dd8184..0b9a19b5c9ba 100644 --- a/clang/test/CIR/Lowering/array-init.c +++ b/clang/test/CIR/Lowering/array-init.c @@ -1,6 +1,12 @@ // 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 +// LLVM: charInit1.ar = internal global [4 x [4 x i8]] {{.*}}4 x i8] c"aa\00\00", [4 x i8] c"aa\00\00", [4 x i8] c"aa\00\00", [4 x i8] c"aa\00\00"], align 16 +char charInit1() { + static char ar[][4] = {"aa", "aa", "aa", "aa"}; + return ar[0][0]; +} + // LLVM: define dso_local void @zeroInit // LLVM: [[RES:%.*]] = alloca [3 x i32], i64 1 // LLVM: store [3 x i32] zeroinitializer, ptr [[RES]] @@ -8,14 +14,14 @@ void zeroInit() { int a[3] = {0, 0, 0}; } -// LLVM{LITERAL}: %1 = alloca [4 x [1 x i8]], i64 1, align 1, !dbg !9 -// LLVM{LITERAL}: store [4 x [1 x i8]] [[1 x i8] c"a", [1 x i8] c"b", [1 x i8] c"c", [1 x i8] c"d"], ptr %1, align 1, !dbg !9 -void charInit1() { +// LLVM: %1 = alloca [4 x [1 x i8]], i64 1, align 1 +// LLVM: store [4 x [1 x i8]] {{.*}}1 x i8] c"a", [1 x i8] c"b", [1 x i8] c"c", [1 x i8] c"d"], ptr %1, align 1 +void charInit2() { char arr[4][1] = {"a", "b", "c", "d"}; } -// LLVM{LITERAL}: %1 = alloca [4 x [2 x i8]], i64 1, align 1, !dbg !12 -// LLVM{LITERAL}: store [4 x [2 x i8]] [[2 x i8] c"ab", [2 x i8] c"cd", [2 x i8] c"ef", [2 x i8] c"gh"], ptr %1, align 1, !dbg !12 -void charInit2() { +// LLVM: %1 = alloca [4 x [2 x i8]], i64 1, align 1 +// LLVM: store [4 x [2 x i8]] {{.*}}2 x i8] c"ab", [2 x i8] c"cd", [2 x i8] c"ef", [2 x i8] c"gh"], ptr %1, align 1 +void charInit3() { char arr[4][2] = {"ab", "cd", "ef", "gh"}; } \ No newline at end of file From 0bfd66de2a99176084e29adcb64f9b0b1f7cb94f Mon Sep 17 00:00:00 2001 From: bruteforceboy Date: Wed, 18 Sep 2024 13:10:16 +0300 Subject: [PATCH 3/5] undo forced push --- clang/lib/CIR/CodeGen/CIRGenExprAgg.cpp | 1 - clang/test/CIR/CodeGen/array-init.cpp | 38 +++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 clang/test/CIR/CodeGen/array-init.cpp diff --git a/clang/lib/CIR/CodeGen/CIRGenExprAgg.cpp b/clang/lib/CIR/CodeGen/CIRGenExprAgg.cpp index 9ed791a75f83..6afcbab7065d 100644 --- a/clang/lib/CIR/CodeGen/CIRGenExprAgg.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenExprAgg.cpp @@ -480,7 +480,6 @@ void AggExprEmitter::buildArrayInit(Address DestPtr, mlir::cir::ArrayType AType, uint64_t NumInitElements = Args.size(); uint64_t NumArrayElements = AType.getSize(); - assert(NumInitElements != 0 && "expected at least one initializaed value"); assert(NumInitElements <= NumArrayElements); QualType elementType = diff --git a/clang/test/CIR/CodeGen/array-init.cpp b/clang/test/CIR/CodeGen/array-init.cpp new file mode 100644 index 000000000000..ffd33cccab55 --- /dev/null +++ b/clang/test/CIR/CodeGen/array-init.cpp @@ -0,0 +1,38 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -std=c++17 -fclangir -emit-cir %s -o %t.cir +// RUN: FileCheck --input-file=%t.cir %s + +typedef struct { + int a; + int b[2]; +} A; + +int bar() { + return 42; +} + +void foo() { + A a = {bar(), {}}; +} +// CHECK: %0 = cir.alloca !ty_A, !cir.ptr, ["a", init] +// CHECK: %1 = cir.alloca !cir.ptr, !cir.ptr>, ["arrayinit.temp", init] +// CHECK: %2 = cir.get_member %0[0] {name = "a"} : !cir.ptr -> !cir.ptr +// CHECK: %3 = cir.call @_Z3barv() : () -> !s32i +// CHECK: cir.store %3, %2 : !s32i, !cir.ptr +// CHECK: %4 = cir.get_member %0[1] {name = "b"} : !cir.ptr -> !cir.ptr> +// CHECK: %5 = cir.cast(array_to_ptrdecay, %4 : !cir.ptr>), !cir.ptr +// CHECK: cir.store %5, %1 : !cir.ptr, !cir.ptr> +// CHECK: %6 = cir.const #cir.int<2> : !s64i +// CHECK: %7 = cir.ptr_stride(%5 : !cir.ptr, %6 : !s64i), !cir.ptr +// CHECK: cir.do { +// CHECK: %8 = cir.load %1 : !cir.ptr>, !cir.ptr +// CHECK: %9 = cir.const #cir.int<0> : !s32i +// CHECK: cir.store %9, %8 : !s32i, !cir.ptr +// CHECK: %10 = cir.const #cir.int<1> : !s64i +// CHECK: %11 = cir.ptr_stride(%8 : !cir.ptr, %10 : !s64i), !cir.ptr +// CHECK: cir.store %11, %1 : !cir.ptr, !cir.ptr> +// CHECK: cir.yield +// CHECK: } while { +// CHECK: %8 = cir.load %1 : !cir.ptr>, !cir.ptr +// CHECK: %9 = cir.cmp(ne, %8, %7) : !cir.ptr, !cir.bool +// CHECK: cir.condition(%9) +// CHECK: } \ No newline at end of file From 5d1234cd1f2473c5dcb5bfac735e8a1990a4187c Mon Sep 17 00:00:00 2001 From: bruteforceboy Date: Fri, 20 Sep 2024 11:32:11 +0300 Subject: [PATCH 4/5] update test --- clang/test/CIR/CodeGen/array-init.cpp | 38 +++++++++++++-------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/clang/test/CIR/CodeGen/array-init.cpp b/clang/test/CIR/CodeGen/array-init.cpp index ffd33cccab55..e051c31a9c6c 100644 --- a/clang/test/CIR/CodeGen/array-init.cpp +++ b/clang/test/CIR/CodeGen/array-init.cpp @@ -13,26 +13,26 @@ int bar() { void foo() { A a = {bar(), {}}; } -// CHECK: %0 = cir.alloca !ty_A, !cir.ptr, ["a", init] -// CHECK: %1 = cir.alloca !cir.ptr, !cir.ptr>, ["arrayinit.temp", init] -// CHECK: %2 = cir.get_member %0[0] {name = "a"} : !cir.ptr -> !cir.ptr -// CHECK: %3 = cir.call @_Z3barv() : () -> !s32i -// CHECK: cir.store %3, %2 : !s32i, !cir.ptr -// CHECK: %4 = cir.get_member %0[1] {name = "b"} : !cir.ptr -> !cir.ptr> -// CHECK: %5 = cir.cast(array_to_ptrdecay, %4 : !cir.ptr>), !cir.ptr -// CHECK: cir.store %5, %1 : !cir.ptr, !cir.ptr> -// CHECK: %6 = cir.const #cir.int<2> : !s64i -// CHECK: %7 = cir.ptr_stride(%5 : !cir.ptr, %6 : !s64i), !cir.ptr +// CHECK: %[[VAL_0:.*]] = cir.alloca !ty_A, !cir.ptr, ["a", init] +// CHECK: %[[VAL_1:.*]] = cir.alloca !cir.ptr, !cir.ptr>, ["arrayinit.temp", init] +// CHECK: %[[VAL_2:.*]] = cir.get_member %[[VAL_0]][0] {name = "a"} : !cir.ptr -> !cir.ptr +// CHECK: %[[VAL_3:.*]] = cir.call @_Z3barv() : () -> !s32i +// CHECK: cir.store %[[VAL_3]], %[[VAL_2]] : !s32i, !cir.ptr +// CHECK: %[[VAL_4:.*]] = cir.get_member %[[VAL_0]][1] {name = "b"} : !cir.ptr -> !cir.ptr> +// CHECK: %[[VAL_5:.*]] = cir.cast(array_to_ptrdecay, %[[VAL_4]] : !cir.ptr>), !cir.ptr +// CHECK: cir.store %[[VAL_5]], %[[VAL_1]] : !cir.ptr, !cir.ptr> +// CHECK: %[[VAL_6:.*]] = cir.const #cir.int<2> : !s64i +// CHECK: %[[VAL_7:.*]] = cir.ptr_stride(%[[VAL_5]] : !cir.ptr, %[[VAL_6]] : !s64i), !cir.ptr // CHECK: cir.do { -// CHECK: %8 = cir.load %1 : !cir.ptr>, !cir.ptr -// CHECK: %9 = cir.const #cir.int<0> : !s32i -// CHECK: cir.store %9, %8 : !s32i, !cir.ptr -// CHECK: %10 = cir.const #cir.int<1> : !s64i -// CHECK: %11 = cir.ptr_stride(%8 : !cir.ptr, %10 : !s64i), !cir.ptr -// CHECK: cir.store %11, %1 : !cir.ptr, !cir.ptr> +// CHECK: %[[VAL_8:.*]] = cir.load %[[VAL_1]] : !cir.ptr>, !cir.ptr +// CHECK: %[[VAL_9:.*]] = cir.const #cir.int<0> : !s32i +// CHECK: cir.store %[[VAL_9]], %[[VAL_8]] : !s32i, !cir.ptr +// CHECK: %[[VAL_10:.*]] = cir.const #cir.int<1> : !s64i +// CHECK: %[[VAL_11:.*]] = cir.ptr_stride(%[[VAL_8]] : !cir.ptr, %[[VAL_10]] : !s64i), !cir.ptr +// CHECK: cir.store %[[VAL_11]], %[[VAL_1]] : !cir.ptr, !cir.ptr> // CHECK: cir.yield // CHECK: } while { -// CHECK: %8 = cir.load %1 : !cir.ptr>, !cir.ptr -// CHECK: %9 = cir.cmp(ne, %8, %7) : !cir.ptr, !cir.bool -// CHECK: cir.condition(%9) +// CHECK: %[[VAL_8:.*]] = cir.load %[[VAL_1]] : !cir.ptr>, !cir.ptr +// CHECK: %[[VAL_9:.*]] = cir.cmp(ne, %[[VAL_8]], %[[VAL_7]]) : !cir.ptr, !cir.bool +// CHECK: cir.condition(%[[VAL_9]]) // CHECK: } \ No newline at end of file From 3846579242d73feb413c6d47f733b6cae8413716 Mon Sep 17 00:00:00 2001 From: bruteforceboy Date: Fri, 20 Sep 2024 11:38:56 +0300 Subject: [PATCH 5/5] undo commits --- clang/lib/CIR/Lowering/LoweringHelpers.cpp | 37 ++++++---------------- clang/test/CIR/Lowering/array-init.c | 17 ---------- 2 files changed, 10 insertions(+), 44 deletions(-) diff --git a/clang/lib/CIR/Lowering/LoweringHelpers.cpp b/clang/lib/CIR/Lowering/LoweringHelpers.cpp index 814ac4015b9c..debe7881d0c4 100644 --- a/clang/lib/CIR/Lowering/LoweringHelpers.cpp +++ b/clang/lib/CIR/Lowering/LoweringHelpers.cpp @@ -61,34 +61,9 @@ mlir::Type getNestedTypeAndElemQuantity(mlir::Type Ty, unsigned &elemQuantity) { return nestTy; } -template -void fillTrailingZeros(mlir::cir::ConstArrayAttr attr, - llvm::SmallVectorImpl &values) { - auto numTrailingZeros = attr.getTrailingZerosNum(); - if (numTrailingZeros) { - auto localArrayTy = mlir::dyn_cast(attr.getType()); - assert(localArrayTy && "expected !cir.array"); - - auto nestTy = localArrayTy.getEltType(); - if (!mlir::isa(nestTy)) - values.insert(values.end(), numTrailingZeros, - getZeroInitFromType(nestTy)); - } -} - template void convertToDenseElementsAttrImpl(mlir::cir::ConstArrayAttr attr, llvm::SmallVectorImpl &values) { - if (auto stringAttr = mlir::dyn_cast(attr.getElts())) { - if (auto arrayType = mlir::dyn_cast(attr.getType())) { - for (auto element : stringAttr) { - auto intAttr = mlir::cir::IntAttr::get(arrayType.getEltType(), element); - values.push_back(mlir::dyn_cast(intAttr).getValue()); - } - return; - } - } - auto arrayAttr = mlir::cast(attr.getElts()); for (auto eltAttr : arrayAttr) { if (auto valueAttr = mlir::dyn_cast(eltAttr)) { @@ -96,7 +71,6 @@ void convertToDenseElementsAttrImpl(mlir::cir::ConstArrayAttr attr, } else if (auto subArrayAttr = mlir::dyn_cast(eltAttr)) { convertToDenseElementsAttrImpl(subArrayAttr, values); - fillTrailingZeros(subArrayAttr, values); } else if (auto zeroAttr = mlir::dyn_cast(eltAttr)) { unsigned numStoredZeros = 0; auto nestTy = @@ -110,7 +84,16 @@ void convertToDenseElementsAttrImpl(mlir::cir::ConstArrayAttr attr, // Only fill in trailing zeros at the local cir.array level where the element // type isn't another array (for the mult-dim case). - fillTrailingZeros(attr, values); + auto numTrailingZeros = attr.getTrailingZerosNum(); + if (numTrailingZeros) { + auto localArrayTy = mlir::dyn_cast(attr.getType()); + assert(localArrayTy && "expected !cir.array"); + + auto nestTy = localArrayTy.getEltType(); + if (!mlir::isa(nestTy)) + values.insert(values.end(), numTrailingZeros, + getZeroInitFromType(nestTy)); + } } template diff --git a/clang/test/CIR/Lowering/array-init.c b/clang/test/CIR/Lowering/array-init.c index 0b9a19b5c9ba..ab0ddb4dd0ea 100644 --- a/clang/test/CIR/Lowering/array-init.c +++ b/clang/test/CIR/Lowering/array-init.c @@ -1,12 +1,6 @@ // 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 -// LLVM: charInit1.ar = internal global [4 x [4 x i8]] {{.*}}4 x i8] c"aa\00\00", [4 x i8] c"aa\00\00", [4 x i8] c"aa\00\00", [4 x i8] c"aa\00\00"], align 16 -char charInit1() { - static char ar[][4] = {"aa", "aa", "aa", "aa"}; - return ar[0][0]; -} - // LLVM: define dso_local void @zeroInit // LLVM: [[RES:%.*]] = alloca [3 x i32], i64 1 // LLVM: store [3 x i32] zeroinitializer, ptr [[RES]] @@ -14,14 +8,3 @@ void zeroInit() { int a[3] = {0, 0, 0}; } -// LLVM: %1 = alloca [4 x [1 x i8]], i64 1, align 1 -// LLVM: store [4 x [1 x i8]] {{.*}}1 x i8] c"a", [1 x i8] c"b", [1 x i8] c"c", [1 x i8] c"d"], ptr %1, align 1 -void charInit2() { - char arr[4][1] = {"a", "b", "c", "d"}; -} - -// LLVM: %1 = alloca [4 x [2 x i8]], i64 1, align 1 -// LLVM: store [4 x [2 x i8]] {{.*}}2 x i8] c"ab", [2 x i8] c"cd", [2 x i8] c"ef", [2 x i8] c"gh"], ptr %1, align 1 -void charInit3() { - char arr[4][2] = {"ab", "cd", "ef", "gh"}; -} \ No newline at end of file