Files
llvm/clang/test/CIR/CodeGen/array-ctor.cpp
Henrich Lauko 04dd71cb0b [CIR] Align inline-kind FuncOp attribute with incubator (#170050)
Switches to more efficient explicit enum property instead of a wrapped
storage, simplifying the string representation. The attribute is now
placed before the symbol name for consistency with other FuncOp
attributes. FileCheck patterns are also simplified to match only the
attributes under test.
2025-12-02 09:53:50 +01:00

176 lines
8.6 KiB
C++

// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -Wno-unused-value -fclangir -emit-cir -mmlir --mlir-print-ir-before=cir-lowering-prepare %s -o - 2>&1 | FileCheck --check-prefixes=CIR-BEFORE-LPP %s
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -Wno-unused-value -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 -Wno-unused-value -fclangir -emit-llvm %s -o %t-cir.ll
// RUN: FileCheck --input-file=%t-cir.ll %s -check-prefix=LLVM
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -Wno-unused-value -emit-llvm %s -o %t.ll
// RUN: FileCheck --input-file=%t.ll %s -check-prefix=OGCG
struct S {
S();
};
void foo() {
S s[42];
}
// CIR-BEFORE-LPP: cir.func {{.*}} @_Z3foov()
// CIR-BEFORE-LPP: %[[ARRAY:.*]] = cir.alloca !cir.array<!rec_S x 42>, !cir.ptr<!cir.array<!rec_S x 42>>, ["s", init]
// CIR-BEFORE-LPP: cir.array.ctor %[[ARRAY]] : !cir.ptr<!cir.array<!rec_S x 42>> {
// CIR-BEFORE-LPP: ^bb0(%[[ARG:.*]]: !cir.ptr<!rec_S>):
// CIR-BEFORE-LPP: cir.call @_ZN1SC1Ev(%[[ARG]]) : (!cir.ptr<!rec_S>) -> ()
// CIR-BEFORE-LPP: cir.yield
// CIR-BEFORE-LPP: }
// CIR-BEFORE-LPP: cir.return
// CIR-BEFORE-LPP: }
// CIR: cir.func {{.*}} @_Z3foov()
// CIR: %[[ARRAY:.*]] = cir.alloca !cir.array<!rec_S x 42>, !cir.ptr<!cir.array<!rec_S x 42>>, ["s", init]
// CIR: %[[CONST42:.*]] = cir.const #cir.int<42> : !u64i
// CIR: %[[DECAY:.*]] = cir.cast array_to_ptrdecay %[[ARRAY]] : !cir.ptr<!cir.array<!rec_S x 42>> -> !cir.ptr<!rec_S>
// CIR: %[[END_PTR:.*]] = cir.ptr_stride %[[DECAY]], %[[CONST42]] : (!cir.ptr<!rec_S>, !u64i) -> !cir.ptr<!rec_S>
// CIR: %[[ITER:.*]] = cir.alloca !cir.ptr<!rec_S>, !cir.ptr<!cir.ptr<!rec_S>>, ["__array_idx"]
// CIR: cir.store %[[DECAY]], %[[ITER]] : !cir.ptr<!rec_S>, !cir.ptr<!cir.ptr<!rec_S>>
// CIR: cir.do {
// CIR: %[[CURRENT:.*]] = cir.load %[[ITER]] : !cir.ptr<!cir.ptr<!rec_S>>, !cir.ptr<!rec_S>
// CIR: cir.call @_ZN1SC1Ev(%[[CURRENT]]) : (!cir.ptr<!rec_S>) -> ()
// CIR: %[[CONST1:.*]] = cir.const #cir.int<1> : !u64i
// CIR: %[[NEXT:.*]] = cir.ptr_stride %[[CURRENT]], %[[CONST1]] : (!cir.ptr<!rec_S>, !u64i) -> !cir.ptr<!rec_S>
// CIR: cir.store %[[NEXT]], %[[ITER]] : !cir.ptr<!rec_S>, !cir.ptr<!cir.ptr<!rec_S>>
// CIR: cir.yield
// CIR: } while {
// CIR: %[[CURRENT2:.*]] = cir.load %[[ITER]] : !cir.ptr<!cir.ptr<!rec_S>>, !cir.ptr<!rec_S>
// CIR: %[[CMP:.*]] = cir.cmp(ne, %[[CURRENT2]], %[[END_PTR]]) : !cir.ptr<!rec_S>, !cir.bool
// CIR: cir.condition(%[[CMP]])
// CIR: }
// CIR: cir.return
// CIR: }
// LLVM: define dso_local void @_Z3foov()
// LLVM: %[[ARRAY:.*]] = alloca [42 x %struct.S]
// LLVM: %[[START:.*]] = getelementptr %struct.S, ptr %[[ARRAY]], i32 0
// LLVM: %[[END:.*]] = getelementptr %struct.S, ptr %[[START]], i64 42
// LLVM: %[[ITER:.*]] = alloca ptr
// LLVM: store ptr %[[START]], ptr %[[ITER]]
// LLVM: br label %[[LOOP:.*]]
// LLVM: [[COND:.*]]:
// LLVM: %[[CURRENT_CHECK:.*]] = load ptr, ptr %[[ITER]]
// LLVM: %[[DONE:.*]] = icmp ne ptr %[[CURRENT_CHECK]], %[[END]]
// LLVM: br i1 %[[DONE]], label %[[LOOP]], label %[[EXIT:.*]]
// LLVM: [[LOOP]]:
// LLVM: %[[CURRENT:.*]] = load ptr, ptr %[[ITER]]
// LLVM: call void @_ZN1SC1Ev(ptr %[[CURRENT]])
// LLVM: %[[NEXT:.*]] = getelementptr %struct.S, ptr %[[CURRENT]], i64 1
// LLVM: store ptr %[[NEXT]], ptr %[[ITER]]
// LLVM: br label %[[COND]]
// LLVM: [[EXIT]]:
// LLVM: ret void
// OGCG: define dso_local void @_Z3foov()
// OGCG: %[[ARRAY:.*]] = alloca [42 x %struct.S]
// OGCG: %[[START:.*]] = getelementptr{{.*}} %struct.S{{.*}}
// OGCG: %[[END:.*]] = getelementptr{{.*}} %struct.S{{.*}} i64 42
// OGCG: br label %[[LOOP:.*]]
// OGCG: [[LOOP]]:
// OGCG: %[[CURRENT:.*]] = phi ptr [ %[[START]], %{{.*}} ], [ %[[NEXT:.*]], %[[LOOP]] ]
// OGCG: call void @_ZN1SC1Ev(ptr{{.*}})
// OGCG: %[[NEXT]] = getelementptr{{.*}} %struct.S{{.*}} i64 1
// OGCG: %[[DONE:.*]] = icmp eq ptr %[[NEXT]], %[[END]]
// OGCG: br i1 %[[DONE]], label %[[EXIT:.*]], label %[[LOOP]]
// OGCG: [[EXIT]]:
// OGCG: ret void
void zero_sized() {
S s[0];
}
// CIR-BEFORE-LPP: cir.func {{.*}} @_Z10zero_sizedv()
// CIR-BEFORE-LPP: cir.alloca !cir.array<!rec_S x 0>, !cir.ptr<!cir.array<!rec_S x 0>>, ["s"]
// CIR-BEFORE-LPP-NOT: cir.array.ctor
// CIR-BEFORE-LPP: cir.return
// CIR: cir.func {{.*}} @_Z10zero_sizedv()
// CIR: cir.alloca !cir.array<!rec_S x 0>, !cir.ptr<!cir.array<!rec_S x 0>>, ["s"]
// CIR-NOT: cir.do
// CIR-NOT: cir.call @_ZN1SC1Ev
// CIR: cir.return
// LLVM: define dso_local void @_Z10zero_sizedv()
// LLVM: alloca [0 x %struct.S]
// LLVM-NOT: call void @_ZN1SC1Ev
// LLVM: ret void
// OGCG: define dso_local void @_Z10zero_sizedv()
// OGCG: alloca [0 x %struct.S]
// OGCG-NOT: call void @_ZN1SC1Ev
// OGCG: ret void
void multi_dimensional() {
S s[3][5];
}
// CIR-BEFORE-LPP: cir.func{{.*}} @_Z17multi_dimensionalv()
// CIR-BEFORE-LPP: %[[S:.*]] = cir.alloca !cir.array<!cir.array<!rec_S x 5> x 3>, !cir.ptr<!cir.array<!cir.array<!rec_S x 5> x 3>>, ["s", init]
// CIR-BEFORE-LPP: %[[FLAT:.*]] = cir.cast bitcast %[[S]] : !cir.ptr<!cir.array<!cir.array<!rec_S x 5> x 3>> -> !cir.ptr<!cir.array<!rec_S x 15>>
// CIR-BEFORE-LPP: cir.array.ctor %[[FLAT]] : !cir.ptr<!cir.array<!rec_S x 15>> {
// CIR-BEFORE-LPP: ^bb0(%[[ARG:.*]]: !cir.ptr<!rec_S>):
// CIR-BEFORE-LPP: cir.call @_ZN1SC1Ev(%[[ARG]]) : (!cir.ptr<!rec_S>) -> ()
// CIR-BEFORE-LPP: cir.yield
// CIR-BEFORE-LPP: }
// CIR-BEFORE-LPP: cir.return
// CIR: cir.func{{.*}} @_Z17multi_dimensionalv()
// CIR: %[[S:.*]] = cir.alloca !cir.array<!cir.array<!rec_S x 5> x 3>, !cir.ptr<!cir.array<!cir.array<!rec_S x 5> x 3>>, ["s", init]
// CIR: %[[CONST15:.*]] = cir.const #cir.int<15> : !u64i
// CIR: %[[DECAY:.*]] = cir.cast array_to_ptrdecay {{.*}} : !cir.ptr<!cir.array<!rec_S x 15>> -> !cir.ptr<!rec_S>
// CIR: %[[END_PTR:.*]] = cir.ptr_stride %[[DECAY]], %[[CONST15]] : (!cir.ptr<!rec_S>, !u64i) -> !cir.ptr<!rec_S>
// CIR: %[[ITER:.*]] = cir.alloca !cir.ptr<!rec_S>, !cir.ptr<!cir.ptr<!rec_S>>, ["__array_idx"]
// CIR: cir.store %[[DECAY]], %[[ITER]] : !cir.ptr<!rec_S>, !cir.ptr<!cir.ptr<!rec_S>>
// CIR: cir.do {
// CIR: %[[CURRENT:.*]] = cir.load %[[ITER]] : !cir.ptr<!cir.ptr<!rec_S>>, !cir.ptr<!rec_S>
// CIR: cir.call @_ZN1SC1Ev(%[[CURRENT]]) : (!cir.ptr<!rec_S>) -> ()
// CIR: %[[CONST1:.*]] = cir.const #cir.int<1> : !u64i
// CIR: %[[NEXT:.*]] = cir.ptr_stride %[[CURRENT]], %[[CONST1]] : (!cir.ptr<!rec_S>, !u64i) -> !cir.ptr<!rec_S>
// CIR: cir.store %[[NEXT]], %[[ITER]] : !cir.ptr<!rec_S>, !cir.ptr<!cir.ptr<!rec_S>>
// CIR: cir.yield
// CIR: } while {
// CIR: %[[CURRENT2:.*]] = cir.load %[[ITER]] : !cir.ptr<!cir.ptr<!rec_S>>, !cir.ptr<!rec_S>
// CIR: %[[CMP:.*]] = cir.cmp(ne, %[[CURRENT2]], %[[END_PTR]]) : !cir.ptr<!rec_S>, !cir.bool
// CIR: cir.condition(%[[CMP]])
// CIR: }
// CIR: cir.return
// LLVM: define{{.*}} @_Z17multi_dimensionalv()
// LLVM: %[[S:.*]] = alloca [3 x [5 x %struct.S]]
// LLVM: %[[START:.*]] = getelementptr %struct.S, ptr %[[S]], i32 0
// LLVM: %[[END:.*]] = getelementptr %struct.S, ptr %[[START]], i64 15
// LLVM: %[[ITER:.*]] = alloca ptr
// LLVM: store ptr %[[START]], ptr %[[ITER]]
// LLVM: br label %[[LOOP:.*]]
// LLVM: [[COND:.*]]:
// LLVM: %[[CURRENT_CHECK:.*]] = load ptr, ptr %[[ITER]]
// LLVM: %[[DONE:.*]] = icmp ne ptr %[[CURRENT_CHECK]], %[[END]]
// LLVM: br i1 %[[DONE]], label %[[LOOP]], label %[[EXIT:.*]]
// LLVM: [[LOOP]]:
// LLVM: %[[CURRENT:.*]] = load ptr, ptr %[[ITER]]
// LLVM: call void @_ZN1SC1Ev(ptr %[[CURRENT]])
// LLVM: %[[NEXT:.*]] = getelementptr %struct.S, ptr %[[CURRENT]], i64 1
// LLVM: store ptr %[[NEXT]], ptr %[[ITER]]
// LLVM: br label %[[COND]]
// LLVM: [[EXIT]]:
// LLVM: ret void
// OGCG: define{{.*}} @_Z17multi_dimensionalv()
// OGCG: %[[S:.*]] = alloca [3 x [5 x %struct.S]]
// OGCG: %[[START:.*]] = getelementptr{{.*}} %struct.S{{.*}}
// OGCG: %[[END:.*]] = getelementptr{{.*}} %struct.S{{.*}} i64 15
// OGCG: br label %[[LOOP:.*]]
// OGCG: [[LOOP]]:
// OGCG: %[[CURRENT:.*]] = phi ptr [ %[[START]], %{{.*}} ], [ %[[NEXT:.*]], %[[LOOP]] ]
// OGCG: call void @_ZN1SC1Ev(ptr{{.*}})
// OGCG: %[[NEXT]] = getelementptr{{.*}} %struct.S{{.*}} i64 1
// OGCG: %[[DONE:.*]] = icmp eq ptr %[[NEXT]], %[[END]]
// OGCG: br i1 %[[DONE]], label %[[EXIT:.*]], label %[[LOOP]]
// OGCG: [[EXIT]]:
// OGCG: ret void