aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Dunbar <daniel@zuster.org>2009-05-13 18:54:26 +0000
committerDaniel Dunbar <daniel@zuster.org>2009-05-13 18:54:26 +0000
commit7ef455be9beb7a755d815bfbdc38d55d1ce59b86 (patch)
treef8f9659a1e46885813a2e677abe8a98c71b2dd2f
parentff66803b43f2ea9206637dceb793e9505f3b9c48 (diff)
ABI handling: Fix invalid assertion, it is possible for a valid
coercion to be specified which truncates padding bits. It would be nice to still have the assert, but we don't have any API call for the unpadding size of a type yet. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@71695 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/CodeGen/CGCall.cpp22
-rw-r--r--test/CodeGen/x86_32-arguments.c8
-rw-r--r--test/CodeGen/x86_64-arguments.c6
3 files changed, 26 insertions, 10 deletions
diff --git a/lib/CodeGen/CGCall.cpp b/lib/CodeGen/CGCall.cpp
index 072cc58e08..2c89f3f50d 100644
--- a/lib/CodeGen/CGCall.cpp
+++ b/lib/CodeGen/CGCall.cpp
@@ -1578,7 +1578,14 @@ static llvm::Value *CreateCoercedLoad(llvm::Value *SrcPtr,
uint64_t DstSize = CGF.CGM.getTargetData().getTypeAllocSize(Ty);
// If load is legal, just bitcast the src pointer.
- if (SrcSize == DstSize) {
+ if (SrcSize >= DstSize) {
+ // Generally SrcSize is never greater than DstSize, since this
+ // means we are losing bits. However, this can happen in cases
+ // where the structure has additional padding, for example due to
+ // a user specified alignment.
+ //
+ // FIXME: Assert that we aren't truncating non-padding bits when
+ // have access to that information.
llvm::Value *Casted =
CGF.Builder.CreateBitCast(SrcPtr, llvm::PointerType::getUnqual(Ty));
llvm::LoadInst *Load = CGF.Builder.CreateLoad(Casted);
@@ -1586,8 +1593,6 @@ static llvm::Value *CreateCoercedLoad(llvm::Value *SrcPtr,
Load->setAlignment(1);
return Load;
} else {
- assert(SrcSize < DstSize && "Coercion is losing source bits!");
-
// Otherwise do coercion through memory. This is stupid, but
// simple.
llvm::Value *Tmp = CGF.CreateTempAlloca(Ty);
@@ -1617,14 +1622,19 @@ static void CreateCoercedStore(llvm::Value *Src,
uint64_t DstSize = CGF.CGM.getTargetData().getTypeAllocSize(DstTy);
// If store is legal, just bitcast the src pointer.
- if (SrcSize == DstSize) {
+ if (SrcSize >= DstSize) {
+ // Generally SrcSize is never greater than DstSize, since this
+ // means we are losing bits. However, this can happen in cases
+ // where the structure has additional padding, for example due to
+ // a user specified alignment.
+ //
+ // FIXME: Assert that we aren't truncating non-padding bits when
+ // have access to that information.
llvm::Value *Casted =
CGF.Builder.CreateBitCast(DstPtr, llvm::PointerType::getUnqual(SrcTy));
// FIXME: Use better alignment / avoid requiring aligned store.
CGF.Builder.CreateStore(Src, Casted)->setAlignment(1);
} else {
- assert(SrcSize > DstSize && "Coercion is missing bits!");
-
// Otherwise do coercion through memory. This is stupid, but
// simple.
llvm::Value *Tmp = CGF.CreateTempAlloca(SrcTy);
diff --git a/test/CodeGen/x86_32-arguments.c b/test/CodeGen/x86_32-arguments.c
index fae49cbdd8..8980c66b20 100644
--- a/test/CodeGen/x86_32-arguments.c
+++ b/test/CodeGen/x86_32-arguments.c
@@ -131,7 +131,7 @@ struct s29 { struct { } a[1]; char b; char c; } f29(void) {}
struct s30 { char a; char b : 4; } f30(void) {}
// RUN: grep 'define float @f31()' %t &&
-struct s31 { char : 0; float b; char : 0} f31(void) {}
+struct s31 { char : 0; float b; char : 0; } f31(void) {}
// RUN: grep 'define i32 @f32()' %t &&
struct s32 { char a; unsigned : 0; } f32(void) {}
@@ -140,13 +140,13 @@ struct s32 { char a; unsigned : 0; } f32(void) {}
struct s33 { float a; long long : 0; } f33(void) {}
// RUN: grep 'define float @f34()' %t &&
-struct s34 { struct { int : 0 } a; float b; } f34(void) {}
+struct s34 { struct { int : 0; } a; float b; } f34(void) {}
// RUN: grep 'define i16 @f35()' %t &&
-struct s35 { struct { int : 0 } a; char b; char c; } f35(void) {}
+struct s35 { struct { int : 0; } a; char b; char c; } f35(void) {}
// RUN: grep 'define i16 @f36()' %t &&
-struct s36 { struct { int : 0 } a[2][10]; char b; char c; } f36(void) {}
+struct s36 { struct { int : 0; } a[2][10]; char b; char c; } f36(void) {}
// RUN: grep 'define float @f37()' %t &&
struct s37 { float c[1][1]; } f37(void) {}
diff --git a/test/CodeGen/x86_64-arguments.c b/test/CodeGen/x86_64-arguments.c
index 2e5debe7cb..b28e064d35 100644
--- a/test/CodeGen/x86_64-arguments.c
+++ b/test/CodeGen/x86_64-arguments.c
@@ -55,4 +55,10 @@ void f10(struct s10 a0) {}
// RUN: grep 'define void @f11(.union.anon. noalias sret .agg.result)' %t &&
union { long double a; float b; } f11() {}
+// RUN: grep 'define i64 @f12_0()' %t &&
+// RUN: grep 'define void @f12_1(i64)' %t &&
+struct s12 { int a __attribute__((aligned(16))); };
+struct s12 f12_0(void) {}
+void f12_1(struct s12 a0) {}
+
// RUN: true