From cde227bc2a52c6e05c083df47eb08a01a94a09b1 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Tue, 24 Jul 2012 21:40:17 +0000 Subject: [PATCH] In order to correctly compile struct s { double x1; float x2; }; __attribute__((regparm(3))) struct s f(int a, int b, int c); void g(void) { f(41, 42, 43); } We need to be able to represent passing the address of s to f (sret) in a register (inreg). Turns out that all that is needed is to not mark them as mutually incompatible. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@160695 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Attributes.h | 5 +++-- test/CodeGen/X86/inreg.ll | 19 +++++++++++++++++++ 2 files changed, 22 insertions(+), 2 deletions(-) create mode 100644 test/CodeGen/X86/inreg.ll diff --git a/include/llvm/Attributes.h b/include/llvm/Attributes.h index 59fdd993751..0228d8691d2 100644 --- a/include/llvm/Attributes.h +++ b/include/llvm/Attributes.h @@ -165,8 +165,9 @@ const AttrConst FunctionOnly = {NoReturn_i | NoUnwind_i | ReadNone_i | const AttrConst VarArgsIncompatible = {StructRet_i}; /// @brief Attributes that are mutually incompatible. -const AttrConst MutuallyIncompatible[4] = { - {ByVal_i | InReg_i | Nest_i | StructRet_i}, +const AttrConst MutuallyIncompatible[5] = { + {ByVal_i | Nest_i | StructRet_i}, + {ByVal_i | Nest_i | InReg_i }, {ZExt_i | SExt_i}, {ReadNone_i | ReadOnly_i}, {NoInline_i | AlwaysInline_i} diff --git a/test/CodeGen/X86/inreg.ll b/test/CodeGen/X86/inreg.ll new file mode 100644 index 00000000000..89810339a6c --- /dev/null +++ b/test/CodeGen/X86/inreg.ll @@ -0,0 +1,19 @@ +; RUN: llc < %s -march=x86 | FileCheck %s + +%struct.s = type { double, float } + +define void @g() nounwind { +entry: + %tmp = alloca %struct.s, align 4 + call void @f(%struct.s* inreg sret %tmp, i32 inreg 41, i32 inreg 42, i32 43) + ret void + ; CHECK: g: + ; CHECK: subl {{.*}}, %esp + ; CHECK-NEXT: $43, (%esp) + ; CHECK-NEXT: leal 16(%esp), %eax + ; CHECK-NEXT: movl $41, %edx + ; CHECK-NEXT: movl $42, %ecx + ; CHECK-NEXT: calll f +} + +declare void @f(%struct.s* inreg sret, i32 inreg, i32 inreg, i32)