16bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// RUN: %clang_cc1 -triple arm64-apple-ios7 -target-feature +neon -target-abi darwinpcs -ffreestanding -emit-llvm -w -o - %s | FileCheck %s 2651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 3651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define signext i8 @f0() 4651f13cea278ec967336033dd032faef0e9fc2ecStephen Hineschar f0(void) { 5651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return 0; 6651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 7651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 8651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// Struct as return type. Aggregates <= 16 bytes are passed directly and round 9651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// up to multiple of 8 bytes. 10651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define i64 @f1() 11651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct s1 { char f0; }; 12651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct s1 f1(void) {} 13651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 14651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define i64 @f2() 15651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct s2 { short f0; }; 16651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct s2 f2(void) {} 17651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 18651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define i64 @f3() 19651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct s3 { int f0; }; 20651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct s3 f3(void) {} 21651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 22651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define i64 @f4() 23651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct s4 { struct s4_0 { int f0; } f0; }; 24651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct s4 f4(void) {} 25651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 26651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define i64 @f5() 27651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct s5 { struct { } f0; int f1; }; 28651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct s5 f5(void) {} 29651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 30651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define i64 @f6() 31651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct s6 { int f0[1]; }; 32651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct s6 f6(void) {} 33651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 34651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define void @f7() 35651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct s7 { struct { int : 0; } f0; }; 36651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct s7 f7(void) {} 37651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 38651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define void @f8() 39651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct s8 { struct { int : 0; } f0[1]; }; 40651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct s8 f8(void) {} 41651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 42651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define i64 @f9() 43651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct s9 { int f0; int : 0; }; 44651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct s9 f9(void) {} 45651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 46651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define i64 @f10() 47651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct s10 { int f0; int : 0; int : 0; }; 48651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct s10 f10(void) {} 49651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 50651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define i64 @f11() 51651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct s11 { int : 0; int f0; }; 52651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct s11 f11(void) {} 53651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 54651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define i64 @f12() 55651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesunion u12 { char f0; short f1; int f2; }; 56651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesunion u12 f12(void) {} 57651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 58651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// Homogeneous Aggregate as return type will be passed directly. 59651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define %struct.s13 @f13() 60651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct s13 { float f0; }; 61651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct s13 f13(void) {} 62651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define %union.u14 @f14() 63651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesunion u14 { float f0; }; 64651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesunion u14 f14(void) {} 65651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 66651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define void @f15() 67651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesvoid f15(struct s7 a0) {} 68651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 69651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define void @f16() 70651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesvoid f16(struct s8 a0) {} 71651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 72651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define i64 @f17() 73651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct s17 { short f0 : 13; char f1 : 4; }; 74651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct s17 f17(void) {} 75651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 76651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define i64 @f18() 77651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct s18 { short f0; char f1 : 4; }; 78651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct s18 f18(void) {} 79651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 80651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define i64 @f19() 81651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct s19 { int f0; struct s8 f1; }; 82651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct s19 f19(void) {} 83651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 84651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define i64 @f20() 85651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct s20 { struct s8 f1; int f0; }; 86651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct s20 f20(void) {} 87651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 88651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define i64 @f21() 89651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct s21 { struct {} f1; int f0 : 4; }; 90651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct s21 f21(void) {} 91651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 92651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define i64 @f22() 93651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define i64 @f23() 94651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define i64 @f24() 95651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define i128 @f25() 96651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define { float, float } @f26() 97651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define { double, double } @f27() 98651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines_Complex char f22(void) {} 99651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines_Complex short f23(void) {} 100651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines_Complex int f24(void) {} 101651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines_Complex long long f25(void) {} 102651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines_Complex float f26(void) {} 103651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines_Complex double f27(void) {} 104651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 105651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define i64 @f28() 106651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct s28 { _Complex char f0; }; 107651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct s28 f28() {} 108651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 109651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define i64 @f29() 110651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct s29 { _Complex short f0; }; 111651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct s29 f29() {} 112651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 113651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define i64 @f30() 114651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct s30 { _Complex int f0; }; 115651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct s30 f30() {} 116651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 117651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct s31 { char x; }; 118651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesvoid f31(struct s31 s) { } 119651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define void @f31(i64 %s.coerce) 120651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: %s = alloca %struct.s31, align 8 121651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: trunc i64 %s.coerce to i8 122651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: store i8 %{{.*}}, 123651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 124651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct s32 { double x; }; 125651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesvoid f32(struct s32 s) { } 1260e2c34f92f00628d48968dfea096d36381f494cbStephen Hines// CHECK: @f32([1 x double] %{{.*}}) 127651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 128651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// A composite type larger than 16 bytes should be passed indirectly. 129651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct s33 { char buf[32*32]; }; 130651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesvoid f33(struct s33 s) { } 131651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define void @f33(%struct.s33* %s) 132651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 133651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct s34 { char c; }; 134651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesvoid f34(struct s34 s); 135651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesvoid g34(struct s34 *s) { f34(*s); } 136651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: @g34(%struct.s34* %s) 1373ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: %[[a:.*]] = load i8, i8* %{{.*}} 138651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: zext i8 %[[a]] to i64 139651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: call void @f34(i64 %{{.*}}) 140651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 141651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines/* 142651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines * Check that va_arg accesses stack according to ABI alignment 143651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines */ 144651f13cea278ec967336033dd032faef0e9fc2ecStephen Hineslong long t1(int i, ...) { 145651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // CHECK: t1 146651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines __builtin_va_list ap; 147651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines __builtin_va_start(ap, i); 148651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // CHECK-NOT: add i32 %{{.*}} 7 149651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // CHECK-NOT: and i32 %{{.*}} -8 150651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines long long ll = __builtin_va_arg(ap, long long); 151651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines __builtin_va_end(ap); 152651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return ll; 153651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 154651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesdouble t2(int i, ...) { 155651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // CHECK: t2 156651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines __builtin_va_list ap; 157651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines __builtin_va_start(ap, i); 158651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // CHECK-NOT: add i32 %{{.*}} 7 159651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // CHECK-NOT: and i32 %{{.*}} -8 160651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines double ll = __builtin_va_arg(ap, double); 161651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines __builtin_va_end(ap); 162651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return ll; 163651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 164651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 165651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#include <arm_neon.h> 166651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 167651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// Homogeneous Vector Aggregate as return type and argument type. 168651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define %struct.int8x16x2_t @f0_0(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}) 169651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesint8x16x2_t f0_0(int8x16_t a0, int8x16_t a1) { 170651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return vzipq_s8(a0, a1); 171651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 172651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 173651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// Test direct vector passing. 174651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinestypedef float T_float32x2 __attribute__ ((__vector_size__ (8))); 175651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinestypedef float T_float32x4 __attribute__ ((__vector_size__ (16))); 176651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinestypedef float T_float32x8 __attribute__ ((__vector_size__ (32))); 177651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinestypedef float T_float32x16 __attribute__ ((__vector_size__ (64))); 178651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 179651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define <2 x float> @f1_0(<2 x float> %{{.*}}) 180651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesT_float32x2 f1_0(T_float32x2 a0) { return a0; } 181651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define <4 x float> @f1_1(<4 x float> %{{.*}}) 182651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesT_float32x4 f1_1(T_float32x4 a0) { return a0; } 183651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// Vector with length bigger than 16-byte is illegal and is passed indirectly. 184651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define void @f1_2(<8 x float>* noalias sret %{{.*}}, <8 x float>*) 185651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesT_float32x8 f1_2(T_float32x8 a0) { return a0; } 186651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define void @f1_3(<16 x float>* noalias sret %{{.*}}, <16 x float>*) 187651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesT_float32x16 f1_3(T_float32x16 a0) { return a0; } 188651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 189651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// Testing alignment with aggregates: HFA, aggregates with size <= 16 bytes and 190651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// aggregates with size > 16 bytes. 191651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct s35 192651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines{ 193651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines float v[4]; //Testing HFA. 194651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} __attribute__((aligned(16))); 195651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinestypedef struct s35 s35_with_align; 196651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 197651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinestypedef __attribute__((neon_vector_type(4))) float float32x4_t; 198651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesfloat32x4_t f35(int i, s35_with_align s1, s35_with_align s2) { 1990e2c34f92f00628d48968dfea096d36381f494cbStephen Hines// CHECK: define <4 x float> @f35(i32 %i, [4 x float] %s1.coerce, [4 x float] %s2.coerce) 200651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: %s1 = alloca %struct.s35, align 16 201651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: %s2 = alloca %struct.s35, align 16 202651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: %[[a:.*]] = bitcast %struct.s35* %s1 to <4 x float>* 2033ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: load <4 x float>, <4 x float>* %[[a]], align 16 204651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: %[[b:.*]] = bitcast %struct.s35* %s2 to <4 x float>* 2053ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: load <4 x float>, <4 x float>* %[[b]], align 16 206651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines float32x4_t v = vaddq_f32(*(float32x4_t *)&s1, 207651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines *(float32x4_t *)&s2); 208651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return v; 209651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 210651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 211651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct s36 212651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines{ 213651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines int v[4]; //Testing 16-byte aggregate. 214651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} __attribute__((aligned(16))); 215651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinestypedef struct s36 s36_with_align; 216651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 217651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinestypedef __attribute__((neon_vector_type(4))) int int32x4_t; 218651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesint32x4_t f36(int i, s36_with_align s1, s36_with_align s2) { 219651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define <4 x i32> @f36(i32 %i, i128 %s1.coerce, i128 %s2.coerce) 220651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: %s1 = alloca %struct.s36, align 16 221651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: %s2 = alloca %struct.s36, align 16 222651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: store i128 %s1.coerce, i128* %{{.*}}, align 1 223651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: store i128 %s2.coerce, i128* %{{.*}}, align 1 224651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: %[[a:.*]] = bitcast %struct.s36* %s1 to <4 x i32>* 2253ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: load <4 x i32>, <4 x i32>* %[[a]], align 16 226651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: %[[b:.*]] = bitcast %struct.s36* %s2 to <4 x i32>* 2273ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: load <4 x i32>, <4 x i32>* %[[b]], align 16 228651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines int32x4_t v = vaddq_s32(*(int32x4_t *)&s1, 229651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines *(int32x4_t *)&s2); 230651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return v; 231651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 232651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 233651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct s37 234651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines{ 235651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines int v[18]; //Testing large aggregate. 236651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} __attribute__((aligned(16))); 237651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinestypedef struct s37 s37_with_align; 238651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 239651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesint32x4_t f37(int i, s37_with_align s1, s37_with_align s2) { 240651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define <4 x i32> @f37(i32 %i, %struct.s37* %s1, %struct.s37* %s2) 241651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: %[[a:.*]] = bitcast %struct.s37* %s1 to <4 x i32>* 2423ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: load <4 x i32>, <4 x i32>* %[[a]], align 16 243651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: %[[b:.*]] = bitcast %struct.s37* %s2 to <4 x i32>* 2443ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: load <4 x i32>, <4 x i32>* %[[b]], align 16 245651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines int32x4_t v = vaddq_s32(*(int32x4_t *)&s1, 246651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines *(int32x4_t *)&s2); 247651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return v; 248651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 249651f13cea278ec967336033dd032faef0e9fc2ecStephen Hiness37_with_align g37; 250651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesint32x4_t caller37() { 251651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: caller37 252651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: %[[a:.*]] = alloca %struct.s37, align 16 253651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: %[[b:.*]] = alloca %struct.s37, align 16 254651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: call void @llvm.memcpy 255651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: call void @llvm.memcpy 256651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: call <4 x i32> @f37(i32 3, %struct.s37* %[[a]], %struct.s37* %[[b]]) 257651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return f37(3, g37, g37); 258651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 259651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 260651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// rdar://problem/12648441 261651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// Test passing structs with size < 8, < 16 and > 16 262651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// with alignment of 16 and without 263651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 264651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// structs with size <= 8 bytes, without alignment attribute 265651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// passed as i64 regardless of the align attribute 266651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct s38 267651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines{ 268651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines int i; 269651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines short s; 270651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}; 271651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinestypedef struct s38 s38_no_align; 272651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// passing structs in registers 273651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines__attribute__ ((noinline)) 274651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesint f38(int i, s38_no_align s1, s38_no_align s2) { 275651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define i32 @f38(i32 %i, i64 %s1.coerce, i64 %s2.coerce) 276651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: %s1 = alloca %struct.s38, align 8 277651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: %s2 = alloca %struct.s38, align 8 278651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: store i64 %s1.coerce, i64* %{{.*}}, align 1 279651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: store i64 %s2.coerce, i64* %{{.*}}, align 1 2803ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: getelementptr inbounds %struct.s38, %struct.s38* %s1, i32 0, i32 0 2813ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: getelementptr inbounds %struct.s38, %struct.s38* %s2, i32 0, i32 0 2823ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: getelementptr inbounds %struct.s38, %struct.s38* %s1, i32 0, i32 1 2833ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: getelementptr inbounds %struct.s38, %struct.s38* %s2, i32 0, i32 1 284651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return s1.i + s2.i + i + s1.s + s2.s; 285651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 286651f13cea278ec967336033dd032faef0e9fc2ecStephen Hiness38_no_align g38; 287651f13cea278ec967336033dd032faef0e9fc2ecStephen Hiness38_no_align g38_2; 288651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesint caller38() { 289651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define i32 @caller38() 2903ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: %[[a:.*]] = load i64, i64* bitcast (%struct.s38* @g38 to i64*), align 1 2913ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: %[[b:.*]] = load i64, i64* bitcast (%struct.s38* @g38_2 to i64*), align 1 292651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: call i32 @f38(i32 3, i64 %[[a]], i64 %[[b]]) 293651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return f38(3, g38, g38_2); 294651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 295651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// passing structs on stack 296651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines__attribute__ ((noinline)) 297651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesint f38_stack(int i, int i2, int i3, int i4, int i5, int i6, int i7, int i8, 298651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines int i9, s38_no_align s1, s38_no_align s2) { 299651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define i32 @f38_stack(i32 %i, i32 %i2, i32 %i3, i32 %i4, i32 %i5, i32 %i6, i32 %i7, i32 %i8, i32 %i9, i64 %s1.coerce, i64 %s2.coerce) 300651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: %s1 = alloca %struct.s38, align 8 301651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: %s2 = alloca %struct.s38, align 8 302651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: store i64 %s1.coerce, i64* %{{.*}}, align 1 303651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: store i64 %s2.coerce, i64* %{{.*}}, align 1 3043ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: getelementptr inbounds %struct.s38, %struct.s38* %s1, i32 0, i32 0 3053ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: getelementptr inbounds %struct.s38, %struct.s38* %s2, i32 0, i32 0 3063ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: getelementptr inbounds %struct.s38, %struct.s38* %s1, i32 0, i32 1 3073ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: getelementptr inbounds %struct.s38, %struct.s38* %s2, i32 0, i32 1 308651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return s1.i + s2.i + i + i2 + i3 + i4 + i5 + i6 + i7 + i8 + i9 + s1.s + s2.s; 309651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 310651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesint caller38_stack() { 311651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define i32 @caller38_stack() 3123ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: %[[a:.*]] = load i64, i64* bitcast (%struct.s38* @g38 to i64*), align 1 3133ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: %[[b:.*]] = load i64, i64* bitcast (%struct.s38* @g38_2 to i64*), align 1 314651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: call i32 @f38_stack(i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i64 %[[a]], i64 %[[b]]) 315651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return f38_stack(1, 2, 3, 4, 5, 6, 7, 8, 9, g38, g38_2); 316651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 317651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 318651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// structs with size <= 8 bytes, with alignment attribute 319651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct s39 320651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines{ 321651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines int i; 322651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines short s; 323651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} __attribute__((aligned(16))); 324651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinestypedef struct s39 s39_with_align; 325651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// passing aligned structs in registers 326651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines__attribute__ ((noinline)) 327651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesint f39(int i, s39_with_align s1, s39_with_align s2) { 328651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define i32 @f39(i32 %i, i128 %s1.coerce, i128 %s2.coerce) 329651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: %s1 = alloca %struct.s39, align 16 330651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: %s2 = alloca %struct.s39, align 16 331651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: store i128 %s1.coerce, i128* %{{.*}}, align 1 332651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: store i128 %s2.coerce, i128* %{{.*}}, align 1 3333ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: getelementptr inbounds %struct.s39, %struct.s39* %s1, i32 0, i32 0 3343ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: getelementptr inbounds %struct.s39, %struct.s39* %s2, i32 0, i32 0 3353ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: getelementptr inbounds %struct.s39, %struct.s39* %s1, i32 0, i32 1 3363ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: getelementptr inbounds %struct.s39, %struct.s39* %s2, i32 0, i32 1 337651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return s1.i + s2.i + i + s1.s + s2.s; 338651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 339651f13cea278ec967336033dd032faef0e9fc2ecStephen Hiness39_with_align g39; 340651f13cea278ec967336033dd032faef0e9fc2ecStephen Hiness39_with_align g39_2; 341651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesint caller39() { 342651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define i32 @caller39() 3433ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: %[[a:.*]] = load i128, i128* bitcast (%struct.s39* @g39 to i128*), align 1 3443ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: %[[b:.*]] = load i128, i128* bitcast (%struct.s39* @g39_2 to i128*), align 1 345651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: call i32 @f39(i32 3, i128 %[[a]], i128 %[[b]]) 346651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return f39(3, g39, g39_2); 347651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 348651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// passing aligned structs on stack 349651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines__attribute__ ((noinline)) 350651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesint f39_stack(int i, int i2, int i3, int i4, int i5, int i6, int i7, int i8, 351651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines int i9, s39_with_align s1, s39_with_align s2) { 352651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define i32 @f39_stack(i32 %i, i32 %i2, i32 %i3, i32 %i4, i32 %i5, i32 %i6, i32 %i7, i32 %i8, i32 %i9, i128 %s1.coerce, i128 %s2.coerce) 353651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: %s1 = alloca %struct.s39, align 16 354651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: %s2 = alloca %struct.s39, align 16 355651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: store i128 %s1.coerce, i128* %{{.*}}, align 1 356651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: store i128 %s2.coerce, i128* %{{.*}}, align 1 3573ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: getelementptr inbounds %struct.s39, %struct.s39* %s1, i32 0, i32 0 3583ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: getelementptr inbounds %struct.s39, %struct.s39* %s2, i32 0, i32 0 3593ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: getelementptr inbounds %struct.s39, %struct.s39* %s1, i32 0, i32 1 3603ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: getelementptr inbounds %struct.s39, %struct.s39* %s2, i32 0, i32 1 361651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return s1.i + s2.i + i + i2 + i3 + i4 + i5 + i6 + i7 + i8 + i9 + s1.s + s2.s; 362651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 363651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesint caller39_stack() { 364651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define i32 @caller39_stack() 3653ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: %[[a:.*]] = load i128, i128* bitcast (%struct.s39* @g39 to i128*), align 1 3663ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: %[[b:.*]] = load i128, i128* bitcast (%struct.s39* @g39_2 to i128*), align 1 367651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: call i32 @f39_stack(i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i128 %[[a]], i128 %[[b]]) 368651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return f39_stack(1, 2, 3, 4, 5, 6, 7, 8, 9, g39, g39_2); 369651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 370651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 371651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// structs with size <= 16 bytes, without alignment attribute 372651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct s40 373651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines{ 374651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines int i; 375651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines short s; 376651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines int i2; 377651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines short s2; 378651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}; 379651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinestypedef struct s40 s40_no_align; 380651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// passing structs in registers 381651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines__attribute__ ((noinline)) 382651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesint f40(int i, s40_no_align s1, s40_no_align s2) { 383651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define i32 @f40(i32 %i, [2 x i64] %s1.coerce, [2 x i64] %s2.coerce) 384651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: %s1 = alloca %struct.s40, align 8 385651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: %s2 = alloca %struct.s40, align 8 386651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: store [2 x i64] %s1.coerce, [2 x i64]* %{{.*}}, align 1 387651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: store [2 x i64] %s2.coerce, [2 x i64]* %{{.*}}, align 1 3883ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: getelementptr inbounds %struct.s40, %struct.s40* %s1, i32 0, i32 0 3893ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: getelementptr inbounds %struct.s40, %struct.s40* %s2, i32 0, i32 0 3903ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: getelementptr inbounds %struct.s40, %struct.s40* %s1, i32 0, i32 1 3913ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: getelementptr inbounds %struct.s40, %struct.s40* %s2, i32 0, i32 1 392651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return s1.i + s2.i + i + s1.s + s2.s; 393651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 394651f13cea278ec967336033dd032faef0e9fc2ecStephen Hiness40_no_align g40; 395651f13cea278ec967336033dd032faef0e9fc2ecStephen Hiness40_no_align g40_2; 396651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesint caller40() { 397651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define i32 @caller40() 3983ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: %[[a:.*]] = load [2 x i64], [2 x i64]* bitcast (%struct.s40* @g40 to [2 x i64]*), align 1 3993ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: %[[b:.*]] = load [2 x i64], [2 x i64]* bitcast (%struct.s40* @g40_2 to [2 x i64]*), align 1 400651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: call i32 @f40(i32 3, [2 x i64] %[[a]], [2 x i64] %[[b]]) 401651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return f40(3, g40, g40_2); 402651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 403651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// passing structs on stack 404651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines__attribute__ ((noinline)) 405651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesint f40_stack(int i, int i2, int i3, int i4, int i5, int i6, int i7, int i8, 406651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines int i9, s40_no_align s1, s40_no_align s2) { 407651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define i32 @f40_stack(i32 %i, i32 %i2, i32 %i3, i32 %i4, i32 %i5, i32 %i6, i32 %i7, i32 %i8, i32 %i9, [2 x i64] %s1.coerce, [2 x i64] %s2.coerce) 408651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: %s1 = alloca %struct.s40, align 8 409651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: %s2 = alloca %struct.s40, align 8 410651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: store [2 x i64] %s1.coerce, [2 x i64]* %{{.*}}, align 1 411651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: store [2 x i64] %s2.coerce, [2 x i64]* %{{.*}}, align 1 4123ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: getelementptr inbounds %struct.s40, %struct.s40* %s1, i32 0, i32 0 4133ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: getelementptr inbounds %struct.s40, %struct.s40* %s2, i32 0, i32 0 4143ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: getelementptr inbounds %struct.s40, %struct.s40* %s1, i32 0, i32 1 4153ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: getelementptr inbounds %struct.s40, %struct.s40* %s2, i32 0, i32 1 416651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return s1.i + s2.i + i + i2 + i3 + i4 + i5 + i6 + i7 + i8 + i9 + s1.s + s2.s; 417651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 418651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesint caller40_stack() { 419651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define i32 @caller40_stack() 4203ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: %[[a:.*]] = load [2 x i64], [2 x i64]* bitcast (%struct.s40* @g40 to [2 x i64]*), align 1 4213ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: %[[b:.*]] = load [2 x i64], [2 x i64]* bitcast (%struct.s40* @g40_2 to [2 x i64]*), align 1 422651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: call i32 @f40_stack(i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, [2 x i64] %[[a]], [2 x i64] %[[b]]) 423651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return f40_stack(1, 2, 3, 4, 5, 6, 7, 8, 9, g40, g40_2); 424651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 425651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 426651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// structs with size <= 16 bytes, with alignment attribute 427651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct s41 428651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines{ 429651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines int i; 430651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines short s; 431651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines int i2; 432651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines short s2; 433651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} __attribute__((aligned(16))); 434651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinestypedef struct s41 s41_with_align; 435651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// passing aligned structs in registers 436651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines__attribute__ ((noinline)) 437651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesint f41(int i, s41_with_align s1, s41_with_align s2) { 438651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define i32 @f41(i32 %i, i128 %s1.coerce, i128 %s2.coerce) 439651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: %s1 = alloca %struct.s41, align 16 440651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: %s2 = alloca %struct.s41, align 16 441651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: store i128 %s1.coerce, i128* %{{.*}}, align 1 442651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: store i128 %s2.coerce, i128* %{{.*}}, align 1 4433ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: getelementptr inbounds %struct.s41, %struct.s41* %s1, i32 0, i32 0 4443ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: getelementptr inbounds %struct.s41, %struct.s41* %s2, i32 0, i32 0 4453ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: getelementptr inbounds %struct.s41, %struct.s41* %s1, i32 0, i32 1 4463ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: getelementptr inbounds %struct.s41, %struct.s41* %s2, i32 0, i32 1 447651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return s1.i + s2.i + i + s1.s + s2.s; 448651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 449651f13cea278ec967336033dd032faef0e9fc2ecStephen Hiness41_with_align g41; 450651f13cea278ec967336033dd032faef0e9fc2ecStephen Hiness41_with_align g41_2; 451651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesint caller41() { 452651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define i32 @caller41() 4533ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: %[[a:.*]] = load i128, i128* bitcast (%struct.s41* @g41 to i128*), align 1 4543ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: %[[b:.*]] = load i128, i128* bitcast (%struct.s41* @g41_2 to i128*), align 1 455651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: call i32 @f41(i32 3, i128 %[[a]], i128 %[[b]]) 456651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return f41(3, g41, g41_2); 457651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 458651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// passing aligned structs on stack 459651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines__attribute__ ((noinline)) 460651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesint f41_stack(int i, int i2, int i3, int i4, int i5, int i6, int i7, int i8, 461651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines int i9, s41_with_align s1, s41_with_align s2) { 462651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define i32 @f41_stack(i32 %i, i32 %i2, i32 %i3, i32 %i4, i32 %i5, i32 %i6, i32 %i7, i32 %i8, i32 %i9, i128 %s1.coerce, i128 %s2.coerce) 463651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: %s1 = alloca %struct.s41, align 16 464651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: %s2 = alloca %struct.s41, align 16 465651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: store i128 %s1.coerce, i128* %{{.*}}, align 1 466651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: store i128 %s2.coerce, i128* %{{.*}}, align 1 4673ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: getelementptr inbounds %struct.s41, %struct.s41* %s1, i32 0, i32 0 4683ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: getelementptr inbounds %struct.s41, %struct.s41* %s2, i32 0, i32 0 4693ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: getelementptr inbounds %struct.s41, %struct.s41* %s1, i32 0, i32 1 4703ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: getelementptr inbounds %struct.s41, %struct.s41* %s2, i32 0, i32 1 471651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return s1.i + s2.i + i + i2 + i3 + i4 + i5 + i6 + i7 + i8 + i9 + s1.s + s2.s; 472651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 473651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesint caller41_stack() { 474651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define i32 @caller41_stack() 4753ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: %[[a:.*]] = load i128, i128* bitcast (%struct.s41* @g41 to i128*), align 1 4763ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: %[[b:.*]] = load i128, i128* bitcast (%struct.s41* @g41_2 to i128*), align 1 477651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: call i32 @f41_stack(i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i128 %[[a]], i128 %[[b]]) 478651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return f41_stack(1, 2, 3, 4, 5, 6, 7, 8, 9, g41, g41_2); 479651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 480651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 481651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// structs with size > 16 bytes, without alignment attribute 482651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct s42 483651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines{ 484651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines int i; 485651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines short s; 486651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines int i2; 487651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines short s2; 488651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines int i3; 489651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines short s3; 490651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}; 491651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinestypedef struct s42 s42_no_align; 492651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// passing structs in registers 493651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines__attribute__ ((noinline)) 494651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesint f42(int i, s42_no_align s1, s42_no_align s2) { 495651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define i32 @f42(i32 %i, %struct.s42* %s1, %struct.s42* %s2) 4963ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: getelementptr inbounds %struct.s42, %struct.s42* %s1, i32 0, i32 0 4973ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: getelementptr inbounds %struct.s42, %struct.s42* %s2, i32 0, i32 0 4983ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: getelementptr inbounds %struct.s42, %struct.s42* %s1, i32 0, i32 1 4993ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: getelementptr inbounds %struct.s42, %struct.s42* %s2, i32 0, i32 1 500651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return s1.i + s2.i + i + s1.s + s2.s; 501651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 502651f13cea278ec967336033dd032faef0e9fc2ecStephen Hiness42_no_align g42; 503651f13cea278ec967336033dd032faef0e9fc2ecStephen Hiness42_no_align g42_2; 504651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesint caller42() { 505651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define i32 @caller42() 506651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: %[[a:.*]] = alloca %struct.s42, align 4 507651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: %[[b:.*]] = alloca %struct.s42, align 4 508651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: %[[c:.*]] = bitcast %struct.s42* %[[a]] to i8* 509651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64 510651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: %[[d:.*]] = bitcast %struct.s42* %[[b]] to i8* 511651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64 512651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: call i32 @f42(i32 3, %struct.s42* %[[a]], %struct.s42* %[[b]]) 513651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return f42(3, g42, g42_2); 514651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 515651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// passing structs on stack 516651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines__attribute__ ((noinline)) 517651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesint f42_stack(int i, int i2, int i3, int i4, int i5, int i6, int i7, int i8, 518651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines int i9, s42_no_align s1, s42_no_align s2) { 519651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define i32 @f42_stack(i32 %i, i32 %i2, i32 %i3, i32 %i4, i32 %i5, i32 %i6, i32 %i7, i32 %i8, i32 %i9, %struct.s42* %s1, %struct.s42* %s2) 5203ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: getelementptr inbounds %struct.s42, %struct.s42* %s1, i32 0, i32 0 5213ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: getelementptr inbounds %struct.s42, %struct.s42* %s2, i32 0, i32 0 5223ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: getelementptr inbounds %struct.s42, %struct.s42* %s1, i32 0, i32 1 5233ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: getelementptr inbounds %struct.s42, %struct.s42* %s2, i32 0, i32 1 524651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return s1.i + s2.i + i + i2 + i3 + i4 + i5 + i6 + i7 + i8 + i9 + s1.s + s2.s; 525651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 526651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesint caller42_stack() { 527651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define i32 @caller42_stack() 528651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: %[[a:.*]] = alloca %struct.s42, align 4 529651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: %[[b:.*]] = alloca %struct.s42, align 4 530651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: %[[c:.*]] = bitcast %struct.s42* %[[a]] to i8* 531651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64 532651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: %[[d:.*]] = bitcast %struct.s42* %[[b]] to i8* 533651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64 534651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: call i32 @f42_stack(i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, %struct.s42* %[[a]], %struct.s42* %[[b]]) 535651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return f42_stack(1, 2, 3, 4, 5, 6, 7, 8, 9, g42, g42_2); 536651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 537651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 538651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// structs with size > 16 bytes, with alignment attribute 539651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct s43 540651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines{ 541651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines int i; 542651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines short s; 543651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines int i2; 544651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines short s2; 545651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines int i3; 546651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines short s3; 547651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} __attribute__((aligned(16))); 548651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinestypedef struct s43 s43_with_align; 549651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// passing aligned structs in registers 550651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines__attribute__ ((noinline)) 551651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesint f43(int i, s43_with_align s1, s43_with_align s2) { 552651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define i32 @f43(i32 %i, %struct.s43* %s1, %struct.s43* %s2) 5533ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: getelementptr inbounds %struct.s43, %struct.s43* %s1, i32 0, i32 0 5543ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: getelementptr inbounds %struct.s43, %struct.s43* %s2, i32 0, i32 0 5553ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: getelementptr inbounds %struct.s43, %struct.s43* %s1, i32 0, i32 1 5563ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: getelementptr inbounds %struct.s43, %struct.s43* %s2, i32 0, i32 1 557651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return s1.i + s2.i + i + s1.s + s2.s; 558651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 559651f13cea278ec967336033dd032faef0e9fc2ecStephen Hiness43_with_align g43; 560651f13cea278ec967336033dd032faef0e9fc2ecStephen Hiness43_with_align g43_2; 561651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesint caller43() { 562651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define i32 @caller43() 563651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: %[[a:.*]] = alloca %struct.s43, align 16 564651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: %[[b:.*]] = alloca %struct.s43, align 16 565651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: %[[c:.*]] = bitcast %struct.s43* %[[a]] to i8* 566651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64 567651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: %[[d:.*]] = bitcast %struct.s43* %[[b]] to i8* 568651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64 569651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: call i32 @f43(i32 3, %struct.s43* %[[a]], %struct.s43* %[[b]]) 570651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return f43(3, g43, g43_2); 571651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 572651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// passing aligned structs on stack 573651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines__attribute__ ((noinline)) 574651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesint f43_stack(int i, int i2, int i3, int i4, int i5, int i6, int i7, int i8, 575651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines int i9, s43_with_align s1, s43_with_align s2) { 576651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define i32 @f43_stack(i32 %i, i32 %i2, i32 %i3, i32 %i4, i32 %i5, i32 %i6, i32 %i7, i32 %i8, i32 %i9, %struct.s43* %s1, %struct.s43* %s2) 5773ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: getelementptr inbounds %struct.s43, %struct.s43* %s1, i32 0, i32 0 5783ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: getelementptr inbounds %struct.s43, %struct.s43* %s2, i32 0, i32 0 5793ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: getelementptr inbounds %struct.s43, %struct.s43* %s1, i32 0, i32 1 5803ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: getelementptr inbounds %struct.s43, %struct.s43* %s2, i32 0, i32 1 581651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return s1.i + s2.i + i + i2 + i3 + i4 + i5 + i6 + i7 + i8 + i9 + s1.s + s2.s; 582651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 583651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesint caller43_stack() { 584651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define i32 @caller43_stack() 585651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: %[[a:.*]] = alloca %struct.s43, align 16 586651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: %[[b:.*]] = alloca %struct.s43, align 16 587651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: %[[c:.*]] = bitcast %struct.s43* %[[a]] to i8* 588651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64 589651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: %[[d:.*]] = bitcast %struct.s43* %[[b]] to i8* 590651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64 591651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: call i32 @f43_stack(i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, %struct.s43* %[[a]], %struct.s43* %[[b]]) 592651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return f43_stack(1, 2, 3, 4, 5, 6, 7, 8, 9, g43, g43_2); 593651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 594651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 595651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// rdar://13668927 596651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// We should not split argument s1 between registers and stack. 597651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines__attribute__ ((noinline)) 598651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesint f40_split(int i, int i2, int i3, int i4, int i5, int i6, int i7, 599651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines s40_no_align s1, s40_no_align s2) { 6000e2c34f92f00628d48968dfea096d36381f494cbStephen Hines// CHECK: define i32 @f40_split(i32 %i, i32 %i2, i32 %i3, i32 %i4, i32 %i5, i32 %i6, i32 %i7, [2 x i64] %s1.coerce, [2 x i64] %s2.coerce) 601651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return s1.i + s2.i + i + i2 + i3 + i4 + i5 + i6 + i7 + s1.s + s2.s; 602651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 603651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesint caller40_split() { 604651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define i32 @caller40_split() 6050e2c34f92f00628d48968dfea096d36381f494cbStephen Hines// CHECK: call i32 @f40_split(i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, [2 x i64] %{{.*}} [2 x i64] %{{.*}}) 606651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return f40_split(1, 2, 3, 4, 5, 6, 7, g40, g40_2); 607651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 608651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 609651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines__attribute__ ((noinline)) 610651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesint f41_split(int i, int i2, int i3, int i4, int i5, int i6, int i7, 611651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines s41_with_align s1, s41_with_align s2) { 6120e2c34f92f00628d48968dfea096d36381f494cbStephen Hines// CHECK: define i32 @f41_split(i32 %i, i32 %i2, i32 %i3, i32 %i4, i32 %i5, i32 %i6, i32 %i7, i128 %s1.coerce, i128 %s2.coerce) 613651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return s1.i + s2.i + i + i2 + i3 + i4 + i5 + i6 + i7 + s1.s + s2.s; 614651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 615651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesint caller41_split() { 616651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: define i32 @caller41_split() 6170e2c34f92f00628d48968dfea096d36381f494cbStephen Hines// CHECK: call i32 @f41_split(i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i128 %{{.*}}, i128 %{{.*}}) 618651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return f41_split(1, 2, 3, 4, 5, 6, 7, g41, g41_2); 619651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 620651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 621651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// Handle homogeneous aggregates properly in variadic functions. 622651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct HFA { 623651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines float a, b, c, d; 624651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}; 625651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 626651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesfloat test_hfa(int n, ...) { 627651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK-LABEL: define float @test_hfa(i32 %n, ...) 628651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: [[THELIST:%.*]] = alloca i8* 6293ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: [[CURLIST:%.*]] = load i8*, i8** [[THELIST]] 630651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 631651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // HFA is not indirect, so occupies its full 16 bytes on the stack. 6323ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: [[NEXTLIST:%.*]] = getelementptr i8, i8* [[CURLIST]], i32 16 633651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: store i8* [[NEXTLIST]], i8** [[THELIST]] 634651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 635651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: bitcast i8* [[CURLIST]] to %struct.HFA* 636651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines __builtin_va_list thelist; 637651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines __builtin_va_start(thelist, n); 638651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines struct HFA h = __builtin_va_arg(thelist, struct HFA); 639651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return h.d; 640651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 641651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 6426bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesfloat test_hfa_call(struct HFA *a) { 6436bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// CHECK-LABEL: define float @test_hfa_call(%struct.HFA* %a) 64433337ca4d89605025818daf83390ab4271d598d9Pirama Arumuga Nainar// CHECK: call float (i32, ...) @test_hfa(i32 1, [4 x float] {{.*}}) 6456bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines test_hfa(1, *a); 6466bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines} 6476bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 648651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct TooBigHFA { 649651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines float a, b, c, d, e; 650651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}; 651651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 652651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesfloat test_toobig_hfa(int n, ...) { 653651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK-LABEL: define float @test_toobig_hfa(i32 %n, ...) 654651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: [[THELIST:%.*]] = alloca i8* 6553ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: [[CURLIST:%.*]] = load i8*, i8** [[THELIST]] 656651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 657651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // TooBigHFA is not actually an HFA, so gets passed indirectly. Only 8 bytes 658651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // of stack consumed. 6593ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: [[NEXTLIST:%.*]] = getelementptr i8, i8* [[CURLIST]], i32 8 660651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: store i8* [[NEXTLIST]], i8** [[THELIST]] 661651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 662651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: [[HFAPTRPTR:%.*]] = bitcast i8* [[CURLIST]] to i8** 6633ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: [[HFAPTR:%.*]] = load i8*, i8** [[HFAPTRPTR]] 664651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: bitcast i8* [[HFAPTR]] to %struct.TooBigHFA* 665651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines __builtin_va_list thelist; 666651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines __builtin_va_start(thelist, n); 667651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines struct TooBigHFA h = __builtin_va_arg(thelist, struct TooBigHFA); 668651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return h.d; 669651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 670651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 671651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct HVA { 672651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines int32x4_t a, b; 673651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}; 674651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 675651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesint32x4_t test_hva(int n, ...) { 676651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK-LABEL: define <4 x i32> @test_hva(i32 %n, ...) 677651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: [[THELIST:%.*]] = alloca i8* 6783ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: [[CURLIST:%.*]] = load i8*, i8** [[THELIST]] 679651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 680651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // HVA is not indirect, so occupies its full 16 bytes on the stack. but it 681651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // must be properly aligned. 6823ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: [[ALIGN0:%.*]] = getelementptr i8, i8* [[CURLIST]], i32 15 683651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: [[ALIGN1:%.*]] = ptrtoint i8* [[ALIGN0]] to i64 684651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: [[ALIGN2:%.*]] = and i64 [[ALIGN1]], -16 685651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: [[ALIGNED_LIST:%.*]] = inttoptr i64 [[ALIGN2]] to i8* 686651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 6873ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: [[NEXTLIST:%.*]] = getelementptr i8, i8* [[ALIGNED_LIST]], i32 32 688651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: store i8* [[NEXTLIST]], i8** [[THELIST]] 689651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 690651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: bitcast i8* [[ALIGNED_LIST]] to %struct.HVA* 691651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines __builtin_va_list thelist; 692651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines __builtin_va_start(thelist, n); 693651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines struct HVA h = __builtin_va_arg(thelist, struct HVA); 694651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return h.b; 695651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 696651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 697651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct TooBigHVA { 698651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines int32x4_t a, b, c, d, e; 699651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}; 700651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 701651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesint32x4_t test_toobig_hva(int n, ...) { 702651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK-LABEL: define <4 x i32> @test_toobig_hva(i32 %n, ...) 703651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: [[THELIST:%.*]] = alloca i8* 7043ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: [[CURLIST:%.*]] = load i8*, i8** [[THELIST]] 705651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 706651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // TooBigHVA is not actually an HVA, so gets passed indirectly. Only 8 bytes 707651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // of stack consumed. 7083ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: [[NEXTLIST:%.*]] = getelementptr i8, i8* [[CURLIST]], i32 8 709651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: store i8* [[NEXTLIST]], i8** [[THELIST]] 710651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 711651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: [[HVAPTRPTR:%.*]] = bitcast i8* [[CURLIST]] to i8** 7123ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar// CHECK: [[HVAPTR:%.*]] = load i8*, i8** [[HVAPTRPTR]] 713651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// CHECK: bitcast i8* [[HVAPTR]] to %struct.TooBigHVA* 714651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines __builtin_va_list thelist; 715651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines __builtin_va_start(thelist, n); 716651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines struct TooBigHVA h = __builtin_va_arg(thelist, struct TooBigHVA); 717651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return h.d; 718651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 719