[cfe-commits] r109681 - in /cfe/trunk: lib/CodeGen/TargetInfo.cpp test/CodeGen/x86_64-arguments.c
Chris Lattner
sabre at nondot.org
Wed Jul 28 15:15:08 PDT 2010
Author: lattner
Date: Wed Jul 28 17:15:08 2010
New Revision: 109681
URL: http://llvm.org/viewvc/llvm-project?rev=109681&view=rev
Log:
fix PR7714 by not referencing off the end of a struct when passed by value in
x86-64 abi. This also improves codegen as well. Some refactoring is needed of
this code.
Modified:
cfe/trunk/lib/CodeGen/TargetInfo.cpp
cfe/trunk/test/CodeGen/x86_64-arguments.c
Modified: cfe/trunk/lib/CodeGen/TargetInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/TargetInfo.cpp?rev=109681&r1=109680&r2=109681&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/TargetInfo.cpp (original)
+++ cfe/trunk/lib/CodeGen/TargetInfo.cpp Wed Jul 28 17:15:08 2010
@@ -1112,7 +1112,12 @@
ABIArgInfo X86_64ABIInfo::getCoerceResult(QualType Ty,
const llvm::Type *CoerceTo) const {
- if (CoerceTo->isIntegerTy(64) || isa<llvm::PointerType>(CoerceTo)) {
+ // If this is a pointer passed as a pointer, just pass it directly.
+ if ((isa<llvm::PointerType>(CoerceTo) || CoerceTo->isIntegerTy(64)) &&
+ Ty->hasPointerRepresentation())
+ return ABIArgInfo::getExtend();
+
+ if (isa<llvm::IntegerType>(CoerceTo)) {
// Integer and pointer types will end up in a general purpose
// register.
@@ -1120,10 +1125,12 @@
if (const EnumType *EnumTy = Ty->getAs<EnumType>())
Ty = EnumTy->getDecl()->getIntegerType();
- if (Ty->isIntegralOrEnumerationType() || Ty->hasPointerRepresentation())
+ if (Ty->isIntegralOrEnumerationType())
return (Ty->isPromotableIntegerType() ?
ABIArgInfo::getExtend() : ABIArgInfo::getDirect());
+ // FIXME: Zap this.
+
// If this is a 8/16/32-bit structure that is passed as an int64, then it
// will be passed in the low 8/16/32-bits of a 64-bit GPR, which is the same
// as how an i8/i16/i32 is passed. Coerce to a i8/i16/i32 instead of a i64.
@@ -1320,6 +1327,8 @@
X86_64ABIInfo::Class Lo, Hi;
classify(Ty, 0, Lo, Hi);
+ uint64_t TySizeInBytes = Context.getTypeSizeInChars(Ty).getQuantity();
+
// Check some invariants.
// FIXME: Enforce these by construction.
assert((Hi != Memory || Lo == Memory) && "Invalid memory classification.");
@@ -1351,8 +1360,6 @@
// available register of the sequence %rdi, %rsi, %rdx, %rcx, %r8
// and %r9 is used.
case Integer:
- // It is always safe to classify this as an i64 argument.
- ResType = llvm::Type::getInt64Ty(VMContext);
++neededInt;
// If we can choose a better 8-byte type based on the preferred type, and if
@@ -1361,6 +1368,19 @@
if (isa<llvm::IntegerType>(PrefTypeLo) ||
isa<llvm::PointerType>(PrefTypeLo))
ResType = PrefTypeLo;
+
+ if (ResType == 0) {
+ // It is always safe to classify this as an integer type up to i64 that
+ // isn't larger than the structure.
+ if (TySizeInBytes == 1)
+ ResType = llvm::Type::getInt8Ty(VMContext);
+ else if (TySizeInBytes == 2)
+ ResType = llvm::Type::getInt16Ty(VMContext);
+ else if (TySizeInBytes <= 4)
+ ResType = llvm::Type::getInt32Ty(VMContext);
+ else
+ ResType = llvm::Type::getInt64Ty(VMContext);
+ }
break;
// AMD64-ABI 3.2.3p3: Rule 3. If the class is SSE, the next
@@ -1385,8 +1405,7 @@
case NoClass: break;
case Integer: {
- // It is always safe to classify this as an i64 argument.
- const llvm::Type *HiType = llvm::Type::getInt64Ty(VMContext);
+ const llvm::Type *HiType = 0;
++neededInt;
// If we can choose a better 8-byte type based on the preferred type, and if
@@ -1395,7 +1414,20 @@
if (isa<llvm::IntegerType>(PrefTypeHi) ||
isa<llvm::PointerType>(PrefTypeHi))
HiType = PrefTypeHi;
-
+
+ if (HiType == 0) {
+ // It is always safe to classify this as an integer type up to i64 that
+ // isn't larger than the structure.
+ if (TySizeInBytes == 9)
+ HiType = llvm::Type::getInt8Ty(VMContext);
+ else if (TySizeInBytes == 10)
+ HiType = llvm::Type::getInt16Ty(VMContext);
+ else if (TySizeInBytes <= 12)
+ HiType = llvm::Type::getInt32Ty(VMContext);
+ else
+ HiType = llvm::Type::getInt64Ty(VMContext);
+ }
+
ResType = llvm::StructType::get(VMContext, ResType, HiType, NULL);
break;
}
Modified: cfe/trunk/test/CodeGen/x86_64-arguments.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/x86_64-arguments.c?rev=109681&r1=109680&r2=109681&view=diff
==============================================================================
--- cfe/trunk/test/CodeGen/x86_64-arguments.c (original)
+++ cfe/trunk/test/CodeGen/x86_64-arguments.c Wed Jul 28 17:15:08 2010
@@ -131,3 +131,17 @@
// CHECK: %y = alloca{{.*}}, align 16
+
+// PR7714
+struct f23S {
+ short f0;
+ unsigned f1;
+ int f2;
+};
+
+void f23(int A, struct f23S B) {
+ // CHECK: define void @f23(i32 %A, i64 %B.coerce0, i32 %B.coerce1)
+}
+
+
+
More information about the cfe-commits
mailing list