1 // RUN: %clang_cc1 -fms-extensions -w -triple i386-pc-win32 -emit-llvm -o - %s | FileCheck %s 2 3 // PR44395 4 // MSVC passes overaligned types indirectly since MSVC 2015. Make sure that 5 // works with inalloca. 6 7 // FIXME: Pass non-trivial *and* overaligned types indirectly. Right now the C++ 8 // ABI rules say to use inalloca, and they take precedence, so it's not easy to 9 // implement this. 10 11 12 struct NonTrivial { 13 NonTrivial(); 14 NonTrivial(const NonTrivial &o); 15 int x; 16 }; 17 18 struct __declspec(align(64)) OverAligned { 19 OverAligned(); 20 int buf[16]; 21 }; 22 23 extern int gvi32; 24 25 int receive_inalloca_overaligned(NonTrivial nt, OverAligned o) { 26 return nt.x + o.buf[0]; 27 } 28 29 // CHECK-LABEL: define dso_local i32 @"?receive_inalloca_overaligned@@Y{{.*}}" 30 // CHECK-SAME: (<{ %struct.NonTrivial, %struct.OverAligned* }>* inalloca %0) 31 32 int pass_inalloca_overaligned() { 33 gvi32 = receive_inalloca_overaligned(NonTrivial(), OverAligned()); 34 return gvi32; 35 } 36 37 // CHECK-LABEL: define dso_local i32 @"?pass_inalloca_overaligned@@Y{{.*}}" 38 // CHECK: [[TMP:%[^ ]*]] = alloca %struct.OverAligned, align 64 39 // CHECK: call i8* @llvm.stacksave() 40 // CHECK: alloca inalloca <{ %struct.NonTrivial, %struct.OverAligned* }> 41 42 // Construct OverAligned into TMP. 43 // CHECK: call x86_thiscallcc %struct.OverAligned* @"??0OverAligned@@QAE@XZ"(%struct.OverAligned* [[TMP]]) 44 45 // Construct NonTrivial into the GEP. 46 // CHECK: [[GEP:%[^ ]*]] = getelementptr inbounds <{ %struct.NonTrivial, %struct.OverAligned* }>, <{ %struct.NonTrivial, %struct.OverAligned* }>* %{{.*}}, i32 0, i32 0 47 // CHECK: call x86_thiscallcc %struct.NonTrivial* @"??0NonTrivial@@QAE@XZ"(%struct.NonTrivial* [[GEP]]) 48 49 // Store the address of an OverAligned temporary into the struct. 50 // CHECK: getelementptr inbounds <{ %struct.NonTrivial, %struct.OverAligned* }>, <{ %struct.NonTrivial, %struct.OverAligned* }>* %{{.*}}, i32 0, i32 1 51 // CHECK: store %struct.OverAligned* [[TMP]], %struct.OverAligned** %{{.*}}, align 4 52 // CHECK: call i32 @"?receive_inalloca_overaligned@@Y{{.*}}"(<{ %struct.NonTrivial, %struct.OverAligned* }>* inalloca %argmem) 53