brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.7 KiB · 305b8c5 Raw
112 lines · cpp
1// RUN: %clang_cc1 -fms-extensions -w -triple i386-pc-win32 -emit-llvm -o - %s | FileCheck %s2 3// PR443954// MSVC passes overaligned types indirectly since MSVC 2015. Make sure that5// works with inalloca.6 7struct NonTrivial {8  NonTrivial();9  NonTrivial(const NonTrivial &o);10  int x;11};12 13struct __declspec(align(64)) OverAligned {14  OverAligned();15  int buf[16];16};17 18struct __declspec(align(8)) Both {19  Both();20  Both(const Both &o);21  int x, y;22};23 24extern int gvi32;25 26int receive_inalloca_overaligned(NonTrivial nt, OverAligned o) {27  return nt.x + o.buf[0];28}29 30// CHECK-LABEL: define dso_local noundef i32 @"?receive_inalloca_overaligned@@Y{{.*}}"31// CHECK-SAME: (ptr inalloca(<{ %struct.NonTrivial, ptr }>) %0)32 33int pass_inalloca_overaligned() {34  gvi32 = receive_inalloca_overaligned(NonTrivial(), OverAligned());35  return gvi32;36}37 38// CHECK-LABEL: define dso_local noundef i32 @"?pass_inalloca_overaligned@@Y{{.*}}"39// CHECK: [[TMP:%[^ ]*]] = alloca %struct.OverAligned, align 6440// CHECK: call ptr @llvm.stacksave.p0()41// CHECK: alloca inalloca <{ %struct.NonTrivial, ptr }>42 43// Construct OverAligned into TMP.44// CHECK: call x86_thiscallcc noundef ptr @"??0OverAligned@@QAE@XZ"(ptr {{[^,]*}} [[TMP]])45 46// Construct NonTrivial into the GEP.47// CHECK: [[GEP:%[^ ]*]] = getelementptr inbounds nuw <{ %struct.NonTrivial, ptr }>, ptr %{{.*}}, i32 0, i32 048// CHECK: call x86_thiscallcc noundef ptr @"??0NonTrivial@@QAE@XZ"(ptr {{[^,]*}} [[GEP]])49 50// Store the address of an OverAligned temporary into the struct.51// CHECK: getelementptr inbounds nuw <{ %struct.NonTrivial, ptr }>, ptr %{{.*}}, i32 0, i32 152// CHECK: store ptr [[TMP]], ptr %{{.*}}, align 453// CHECK: call noundef i32 @"?receive_inalloca_overaligned@@Y{{.*}}"(ptr inalloca(<{ %struct.NonTrivial, ptr }>) %argmem)54 55int receive_both(Both o) {56  return o.x + o.y;57}58 59// CHECK-LABEL: define dso_local noundef i32 @"?receive_both@@Y{{.*}}"60// CHECK-SAME: (ptr dead_on_return noundef %o)61 62int pass_both() {63  gvi32 = receive_both(Both());64  return gvi32;65}66 67// CHECK-LABEL: define dso_local noundef i32 @"?pass_both@@Y{{.*}}"68// CHECK: [[TMP:%[^ ]*]] = alloca %struct.Both, align 869// CHECK: call x86_thiscallcc noundef ptr @"??0Both@@QAE@XZ"(ptr {{[^,]*}} [[TMP]])70// CHECK: call noundef i32 @"?receive_both@@Y{{.*}}"(ptr dead_on_return noundef [[TMP]])71 72int receive_inalloca_both(NonTrivial nt, Both o) {73  return nt.x + o.x + o.y;74}75 76// CHECK-LABEL: define dso_local noundef i32 @"?receive_inalloca_both@@Y{{.*}}"77// CHECK-SAME: (ptr inalloca(<{ %struct.NonTrivial, ptr }>) %0)78 79int pass_inalloca_both() {80  gvi32 = receive_inalloca_both(NonTrivial(), Both());81  return gvi32;82}83 84// CHECK-LABEL: define dso_local noundef i32 @"?pass_inalloca_both@@Y{{.*}}"85// CHECK: [[TMP:%[^ ]*]] = alloca %struct.Both, align 886// CHECK: call x86_thiscallcc noundef ptr @"??0Both@@QAE@XZ"(ptr {{[^,]*}} [[TMP]])87// CHECK: call noundef i32 @"?receive_inalloca_both@@Y{{.*}}"(ptr inalloca(<{ %struct.NonTrivial, ptr }>) %argmem)88 89// Here we have a type that is:90// - overaligned91// - not trivially copyable92// - can be "passed in registers" due to [[trivial_abi]]93// Clang should pass it directly.94struct [[trivial_abi]] alignas(8) MyPtr {95  MyPtr();96  MyPtr(const MyPtr &o);97  ~MyPtr();98  int *ptr;99};100 101int receiveMyPtr(MyPtr o) { return *o.ptr; }102 103// CHECK-LABEL: define dso_local noundef i32 @"?receiveMyPtr@@Y{{.*}}"104// CHECK-SAME: (ptr dead_on_return noundef %o)105 106int passMyPtr() { return receiveMyPtr(MyPtr()); }107 108// CHECK-LABEL: define dso_local noundef i32 @"?passMyPtr@@Y{{.*}}"109// CHECK: [[TMP:%[^ ]*]] = alloca %struct.MyPtr, align 8110// CHECK: call x86_thiscallcc noundef ptr @"??0MyPtr@@QAE@XZ"(ptr {{[^,]*}} [[TMP]])111// CHECK: call noundef i32 @"?receiveMyPtr@@Y{{.*}}"(ptr dead_on_return noundef [[TMP]])112