372 lines · cpp
1// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o %t.cir2// RUN: FileCheck --check-prefix=CIR --input-file=%t.cir %s3// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm %s -o %t-cir.ll4// RUN: FileCheck --check-prefix=LLVM --input-file=%t-cir.ll %s5// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm %s -o %t.ll6// RUN: FileCheck --check-prefix=OGCG --input-file=%t.ll %s7 8struct IncompleteS;9IncompleteS *p;10 11// CIR: cir.global external @p = #cir.ptr<null> : !cir.ptr<!rec_IncompleteS>12// LLVM: @p = global ptr null13// OGCG: @p = global ptr null, align 814 15struct CompleteS {16 int a;17 char b;18};19 20CompleteS cs;21 22// CIR: cir.global external @cs = #cir.zero : !rec_CompleteS23// LLVM-DAG: @cs = global %struct.CompleteS zeroinitializer24// OGCG-DAG: @cs = global %struct.CompleteS zeroinitializer, align 425 26void f(void) {27 IncompleteS *p;28}29 30// CIR: cir.func{{.*}} @_Z1fv()31// CIR-NEXT: cir.alloca !cir.ptr<!rec_IncompleteS>, !cir.ptr<!cir.ptr<!rec_IncompleteS>>, ["p"]32// CIR-NEXT: cir.return33 34// LLVM: define{{.*}} void @_Z1fv()35// LLVM-NEXT: %[[P:.*]] = alloca ptr, i64 1, align 836// LLVM-NEXT: ret void37 38// OGCG: define{{.*}} void @_Z1fv()39// OGCG-NEXT: entry:40// OGCG-NEXT: %[[P:.*]] = alloca ptr, align 841// OGCG-NEXT: ret void42 43char f2(CompleteS &s) {44 return s.b;45}46 47// CIR: cir.func{{.*}} @_Z2f2R9CompleteS(%[[ARG_S:.*]]: !cir.ptr<!rec_CompleteS>{{.*}})48// CIR: %[[S_ADDR:.*]] = cir.alloca !cir.ptr<!rec_CompleteS>, !cir.ptr<!cir.ptr<!rec_CompleteS>>, ["s", init, const]49// CIR: cir.store %[[ARG_S]], %[[S_ADDR]]50// CIR: %[[S_REF:.*]] = cir.load{{.*}} %[[S_ADDR]]51// CIR: %[[S_ADDR2:.*]] = cir.get_member %[[S_REF]][1] {name = "b"}52// CIR: %[[S_B:.*]] = cir.load{{.*}} %[[S_ADDR2]]53 54// LLVM: define{{.*}} i8 @_Z2f2R9CompleteS(ptr %[[ARG_S:.*]])55// LLVM: %[[S_ADDR:.*]] = alloca ptr56// LLVM: store ptr %[[ARG_S]], ptr %[[S_ADDR]]57// LLVM: %[[S_REF:.*]] = load ptr, ptr %[[S_ADDR]], align 858// LLVM: %[[S_ADDR2:.*]] = getelementptr %struct.CompleteS, ptr %[[S_REF]], i32 0, i32 159// LLVM: %[[S_B:.*]] = load i8, ptr %[[S_ADDR2]]60 61// OGCG: define{{.*}} i8 @_Z2f2R9CompleteS(ptr{{.*}} %[[ARG_S:.*]])62// OGCG: entry:63// OGCG: %[[S_ADDR:.*]] = alloca ptr64// OGCG: store ptr %[[ARG_S]], ptr %[[S_ADDR]]65// OGCG: %[[S_REF:.*]] = load ptr, ptr %[[S_ADDR]]66// OGCG: %[[S_ADDR2:.*]] = getelementptr inbounds nuw %struct.CompleteS, ptr %[[S_REF]], i32 0, i32 167// OGCG: %[[S_B:.*]] = load i8, ptr %[[S_ADDR2]]68 69struct Inner {70 int n;71};72 73struct Outer {74 Inner i;75};76 77void f3() {78 Outer o;79 o.i.n;80}81 82// CIR: cir.func{{.*}} @_Z2f3v()83// CIR: %[[O:.*]] = cir.alloca !rec_Outer, !cir.ptr<!rec_Outer>, ["o"]84// CIR: %[[O_I:.*]] = cir.get_member %[[O]][0] {name = "i"}85// CIR: %[[O_I_N:.*]] = cir.get_member %[[O_I]][0] {name = "n"}86 87// LLVM: define{{.*}} void @_Z2f3v()88// LLVM: %[[O:.*]] = alloca %struct.Outer, i64 1, align 489// LLVM: %[[O_I:.*]] = getelementptr %struct.Outer, ptr %[[O]], i32 0, i32 090// LLVM: %[[O_I_N:.*]] = getelementptr %struct.Inner, ptr %[[O_I]], i32 0, i32 091 92// OGCG: define{{.*}} void @_Z2f3v()93// OGCG: %[[O:.*]] = alloca %struct.Outer, align 494// OGCG: %[[O_I:.*]] = getelementptr inbounds nuw %struct.Outer, ptr %[[O]], i32 0, i32 095// OGCG: %[[O_I_N:.*]] = getelementptr inbounds nuw %struct.Inner, ptr %[[O_I]], i32 0, i32 096 97void paren_expr() {98 struct Point {99 int x;100 int y;101 };102 103 Point a = (Point{});104 Point b = (a);105}106 107// CIR: cir.func{{.*}} @_Z10paren_exprv()108// CIR: %[[A_ADDR:.*]] = cir.alloca !rec_Point, !cir.ptr<!rec_Point>, ["a", init]109// CIR: %[[B_ADDR:.*]] = cir.alloca !rec_Point, !cir.ptr<!rec_Point>, ["b", init]110// CIR: %[[CONST:.*]] = cir.const #cir.zero : !rec_Point111// CIR: cir.store{{.*}} %[[CONST]], %[[A_ADDR]] : !rec_Point, !cir.ptr<!rec_Point>112// CIR: cir.call @_ZZ10paren_exprvEN5PointC1ERKS_(%[[B_ADDR]], %[[A_ADDR]]) nothrow : (!cir.ptr<!rec_Point>, !cir.ptr<!rec_Point>) -> ()113 114// LLVM: define{{.*}} void @_Z10paren_exprv()115// LLVM: %[[A_ADDR:.*]] = alloca %struct.Point, i64 1, align 4116// LLVM: %[[B_ADDR:.*]] = alloca %struct.Point, i64 1, align 4117// LLVM: store %struct.Point zeroinitializer, ptr %[[A_ADDR]], align 4118// LLVM: call void @_ZZ10paren_exprvEN5PointC1ERKS_(ptr %[[B_ADDR]], ptr %[[A_ADDR]])119 120// OGCG: define{{.*}} void @_Z10paren_exprv()121// OGCG: %[[A_ADDR:.*]] = alloca %struct.Point, align 4122// OGCG: %[[B_ADDR:.*]] = alloca %struct.Point, align 4123// OGCG: call void @llvm.memset.p0.i64(ptr align 4 %[[A_ADDR]], i8 0, i64 8, i1 false)124// OGCG: call void @llvm.memcpy.p0.p0.i64(ptr align 4 %[[B_ADDR]], ptr align 4 %[[A_ADDR]], i64 8, i1 false)125 126void choose_expr() {127 CompleteS a;128 CompleteS b;129 CompleteS c = __builtin_choose_expr(true, a, b);130}131 132// CIR: cir.func{{.*}} @_Z11choose_exprv()133// CIR: %[[A_ADDR:.*]] = cir.alloca !rec_CompleteS, !cir.ptr<!rec_CompleteS>, ["a"]134// CIR: %[[B_ADDR:.*]] = cir.alloca !rec_CompleteS, !cir.ptr<!rec_CompleteS>, ["b"]135// CIR: %[[C_ADDR:.*]] = cir.alloca !rec_CompleteS, !cir.ptr<!rec_CompleteS>, ["c", init]136// TODO(cir): Call to default copy constructor should be replaced by `cir.copy` op137// CIR: cir.call @_ZN9CompleteSC1ERKS_(%[[C_ADDR]], %[[A_ADDR]]) nothrow : (!cir.ptr<!rec_CompleteS>, !cir.ptr<!rec_CompleteS>) -> ()138 139// LLVM: define{{.*}} void @_Z11choose_exprv()140// LLVM: %[[A_ADDR:.*]] = alloca %struct.CompleteS, i64 1, align 4141// LLVM: %[[B_ADDR:.*]] = alloca %struct.CompleteS, i64 1, align 4142// LLVM: %[[C_ADDR:.*]] = alloca %struct.CompleteS, i64 1, align 4143// LLVM: call void @_ZN9CompleteSC1ERKS_(ptr %[[C_ADDR]], ptr %[[A_ADDR]])144 145// OGCG: define{{.*}} void @_Z11choose_exprv()146// OGCG: %[[A_ADDR:.*]] = alloca %struct.CompleteS, align 4147// OGCG: %[[B_ADDR:.*]] = alloca %struct.CompleteS, align 4148// OGCG: %[[C_ADDR:.*]] = alloca %struct.CompleteS, align 4149// OGCG: call void @llvm.memcpy.p0.p0.i64(ptr align 4 %[[C_ADDR]], ptr align 4 %[[A_ADDR]], i64 8, i1 false)150 151void generic_selection() {152 CompleteS a;153 CompleteS b;154 int c;155 CompleteS d = _Generic(c, int : a, default: b);156}157 158// CIR: cir.func{{.*}} @_Z17generic_selectionv()159// CIR: %[[A_ADDR:.*]] = cir.alloca !rec_CompleteS, !cir.ptr<!rec_CompleteS>, ["a"]160// CIR: %[[B_ADDR:.*]] = cir.alloca !rec_CompleteS, !cir.ptr<!rec_CompleteS>, ["b"]161// CIR: %[[C_ADDR:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["c"]162// CIR: %[[D_ADDR:.*]] = cir.alloca !rec_CompleteS, !cir.ptr<!rec_CompleteS>, ["d", init]163// TODO(cir): Call to default copy constructor should be replaced by `cir.copy` op164// CIR: cir.call @_ZN9CompleteSC1ERKS_(%[[D_ADDR]], %[[A_ADDR]]) nothrow : (!cir.ptr<!rec_CompleteS>, !cir.ptr<!rec_CompleteS>) -> ()165 166// LLVM: define{{.*}} void @_Z17generic_selectionv()167// LLVM: %1 = alloca %struct.CompleteS, i64 1, align 4168// LLVM: %2 = alloca %struct.CompleteS, i64 1, align 4169// LLVM: %3 = alloca i32, i64 1, align 4170// LLVM: %4 = alloca %struct.CompleteS, i64 1, align 4171// LLVM: call void @_ZN9CompleteSC1ERKS_(ptr %4, ptr %1)172 173// OGCG: define{{.*}} void @_Z17generic_selectionv()174// OGCG: %[[A_ADDR:.*]] = alloca %struct.CompleteS, align 4175// OGCG: %[[B_ADDR:.*]] = alloca %struct.CompleteS, align 4176// OGCG: %[[C_ADDR:.*]] = alloca i32, align 4177// OGCG: %[[D_ADDR:.*]] = alloca %struct.CompleteS, align 4178// OGCG: call void @llvm.memcpy.p0.p0.i64(ptr align 4 %[[D_ADDR]], ptr align 4 %[[A_ADDR]], i64 8, i1 false)179 180void designated_init_update_expr() {181 CompleteS a;182 183 struct Container {184 CompleteS c;185 } b = {a, .c.a = 1};186}187 188// CIR: %[[A_ADDR:.*]] = cir.alloca !rec_CompleteS, !cir.ptr<!rec_CompleteS>, ["a"]189// CIR: %[[B_ADDR:.*]] = cir.alloca !rec_Container, !cir.ptr<!rec_Container>, ["b", init]190// CIR: %[[C_ADDR:.*]] = cir.get_member %[[B_ADDR]][0] {name = "c"} : !cir.ptr<!rec_Container> -> !cir.ptr<!rec_CompleteS>191// CIR: cir.call @_ZN9CompleteSC1ERKS_(%2, %[[A_ADDR]]) nothrow : (!cir.ptr<!rec_CompleteS>, !cir.ptr<!rec_CompleteS>) -> ()192// CIR: %[[ELEM_0_PTR:.*]] = cir.get_member %[[C_ADDR]][0] {name = "a"} : !cir.ptr<!rec_CompleteS> -> !cir.ptr<!s32i>193// CIR: %[[CONST_1:.*]] = cir.const #cir.int<1> : !s32i194// CIR: cir.store{{.*}} %[[CONST_1]], %[[ELEM_0_PTR]] : !s32i, !cir.ptr<!s32i>195// CIR: %[[ELEM_1_PTR:.*]] = cir.get_member %[[C_ADDR]][1] {name = "b"} : !cir.ptr<!rec_CompleteS> -> !cir.ptr<!s8i>196 197// LLVM: %[[A_ADDR:.*]] = alloca %struct.CompleteS, i64 1, align 4198// LLVM: %[[B_ADDR:.*]] = alloca %struct.Container, i64 1, align 4199// LLVM: %[[C_ADDR:.*]] = getelementptr %struct.Container, ptr %[[B_ADDR]], i32 0, i32 0200// LLVM: call void @_ZN9CompleteSC1ERKS_(ptr %[[C_ADDR]], ptr %[[A_ADDR]])201// LLVM: %[[ELEM_0_PTR:.*]] = getelementptr %struct.CompleteS, ptr %[[C_ADDR]], i32 0, i32 0202// LLVM: store i32 1, ptr %[[ELEM_0_PTR]], align 4203// LLVM: %[[ELEM_1_PTR:.*]] = getelementptr %struct.CompleteS, ptr %[[C_ADDR]], i32 0, i32 1204 205// OGCG: %[[A_ADDR:.*]] = alloca %struct.CompleteS, align 4206// OGCG: %[[B_ADDR:.*]] = alloca %struct.Container, align 4207// OGCG: %[[C_ADDR:.*]] = getelementptr inbounds nuw %struct.Container, ptr %[[B_ADDR]], i32 0, i32 0208// OGCG: call void @llvm.memcpy.p0.p0.i64(ptr align 4 %[[C_ADDR]], ptr align 4 %[[A_ADDR]], i64 8, i1 false)209// OGCG: %[[ELEM_0_PTR:.*]] = getelementptr inbounds nuw %struct.CompleteS, ptr %[[C_ADDR]], i32 0, i32 0210// OGCG: store i32 1, ptr %[[ELEM_0_PTR]], align 4211// OGCG: %[[ELEM_1_PTR:.*]] = getelementptr inbounds nuw %struct.CompleteS, ptr %[[C_ADDR]], i32 0, i32 1212 213void atomic_init() {214 _Atomic CompleteS a;215 __c11_atomic_init(&a, {});216}217 218// CIR: cir.func{{.*}} @_Z11atomic_initv()219// CIR: %[[A_ADDR:.*]] = cir.alloca !rec_CompleteS, !cir.ptr<!rec_CompleteS>, ["a"]220// CIR: %[[ELEM_0_PTR:.*]] = cir.get_member %[[A_ADDR]][0] {name = "a"} : !cir.ptr<!rec_CompleteS> -> !cir.ptr<!s32i>221// CIR: %[[CONST_0:.*]] = cir.const #cir.int<0> : !s32i222// CIR: cir.store{{.*}} %[[CONST_0]], %[[ELEM_0_PTR]] : !s32i, !cir.ptr<!s32i>223// CIR: %[[ELEM_1_PTR:.*]] = cir.get_member %[[A_ADDR]][1] {name = "b"} : !cir.ptr<!rec_CompleteS> -> !cir.ptr<!s8i>224// CIR: %[[CONST_0:.*]] = cir.const #cir.int<0> : !s8i225// CIR: cir.store{{.*}} %[[CONST_0]], %[[ELEM_1_PTR]] : !s8i, !cir.ptr<!s8i>226 227// LLVM: define{{.*}} void @_Z11atomic_initv()228// LLVM: %[[A_ADDR:.*]] = alloca %struct.CompleteS, i64 1, align 8229// LLVM: %[[ELEM_0_PTR:.*]] = getelementptr %struct.CompleteS, ptr %[[A_ADDR]], i32 0, i32 0230// LLVM: store i32 0, ptr %[[ELEM_0_PTR]], align 8231// LLVM: %[[ELEM_1_PTR:.*]] = getelementptr %struct.CompleteS, ptr %[[A_ADDR]], i32 0, i32 1232// LLVM: store i8 0, ptr %[[ELEM_1_PTR]], align 4233 234// OGCG: define{{.*}} void @_Z11atomic_initv()235// OGCG: %[[A_ADDR:.*]] = alloca %struct.CompleteS, align 8236// OGCG: %[[ELEM_0_PTR:.*]] = getelementptr inbounds nuw %struct.CompleteS, ptr %[[A_ADDR]], i32 0, i32 0237// OGCG: store i32 0, ptr %[[ELEM_0_PTR]], align 8238// OGCG: %[[ELEM_1_PTR:.*]] = getelementptr inbounds nuw %struct.CompleteS, ptr %[[A_ADDR]], i32 0, i32 1239// OGCG: store i8 0, ptr %[[ELEM_1_PTR]], align 4240 241void unary_extension() {242 CompleteS a = __extension__ CompleteS();243}244 245// CIR: %[[A_ADDR:.*]] = cir.alloca !rec_CompleteS, !cir.ptr<!rec_CompleteS>, ["a", init]246// CIR: %[[ZERO_INIT:.*]] = cir.const #cir.zero : !rec_CompleteS247// CIR: cir.store{{.*}} %[[ZERO_INIT]], %[[A_ADDR]] : !rec_CompleteS, !cir.ptr<!rec_CompleteS>248 249// LLVM: %[[A_ADDR:.*]] = alloca %struct.CompleteS, i64 1, align 4250// LLVM: store %struct.CompleteS zeroinitializer, ptr %[[A_ADDR]], align 4251 252// OGCG: %[[A_ADDR:.*]] = alloca %struct.CompleteS, align 4253// OGCG: call void @llvm.memset.p0.i64(ptr align 4 %[[A_ADDR]], i8 0, i64 8, i1 false)254 255void bin_comma() { 256 CompleteS a = (CompleteS(), CompleteS());257}258 259// CIR: cir.func{{.*}} @_Z9bin_commav()260// CIR: %[[A_ADDR:.*]] = cir.alloca !rec_CompleteS, !cir.ptr<!rec_CompleteS>, ["a", init]261// CIR: %[[CONST:.*]] = cir.const #cir.zero : !rec_CompleteS262// CIR: cir.store{{.*}} %[[CONST]], %[[A_ADDR]] : !rec_CompleteS, !cir.ptr<!rec_CompleteS>263 264// LLVM: define{{.*}} void @_Z9bin_commav()265// LLVM: %[[A_ADDR:.*]] = alloca %struct.CompleteS, i64 1, align 4266// LLVM: store %struct.CompleteS zeroinitializer, ptr %[[A_ADDR]], align 4267 268// OGCG: define{{.*}} void @_Z9bin_commav()269// OGCG: %[[A_ADDR:.*]] = alloca %struct.CompleteS, align 4270// OGCG: call void @llvm.memset.p0.i64(ptr align 4 %[[A_ADDR]], i8 0, i64 8, i1 false)271 272void compound_literal_expr() { CompleteS a = (CompleteS){}; }273 274// CIR: %[[A_ADDR:.*]] = cir.alloca !rec_CompleteS, !cir.ptr<!rec_CompleteS>, ["a", init]275// CIR: %[[CONST:.*]] = cir.const #cir.zero : !rec_CompleteS276// CIR: cir.store{{.*}} %[[CONST]], %[[A_ADDR]] : !rec_CompleteS, !cir.ptr<!rec_CompleteS>277 278// TODO(cir): zero-initialize the padding279 280// LLVM: %[[A_ADDR:.*]] = alloca %struct.CompleteS, i64 1, align 4281// LLVM: store %struct.CompleteS zeroinitializer, ptr %[[A_ADDR]], align 4282 283// OGCG: %[[A_ADDR:.*]] = alloca %struct.CompleteS, align 4284// OGCG: call void @llvm.memset.p0.i64(ptr align 4 %[[A_ADDR]], i8 0, i64 8, i1 false)285 286struct StructWithConstMember {287 int a : 1;288};289 290void struct_with_const_member_expr() {291 int a = (StructWithConstMember){}.a;292}293 294// CIR: %[[A_ADDR:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["a", init]295// CIR: %[[RESULT:.*]] = cir.scope {296// CIR: %[[REF_ADDR:.*]] = cir.alloca !rec_StructWithConstMember, !cir.ptr<!rec_StructWithConstMember>, ["ref.tmp0"]297// CIR: %[[ELEM_0_PTR:.*]] = cir.get_member %[[REF_ADDR]][0] {name = "a"} : !cir.ptr<!rec_StructWithConstMember> -> !cir.ptr<!u8i>298// CIR: %[[CONST_0:.*]] = cir.const #cir.int<0> : !s32i299// CIR: %[[SET_BF:.*]] = cir.set_bitfield{{.*}} (#bfi_a, %[[ELEM_0_PTR]] : !cir.ptr<!u8i>, %[[CONST_0]] : !s32i) -> !s32i300// CIR: %[[CONST_0:.*]] = cir.const #cir.int<0> : !s32i301// CIR: cir.yield %[[CONST_0]] : !s32i302// CIR: } : !s32i303// CIR: cir.store{{.*}} %[[RESULT]], %[[A_ADDR]] : !s32i, !cir.ptr<!s32i>304 305// TODO(cir): zero-initialize the padding306 307// LLVM: %[[REF_ADDR:.*]] = alloca %struct.StructWithConstMember, i64 1, align 4308// LLVM: %[[A_ADDR:.*]] = alloca i32, i64 1, align 4309// LLVM: br label %[[BF_LABEL:.*]]310// LLVM: [[BF_LABEL]]:311// LLVM: %[[ELEM_0_PTR:.*]] = getelementptr %struct.StructWithConstMember, ptr %[[REF_ADDR]], i32 0, i32 0312// LLVM: %[[TMP_REF:.*]] = load i8, ptr %[[ELEM_0_PTR]], align 4313// LLVM: %[[BF_CLEAR:.*]] = and i8 %[[TMP_REF]], -2314// LLVM: %[[BF_SET:.*]] = or i8 %[[BF_CLEAR]], 0315// LLVM: store i8 %[[BF_SET]], ptr %[[ELEM_0_PTR]], align 4316// LLVM: br label %[[RESULT_LABEL:.*]]317// LLVM: [[RESULT_LABEL]]:318// LLVM: %[[RESULT:.*]] = phi i32 [ 0, %[[BF_LABEL]] ]319// LLVM: store i32 %[[RESULT]], ptr %[[A_ADDR]], align 4320 321// OGCG: %[[A_ADDR:.*]] = alloca i32, align 4322// OGCG: %[[REF_ADDR:.*]] = alloca %struct.StructWithConstMember, align 4323// OGCG: %[[TMP_REF:.*]] = load i8, ptr %[[REF_ADDR]], align 4324// OGCG: %[[BF_CLEAR:.*]] = and i8 %[[TMP_REF]], -2325// OGCG: %[[BF_SET:.*]] = or i8 %[[BF_CLEAR]], 0326// OGCG: store i8 %[[BF_SET]], ptr %[[REF_ADDR]], align 4327// OGCG: store i32 0, ptr %[[A_ADDR]], align 4328 329void function_arg_with_default_value(CompleteS a = {1, 2}) {}330 331// CIR: %[[ARG_ADDR:.*]] = cir.alloca !rec_CompleteS, !cir.ptr<!rec_CompleteS>, ["a", init]332// CIR: cir.store %{{.*}}, %[[ARG_ADDR]] : !rec_CompleteS, !cir.ptr<!rec_CompleteS>333 334// LLVM: %[[ARG_ADDR:.*]] = alloca %struct.CompleteS, i64 1, align 4335// LLVM: store %struct.CompleteS %{{.*}}, ptr %[[ARG_ADDR]], align 4336 337// OGCG: %[[ARG_ADDR:.*]] = alloca %struct.CompleteS, align 4338// OGCG: store i64 %{{.*}}, ptr %[[ARG_ADDR]], align 4339 340void calling_function_with_default_values() {341 function_arg_with_default_value();342}343 344// CIR: %[[AGG_ADDR:.*]] = cir.alloca !rec_CompleteS, !cir.ptr<!rec_CompleteS>, ["agg.tmp0"]345// CIR: %[[ELEM_0_PTR:.*]] = cir.get_member %[[AGG_ADDR]][0] {name = "a"} : !cir.ptr<!rec_CompleteS> -> !cir.ptr<!s32i>346// CIR: %[[CONST_1:.*]] = cir.const #cir.int<1> : !s32i347// CIR: cir.store{{.*}} %[[CONST_1]], %[[ELEM_0_PTR]] : !s32i, !cir.ptr<!s32i>348// CIR: %[[ELEM_1_PTR:.*]] = cir.get_member %[[AGG_ADDR]][1] {name = "b"} : !cir.ptr<!rec_CompleteS> -> !cir.ptr<!s8i>349// CIR: %[[CONST_2:.*]] = cir.const #cir.int<2> : !s32i350// CIR: %[[CONST_2_I8:.*]] = cir.cast integral %[[CONST_2]] : !s32i -> !s8i351// CIR: cir.store{{.*}} %[[CONST_2_I8]], %[[ELEM_1_PTR]] : !s8i, !cir.ptr<!s8i>352// CIR: %[[TMP_AGG:.*]] = cir.load{{.*}} %[[AGG_ADDR]] : !cir.ptr<!rec_CompleteS>, !rec_CompleteS353// CIR: cir.call @_Z31function_arg_with_default_value9CompleteS(%[[TMP_AGG]]) : (!rec_CompleteS) -> ()354 355// TODO(CIR): the difference between the CIR LLVM and OGCG is because the lack of calling convention lowering,356 357// LLVM: %[[AGG_ADDR:.*]] = alloca %struct.CompleteS, i64 1, align 4358// LLVM: %[[ELEM_0_PTR:.*]] = getelementptr %struct.CompleteS, ptr %[[AGG_ADDR]], i32 0, i32 0359// LLVM: store i32 1, ptr %[[ELEM_0_PTR]], align 4360// LLVM: %[[ELEM_1_PTR:.*]] = getelementptr %struct.CompleteS, ptr %[[AGG_ADDR]], i32 0, i32 1361// LLVM: store i8 2, ptr %[[ELEM_1_PTR]], align 4362// LLVM: %[[TMP_AGG:.*]] = load %struct.CompleteS, ptr %[[AGG_ADDR]], align 4363// LLVM: call void @_Z31function_arg_with_default_value9CompleteS(%struct.CompleteS %[[TMP_AGG]])364 365// OGCG: %[[AGG_ADDR:.*]] = alloca %struct.CompleteS, align 4366// OGCG: %[[ELEM_0_PTR:.*]] = getelementptr inbounds nuw %struct.CompleteS, ptr %[[AGG_ADDR]], i32 0, i32 0367// OGCG: store i32 1, ptr %[[ELEM_0_PTR]], align 4368// OGCG: %[[ELEM_1_PTR:.*]] = getelementptr inbounds nuw %struct.CompleteS, ptr %[[AGG_ADDR]], i32 0, i32 1369// OGCG: store i8 2, ptr %[[ELEM_1_PTR]], align 4370// OGCG: %[[TMP_AGG:.*]] = load i64, ptr %[[AGG_ADDR]], align 4371// OGCG: call void @_Z31function_arg_with_default_value9CompleteS(i64 %[[TMP_AGG]])372