1 // RUN: %clang_cc1 -triple x86_64-apple-darwin -emit-llvm %s -o - | FileCheck %s 2 3 // Capture the type and name so matching later is cleaner. 4 struct CompoundTy { int a; }; 5 // CHECK: @MyCLH = constant [[MY_CLH:[^,]+]] 6 const struct CompoundTy *const MyCLH = &(struct CompoundTy){3}; 7 8 int* a = &(int){1}; 9 struct s {int a, b, c;} * b = &(struct s) {1, 2, 3}; 10 _Complex double * x = &(_Complex double){1.0f}; 11 typedef int v4i32 __attribute((vector_size(16))); 12 v4i32 *y = &(v4i32){1,2,3,4}; 13 14 void xxx() { 15 int* a = &(int){1}; 16 struct s {int a, b, c;} * b = &(struct s) {1, 2, 3}; 17 _Complex double * x = &(_Complex double){1.0f}; 18 } 19 20 // CHECK-LABEL: define void @f() 21 void f() { 22 typedef struct S { int x,y; } S; 23 // CHECK: [[S:%[a-zA-Z0-9.]+]] = alloca [[STRUCT:%[a-zA-Z0-9.]+]], 24 struct S s; 25 // CHECK-NEXT: [[COMPOUNDLIT:%[a-zA-Z0-9.]+]] = alloca [[STRUCT]] 26 // CHECK-NEXT: [[CX:%[a-zA-Z0-9.]+]] = getelementptr inbounds [[STRUCT]], [[STRUCT]]* [[COMPOUNDLIT]], i32 0, i32 0 27 // CHECK-NEXT: [[SY:%[a-zA-Z0-9.]+]] = getelementptr inbounds [[STRUCT]], [[STRUCT]]* [[S]], i32 0, i32 1 28 // CHECK-NEXT: [[TMP:%[a-zA-Z0-9.]+]] = load i32, i32* [[SY]] 29 // CHECK-NEXT: store i32 [[TMP]], i32* [[CX]] 30 // CHECK-NEXT: [[CY:%[a-zA-Z0-9.]+]] = getelementptr inbounds [[STRUCT]], [[STRUCT]]* [[COMPOUNDLIT]], i32 0, i32 1 31 // CHECK-NEXT: [[SX:%[a-zA-Z0-9.]+]] = getelementptr inbounds [[STRUCT]], [[STRUCT]]* [[S]], i32 0, i32 0 32 // CHECK-NEXT: [[TMP:%[a-zA-Z0-9.]+]] = load i32, i32* [[SX]] 33 // CHECK-NEXT: store i32 [[TMP]], i32* [[CY]] 34 // CHECK-NEXT: [[SI8:%[a-zA-Z0-9.]+]] = bitcast [[STRUCT]]* [[S]] to i8* 35 // CHECK-NEXT: [[COMPOUNDLITI8:%[a-zA-Z0-9.]+]] = bitcast [[STRUCT]]* [[COMPOUNDLIT]] to i8* 36 // CHECK-NEXT: call void @llvm.memcpy{{.*}}(i8* align {{[0-9]+}} [[SI8]], i8* align {{[0-9]+}} [[COMPOUNDLITI8]] 37 s = (S){s.y,s.x}; 38 // CHECK-NEXT: ret void 39 } 40 41 // CHECK-LABEL: define i48 @g( 42 struct G { short x, y, z; }; 43 struct G g(int x, int y, int z) { 44 // CHECK: [[RESULT:%.*]] = alloca [[G:%.*]], align 2 45 // CHECK-NEXT: [[X:%.*]] = alloca i32, align 4 46 // CHECK-NEXT: [[Y:%.*]] = alloca i32, align 4 47 // CHECK-NEXT: [[Z:%.*]] = alloca i32, align 4 48 // CHECK-NEXT: [[COERCE_TEMP:%.*]] = alloca i48 49 // CHECK-NEXT: store i32 50 // CHECK-NEXT: store i32 51 // CHECK-NEXT: store i32 52 53 // Evaluate the compound literal directly in the result value slot. 54 // CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[G]], [[G]]* [[RESULT]], i32 0, i32 0 55 // CHECK-NEXT: [[T1:%.*]] = load i32, i32* [[X]], align 4 56 // CHECK-NEXT: [[T2:%.*]] = trunc i32 [[T1]] to i16 57 // CHECK-NEXT: store i16 [[T2]], i16* [[T0]], align 2 58 // CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[G]], [[G]]* [[RESULT]], i32 0, i32 1 59 // CHECK-NEXT: [[T1:%.*]] = load i32, i32* [[Y]], align 4 60 // CHECK-NEXT: [[T2:%.*]] = trunc i32 [[T1]] to i16 61 // CHECK-NEXT: store i16 [[T2]], i16* [[T0]], align 2 62 // CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[G]], [[G]]* [[RESULT]], i32 0, i32 2 63 // CHECK-NEXT: [[T1:%.*]] = load i32, i32* [[Z]], align 4 64 // CHECK-NEXT: [[T2:%.*]] = trunc i32 [[T1]] to i16 65 // CHECK-NEXT: store i16 [[T2]], i16* [[T0]], align 2 66 return (struct G) { x, y, z }; 67 68 // CHECK-NEXT: [[T0:%.*]] = bitcast i48* [[COERCE_TEMP]] to i8* 69 // CHECK-NEXT: [[T1:%.*]] = bitcast [[G]]* [[RESULT]] to i8* 70 // CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align {{[0-9]+}} [[T0]], i8* align {{[0-9]+}} [[T1]], i64 6 71 // CHECK-NEXT: [[T0:%.*]] = load i48, i48* [[COERCE_TEMP]] 72 // CHECK-NEXT: ret i48 [[T0]] 73 } 74 75 // We had a bug where we'd emit a new GlobalVariable for each time we used a 76 // const pointer to a variable initialized by a compound literal. 77 // CHECK-LABEL: define i32 @compareMyCLH() #0 78 int compareMyCLH() { 79 // CHECK: store i8* bitcast ([[MY_CLH]] to i8*) 80 const void *a = MyCLH; 81 // CHECK: store i8* bitcast ([[MY_CLH]] to i8*) 82 const void *b = MyCLH; 83 return a == b; 84 } 85