brintos

brintos / llvm-project-archived public Read only

0
0
Text · 6.9 KiB · 9f8c477 Raw
150 lines · c
1// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 62// RUN: %clang_cc1 -triple=x86_64 -std=c2y %s -emit-llvm -o - | FileCheck %s3 4/* WG14 N3254: Yes5 * Accessing byte arrays6 *7 * NB: this basically boils down to how LLVM handles TBAA, so the best we can8 * do for a Clang test is to test that the LLVM IR we pass is reasonable and we9 * presume that LLVM has the test coverage to ensure that this behavior isn't10 * regressed.11 */12 13struct S {14  int x;15  char c;16  float f;17};18 19#define DECL_BUFFER(Ty, Name) alignas(Ty) unsigned char Name[sizeof(Ty)]20 21// CHECK-LABEL: define dso_local i32 @foo(22// CHECK-SAME: ) #[[ATTR0:[0-9]+]] {23// CHECK-NEXT:  [[ENTRY:.*:]]24// CHECK-NEXT:    [[BUFFER:%.*]] = alloca [12 x i8], align 425// CHECK-NEXT:    [[S_PTR:%.*]] = alloca ptr, align 826// CHECK-NEXT:    call void @llvm.memset.p0.i64(ptr align 4 [[BUFFER]], i8 0, i64 12, i1 false)27// CHECK-NEXT:    [[ARRAYDECAY:%.*]] = getelementptr inbounds [12 x i8], ptr [[BUFFER]], i64 0, i64 028// CHECK-NEXT:    store ptr [[ARRAYDECAY]], ptr [[S_PTR]], align 829// CHECK-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[S_PTR]], align 830// CHECK-NEXT:    [[X:%.*]] = getelementptr inbounds nuw [[STRUCT_S:%.*]], ptr [[TMP0]], i32 0, i32 031// CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[X]], align 432// CHECK-NEXT:    ret i32 [[TMP1]]33//34int foo() {35  DECL_BUFFER(struct S, buffer) = {};36  struct S *s_ptr = (struct S *)buffer;37  return s_ptr->x;38}39 40// CHECK-LABEL: define dso_local signext i8 @bar(41// CHECK-SAME: ) #[[ATTR0]] {42// CHECK-NEXT:  [[ENTRY:.*:]]43// CHECK-NEXT:    [[BUFFER:%.*]] = alloca [12 x i8], align 444// CHECK-NEXT:    [[ARRAYDECAY:%.*]] = getelementptr inbounds [12 x i8], ptr [[BUFFER]], i64 0, i64 045// CHECK-NEXT:    [[C:%.*]] = getelementptr inbounds nuw [[STRUCT_S:%.*]], ptr [[ARRAYDECAY]], i32 0, i32 146// CHECK-NEXT:    store i8 97, ptr [[C]], align 447// CHECK-NEXT:    [[ARRAYDECAY1:%.*]] = getelementptr inbounds [12 x i8], ptr [[BUFFER]], i64 0, i64 048// CHECK-NEXT:    [[C2:%.*]] = getelementptr inbounds nuw [[STRUCT_S]], ptr [[ARRAYDECAY1]], i32 0, i32 149// CHECK-NEXT:    [[TMP0:%.*]] = load i8, ptr [[C2]], align 450// CHECK-NEXT:    ret i8 [[TMP0]]51//52char bar() {53  DECL_BUFFER(struct S, buffer);54  ((struct S *)buffer)->c = 'a';55  return ((struct S *)buffer)->c;56}57 58// CHECK-LABEL: define dso_local float @baz(59// CHECK-SAME: ) #[[ATTR0]] {60// CHECK-NEXT:  [[ENTRY:.*:]]61// CHECK-NEXT:    [[BUFFER:%.*]] = alloca [12 x i8], align 462// CHECK-NEXT:    [[ARRAYDECAY:%.*]] = getelementptr inbounds [12 x i8], ptr [[BUFFER]], i64 0, i64 063// CHECK-NEXT:    [[F:%.*]] = getelementptr inbounds nuw [[STRUCT_S:%.*]], ptr [[ARRAYDECAY]], i32 0, i32 264// CHECK-NEXT:    store float 3.000000e+00, ptr [[F]], align 465// CHECK-NEXT:    [[ARRAYDECAY1:%.*]] = getelementptr inbounds [12 x i8], ptr [[BUFFER]], i64 0, i64 066// CHECK-NEXT:    [[F2:%.*]] = getelementptr inbounds nuw [[STRUCT_S]], ptr [[ARRAYDECAY1]], i32 0, i32 267// CHECK-NEXT:    [[TMP0:%.*]] = load float, ptr [[F2]], align 468// CHECK-NEXT:    ret float [[TMP0]]69//70float baz() {71  DECL_BUFFER(struct S, buffer);72  ((struct S *)buffer)->f = 3.0f;73  return ((const struct S *)buffer)->f;74}75 76struct T {77  DECL_BUFFER(struct S, buffer);78};79 80// CHECK-LABEL: define dso_local signext i8 @quux(81// CHECK-SAME: ) #[[ATTR0]] {82// CHECK-NEXT:  [[ENTRY:.*:]]83// CHECK-NEXT:    [[T:%.*]] = alloca [[STRUCT_T:%.*]], align 484// CHECK-NEXT:    [[S_PTR:%.*]] = alloca ptr, align 885// CHECK-NEXT:    call void @llvm.memset.p0.i64(ptr align 4 [[T]], i8 0, i64 12, i1 false)86// CHECK-NEXT:    [[BUFFER:%.*]] = getelementptr inbounds nuw [[STRUCT_T]], ptr [[T]], i32 0, i32 087// CHECK-NEXT:    [[ARRAYDECAY:%.*]] = getelementptr inbounds [12 x i8], ptr [[BUFFER]], i64 0, i64 088// CHECK-NEXT:    store ptr [[ARRAYDECAY]], ptr [[S_PTR]], align 889// CHECK-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[S_PTR]], align 890// CHECK-NEXT:    [[C:%.*]] = getelementptr inbounds nuw [[STRUCT_S:%.*]], ptr [[TMP0]], i32 0, i32 191// CHECK-NEXT:    [[TMP1:%.*]] = load i8, ptr [[C]], align 492// CHECK-NEXT:    ret i8 [[TMP1]]93//94char quux() {95  struct T t = {};96  struct S *s_ptr = (struct S *)t.buffer;97  return s_ptr->c;98}99 100// CHECK-LABEL: define dso_local float @quibble(101// CHECK-SAME: ) #[[ATTR0]] {102// CHECK-NEXT:  [[ENTRY:.*:]]103// CHECK-NEXT:    [[BUFFER:%.*]] = alloca [12 x i8], align 4104// CHECK-NEXT:    [[T_PTR:%.*]] = alloca ptr, align 8105// CHECK-NEXT:    [[S_PTR:%.*]] = alloca ptr, align 8106// CHECK-NEXT:    call void @llvm.memset.p0.i64(ptr align 4 [[BUFFER]], i8 0, i64 12, i1 false)107// CHECK-NEXT:    [[ARRAYDECAY:%.*]] = getelementptr inbounds [12 x i8], ptr [[BUFFER]], i64 0, i64 0108// CHECK-NEXT:    store ptr [[ARRAYDECAY]], ptr [[T_PTR]], align 8109// CHECK-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[T_PTR]], align 8110// CHECK-NEXT:    [[BUFFER1:%.*]] = getelementptr inbounds nuw [[STRUCT_T:%.*]], ptr [[TMP0]], i32 0, i32 0111// CHECK-NEXT:    [[ARRAYDECAY2:%.*]] = getelementptr inbounds [12 x i8], ptr [[BUFFER1]], i64 0, i64 0112// CHECK-NEXT:    store ptr [[ARRAYDECAY2]], ptr [[S_PTR]], align 8113// CHECK-NEXT:    [[TMP1:%.*]] = load ptr, ptr [[S_PTR]], align 8114// CHECK-NEXT:    [[F:%.*]] = getelementptr inbounds nuw [[STRUCT_S:%.*]], ptr [[TMP1]], i32 0, i32 2115// CHECK-NEXT:    [[TMP2:%.*]] = load float, ptr [[F]], align 4116// CHECK-NEXT:    ret float [[TMP2]]117//118float quibble() {119  DECL_BUFFER(struct T, buffer) = {};120  const struct T *t_ptr = (struct T *)buffer;121  const struct S *s_ptr = (struct S *)t_ptr->buffer;122  return s_ptr->f;123}124 125// CHECK-LABEL: define dso_local i32 @quorble(126// CHECK-SAME: ) #[[ATTR0]] {127// CHECK-NEXT:  [[ENTRY:.*:]]128// CHECK-NEXT:    [[BUFFER:%.*]] = alloca [12 x i8], align 4129// CHECK-NEXT:    [[S_PTR:%.*]] = alloca ptr, align 8130// CHECK-NEXT:    [[ARRAYDECAY:%.*]] = getelementptr inbounds [12 x i8], ptr [[BUFFER]], i64 0, i64 0131// CHECK-NEXT:    [[BUFFER1:%.*]] = getelementptr inbounds nuw [[STRUCT_T:%.*]], ptr [[ARRAYDECAY]], i32 0, i32 0132// CHECK-NEXT:    [[ARRAYDECAY2:%.*]] = getelementptr inbounds [12 x i8], ptr [[BUFFER1]], i64 0, i64 0133// CHECK-NEXT:    [[X:%.*]] = getelementptr inbounds nuw [[STRUCT_S:%.*]], ptr [[ARRAYDECAY2]], i32 0, i32 0134// CHECK-NEXT:    store i32 12, ptr [[X]], align 4135// CHECK-NEXT:    [[ARRAYDECAY3:%.*]] = getelementptr inbounds [12 x i8], ptr [[BUFFER]], i64 0, i64 0136// CHECK-NEXT:    [[BUFFER4:%.*]] = getelementptr inbounds nuw [[STRUCT_T]], ptr [[ARRAYDECAY3]], i32 0, i32 0137// CHECK-NEXT:    [[ARRAYDECAY5:%.*]] = getelementptr inbounds [12 x i8], ptr [[BUFFER4]], i64 0, i64 0138// CHECK-NEXT:    store ptr [[ARRAYDECAY5]], ptr [[S_PTR]], align 8139// CHECK-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[S_PTR]], align 8140// CHECK-NEXT:    [[X6:%.*]] = getelementptr inbounds nuw [[STRUCT_S]], ptr [[TMP0]], i32 0, i32 0141// CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[X6]], align 4142// CHECK-NEXT:    ret i32 [[TMP1]]143//144int quorble() {145  DECL_BUFFER(struct T, buffer);146  ((struct S *)((struct T *)buffer)->buffer)->x = 12;147  const struct S *s_ptr = (struct S *)((struct T *)buffer)->buffer;148  return s_ptr->x;149}150