summaryrefslogtreecommitdiffstats
path: root/llvm
diff options
context:
space:
mode:
authorRafael Espindola <rafael.espindola@gmail.com>2012-07-24 21:40:17 +0000
committerRafael Espindola <rafael.espindola@gmail.com>2012-07-24 21:40:17 +0000
commita44e193a11a5e8aa6fcbe6b4b65638ff2d0b0e26 (patch)
tree978eaac495281610968f9cd662dff0cc910d86f9 /llvm
parent216ac319719179dff3fbac5fa70f3238675dc8cd (diff)
downloadbcm5719-llvm-a44e193a11a5e8aa6fcbe6b4b65638ff2d0b0e26.tar.gz
bcm5719-llvm-a44e193a11a5e8aa6fcbe6b4b65638ff2d0b0e26.zip
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. llvm-svn: 160695
Diffstat (limited to 'llvm')
-rw-r--r--llvm/include/llvm/Attributes.h5
-rw-r--r--llvm/test/CodeGen/X86/inreg.ll19
2 files changed, 22 insertions, 2 deletions
diff --git a/llvm/include/llvm/Attributes.h b/llvm/include/llvm/Attributes.h
index 59fdd993751..0228d8691d2 100644
--- a/llvm/include/llvm/Attributes.h
+++ b/llvm/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/llvm/test/CodeGen/X86/inreg.ll b/llvm/test/CodeGen/X86/inreg.ll
new file mode 100644
index 00000000000..89810339a6c
--- /dev/null
+++ b/llvm/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)
OpenPOWER on IntegriCloud