1; RUN: opt -always-inline -S < %s | FileCheck %s 2; RUN: opt -passes=always-inline -S < %s | FileCheck %s 3 4; We used to misclassify inalloca as a static alloca in the inliner. This only 5; arose with for alwaysinline functions, because the normal inliner refuses to 6; inline such things. 7 8; Generated using this C++ source: 9; struct Foo { 10; Foo(); 11; Foo(const Foo &o); 12; ~Foo(); 13; int a; 14; }; 15; __forceinline void h(Foo o) {} 16; __forceinline void g() { h(Foo()); } 17; void f() { g(); } 18 19; ModuleID = 't.cpp' 20source_filename = "t.cpp" 21target datalayout = "e-m:x-p:32:32-i64:64-f80:32-n8:16:32-a:0:32-S32" 22target triple = "i386-pc-windows-msvc19.0.24210" 23 24%struct.Foo = type { i32 } 25 26declare i8* @llvm.stacksave() 27declare void @llvm.stackrestore(i8*) 28 29declare x86_thiscallcc %struct.Foo* @"\01??0Foo@@QAE@XZ"(%struct.Foo* returned) unnamed_addr 30declare x86_thiscallcc void @"\01??1Foo@@QAE@XZ"(%struct.Foo*) unnamed_addr 31 32define void @f() { 33entry: 34 call void @g() 35 ret void 36} 37 38define internal void @g() alwaysinline { 39entry: 40 %inalloca.save = call i8* @llvm.stacksave() 41 %argmem = alloca inalloca <{ %struct.Foo }>, align 4 42 %0 = getelementptr inbounds <{ %struct.Foo }>, <{ %struct.Foo }>* %argmem, i32 0, i32 0 43 %call = call x86_thiscallcc %struct.Foo* @"\01??0Foo@@QAE@XZ"(%struct.Foo* %0) 44 call void @h(<{ %struct.Foo }>* inalloca %argmem) 45 call void @llvm.stackrestore(i8* %inalloca.save) 46 ret void 47} 48 49; Function Attrs: alwaysinline inlinehint nounwind 50define internal void @h(<{ %struct.Foo }>* inalloca) alwaysinline { 51entry: 52 %o = getelementptr inbounds <{ %struct.Foo }>, <{ %struct.Foo }>* %0, i32 0, i32 0 53 call x86_thiscallcc void @"\01??1Foo@@QAE@XZ"(%struct.Foo* %o) 54 ret void 55} 56 57; CHECK: define void @f() 58; CHECK: %[[STACKSAVE:.*]] = call i8* @llvm.stacksave() 59; CHECK: %[[ARGMEM:.*]] = alloca inalloca <{ %struct.Foo }>, align 4 60; CHECK: %[[GEP1:.*]] = getelementptr inbounds <{ %struct.Foo }>, <{ %struct.Foo }>* %[[ARGMEM]], i32 0, i32 0 61; CHECK: %[[CALL:.*]] = call x86_thiscallcc %struct.Foo* @"\01??0Foo@@QAE@XZ"(%struct.Foo* %[[GEP1]]) 62; CHECK: %[[GEP2:.*]] = getelementptr inbounds <{ %struct.Foo }>, <{ %struct.Foo }>* %[[ARGMEM]], i32 0, i32 0 63; CHECK: call x86_thiscallcc void @"\01??1Foo@@QAE@XZ"(%struct.Foo* %[[GEP2]]) 64; CHECK: call void @llvm.stackrestore(i8* %[[STACKSAVE]]) 65; CHECK: ret void 66