brintos

brintos / llvm-project-archived public Read only

0
0
Text · 13.6 KiB · aa7c4cf Raw
330 lines · c
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 8// For LLVM IR checks, the structs are defined before the variables, so these9// checks are at the top.10// CIR-DAG: !rec_IncompleteS = !cir.record<struct "IncompleteS" incomplete>11// CIR-DAG: !rec_CompleteS = !cir.record<struct "CompleteS" {!s32i, !s8i}>12// CIR-DAG: !rec_OuterS = !cir.record<struct "OuterS" {!rec_InnerS, !s32i}>  13// CIR-DAG: !rec_InnerS = !cir.record<struct "InnerS" {!s32i, !s8i}>14// CIR-DAG: !rec_PackedS = !cir.record<struct "PackedS" packed {!s32i, !s8i}>15// CIR-DAG: !rec_PackedAndPaddedS = !cir.record<struct "PackedAndPaddedS" packed padded {!s32i, !s8i, !u8i}>16// CIR-DAG: !rec_NodeS = !cir.record<struct "NodeS" {!cir.ptr<!cir.record<struct "NodeS">>}>17// CIR-DAG: !rec_RightS = !cir.record<struct "RightS" {!cir.ptr<!cir.record<struct "LeftS" {!cir.ptr<!cir.record<struct "RightS">>}>>}>18// CIR-DAG: !rec_LeftS = !cir.record<struct "LeftS" {!cir.ptr<!rec_RightS>}>19// CIR-DAG: !rec_CycleEnd = !cir.record<struct "CycleEnd" {!cir.ptr<!cir.record<struct "CycleStart" {!cir.ptr<!cir.record<struct "CycleMiddle" {!cir.ptr<!cir.record<struct "CycleEnd">>}>>}>>}>20// CIR-DAG: !rec_CycleMiddle = !cir.record<struct "CycleMiddle" {!cir.ptr<!rec_CycleEnd>}>21// CIR-DAG: !rec_CycleStart = !cir.record<struct "CycleStart" {!cir.ptr<!rec_CycleMiddle>}>22// CIR-DAG: !rec_IncompleteArray = !cir.record<struct "IncompleteArray" {!cir.array<!s32i x 0>}>23// LLVM-DAG: %struct.CompleteS = type { i32, i8 }24// LLVM-DAG: %struct.OuterS = type { %struct.InnerS, i32 }25// LLVM-DAG: %struct.InnerS = type { i32, i8 }26// LLVM-DAG: %struct.PackedS = type <{ i32, i8 }>27// LLVM-DAG: %struct.PackedAndPaddedS = type <{ i32, i8, i8 }>28// LLVM-DAG: %struct.NodeS = type { ptr }29// LLVM-DAG: %struct.LeftS = type { ptr }30// LLVM-DAG: %struct.RightS = type { ptr }31// LLVM-DAG: %struct.CycleStart = type { ptr }32// LLVM-DAG: %struct.CycleMiddle = type { ptr }33// LLVM-DAG: %struct.CycleEnd = type { ptr }34// LLVM-DAG: %struct.IncompleteArray = type { [0 x i32] }35// OGCG-DAG: %struct.CompleteS = type { i32, i8 }36// OGCG-DAG: %struct.OuterS = type { %struct.InnerS, i32 }37// OGCG-DAG: %struct.InnerS = type { i32, i8 }38// OGCG-DAG: %struct.PackedS = type <{ i32, i8 }>39// OGCG-DAG: %struct.PackedAndPaddedS = type <{ i32, i8, i8 }>40// OGCG-DAG: %struct.NodeS = type { ptr }41// OGCG-DAG: %struct.LeftS = type { ptr }42// OGCG-DAG: %struct.RightS = type { ptr }43// OGCG-DAG: %struct.CycleStart = type { ptr }44// OGCG-DAG: %struct.CycleMiddle = type { ptr }45// OGCG-DAG: %struct.CycleEnd = type { ptr }46// OGCG-DAG: %struct.IncompleteArray = type { [0 x i32] }47 48struct CompleteS {49  int a;50  char b;51} cs;52 53// CIR:       cir.global external @cs = #cir.zero : !rec_CompleteS54// LLVM-DAG:  @cs = global %struct.CompleteS zeroinitializer55// OGCG-DAG:  @cs = global %struct.CompleteS zeroinitializer, align 456 57struct IncompleteS *p;58 59// CIR:      cir.global external @p = #cir.ptr<null> : !cir.ptr<!rec_IncompleteS>60// LLVM-DAG: @p = global ptr null61// OGCG-DAG: @p = global ptr null, align 862 63struct InnerS {64  int a;65  char b;66};67 68struct OuterS {69  struct InnerS is;70  int c;71};72 73struct OuterS os;74 75// CIR:       cir.global external @os = #cir.zero : !rec_OuterS76// LLVM-DAG:  @os = global %struct.OuterS zeroinitializer77// OGCG-DAG:  @os = global %struct.OuterS zeroinitializer, align 478 79#pragma pack(push)80#pragma pack(1)81 82struct PackedS {83  int  a0;84  char a1;85} ps;86 87// CIR:       cir.global external @ps = #cir.zero : !rec_PackedS88// LLVM-DAG:  @ps = global %struct.PackedS zeroinitializer89// OGCG-DAG:  @ps = global %struct.PackedS zeroinitializer, align 190 91struct PackedAndPaddedS {92  int  b0;93  char b1;94} __attribute__((aligned(2))) pps;95 96// CIR:       cir.global external @pps = #cir.zero : !rec_PackedAndPaddedS97// LLVM-DAG:  @pps = global %struct.PackedAndPaddedS zeroinitializer98// OGCG-DAG:  @pps = global %struct.PackedAndPaddedS zeroinitializer, align 299 100#pragma pack(pop)101 102// Recursive type103struct NodeS {104  struct NodeS* next;105} node;106 107// CIR:      cir.global{{.*}} @node = #cir.zero : !rec_NodeS108// LLVM-DAG:  @node = global %struct.NodeS zeroinitializer109// OGCG-DAG:  @node = global %struct.NodeS zeroinitializer110 111// Mutually dependent types112struct RightS;113struct LeftS {114  struct RightS* right;115} ls;116 117// CIR:      cir.global{{.*}} @ls = #cir.zero : !rec_LeftS118// LLVM-DAG:  @ls = global %struct.LeftS zeroinitializer119// OGCG-DAG:  @ls = global %struct.LeftS zeroinitializer120 121struct RightS {122  struct LeftS* left;123} rs;124 125// CIR:      cir.global{{.*}} @rs = #cir.zero : !rec_RightS126// LLVM-DAG:  @rs = global %struct.RightS zeroinitializer127// OGCG-DAG:  @rs = global %struct.RightS zeroinitializer128 129struct CycleMiddle;130struct CycleEnd;131struct CycleStart {132  struct CycleMiddle* middle;133} start;134 135// CIR:      cir.global{{.*}} @start = #cir.zero : !rec_CycleStart136// LLVM-DAG:  @start = global %struct.CycleStart zeroinitializer137// OGCG-DAG:  @start = global %struct.CycleStart zeroinitializer138 139struct CycleMiddle {140  struct CycleEnd* end;141} middle;142 143// CIR:      cir.global{{.*}} @middle = #cir.zero : !rec_CycleMiddle144// LLVM-DAG:  @middle = global %struct.CycleMiddle zeroinitializer145// OGCG-DAG:  @middle = global %struct.CycleMiddle zeroinitializer146 147struct CycleEnd {148  struct CycleStart* start;149} end;150 151// CIR:      cir.global{{.*}} @end = #cir.zero : !rec_CycleEnd152// LLVM-DAG:  @end = global %struct.CycleEnd zeroinitializer153// OGCG-DAG:  @end = global %struct.CycleEnd zeroinitializer154 155struct IncompleteArray {156  int array[];157} incomplete;158 159// CIR: cir.global external @incomplete = #cir.zero : !rec_IncompleteArray160 161// LLVM-DAG: global %struct.IncompleteArray zeroinitializer162 163// OGCG-DAG: global %struct.IncompleteArray zeroinitializer164 165void f(void) {166  struct IncompleteS *p;167}168 169// CIR:      cir.func{{.*}} @f()170// CIR-NEXT:   cir.alloca !cir.ptr<!rec_IncompleteS>, !cir.ptr<!cir.ptr<!rec_IncompleteS>>, ["p"] {alignment = 8 : i64}171// CIR-NEXT:   cir.return172 173// LLVM:      define{{.*}} void @f()174// LLVM-NEXT:   %[[P:.*]] = alloca ptr, i64 1, align 8175// LLVM-NEXT:   ret void176 177// OGCG:      define{{.*}} void @f()178// OGCG-NEXT: entry:179// OGCG-NEXT:   %[[P:.*]] = alloca ptr, align 8180// OGCG-NEXT:   ret void181 182void f2(void) {183  struct CompleteS s;184}185 186// CIR:      cir.func{{.*}} @f2()187// CIR-NEXT:   cir.alloca !rec_CompleteS, !cir.ptr<!rec_CompleteS>, ["s"] {alignment = 4 : i64}188// CIR-NEXT:   cir.return189 190// LLVM:      define{{.*}} void @f2()191// LLVM-NEXT:   %[[S:.*]] = alloca %struct.CompleteS, i64 1, align 4192// LLVM-NEXT:   ret void193 194// OGCG:      define{{.*}} void @f2()195// OGCG-NEXT: entry:196// OGCG-NEXT:   %[[S:.*]] = alloca %struct.CompleteS, align 4197// OGCG-NEXT:   ret void198 199char f3(int a) {200  cs.a = a;201  return cs.b;202}203 204// CIR:      cir.func{{.*}} @f3(%[[ARG_A:.*]]: !s32i205// CIR-NEXT:   %[[A_ADDR:.*]] = cir.alloca {{.*}} ["a", init] {alignment = 4 : i64}206// CIR-NEXT:   %[[RETVAL_ADDR:.*]] = cir.alloca {{.*}} ["__retval"] {alignment = 1 : i64}207// CIR-NEXT:   cir.store{{.*}} %[[ARG_A]], %[[A_ADDR]]208// CIR-NEXT:   %[[A_VAL:.*]] = cir.load{{.*}} %[[A_ADDR]]209// CIR-NEXT:   %[[CS:.*]] = cir.get_global @cs210// CIR-NEXT:   %[[CS_A:.*]] = cir.get_member %[[CS]][0] {name = "a"}211// CIR-NEXT:   cir.store{{.*}} %[[A_VAL]], %[[CS_A]]212// CIR-NEXT:   %[[CS2:.*]] = cir.get_global @cs213// CIR-NEXT:   %[[CS_B:.*]] = cir.get_member %[[CS2]][1] {name = "b"}214// CIR-NEXT:   %[[CS_B_VAL:.*]] = cir.load{{.*}} %[[CS_B]]215// CIR-NEXT:   cir.store{{.*}} %[[CS_B_VAL]], %[[RETVAL_ADDR]]216// CIR-NEXT:   %[[RETVAL:.*]] = cir.load{{.*}} %[[RETVAL_ADDR]]217// CIR-NEXT:   cir.return %[[RETVAL]]218 219// LLVM:      define{{.*}} i8 @f3(i32 %[[ARG_A:.*]])220// LLVM-NEXT:   %[[A_ADDR:.*]] = alloca i32, i64 1, align 4221// LLVM-NEXT:   %[[RETVAL_ADDR:.*]] = alloca i8, i64 1, align 1222// LLVM-NEXT:   store i32 %[[ARG_A]], ptr %[[A_ADDR]], align 4223// LLVM-NEXT:   %[[A_VAL:.*]] = load i32, ptr %[[A_ADDR]], align 4224// LLVM-NEXT:   store i32 %[[A_VAL]], ptr @cs, align 4225// LLVM-NEXT:   %[[CS_B_VAL:.*]] = load i8, ptr getelementptr inbounds nuw (i8, ptr @cs, i64 4), align 4226// LLVM-NEXT:   store i8 %[[CS_B_VAL]], ptr %[[RETVAL_ADDR]], align 1227// LLVM-NEXT:   %[[RETVAL:.*]] = load i8, ptr %[[RETVAL_ADDR]], align 1228// LLVM-NEXT:   ret i8 %[[RETVAL]]229 230// OGCG:      define{{.*}} i8 @f3(i32{{.*}} %[[ARG_A:.*]])231// OGCG-NEXT: entry:232// OGCG-NEXT:   %[[A_ADDR:.*]] = alloca i32, align 4233// OGCG-NEXT:   store i32 %[[ARG_A]], ptr %[[A_ADDR]], align 4234// OGCG-NEXT:   %[[A_VAL:.*]] = load i32, ptr %[[A_ADDR]], align 4235// OGCG-NEXT:   store i32 %[[A_VAL]], ptr @cs, align 4236// OGCG-NEXT:   %[[CS_B_VAL:.*]] = load i8, ptr getelementptr inbounds nuw (%struct.CompleteS, ptr @cs, i32 0, i32 1), align 4237// OGCG-NEXT:   ret i8 %[[CS_B_VAL]]238 239char f4(int a, struct CompleteS *p) {240  p->a = a;241  return p->b;242}243 244// CIR:      cir.func{{.*}} @f4(%[[ARG_A:.*]]: !s32i {{.*}}, %[[ARG_P:.*]]: !cir.ptr<!rec_CompleteS>245// CIR-NEXT:   %[[A_ADDR:.*]] = cir.alloca {{.*}} ["a", init] {alignment = 4 : i64}246// CIR-NEXT:   %[[P_ADDR:.*]] = cir.alloca {{.*}} ["p", init] {alignment = 8 : i64}247// CIR-NEXT:   %[[RETVAL_ADDR:.*]] = cir.alloca {{.*}} ["__retval"] {alignment = 1 : i64}248// CIR-NEXT:   cir.store{{.*}} %[[ARG_A]], %[[A_ADDR]]249// CIR-NEXT:   cir.store{{.*}} %[[ARG_P]], %[[P_ADDR]]250// CIR-NEXT:   %[[A_VAL:.*]] = cir.load{{.*}} %[[A_ADDR]]251// CIR-NEXT:   %[[P:.*]] = cir.load{{.*}} %[[P_ADDR]]252// CIR-NEXT:   %[[P_A:.*]] = cir.get_member %[[P]][0] {name = "a"}253// CIR-NEXT:   cir.store{{.*}} %[[A_VAL]], %[[P_A]]254// CIR-NEXT:   %[[P2:.*]] = cir.load{{.*}} %[[P_ADDR]]255// CIR-NEXT:   %[[P_B:.*]] = cir.get_member %[[P2]][1] {name = "b"}256// CIR-NEXT:   %[[P_B_VAL:.*]] = cir.load{{.*}} %[[P_B]]257// CIR-NEXT:   cir.store{{.*}} %[[P_B_VAL]], %[[RETVAL_ADDR]]258// CIR-NEXT:   %[[RETVAL:.*]] = cir.load{{.*}} %[[RETVAL_ADDR]]259// CIR-NEXT:   cir.return %[[RETVAL]]260 261// LLVM:      define{{.*}} i8 @f4(i32 %[[ARG_A:.*]], ptr %[[ARG_P:.*]])262// LLVM-NEXT:   %[[A_ADDR:.*]] = alloca i32, i64 1, align 4263// LLVM-NEXT:   %[[P_ADDR:.*]] = alloca ptr, i64 1, align 8264// LLVM-NEXT:   %[[RETVAL_ADDR:.*]] = alloca i8, i64 1, align 1265// LLVM-NEXT:   store i32 %[[ARG_A]], ptr %[[A_ADDR]], align 4266// LLVM-NEXT:   store ptr %[[ARG_P]], ptr %[[P_ADDR]], align 8267// LLVM-NEXT:   %[[A_VAL:.*]] = load i32, ptr %[[A_ADDR]], align 4268// LLVM-NEXT:   %[[P_VAL:.*]] = load ptr, ptr %[[P_ADDR]], align 8269// LLVM-NEXT:   %[[P_A:.*]] = getelementptr %struct.CompleteS, ptr %[[P_VAL]], i32 0, i32 0270// LLVM-NEXT:   store i32 %[[A_VAL]], ptr %[[P_A]], align 4271// LLVM-NEXT:   %[[P_VAL2:.*]] = load ptr, ptr %[[P_ADDR]], align 8272// LLVM-NEXT:   %[[P_B:.*]] = getelementptr %struct.CompleteS, ptr %[[P_VAL2]], i32 0, i32 1273// LLVM-NEXT:   %[[P_B_VAL:.*]] = load i8, ptr %[[P_B]], align 4274// LLVM-NEXT:   store i8 %[[P_B_VAL]], ptr %[[RETVAL_ADDR]], align 1275// LLVM-NEXT:   %[[RETVAL:.*]] = load i8, ptr %[[RETVAL_ADDR]], align 1276// LLVM-NEXT:   ret i8 %[[RETVAL]]277 278// OGCG:      define{{.*}} i8 @f4(i32{{.*}} %[[ARG_A:.*]], ptr{{.*}} %[[ARG_P:.*]])279// OGCG-NEXT: entry:280// OGCG-NEXT:   %[[A_ADDR:.*]] = alloca i32, align 4281// OGCG-NEXT:   %[[P_ADDR:.*]] = alloca ptr, align 8282// OGCG-NEXT:   store i32 %[[ARG_A]], ptr %[[A_ADDR]], align 4283// OGCG-NEXT:   store ptr %[[ARG_P]], ptr %[[P_ADDR]], align 8284// OGCG-NEXT:   %[[A_VAL:.*]] = load i32, ptr %[[A_ADDR]], align 4285// OGCG-NEXT:   %[[P:.*]] = load ptr, ptr %[[P_ADDR]], align 8286// OGCG-NEXT:   %[[P_A:.*]] = getelementptr inbounds nuw %struct.CompleteS, ptr %[[P]], i32 0, i32 0287// OGCG-NEXT:   store i32 %[[A_VAL]], ptr %[[P_A]], align 4288// OGCG-NEXT:   %[[P2:.*]] = load ptr, ptr %[[P_ADDR]], align 8289// OGCG-NEXT:   %[[P_B:.*]] = getelementptr inbounds nuw %struct.CompleteS, ptr %[[P2]], i32 0, i32 1290// OGCG-NEXT:   %[[P_B_VAL:.*]] = load i8, ptr %[[P_B]], align 4291// OGCG-NEXT:   ret i8 %[[P_B_VAL]]292 293void f5(struct NodeS* a) {294  a->next = 0;295}296 297// CIR: cir.func{{.*}} @f5298// CIR:   %[[NEXT:.*]] = cir.get_member {{%.}}[0] {name = "next"} : !cir.ptr<!rec_NodeS> -> !cir.ptr<!cir.ptr<!rec_NodeS>>299// CIR:   cir.store {{.*}}, %[[NEXT]]300 301// LLVM: define{{.*}} void @f5302// LLVM:   %[[NEXT:.*]] = getelementptr %struct.NodeS, ptr %{{.*}}, i32 0, i32 0303// LLVM:   store ptr null, ptr %[[NEXT]]304 305// OGCG: define{{.*}} void @f5306// OGCG:   %[[NEXT:.*]] = getelementptr inbounds nuw %struct.NodeS, ptr %{{.*}}, i32 0, i32 0307// OGCG:   store ptr null, ptr %[[NEXT]]308 309void f6(struct CycleStart *start) {310  struct CycleMiddle *middle = start->middle;311  struct CycleEnd *end = middle->end;312  struct CycleStart *start2 = end->start;313}314 315// CIR: cir.func{{.*}} @f6316// CIR:   %[[MIDDLE:.*]] = cir.get_member {{.*}}[0] {name = "middle"} : !cir.ptr<!rec_CycleStart> -> !cir.ptr<!cir.ptr<!rec_CycleMiddle>>317// CIR:   %[[END:.*]] = cir.get_member %{{.*}}[0] {name = "end"} : !cir.ptr<!rec_CycleMiddle> -> !cir.ptr<!cir.ptr<!rec_CycleEnd>>318// CIR:   %[[START2:.*]] = cir.get_member %{{.*}}[0] {name = "start"} : !cir.ptr<!rec_CycleEnd> -> !cir.ptr<!cir.ptr<!rec_CycleStart>>319 320// LLVM: define{{.*}} void @f6321// LLVM:   %[[MIDDLE:.*]] = getelementptr %struct.CycleStart, ptr %{{.*}}, i32 0, i32 0322// LLVM:   %[[END:.*]] = getelementptr %struct.CycleMiddle, ptr %{{.*}}, i32 0, i32 0323// LLVM:   %[[START2:.*]] = getelementptr %struct.CycleEnd, ptr %{{.*}}, i32 0, i32 0324 325// OGCG: define{{.*}} void @f6326// OGCG:   %[[MIDDLE:.*]] = getelementptr inbounds nuw %struct.CycleStart, ptr %{{.*}}, i32 0, i32 0327// OGCG:   %[[END:.*]] = getelementptr inbounds nuw %struct.CycleMiddle, ptr %{{.*}}, i32 0, i32 0328// OGCG:   %[[START2:.*]] = getelementptr inbounds nuw %struct.CycleEnd, ptr %{{.*}}, i32 0, i32 0329 330