176 lines · cpp
1// 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 %s2// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -Wno-unused-value -fclangir -emit-cir %s -o %t.cir3// RUN: FileCheck --input-file=%t.cir %s -check-prefix=CIR4// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -Wno-unused-value -fclangir -emit-llvm %s -o %t-cir.ll5// RUN: FileCheck --input-file=%t-cir.ll %s -check-prefix=LLVM6// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -Wno-unused-value -emit-llvm %s -o %t.ll7// RUN: FileCheck --input-file=%t.ll %s -check-prefix=OGCG8 9struct S {10 S();11};12 13void foo() {14 S s[42];15}16 17// CIR-BEFORE-LPP: cir.func dso_local @_Z3foov()18// CIR-BEFORE-LPP: %[[ARRAY:.*]] = cir.alloca !cir.array<!rec_S x 42>, !cir.ptr<!cir.array<!rec_S x 42>>, ["s", init]19// CIR-BEFORE-LPP: cir.array.ctor %[[ARRAY]] : !cir.ptr<!cir.array<!rec_S x 42>> {20// CIR-BEFORE-LPP: ^bb0(%[[ARG:.*]]: !cir.ptr<!rec_S>):21// CIR-BEFORE-LPP: cir.call @_ZN1SC1Ev(%[[ARG]]) : (!cir.ptr<!rec_S>) -> ()22// CIR-BEFORE-LPP: cir.yield23// CIR-BEFORE-LPP: }24// CIR-BEFORE-LPP: cir.return25// CIR-BEFORE-LPP: }26 27// CIR: cir.func dso_local @_Z3foov()28// CIR: %[[ARRAY:.*]] = cir.alloca !cir.array<!rec_S x 42>, !cir.ptr<!cir.array<!rec_S x 42>>, ["s", init]29// CIR: %[[CONST42:.*]] = cir.const #cir.int<42> : !u64i30// CIR: %[[DECAY:.*]] = cir.cast array_to_ptrdecay %[[ARRAY]] : !cir.ptr<!cir.array<!rec_S x 42>> -> !cir.ptr<!rec_S>31// CIR: %[[END_PTR:.*]] = cir.ptr_stride %[[DECAY]], %[[CONST42]] : (!cir.ptr<!rec_S>, !u64i) -> !cir.ptr<!rec_S>32// CIR: %[[ITER:.*]] = cir.alloca !cir.ptr<!rec_S>, !cir.ptr<!cir.ptr<!rec_S>>, ["__array_idx"]33// CIR: cir.store %[[DECAY]], %[[ITER]] : !cir.ptr<!rec_S>, !cir.ptr<!cir.ptr<!rec_S>>34// CIR: cir.do {35// CIR: %[[CURRENT:.*]] = cir.load %[[ITER]] : !cir.ptr<!cir.ptr<!rec_S>>, !cir.ptr<!rec_S>36// CIR: cir.call @_ZN1SC1Ev(%[[CURRENT]]) : (!cir.ptr<!rec_S>) -> ()37// CIR: %[[CONST1:.*]] = cir.const #cir.int<1> : !u64i38// CIR: %[[NEXT:.*]] = cir.ptr_stride %[[CURRENT]], %[[CONST1]] : (!cir.ptr<!rec_S>, !u64i) -> !cir.ptr<!rec_S>39// CIR: cir.store %[[NEXT]], %[[ITER]] : !cir.ptr<!rec_S>, !cir.ptr<!cir.ptr<!rec_S>>40// CIR: cir.yield41// CIR: } while {42// CIR: %[[CURRENT2:.*]] = cir.load %[[ITER]] : !cir.ptr<!cir.ptr<!rec_S>>, !cir.ptr<!rec_S>43// CIR: %[[CMP:.*]] = cir.cmp(ne, %[[CURRENT2]], %[[END_PTR]]) : !cir.ptr<!rec_S>, !cir.bool44// CIR: cir.condition(%[[CMP]])45// CIR: }46// CIR: cir.return47// CIR: }48 49// LLVM: define dso_local void @_Z3foov()50// LLVM: %[[ARRAY:.*]] = alloca [42 x %struct.S]51// LLVM: %[[START:.*]] = getelementptr %struct.S, ptr %[[ARRAY]], i32 052// LLVM: %[[END:.*]] = getelementptr %struct.S, ptr %[[START]], i64 4253// LLVM: %[[ITER:.*]] = alloca ptr54// LLVM: store ptr %[[START]], ptr %[[ITER]]55// LLVM: br label %[[LOOP:.*]]56// LLVM: [[COND:.*]]:57// LLVM: %[[CURRENT_CHECK:.*]] = load ptr, ptr %[[ITER]]58// LLVM: %[[DONE:.*]] = icmp ne ptr %[[CURRENT_CHECK]], %[[END]]59// LLVM: br i1 %[[DONE]], label %[[LOOP]], label %[[EXIT:.*]]60// LLVM: [[LOOP]]:61// LLVM: %[[CURRENT:.*]] = load ptr, ptr %[[ITER]]62// LLVM: call void @_ZN1SC1Ev(ptr %[[CURRENT]])63// LLVM: %[[NEXT:.*]] = getelementptr %struct.S, ptr %[[CURRENT]], i64 164// LLVM: store ptr %[[NEXT]], ptr %[[ITER]]65// LLVM: br label %[[COND]]66// LLVM: [[EXIT]]:67// LLVM: ret void68 69// OGCG: define dso_local void @_Z3foov()70// OGCG: %[[ARRAY:.*]] = alloca [42 x %struct.S]71// OGCG: %[[START:.*]] = getelementptr{{.*}} %struct.S{{.*}}72// OGCG: %[[END:.*]] = getelementptr{{.*}} %struct.S{{.*}} i64 4273// OGCG: br label %[[LOOP:.*]]74// OGCG: [[LOOP]]:75// OGCG: %[[CURRENT:.*]] = phi ptr [ %[[START]], %{{.*}} ], [ %[[NEXT:.*]], %[[LOOP]] ]76// OGCG: call void @_ZN1SC1Ev(ptr{{.*}})77// OGCG: %[[NEXT]] = getelementptr{{.*}} %struct.S{{.*}} i64 178// OGCG: %[[DONE:.*]] = icmp eq ptr %[[NEXT]], %[[END]]79// OGCG: br i1 %[[DONE]], label %[[EXIT:.*]], label %[[LOOP]]80// OGCG: [[EXIT]]:81// OGCG: ret void82 83void zero_sized() {84 S s[0];85}86 87// CIR-BEFORE-LPP: cir.func dso_local @_Z10zero_sizedv()88// CIR-BEFORE-LPP: cir.alloca !cir.array<!rec_S x 0>, !cir.ptr<!cir.array<!rec_S x 0>>, ["s"]89// CIR-BEFORE-LPP-NOT: cir.array.ctor90// CIR-BEFORE-LPP: cir.return91 92// CIR: cir.func dso_local @_Z10zero_sizedv()93// CIR: cir.alloca !cir.array<!rec_S x 0>, !cir.ptr<!cir.array<!rec_S x 0>>, ["s"]94// CIR-NOT: cir.do95// CIR-NOT: cir.call @_ZN1SC1Ev96// CIR: cir.return97 98// LLVM: define dso_local void @_Z10zero_sizedv()99// LLVM: alloca [0 x %struct.S]100// LLVM-NOT: call void @_ZN1SC1Ev101// LLVM: ret void102 103// OGCG: define dso_local void @_Z10zero_sizedv()104// OGCG: alloca [0 x %struct.S]105// OGCG-NOT: call void @_ZN1SC1Ev106// OGCG: ret void107 108void multi_dimensional() {109 S s[3][5];110}111 112// CIR-BEFORE-LPP: cir.func{{.*}} @_Z17multi_dimensionalv()113// 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]114// 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>>115// CIR-BEFORE-LPP: cir.array.ctor %[[FLAT]] : !cir.ptr<!cir.array<!rec_S x 15>> {116// CIR-BEFORE-LPP: ^bb0(%[[ARG:.*]]: !cir.ptr<!rec_S>):117// CIR-BEFORE-LPP: cir.call @_ZN1SC1Ev(%[[ARG]]) : (!cir.ptr<!rec_S>) -> ()118// CIR-BEFORE-LPP: cir.yield119// CIR-BEFORE-LPP: }120// CIR-BEFORE-LPP: cir.return121 122// CIR: cir.func{{.*}} @_Z17multi_dimensionalv()123// 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]124// CIR: %[[CONST15:.*]] = cir.const #cir.int<15> : !u64i125// CIR: %[[DECAY:.*]] = cir.cast array_to_ptrdecay {{.*}} : !cir.ptr<!cir.array<!rec_S x 15>> -> !cir.ptr<!rec_S>126// CIR: %[[END_PTR:.*]] = cir.ptr_stride %[[DECAY]], %[[CONST15]] : (!cir.ptr<!rec_S>, !u64i) -> !cir.ptr<!rec_S>127// CIR: %[[ITER:.*]] = cir.alloca !cir.ptr<!rec_S>, !cir.ptr<!cir.ptr<!rec_S>>, ["__array_idx"]128// CIR: cir.store %[[DECAY]], %[[ITER]] : !cir.ptr<!rec_S>, !cir.ptr<!cir.ptr<!rec_S>>129// CIR: cir.do {130// CIR: %[[CURRENT:.*]] = cir.load %[[ITER]] : !cir.ptr<!cir.ptr<!rec_S>>, !cir.ptr<!rec_S>131// CIR: cir.call @_ZN1SC1Ev(%[[CURRENT]]) : (!cir.ptr<!rec_S>) -> ()132// CIR: %[[CONST1:.*]] = cir.const #cir.int<1> : !u64i133// CIR: %[[NEXT:.*]] = cir.ptr_stride %[[CURRENT]], %[[CONST1]] : (!cir.ptr<!rec_S>, !u64i) -> !cir.ptr<!rec_S>134// CIR: cir.store %[[NEXT]], %[[ITER]] : !cir.ptr<!rec_S>, !cir.ptr<!cir.ptr<!rec_S>>135// CIR: cir.yield136// CIR: } while {137// CIR: %[[CURRENT2:.*]] = cir.load %[[ITER]] : !cir.ptr<!cir.ptr<!rec_S>>, !cir.ptr<!rec_S>138// CIR: %[[CMP:.*]] = cir.cmp(ne, %[[CURRENT2]], %[[END_PTR]]) : !cir.ptr<!rec_S>, !cir.bool139// CIR: cir.condition(%[[CMP]])140// CIR: }141// CIR: cir.return142 143// LLVM: define{{.*}} @_Z17multi_dimensionalv()144// LLVM: %[[S:.*]] = alloca [3 x [5 x %struct.S]]145// LLVM: %[[START:.*]] = getelementptr %struct.S, ptr %[[S]], i32 0146// LLVM: %[[END:.*]] = getelementptr %struct.S, ptr %[[START]], i64 15147// LLVM: %[[ITER:.*]] = alloca ptr148// LLVM: store ptr %[[START]], ptr %[[ITER]]149// LLVM: br label %[[LOOP:.*]]150// LLVM: [[COND:.*]]:151// LLVM: %[[CURRENT_CHECK:.*]] = load ptr, ptr %[[ITER]]152// LLVM: %[[DONE:.*]] = icmp ne ptr %[[CURRENT_CHECK]], %[[END]]153// LLVM: br i1 %[[DONE]], label %[[LOOP]], label %[[EXIT:.*]]154// LLVM: [[LOOP]]:155// LLVM: %[[CURRENT:.*]] = load ptr, ptr %[[ITER]]156// LLVM: call void @_ZN1SC1Ev(ptr %[[CURRENT]])157// LLVM: %[[NEXT:.*]] = getelementptr %struct.S, ptr %[[CURRENT]], i64 1158// LLVM: store ptr %[[NEXT]], ptr %[[ITER]]159// LLVM: br label %[[COND]]160// LLVM: [[EXIT]]:161// LLVM: ret void162 163// OGCG: define{{.*}} @_Z17multi_dimensionalv()164// OGCG: %[[S:.*]] = alloca [3 x [5 x %struct.S]]165// OGCG: %[[START:.*]] = getelementptr{{.*}} %struct.S{{.*}}166// OGCG: %[[END:.*]] = getelementptr{{.*}} %struct.S{{.*}} i64 15167// OGCG: br label %[[LOOP:.*]]168// OGCG: [[LOOP]]:169// OGCG: %[[CURRENT:.*]] = phi ptr [ %[[START]], %{{.*}} ], [ %[[NEXT:.*]], %[[LOOP]] ]170// OGCG: call void @_ZN1SC1Ev(ptr{{.*}})171// OGCG: %[[NEXT]] = getelementptr{{.*}} %struct.S{{.*}} i64 1172// OGCG: %[[DONE:.*]] = icmp eq ptr %[[NEXT]], %[[END]]173// OGCG: br i1 %[[DONE]], label %[[EXIT:.*]], label %[[LOOP]]174// OGCG: [[EXIT]]:175// OGCG: ret void176