283 lines · c
1// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o %t.cir2// RUN: FileCheck --input-file=%t.cir %s --check-prefix=CIR3// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm %s -o %t-cir.ll4// RUN: FileCheck --input-file=%t-cir.ll %s --check-prefix=LLVM5// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm %s -o %t.ll6// RUN: FileCheck --input-file=%t.ll %s --check-prefix=OGCG7 8int f19(void) {9 return ({ 3;;4; });10}11 12// CIR: cir.func dso_local @f19() -> !s32i13// CIR: %[[RETVAL:.+]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["__retval"]14// CIR: %[[TMP:.+]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["tmp"]15// CIR: cir.scope {16// CIR: %[[C3:.+]] = cir.const #cir.int<3> : !s32i17// CIR: %[[C4:.+]] = cir.const #cir.int<4> : !s32i18// CIR: cir.store {{.*}} %[[C4]], %[[TMP]] : !s32i, !cir.ptr<!s32i>19// CIR: }20// CIR: %[[TMP_VAL:.+]] = cir.load {{.*}} %[[TMP]] : !cir.ptr<!s32i>, !s32i21// CIR: cir.store %[[TMP_VAL]], %[[RETVAL]] : !s32i, !cir.ptr<!s32i>22// CIR: %[[RES:.+]] = cir.load %[[RETVAL]] : !cir.ptr<!s32i>, !s32i23// CIR: cir.return %[[RES]] : !s32i24 25// LLVM: define dso_local i32 @f19()26// LLVM: %[[VAR1:.+]] = alloca i32, i64 127// LLVM: %[[VAR2:.+]] = alloca i32, i64 128// LLVM: br label %[[LBL3:.+]]29// LLVM: [[LBL3]]:30// LLVM: store i32 4, ptr %[[VAR2]]31// LLVM: br label %[[LBL4:.+]]32// LLVM: [[LBL4]]:33// LLVM: %[[V1:.+]] = load i32, ptr %[[VAR2]]34// LLVM: store i32 %[[V1]], ptr %[[VAR1]]35// LLVM: %[[RES:.+]] = load i32, ptr %[[VAR1]]36// LLVM: ret i32 %[[RES]]37 38// OGCG: define dso_local i32 @f19()39// OGCG: entry:40// OGCG: %[[TMP:.+]] = alloca i3241// OGCG: store i32 4, ptr %[[TMP]]42// OGCG: %[[TMP_VAL:.+]] = load i32, ptr %[[TMP]]43// OGCG: ret i32 %[[TMP_VAL]]44 45// PR166036: The trailing NullStmt should result in a void.46void f20(void) {47 return ({ 3;;4;; });48}49 50// CIR-LABEL: cir.func dso_local @f20() {{[^-]*}}51// CIR: cir.return {{[^%]*}}52 53// LLVM-LABEL: define{{.*}} void @f2054// LLVM: ret void55 56int nested(void) {57 ({123;});58 {59 int bar = 987;60 return ({ ({ int asdf = 123; asdf; }); ({9999;}); });61 }62}63 64// CIR: cir.func dso_local @nested() -> !s32i65// CIR: %[[RETVAL:.+]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["__retval"]66// CIR: %[[TMP_OUTER:.+]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["tmp"]67// CIR: cir.scope {68// CIR: %[[C123_OUTER:.+]] = cir.const #cir.int<123> : !s32i69// CIR: cir.store {{.*}} %[[C123_OUTER]], %[[TMP_OUTER]] : !s32i, !cir.ptr<!s32i>70// CIR: }71// CIR: %[[LOAD_TMP_OUTER:.+]] = cir.load {{.*}} %[[TMP_OUTER]] : !cir.ptr<!s32i>, !s32i72// CIR: cir.scope {73// CIR: %[[BAR:.+]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["bar", init]74// CIR: %[[TMP_BARRET:.+]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["tmp"]75// CIR: %[[C987:.+]] = cir.const #cir.int<987> : !s32i76// CIR: cir.store {{.*}} %[[C987]], %[[BAR]] : !s32i, !cir.ptr<!s32i>77// CIR: cir.scope {78// CIR: %[[TMP1:.+]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["tmp"]79// CIR: %[[TMP2:.+]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["tmp"]80// CIR: cir.scope {81// CIR: %[[ASDF:.+]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["asdf", init]82// CIR: %[[C123_INNER:.+]] = cir.const #cir.int<123> : !s32i83// CIR: cir.store {{.*}} %[[C123_INNER]], %[[ASDF]] : !s32i, !cir.ptr<!s32i>84// CIR: %[[LOAD_ASDF:.+]] = cir.load {{.*}} %[[ASDF]] : !cir.ptr<!s32i>, !s32i85// CIR: cir.store {{.*}} %[[LOAD_ASDF]], %[[TMP1]] : !s32i, !cir.ptr<!s32i>86// CIR: }87// CIR: %[[V1:.+]] = cir.load {{.*}} %[[TMP1]] : !cir.ptr<!s32i>, !s32i88// CIR: cir.scope {89// CIR: %[[C9999:.+]] = cir.const #cir.int<9999> : !s32i90// CIR: cir.store {{.*}} %[[C9999]], %[[TMP2]] : !s32i, !cir.ptr<!s32i>91// CIR: }92// CIR: %[[V2:.+]] = cir.load {{.*}} %[[TMP2]] : !cir.ptr<!s32i>, !s32i93// CIR: cir.store {{.*}} %[[V2]], %[[TMP_BARRET]] : !s32i, !cir.ptr<!s32i>94// CIR: }95// CIR: %[[BARRET_VAL:.+]] = cir.load {{.*}} %[[TMP_BARRET]] : !cir.ptr<!s32i>, !s32i96// CIR: cir.store %[[BARRET_VAL]], %[[RETVAL]] : !s32i, !cir.ptr<!s32i>97// CIR: %[[RES:.+]] = cir.load %[[RETVAL]] : !cir.ptr<!s32i>, !s32i98// CIR: cir.return %[[RES]] : !s32i99// CIR: }100// CIR: %[[FINAL_RES:.+]] = cir.load %[[RETVAL]] : !cir.ptr<!s32i>, !s32i101// CIR: cir.return %[[FINAL_RES]] : !s32i102 103// LLVM: define dso_local i32 @nested()104// LLVM: %[[VAR1:.+]] = alloca i32, i64 1105// LLVM: %[[VAR2:.+]] = alloca i32, i64 1106// LLVM: %[[VAR3:.+]] = alloca i32, i64 1107// LLVM: %[[VAR4:.+]] = alloca i32, i64 1108// LLVM: %[[VAR5:.+]] = alloca i32, i64 1109// LLVM: %[[VAR6:.+]] = alloca i32, i64 1110// LLVM: %[[VAR7:.+]] = alloca i32, i64 1111// LLVM: br label %[[LBL8:.+]]112// LLVM: [[LBL8]]:113// LLVM: store i32 123, ptr %[[VAR7]]114// LLVM: br label %[[LBL9:.+]]115// LLVM: [[LBL9]]:116// LLVM: br label %[[LBL10:.+]]117// LLVM: [[LBL10]]:118// LLVM: store i32 987, ptr %[[VAR1]]119// LLVM: br label %[[LBL11:.+]]120// LLVM: [[LBL11]]:121// LLVM: br label %[[LBL12:.+]]122// LLVM: [[LBL12]]:123// LLVM: store i32 123, ptr %[[VAR5]]124// LLVM: %[[V1:.+]] = load i32, ptr %[[VAR5]]125// LLVM: store i32 %[[V1]], ptr %[[VAR3]]126// LLVM: br label %[[LBL14:.+]]127// LLVM: [[LBL14]]:128// LLVM: br label %[[LBL15:.+]]129// LLVM: [[LBL15]]:130// LLVM: store i32 9999, ptr %[[VAR4]]131// LLVM: br label %[[LBL16:.+]]132// LLVM: [[LBL16]]:133// LLVM: %[[V2:.+]] = load i32, ptr %[[VAR4]]134// LLVM: store i32 %[[V2]], ptr %[[VAR2]]135// LLVM: br label %[[LBL18:.+]]136// LLVM: [[LBL18]]:137// LLVM: %[[V3:.+]] = load i32, ptr %[[VAR2]]138// LLVM: store i32 %[[V3]], ptr %[[VAR6]]139// LLVM: %[[RES:.+]] = load i32, ptr %[[VAR6]]140// LLVM: ret i32 %[[RES]]141 142// OGCG: define dso_local i32 @nested()143// OGCG: entry:144// OGCG: %[[TMP_OUTER:.+]] = alloca i32145// OGCG: %[[BAR:.+]] = alloca i32146// OGCG: %[[ASDF:.+]] = alloca i32147// OGCG: %[[TMP1:.+]] = alloca i32148// OGCG: %[[TMP2:.+]] = alloca i32149// OGCG: %[[TMP3:.+]] = alloca i32150// OGCG: store i32 123, ptr %[[TMP_OUTER]]151// OGCG: %[[OUTER_VAL:.+]] = load i32, ptr %[[TMP_OUTER]]152// OGCG: store i32 987, ptr %[[BAR]]153// OGCG: store i32 123, ptr %[[ASDF]]154// OGCG: %[[ASDF_VAL:.+]] = load i32, ptr %[[ASDF]]155// OGCG: store i32 %[[ASDF_VAL]], ptr %[[TMP1]]156// OGCG: %[[TMP1_VAL:.+]] = load i32, ptr %[[TMP1]]157// OGCG: store i32 9999, ptr %[[TMP3]]158// OGCG: %[[TMP3_VAL:.+]] = load i32, ptr %[[TMP3]]159// OGCG: store i32 %[[TMP3_VAL]], ptr %[[TMP2]]160// OGCG: %[[RES:.+]] = load i32, ptr %[[TMP2]]161// OGCG: ret i32 %[[RES]]162 163void empty() {164 return ({;;;;});165}166 167// CIR: cir.func no_proto dso_local @empty()168// CIR-NEXT: cir.return169 170// LLVM: define dso_local void @empty()171// LLVM: ret void172// LLVM: }173 174// OGCG: define dso_local void @empty()175// OGCG: ret void176// OGCG: }177 178void empty2() { ({ }); }179 180// CIR: @empty2181// CIR-NEXT: cir.return182 183// LLVM: @empty2()184// LLVM: ret void185// LLVM: }186 187// OGCG: @empty2()188// OGCG: ret void189// OGCG: }190 191 192// Yields an out-of-scope scalar.193void test2() { ({int x = 3; x; }); }194// CIR: @test2195// CIR: %[[RETVAL:.+]] = cir.alloca !s32i, !cir.ptr<!s32i>196// CIR: cir.scope {197// CIR: %[[VAR:.+]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["x", init]198// [...]199// CIR: %[[TMP:.+]] = cir.load{{.*}} %[[VAR]] : !cir.ptr<!s32i>, !s32i200// CIR: cir.store{{.*}} %[[TMP]], %[[RETVAL]] : !s32i, !cir.ptr<!s32i>201// CIR: }202// CIR: %{{.+}} = cir.load{{.*}} %[[RETVAL]] : !cir.ptr<!s32i>, !s32i203 204// LLVM: define dso_local void @test2()205// LLVM: %[[X:.+]] = alloca i32, i64 1206// LLVM: %[[TMP:.+]] = alloca i32, i64 1207// LLVM: br label %[[LBL3:.+]]208// LLVM: [[LBL3]]:209// LLVM: store i32 3, ptr %[[X]]210// LLVM: %[[X_VAL:.+]] = load i32, ptr %[[X]]211// LLVM: store i32 %[[X_VAL]], ptr %[[TMP]]212// LLVM: br label %[[LBL5:.+]]213// LLVM: [[LBL5]]:214// LLVM: ret void215 216// OGCG: define dso_local void @test2()217// OGCG: entry:218// OGCG: %[[X:.+]] = alloca i32219// OGCG: %[[TMP:.+]] = alloca i32220// OGCG: store i32 3, ptr %[[X]]221// OGCG: %[[X_VAL:.+]] = load i32, ptr %[[X]]222// OGCG: store i32 %[[X_VAL]], ptr %[[TMP]]223// OGCG: %[[TMP_VAL:.+]] = load i32, ptr %[[TMP]]224// OGCG: ret void225 226// Yields an aggregate.227struct S { int x; };228int test3() { return ({ struct S s = {1}; s; }).x; }229// CIR: cir.func no_proto dso_local @test3() -> !s32i230// CIR: %[[RETVAL:.+]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["__retval"]231// CIR: cir.scope {232// CIR: %[[REF_TMP0:.+]] = cir.alloca !rec_S, !cir.ptr<!rec_S>, ["ref.tmp0"]233// CIR: %[[TMP:.+]] = cir.alloca !rec_S, !cir.ptr<!rec_S>, ["tmp"]234// CIR: cir.scope {235// CIR: %[[S:.+]] = cir.alloca !rec_S, !cir.ptr<!rec_S>, ["s", init]236// CIR: %[[CONST:.*]] = cir.const #cir.const_record<{#cir.int<1> : !s32i}> : !rec_S237// CIR: cir.store{{.*}} %[[CONST]], %[[S]] : !rec_S, !cir.ptr<!rec_S>238// CIR: cir.copy %[[S]] to %[[REF_TMP0]] : !cir.ptr<!rec_S>239// CIR: }240// CIR: %[[GEP_X_TMP:.+]] = cir.get_member %[[REF_TMP0]][0] {name = "x"} : !cir.ptr<!rec_S> -> !cir.ptr<!s32i>241// CIR: %[[XVAL:.+]] = cir.load {{.*}} %[[GEP_X_TMP]] : !cir.ptr<!s32i>, !s32i242// CIR: cir.store{{.*}} %[[XVAL]], %[[RETVAL]] : !s32i, !cir.ptr<!s32i>243// CIR: }244// CIR: %[[RES:.+]] = cir.load %[[RETVAL]] : !cir.ptr<!s32i>, !s32i245// CIR: cir.return %[[RES]] : !s32i246 247// LLVM: define dso_local i32 @test3()248// LLVM: %[[VAR1:.+]] = alloca %struct.S, i64 1249// LLVM: %[[VAR2:.+]] = alloca %struct.S, i64 1250// LLVM: %[[VAR3:.+]] = alloca %struct.S, i64 1251// LLVM: %[[VAR4:.+]] = alloca i32, i64 1252// LLVM: br label %[[LBL5:.+]]253// LLVM: [[LBL5]]:254// LLVM: br label %[[LBL6:.+]]255// LLVM: [[LBL6]]:256// LLVM: store %struct.S { i32 1 }, ptr %[[VAR3]]257// LLVM: call void @llvm.memcpy.p0.p0.i32(ptr %[[VAR1]], ptr %[[VAR3]], i32 4, i1 false)258// LLVM: br label %[[LBL8:.+]]259// LLVM: [[LBL8]]:260// LLVM: %[[GEP_VAR1:.+]] = getelementptr %struct.S, ptr %[[VAR1]], i32 0, i32 0261// LLVM: %[[LOAD_X:.+]] = load i32, ptr %[[GEP_VAR1]]262// LLVM: store i32 %[[LOAD_X]], ptr %[[VAR4]]263// LLVM: br label %[[LBL11:.+]]264// LLVM: [[LBL11]]:265// LLVM: %[[RES:.+]] = load i32, ptr %[[VAR4]]266// LLVM: ret i32 %[[RES]]267 268// OGCG: define dso_local i32 @test3()269// OGCG: entry:270// OGCG: %[[REF_TMP:.+]] = alloca %struct.S271// OGCG: %[[S:.+]] = alloca %struct.S272// OGCG: call void @llvm.memcpy.p0.p0.i64(ptr align 4 %[[S]], ptr align 4 @__const.test3.s, i64 4, i1 false)273// OGCG: call void @llvm.memcpy.p0.p0.i64(ptr align 4 %[[REF_TMP]], ptr align 4 %[[S]], i64 4, i1 false)274// OGCG: %[[GEP:.+]] = getelementptr inbounds nuw %struct.S, ptr %[[REF_TMP]], i32 0, i32 0275// OGCG: %[[XVAL:.+]] = load i32, ptr %[[GEP]]276// OGCG: ret i32 %[[XVAL]]277 278// Expression is wrapped in an expression attribute (just ensure it does not crash).279void test4(int x) { ({[[gsl::suppress("foo")]] x;}); }280// CIR: @test4281// LLVM: @test4282// OGCG: @test4283