// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o %t.cir // RUN: FileCheck --check-prefix=CIR --input-file=%t.cir %s // RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm %s -o %t-cir.ll // RUN: FileCheck --check-prefix=LLVM --input-file=%t-cir.ll %s // RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm %s -o %t.ll // RUN: FileCheck --check-prefix=OGCG --input-file=%t.ll %s struct IncompleteS; IncompleteS *p; // CIR: cir.global external @p = #cir.ptr : !cir.ptr // LLVM: @p = global ptr null // OGCG: @p = global ptr null, align 8 struct CompleteS { int a; char b; }; CompleteS cs; // CIR: cir.global external @cs = #cir.zero : !rec_CompleteS // LLVM-DAG: @cs = global %struct.CompleteS zeroinitializer // OGCG-DAG: @cs = global %struct.CompleteS zeroinitializer, align 4 void f(void) { IncompleteS *p; } // CIR: cir.func{{.*}} @_Z1fv() // CIR-NEXT: cir.alloca !cir.ptr, !cir.ptr>, ["p"] // CIR-NEXT: cir.return // LLVM: define{{.*}} void @_Z1fv() // LLVM-NEXT: %[[P:.*]] = alloca ptr, i64 1, align 8 // LLVM-NEXT: ret void // OGCG: define{{.*}} void @_Z1fv() // OGCG-NEXT: entry: // OGCG-NEXT: %[[P:.*]] = alloca ptr, align 8 // OGCG-NEXT: ret void char f2(CompleteS &s) { return s.b; } // CIR: cir.func{{.*}} @_Z2f2R9CompleteS(%[[ARG_S:.*]]: !cir.ptr{{.*}}) // CIR: %[[S_ADDR:.*]] = cir.alloca !cir.ptr, !cir.ptr>, ["s", init, const] // CIR: cir.store %[[ARG_S]], %[[S_ADDR]] // CIR: %[[S_REF:.*]] = cir.load{{.*}} %[[S_ADDR]] // CIR: %[[S_ADDR2:.*]] = cir.get_member %[[S_REF]][1] {name = "b"} // CIR: %[[S_B:.*]] = cir.load{{.*}} %[[S_ADDR2]] // LLVM: define{{.*}} i8 @_Z2f2R9CompleteS(ptr %[[ARG_S:.*]]) // LLVM: %[[S_ADDR:.*]] = alloca ptr // LLVM: store ptr %[[ARG_S]], ptr %[[S_ADDR]] // LLVM: %[[S_REF:.*]] = load ptr, ptr %[[S_ADDR]], align 8 // LLVM: %[[S_ADDR2:.*]] = getelementptr %struct.CompleteS, ptr %[[S_REF]], i32 0, i32 1 // LLVM: %[[S_B:.*]] = load i8, ptr %[[S_ADDR2]] // OGCG: define{{.*}} i8 @_Z2f2R9CompleteS(ptr{{.*}} %[[ARG_S:.*]]) // OGCG: entry: // OGCG: %[[S_ADDR:.*]] = alloca ptr // OGCG: store ptr %[[ARG_S]], ptr %[[S_ADDR]] // OGCG: %[[S_REF:.*]] = load ptr, ptr %[[S_ADDR]] // OGCG: %[[S_ADDR2:.*]] = getelementptr inbounds nuw %struct.CompleteS, ptr %[[S_REF]], i32 0, i32 1 // OGCG: %[[S_B:.*]] = load i8, ptr %[[S_ADDR2]] struct Inner { int n; }; struct Outer { Inner i; }; void f3() { Outer o; o.i.n; } // CIR: cir.func{{.*}} @_Z2f3v() // CIR: %[[O:.*]] = cir.alloca !rec_Outer, !cir.ptr, ["o"] // CIR: %[[O_I:.*]] = cir.get_member %[[O]][0] {name = "i"} // CIR: %[[O_I_N:.*]] = cir.get_member %[[O_I]][0] {name = "n"} // LLVM: define{{.*}} void @_Z2f3v() // LLVM: %[[O:.*]] = alloca %struct.Outer, i64 1, align 4 // LLVM: %[[O_I:.*]] = getelementptr %struct.Outer, ptr %[[O]], i32 0, i32 0 // LLVM: %[[O_I_N:.*]] = getelementptr %struct.Inner, ptr %[[O_I]], i32 0, i32 0 // OGCG: define{{.*}} void @_Z2f3v() // OGCG: %[[O:.*]] = alloca %struct.Outer, align 4 // OGCG: %[[O_I:.*]] = getelementptr inbounds nuw %struct.Outer, ptr %[[O]], i32 0, i32 0 // OGCG: %[[O_I_N:.*]] = getelementptr inbounds nuw %struct.Inner, ptr %[[O_I]], i32 0, i32 0